1 // Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
2 package org.rocksdb.util;
3 
4 import java.io.File;
5 import java.io.IOException;
6 
7 public class Environment {
8   private static String OS = System.getProperty("os.name").toLowerCase();
9   private static String ARCH = System.getProperty("os.arch").toLowerCase();
10   private static boolean MUSL_LIBC;
11 
12   static {
13     try {
14       final Process p = new ProcessBuilder("/usr/bin/env", "sh", "-c", "ldd /usr/bin/env | grep -q musl").start();
15       MUSL_LIBC = p.waitFor() == 0;
16     } catch (final IOException | InterruptedException e) {
17       MUSL_LIBC = false;
18     }
19   }
20 
isAarch64()21   public static boolean isAarch64() {
22     return ARCH.contains("aarch64");
23   }
24 
isPowerPC()25   public static boolean isPowerPC() {
26     return ARCH.contains("ppc");
27   }
28 
isS390x()29   public static boolean isS390x() {
30     return ARCH.contains("s390x");
31   }
32 
isWindows()33   public static boolean isWindows() {
34     return (OS.contains("win"));
35   }
36 
isFreeBSD()37   public static boolean isFreeBSD() {
38     return (OS.contains("freebsd"));
39   }
40 
isMac()41   public static boolean isMac() {
42     return (OS.contains("mac"));
43   }
44 
isAix()45   public static boolean isAix() {
46     return OS.contains("aix");
47   }
48 
isUnix()49   public static boolean isUnix() {
50     return OS.contains("nix") ||
51         OS.contains("nux");
52   }
53 
isMuslLibc()54   public static boolean isMuslLibc() {
55     return MUSL_LIBC;
56   }
57 
isSolaris()58   public static boolean isSolaris() {
59     return OS.contains("sunos");
60   }
61 
isOpenBSD()62   public static boolean isOpenBSD() {
63     return (OS.contains("openbsd"));
64   }
65 
is64Bit()66   public static boolean is64Bit() {
67     if (ARCH.indexOf("sparcv9") >= 0) {
68       return true;
69     }
70     return (ARCH.indexOf("64") > 0);
71   }
72 
getSharedLibraryName(final String name)73   public static String getSharedLibraryName(final String name) {
74     return name + "jni";
75   }
76 
getSharedLibraryFileName(final String name)77   public static String getSharedLibraryFileName(final String name) {
78     return appendLibOsSuffix("lib" + getSharedLibraryName(name), true);
79   }
80 
81   /**
82    * Get the name of the libc implementation
83    *
84    * @return the name of the implementation,
85    *    or null if the default for that platform (e.g. glibc on Linux).
86    */
getLibcName()87   public static /* @Nullable */ String getLibcName() {
88     if (isMuslLibc()) {
89       return "musl";
90     } else {
91       return null;
92     }
93   }
94 
getLibcPostfix()95   private static String getLibcPostfix() {
96     final String libcName = getLibcName();
97     if (libcName == null) {
98       return "";
99     }
100     return "-" + libcName;
101   }
102 
getJniLibraryName(final String name)103   public static String getJniLibraryName(final String name) {
104     if (isUnix()) {
105       final String arch = is64Bit() ? "64" : "32";
106       if (isPowerPC() || isAarch64()) {
107         return String.format("%sjni-linux-%s%s", name, ARCH, getLibcPostfix());
108       } else if (isS390x()) {
109         return String.format("%sjni-linux%s", name, ARCH);
110       } else {
111         return String.format("%sjni-linux%s%s", name, arch, getLibcPostfix());
112       }
113     } else if (isMac()) {
114       return String.format("%sjni-osx", name);
115     } else if (isFreeBSD()) {
116       return String.format("%sjni-freebsd%s", name, is64Bit() ? "64" : "32");
117     } else if (isAix() && is64Bit()) {
118       return String.format("%sjni-aix64", name);
119     } else if (isSolaris()) {
120       final String arch = is64Bit() ? "64" : "32";
121       return String.format("%sjni-solaris%s", name, arch);
122     } else if (isWindows() && is64Bit()) {
123       return String.format("%sjni-win64", name);
124     } else if (isOpenBSD()) {
125       return String.format("%sjni-openbsd%s", name, is64Bit() ? "64" : "32");
126     }
127 
128     throw new UnsupportedOperationException(String.format("Cannot determine JNI library name for ARCH='%s' OS='%s' name='%s'", ARCH, OS, name));
129   }
130 
getJniLibraryFileName(final String name)131   public static String getJniLibraryFileName(final String name) {
132     return appendLibOsSuffix("lib" + getJniLibraryName(name), false);
133   }
134 
appendLibOsSuffix(final String libraryFileName, final boolean shared)135   private static String appendLibOsSuffix(final String libraryFileName, final boolean shared) {
136     if (isUnix() || isAix() || isSolaris() || isFreeBSD() || isOpenBSD()) {
137       return libraryFileName + ".so";
138     } else if (isMac()) {
139       return libraryFileName + (shared ? ".dylib" : ".jnilib");
140     } else if (isWindows()) {
141       return libraryFileName + ".dll";
142     }
143     throw new UnsupportedOperationException();
144   }
145 
getJniLibraryExtension()146   public static String getJniLibraryExtension() {
147     if (isWindows()) {
148       return ".dll";
149     }
150     return (isMac()) ? ".jnilib" : ".so";
151   }
152 }
153