From 80781b9a8b28ea2ab0e1ec257a6d3629d408814d Mon Sep 17 00:00:00 2001 From: Adam Murdoch Date: Wed, 16 Oct 2024 15:03:33 +1100 Subject: [PATCH] Fix architecture detection on macOS so that it reports the machine architecture, rather than the JVM's architecture. --- native-platform/src/main/cpp/posix.cpp | 33 +++++++++++++++++-- .../platform/internal/MutableSystemInfo.java | 13 ++++++-- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/native-platform/src/main/cpp/posix.cpp b/native-platform/src/main/cpp/posix.cpp index f1c03356..fd69af8a 100644 --- a/native-platform/src/main/cpp/posix.cpp +++ b/native-platform/src/main/cpp/posix.cpp @@ -35,6 +35,7 @@ #include #include #include +#include jmethodID fileStatDetailsMethodId; @@ -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 diff --git a/native-platform/src/main/java/net/rubygrapefruit/platform/internal/MutableSystemInfo.java b/native-platform/src/main/java/net/rubygrapefruit/platform/internal/MutableSystemInfo.java index 707a4e0d..460b32c5 100644 --- a/native-platform/src/main/java/net/rubygrapefruit/platform/internal/MutableSystemInfo.java +++ b/native-platform/src/main/java/net/rubygrapefruit/platform/internal/MutableSystemInfo.java @@ -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; } @@ -43,6 +52,7 @@ public String getHostname() { } public Architecture getArchitecture() { + String machineArchitecture = getArchitectureName(); if (machineArchitecture.equals("amd64") || machineArchitecture.equals("x86_64")) { return Architecture.amd64; } @@ -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