Skip to content

Commit

Permalink
Fix architecture detection on macOS so that it reports the machine ar…
Browse files Browse the repository at this point in the history
…chitecture, rather than the JVM's architecture.
  • Loading branch information
adammurdoch committed Oct 16, 2024
1 parent d8d0582 commit 80781b9
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 4 deletions.
33 changes: 31 additions & 2 deletions native-platform/src/main/cpp/posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <sys/utsname.h>
#include <termios.h>
#include <unistd.h>
#include <sys/sysctl.h>

jmethodID fileStatDetailsMethodId;

Expand All @@ -52,10 +53,38 @@ Java_net_rubygrapefruit_platform_internal_jni_NativeLibraryFunctions_getSystemIn
env->SetObjectField(info, osNameField, char_to_java(env, machine_info.sysname, result));
jfieldID osVersionField = env->GetFieldID(infoClass, "osVersion", "Ljava/lang/String;");
env->SetObjectField(info, osVersionField, char_to_java(env, machine_info.release, result));
jfieldID machineArchitectureField = env->GetFieldID(infoClass, "machineArchitecture", "Ljava/lang/String;");
env->SetObjectField(info, machineArchitectureField, char_to_java(env, machine_info.machine, result));
jfieldID hostnameField = env->GetFieldID(infoClass, "hostname", "Ljava/lang/String;");
env->SetObjectField(info, hostnameField, char_to_java(env, machine_info.nodename, result));

jfieldID machineArchitectureField = env->GetFieldID(infoClass, "machineArchitecture", "Ljava/lang/String;");
#ifndef __APPLE__
env->SetObjectField(info, machineArchitectureField, char_to_java(env, machine_info.machine, result));
#else
// On macOS, uname() reports the architecture of the current binary.
// Instead, use a macOS specific sysctl() to query the CPU name, which can be mapped to the architecture
int mib[5];
size_t len = 5;
size_t value_len;
char *value;

if (sysctlnametomib("machdep.cpu.brand_string", mib, &len) != 0) {
mark_failed_with_errno(env, "could not query machine details", result);
return;
}

if (sysctl(mib, len, NULL, &value_len, NULL, 0) != 0) {
mark_failed_with_errno(env, "could not query machine details", result);
return;
}
value = (char*)malloc(value_len);
if (sysctl(mib, len, value, &value_len, NULL, 0) != 0) {
free(value);
mark_failed_with_errno(env, "could not query machine details", result);
return;
}
env->SetObjectField(info, machineArchitectureField, char_to_java(env, value, result));
free(value);
#endif
}

JNIEXPORT void JNICALL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ public String getKernelVersion() {
}

public String getArchitectureName() {
if (osName.startsWith("Darwin")) {
// On macOS, the architecture field contains the CPU name, not the architecture
if (machineArchitecture.startsWith("Apple")) {
return "arm64";
}
if (machineArchitecture.startsWith("Intel")) {
return "x86_64";
}
}
return machineArchitecture;
}

Expand All @@ -43,6 +52,7 @@ public String getHostname() {
}

public Architecture getArchitecture() {
String machineArchitecture = getArchitectureName();
if (machineArchitecture.equals("amd64") || machineArchitecture.equals("x86_64")) {
return Architecture.amd64;
}
Expand All @@ -52,8 +62,7 @@ public Architecture getArchitecture() {
if (machineArchitecture.equals("aarch64") || machineArchitecture.equals("arm64")) {
return Architecture.aarch64;
}
throw new NativeException(String.format("Cannot determine architecture from kernel architecture name '%s'.",
machineArchitecture));
throw new NativeException(String.format("Cannot determine architecture from kernel architecture name '%s'.", machineArchitecture));
}

// Called from native code
Expand Down

0 comments on commit 80781b9

Please sign in to comment.