-
Couldn't load subscription status.
- Fork 288
Adding support for Apple M1 AArch64 Architecture Processor. #150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,11 @@ | ||
| cmake_minimum_required(VERSION 3.0) | ||
|
|
||
| if(APPLE) | ||
| execute_process(COMMAND uname -m OUTPUT_VARIABLE arch OUTPUT_STRIP_TRAILING_WHITESPACE) | ||
| set(HOST_ARCHITECTURE "${arch}") | ||
| string(TOLOWER ${HOST_ARCHITECTURE} HOST_ARCHITECTURE) | ||
| endif() | ||
|
|
||
| # option() honors normal variables. | ||
| # see: https://cmake.org/cmake/help/git-stage/policy/CMP0077.html | ||
| if(POLICY CMP0077) | ||
|
|
@@ -55,16 +61,20 @@ set(PROCESSOR_IS_AARCH64 FALSE) | |
| set(PROCESSOR_IS_X86 FALSE) | ||
| set(PROCESSOR_IS_POWER FALSE) | ||
|
|
||
| if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips") | ||
| set(PROCESSOR_IS_MIPS TRUE) | ||
| elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") | ||
| set(PROCESSOR_IS_ARM TRUE) | ||
| elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64") | ||
| if(HOST_ARCHITECTURE MATCHES "^arm64") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removing the above code, this chunk can be reverted back to original ... with 2 changes as noted below |
||
| set(PROCESSOR_IS_AARCH64 TRUE) | ||
| elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(AMD64|amd64)|(^i.86$)") | ||
| set(PROCESSOR_IS_X86 TRUE) | ||
| elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)") | ||
| set(PROCESSOR_IS_POWER TRUE) | ||
| else() | ||
| if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips") | ||
| set(PROCESSOR_IS_MIPS TRUE) | ||
| elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. swap this and the next |
||
| set(PROCESSOR_IS_ARM TRUE) | ||
| elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. change this to |
||
| set(PROCESSOR_IS_AARCH64 TRUE) | ||
| elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(AMD64|amd64)|(^i.86$)") | ||
| set(PROCESSOR_IS_X86 TRUE) | ||
| elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)") | ||
| set(PROCESSOR_IS_POWER TRUE) | ||
| endif() | ||
| endif() | ||
|
|
||
| macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've been editing things to get this building on M1 (actually Universal) and I had to change the way files are included because generating a project as it stands currently, it'll pick one of the architecture's sets of files to include, but then if you build as universal it obviously does not have the required files for the other architecture. So I changed it locally so that all the files are always included and then added #if per platform in the various platform files. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, and there are also issues with including the libraries because it decides based on the host architecture for some of it (unix_based_hardware_detection) so it can fail to build in those cases too. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah CMake universal builds are a bit of a pain. They are 1 build, making universal targets, so anything done at configure time is probably incorrect. I found that you basically have to move all this stuff ot compile time with ifdefs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. my 2 cents, For universal platform, i don't know if we could/should introduce a "universal" cmake system processor and propagate it accordingly than including everything and using preprocessor everywhere... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The way to build for universal currently means invoking xcodebuild with dual architecture. This is well after cmake has decided which files to include. I know the CMake guys have been doing some work on all this, but its still early days. Think we just have to suck it up for now. Besides, I've always found writing cross-platform code is far easier when its all visible in a project. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I means, instead of adding all files we could simply add files supported by their "universal 2" build, I'm not sure Apple support (mips, ppc, arm, arm64 and x86)...
I think you must talk about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I've tried using that to target a specific target and that's ok, but it does not quite work yet. ie. you can't tell it x86_64;arm64 as it complains. Hence the xcodebuild route. |
||
|
|
@@ -146,7 +156,7 @@ set_property(TARGET cpu_features PROPERTY POSITION_INDEPENDENT_CODE ${BUILD_PIC} | |
| target_include_directories(cpu_features | ||
| PUBLIC $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/cpu_features> | ||
| ) | ||
| if(PROCESSOR_IS_X86) | ||
| if(PROCESSOR_IS_X86 OR PROCESSOR_IS_AARCH64) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know you're following the original code here, but it would make more sense to instead do just a single There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. I'm not great with Cmake yet. I'm sure there will be more changes, but currently it passes the build checks so I'll probably make the change locally and wait on it to submit until we get any more feedback. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My comment here is still valid |
||
| if(APPLE) | ||
| target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME) | ||
| endif() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -146,7 +146,7 @@ flags : aes,avx,cx16,smx,sse4_1,sse4_2,ssse3 | |
| | Android | yes² | yes¹ | yes¹ | yes¹ | N/A | | ||
| | iOS | N/A | not yet | not yet | N/A | N/A | | ||
| | Linux | yes² | yes¹ | yes¹ | yes¹ | yes¹ | | ||
| | MacOs | yes² | N/A | not yet | N/A | no | | ||
| | MacOs | yes² | N/A | yes² | N/A | no | | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since we're modifying this line, let's use |
||
| | Windows | yes² | not yet | not yet | N/A | N/A | | ||
|
|
||
| 1. **Features revealed from Linux.** We gather data from several sources | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,6 +39,10 @@ | |
| #define CPU_FEATURES_ARCH_ARM | ||
| #endif | ||
|
|
||
| #if (defined(__APPLE__) && defined(__arm64__)) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I for one would prefer to join this into the next statement, as |
||
| #define CPU_FEATURES_ARCH_AARCH64 | ||
| #endif | ||
|
|
||
| #if defined(__aarch64__) | ||
| #define CPU_FEATURES_ARCH_AARCH64 | ||
| #endif | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,6 +22,35 @@ | |
| #include "internal/stack_line_reader.h" | ||
| #include "internal/string_view.h" | ||
|
|
||
| // The following includes are necessary to provide SSE detections on pre-AVX | ||
| // microarchitectures. | ||
| #if defined(CPU_FEATURES_OS_DARWIN) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. prefer to join this |
||
| #if !defined(HAVE_SYSCTLBYNAME) | ||
| #error "Darwin needs support for sysctlbyname" | ||
| #endif | ||
| #include <sys/sysctl.h> | ||
| #endif // CPU_FEATURES_OS | ||
|
|
||
| #if defined(CPU_FEATURES_OS_DARWIN) | ||
| #if defined(CPU_FEATURES_MOCK_CPUID_ARM64) | ||
| extern bool GetDarwinSysCtlByName(const char*); | ||
| extern int GetDarwinSysCtlByNameValue(const char*); | ||
| #else // CPU_FEATURES_MOCK_CPUID_ARM64 | ||
| static bool GetDarwinSysCtlByName(const char* name) { | ||
| int enabled; | ||
| size_t enabled_len = sizeof(enabled); | ||
| const int failure = sysctlbyname(name, &enabled, &enabled_len, NULL, 0); | ||
| return failure ? false : enabled; | ||
| } | ||
| static int GetDarwinSysCtlByNameValue(const char* name) { | ||
| int enabled; | ||
| size_t enabled_len = sizeof(enabled); | ||
| const int failure = sysctlbyname(name, &enabled, &enabled_len, NULL, 0); | ||
| return failure ? 0 : enabled; | ||
| } | ||
| #endif | ||
| #endif // CPU_FEATURES_OS_DARWIN | ||
|
|
||
| // Generation of feature's getters/setters functions and kGetters, kSetters, | ||
| // kCpuInfoFlags and kHardwareCapabilities global tables. | ||
| #define DEFINE_TABLE_FEATURES \ | ||
|
|
@@ -125,6 +154,23 @@ Aarch64Info GetAarch64Info(void) { | |
| // /proc/cpuinfo). | ||
| Aarch64Info info = kEmptyAarch64Info; | ||
|
|
||
| #if defined(CPU_FEATURES_OS_DARWIN) | ||
| // Handling Darwin platform through sysctlbyname. | ||
| info.implementer = GetDarwinSysCtlByNameValue("hw.cputype"); | ||
| info.variant = GetDarwinSysCtlByNameValue("hw.cpusubtype"); | ||
| info.part = GetDarwinSysCtlByNameValue("hw.cpufamily"); | ||
| info.revision = GetDarwinSysCtlByNameValue("hw.cpusubfamily"); | ||
|
|
||
| info.features.fp = GetDarwinSysCtlByName("hw.optional.floatingpoint"); | ||
| info.features.fphp = GetDarwinSysCtlByName("hw.optional.neon_hpfp"); | ||
| info.features.sha512 = GetDarwinSysCtlByName("hw.optional.armv8_2_sha512"); | ||
| info.features.atomics = GetDarwinSysCtlByName("hw.optional.armv8_1_atomics"); | ||
| info.features.asimdfhm = GetDarwinSysCtlByName("hw.optional.armv8_2_fhm"); | ||
| info.features.sha3 = GetDarwinSysCtlByName("hw.optional.armv8_2_sha3"); | ||
| info.features.crc32 = GetDarwinSysCtlByName("hw.optional.armv8_crc32"); | ||
|
|
||
| #else | ||
|
|
||
| FillProcCpuInfoData(&info); | ||
| const HardwareCapabilities hwcaps = CpuFeatures_GetHardwareCapabilities(); | ||
| for (size_t i = 0; i < AARCH64_LAST_; ++i) { | ||
|
|
@@ -133,6 +179,8 @@ Aarch64Info GetAarch64Info(void) { | |
| } | ||
| } | ||
|
|
||
| #endif | ||
|
|
||
| return info; | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not the correct location for this code, and at least with CMake 3.21 this code also isn't necessary for Apple ARM64 support;
CMAKE_SYSTEM_PROCESSORis correctly set toarm64just as you're doing here. IDK about prior CMake, except that the variableCMAKE_SYSTEM_PROCESSORhas been around for a long time and seems to represent what you're trying to do here.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the record, CMake as added the M1 support in 3.19 according to https://cmake.org/cmake/help/latest/release/3.19.html#platforms
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While that may be true, still with CMake 3.22.0, I get this build error on an M1 MacBook Pro: