Skip to content

Commit

Permalink
Merge pull request #344 from gradle/am/macos-arch
Browse files Browse the repository at this point in the history
Fix architecture detection on macOS
  • Loading branch information
adammurdoch authored Oct 22, 2024
2 parents d8d0582 + 80781b9 commit 3809c7f
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 3809c7f

Please sign in to comment.