16
16
17
17
package io .objectbox .internal ;
18
18
19
+ import io .objectbox .BoxStore ;
19
20
import org .greenrobot .essentials .io .IoUtils ;
20
21
22
+ import javax .annotation .Nullable ;
21
23
import java .io .BufferedInputStream ;
22
24
import java .io .BufferedOutputStream ;
25
+ import java .io .BufferedReader ;
23
26
import java .io .File ;
24
27
import java .io .FileOutputStream ;
25
28
import java .io .IOException ;
26
29
import java .io .InputStream ;
30
+ import java .io .InputStreamReader ;
27
31
import java .io .OutputStream ;
28
32
import java .lang .reflect .InvocationTargetException ;
29
33
import java .lang .reflect .Method ;
30
34
import java .net .URL ;
31
35
import java .net .URLConnection ;
32
36
33
- import io .objectbox .BoxStore ;
34
-
35
37
/**
36
38
* Separate class, so we can mock BoxStore.
37
39
*/
@@ -110,7 +112,16 @@ public class NativeLibraryLoader {
110
112
}
111
113
}
112
114
115
+ /**
116
+ * Get CPU architecture of the JVM (Note: this can not be used for Android, Android decides arch on its own
117
+ * and looks for library in appropriately named folder).
118
+ * <p>
119
+ * Note that this may not be the architecture of the actual hardware
120
+ * (e.g. when running a x86 JVM on an amd64 machine).
121
+ */
113
122
private static String getCpuArch () {
123
+ // See https://github.com/openjdk/jdk/blob/master/make/autoconf/platform.m4 for possible values.
124
+ // Note: any CPU architecture starting with "arm" is reported as "arm", aarch64 is reported as "aarch64".
114
125
String osArch = System .getProperty ("os.arch" );
115
126
String cpuArch = null ;
116
127
if (osArch != null ) {
@@ -119,23 +130,22 @@ private static String getCpuArch() {
119
130
cpuArch = "x64" ;
120
131
} else if (osArch .equalsIgnoreCase ("x86" )) {
121
132
cpuArch = "x86" ;
122
- } else if (osArch .startsWith ("arm" )) {
123
- switch (osArch ) {
124
- case "armv7" :
125
- case "armv7l" :
126
- case "armeabi-v7a" : // os.arch "armeabi-v7a" might be Android only, but let's try anyway...
127
- cpuArch = "armv7" ;
128
- break ;
129
- case "arm64-v8a" :
130
- cpuArch = "arm64" ;
131
- break ;
132
- case "armv6" :
133
+ } else if (osArch .equals ("aarch64" )) {
134
+ cpuArch = "arm64" ;
135
+ } else if (osArch .equals ("arm" )) {
136
+ // Decide if ARMv6 or ARMv7 library should be used, need to get actual architecture from OS.
137
+ String cpuArchOSOrNull = getCpuArchOSOrNull ();
138
+ if (cpuArchOSOrNull != null ) {
139
+ String cpuArchOSlower = cpuArchOSOrNull .toLowerCase ();
140
+ if (cpuArchOSlower .startsWith ("armv6" )) {
133
141
cpuArch = "armv6" ;
134
- break ;
135
- default :
136
- cpuArch = "armv6" ; // Lowest version we support
137
- System .err .println ("Unknown os.arch \" " + osArch + "\" - ObjectBox is defaulting to " + cpuArch );
138
- break ;
142
+ } else {
143
+ // ARMv7 or 32-bit ARMv8
144
+ cpuArch = "armv7" ;
145
+ }
146
+ } else {
147
+ cpuArch = "armv7" ;
148
+ System .err .println ("Failed to get arch from OS - ObjectBox is defaulting to " + cpuArch );
139
149
}
140
150
}
141
151
}
@@ -147,6 +157,23 @@ private static String getCpuArch() {
147
157
return cpuArch ;
148
158
}
149
159
160
+ /**
161
+ * Get architecture using operating system tools. Currently only Linux is supported (using uname).
162
+ */
163
+ @ Nullable
164
+ private static String getCpuArchOSOrNull () {
165
+ String archOrNull = null ;
166
+ try {
167
+ // Linux
168
+ Process exec = Runtime .getRuntime ().exec ("uname -m" );
169
+ BufferedReader reader = new BufferedReader (new InputStreamReader (exec .getInputStream ()));
170
+ archOrNull = reader .readLine ();
171
+ reader .close ();
172
+ } catch (Exception ignored ) {
173
+ }
174
+ return archOrNull ;
175
+ }
176
+
150
177
private static void checkUnpackLib (String filename ) {
151
178
String path = "/native/" + filename ;
152
179
URL resource = NativeLibraryLoader .class .getResource (path );
0 commit comments