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.File; 008 009/** 010 * A utility class for detecting and providing platform-specific such as OS and CPU architecture. 011 */ 012public final class RuntimeDetector { 013 private static String filePrefix; 014 private static String fileExtension; 015 private static String filePath; 016 017 private static synchronized void computePlatform() { 018 if (fileExtension != null && filePath != null && filePrefix != null) { 019 return; 020 } 021 022 boolean intel32 = is32BitIntel(); 023 boolean intel64 = is64BitIntel(); 024 boolean arm64 = isArm64(); 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 filePath = "/osx/universal/"; 038 } else if (isLinux()) { 039 filePrefix = "lib"; 040 fileExtension = ".so"; 041 if (intel32) { 042 filePath = "/linux/x86/"; 043 } else if (intel64) { 044 filePath = "/linux/x86-64/"; 045 } else if (isAthena()) { 046 filePath = "/linux/athena/"; 047 } else if (isArm32()) { 048 filePath = "/linux/arm32/"; 049 } else if (arm64) { 050 filePath = "/linux/arm64/"; 051 } else { 052 filePath = "/linux/nativearm/"; 053 } 054 } else { 055 throw new IllegalStateException("Failed to determine OS"); 056 } 057 } 058 059 /** 060 * Get the file prefix for the current system. 061 * 062 * @return The file prefix. 063 */ 064 public static synchronized String getFilePrefix() { 065 computePlatform(); 066 067 return filePrefix; 068 } 069 070 /** 071 * Get the file extension for the current system. 072 * 073 * @return The file extension. 074 */ 075 public static synchronized String getFileExtension() { 076 computePlatform(); 077 078 return fileExtension; 079 } 080 081 /** 082 * Get the platform path for the current system. 083 * 084 * @return The platform path. 085 */ 086 public static synchronized String getPlatformPath() { 087 computePlatform(); 088 089 return filePath; 090 } 091 092 /** 093 * Get the path to the requested resource. 094 * 095 * @param libName Library name. 096 * @return The path to the requested resource. 097 */ 098 public static synchronized String getLibraryResource(String libName) { 099 computePlatform(); 100 101 return filePath + filePrefix + libName + fileExtension; 102 } 103 104 /** 105 * Get the path to the hash to the requested resource. 106 * 107 * @param libName Library name. 108 * @return The path to the hash to the requested resource. 109 */ 110 public static synchronized String getHashLibraryResource(String libName) { 111 computePlatform(); 112 113 return filePath + libName + ".hash"; 114 } 115 116 /** 117 * Check if hardware platform is Athena. 118 * 119 * @return True if hardware platform is Athena. 120 */ 121 public static boolean isAthena() { 122 File runRobotFile = new File("/usr/local/frc/bin/frcRunRobot.sh"); 123 return runRobotFile.exists(); 124 } 125 126 /** 127 * Check if OS is Arm32. 128 * 129 * @return True if OS is Arm32. 130 */ 131 public static boolean isArm32() { 132 String arch = System.getProperty("os.arch"); 133 return "arm".equals(arch) || "arm32".equals(arch); 134 } 135 136 /** 137 * Check if architecture is Arm64. 138 * 139 * @return if architecture is Arm64. 140 */ 141 public static boolean isArm64() { 142 String arch = System.getProperty("os.arch"); 143 return "aarch64".equals(arch) || "arm64".equals(arch); 144 } 145 146 /** 147 * Check if OS is Linux. 148 * 149 * @return if OS is Linux. 150 */ 151 public static boolean isLinux() { 152 return System.getProperty("os.name").startsWith("Linux"); 153 } 154 155 /** 156 * Check if OS is Windows. 157 * 158 * @return if OS is Windows. 159 */ 160 public static boolean isWindows() { 161 return System.getProperty("os.name").startsWith("Windows"); 162 } 163 164 /** 165 * Check if OS is Mac. 166 * 167 * @return if OS is Mac. 168 */ 169 public static boolean isMac() { 170 return System.getProperty("os.name").startsWith("Mac"); 171 } 172 173 /** 174 * Check if OS is 32bit Intel. 175 * 176 * @return if OS is 32bit Intel. 177 */ 178 public static boolean is32BitIntel() { 179 String arch = System.getProperty("os.arch"); 180 return "x86".equals(arch) || "i386".equals(arch); 181 } 182 183 /** 184 * Check if OS is 64bit Intel. 185 * 186 * @return if OS is 64bit Intel. 187 */ 188 public static boolean is64BitIntel() { 189 String arch = System.getProperty("os.arch"); 190 return "amd64".equals(arch) || "x86_64".equals(arch); 191 } 192 193 private RuntimeDetector() {} 194}