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