001// Copyright (c) FIRST and other WPILib contributors. 002// Open Source Software; you can modify and/or share it under the terms of 003// the WPILib BSD license file in the root directory of this project. 004 005package edu.wpi.first.util; 006 007import java.io.BufferedReader; 008import java.io.File; 009import java.io.IOException; 010import java.nio.file.Files; 011import java.nio.file.Paths; 012 013public final class RuntimeDetector { 014 private static String filePrefix; 015 private static String fileExtension; 016 private static String filePath; 017 018 private static synchronized void computePlatform() { 019 if (fileExtension != null && filePath != null && filePrefix != null) { 020 return; 021 } 022 023 boolean intel32 = is32BitIntel(); 024 boolean intel64 = is64BitIntel(); 025 026 if (isWindows()) { 027 filePrefix = ""; 028 fileExtension = ".dll"; 029 if (intel32) { 030 filePath = "/windows/x86/"; 031 } else { 032 filePath = "/windows/x86-64/"; 033 } 034 } else if (isMac()) { 035 filePrefix = "lib"; 036 fileExtension = ".dylib"; 037 if (intel32) { 038 filePath = "/osx/x86"; 039 } else { 040 filePath = "/osx/x86-64/"; 041 } 042 } else if (isLinux()) { 043 filePrefix = "lib"; 044 fileExtension = ".so"; 045 if (intel32) { 046 filePath = "/linux/x86/"; 047 } else if (intel64) { 048 filePath = "/linux/x86-64/"; 049 } else if (isAthena()) { 050 filePath = "/linux/athena/"; 051 } else if (isRaspbian()) { 052 filePath = "/linux/raspbian/"; 053 } else if (isAarch64()) { 054 filePath = "/linux/aarch64bionic/"; 055 } else { 056 filePath = "/linux/nativearm/"; 057 } 058 } else { 059 throw new IllegalStateException("Failed to determine OS"); 060 } 061 } 062 063 /** 064 * Get the file prefix for the current system. 065 * 066 * @return The file prefix. 067 */ 068 public static synchronized String getFilePrefix() { 069 computePlatform(); 070 071 return filePrefix; 072 } 073 074 /** 075 * Get the file extension for the current system. 076 * 077 * @return The file extension. 078 */ 079 public static synchronized String getFileExtension() { 080 computePlatform(); 081 082 return fileExtension; 083 } 084 085 /** 086 * Get the platform path for the current system. 087 * 088 * @return The platform path. 089 */ 090 public static synchronized String getPlatformPath() { 091 computePlatform(); 092 093 return filePath; 094 } 095 096 /** 097 * Get the path to the requested resource. 098 * 099 * @param libName Library name. 100 * @return The path to the requested resource. 101 */ 102 public static synchronized String getLibraryResource(String libName) { 103 computePlatform(); 104 105 return filePath + filePrefix + libName + fileExtension; 106 } 107 108 /** 109 * Get the path to the hash to the requested resource. 110 * 111 * @param libName Library name. 112 * @return The path to the hash to the requested resource. 113 */ 114 public static synchronized String getHashLibraryResource(String libName) { 115 computePlatform(); 116 117 return filePath + libName + ".hash"; 118 } 119 120 /** 121 * Check if hardware platform is Athena. 122 * 123 * @return True if hardware platform is Athena. 124 */ 125 public static boolean isAthena() { 126 File runRobotFile = new File("/usr/local/frc/bin/frcRunRobot.sh"); 127 return runRobotFile.exists(); 128 } 129 130 /** 131 * Check if OS is Raspbian. 132 * 133 * @return True if OS is Raspbian. 134 */ 135 public static boolean isRaspbian() { 136 try (BufferedReader reader = Files.newBufferedReader(Paths.get("/etc/os-release"))) { 137 String value = reader.readLine(); 138 if (value == null) { 139 return false; 140 } 141 return value.contains("Raspbian"); 142 } catch (IOException ex) { 143 return false; 144 } 145 } 146 147 /** 148 * check if architecture is aarch64. 149 * 150 * @return if architecture is aarch64 151 */ 152 public static boolean isAarch64() { 153 return "aarch64".equals(System.getProperty("os.arch")); 154 } 155 156 public static boolean isLinux() { 157 return System.getProperty("os.name").startsWith("Linux"); 158 } 159 160 public static boolean isWindows() { 161 return System.getProperty("os.name").startsWith("Windows"); 162 } 163 164 public static boolean isMac() { 165 return System.getProperty("os.name").startsWith("Mac"); 166 } 167 168 public static boolean is32BitIntel() { 169 String arch = System.getProperty("os.arch"); 170 return "x86".equals(arch) || "i386".equals(arch); 171 } 172 173 public static boolean is64BitIntel() { 174 String arch = System.getProperty("os.arch"); 175 return "amd64".equals(arch) || "x86_64".equals(arch); 176 } 177 178 private RuntimeDetector() {} 179}