From 819341658f777c07e29ba0a198cd9ba949ea7ccc Mon Sep 17 00:00:00 2001 From: Pavel Ferencz Date: Tue, 12 Mar 2024 15:50:40 -0700 Subject: [PATCH] Workaround for an issue with Cmake builds that happens when cross-compiling using Cmake on macOS x86_64 CPUs with target CPU arm64 (#12240) Summary: This is a temporary workaround for Cmake bug that only sets the correct CMAKE_SYSTEM_PROCESSOR for cross-compilation when target CMAKE_SYSTEM_NAME differs from CMAKE_HOST_NAME: https://gitlab.kitware.com/cmake/cmake/-/issues/25640 Fix cross-compilation on macOS x86_64 CPUs with target CPU arm64 by manually setting CMAKE_SYSTEM_PROCESSOR to the cross-compilation target whenever CMAKE_SYSTEM_PROCESSOR doesn't match CMAKE_OSX_ARCHITECTURES after project() call. This is probably a Cmake bug that happens on macOS. Closes https://github.com/facebook/rocksdb/issues/12239 The issue happens when RocksDB is built using the follwoing command: cmake -G "Unix Makefiles" -DCMAKE_SYSTEM_PROCESSOR=arm64 .. The build itself succeeds, but because Cmake wrongly sets CMAKE_SYSTEM_PROCESSOR to x86_64 instead of arm64 and causes crc32c_arm64.cc not to be compiled. This in turn makes the project fails any linking with RocksDB: ``` Undefined symbols for architecture arm64: "crc32c_arm64(unsigned int, unsigned char const*, unsigned long)", referenced from: rocksdb::crc32c::ExtendARMImpl(unsigned int, char const*, unsigned long) in librocksdb.a(crc32c.cc.o) ``` Pull Request resolved: https://github.com/facebook/rocksdb/pull/12240 Reviewed By: cbi42 Differential Revision: D54811365 Pulled By: pdillinger fbshipit-source-id: 0958e3092806dadd2f61d582b7251af13a5f3f06 --- CMakeLists.txt | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 24d0f3ef619..6c59b9b18db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,29 @@ project(rocksdb HOMEPAGE_URL https://rocksdb.org/ LANGUAGES CXX C ASM) +if(APPLE) + # On macOS Cmake, when cross-compiling, sometimes CMAKE_SYSTEM_PROCESSOR wrongfully stays + # the same as CMAKE_HOST_SYSTEM_PROCESSOR regardless the target CPU. + # The manual call to set(CMAKE_SYSTEM_PROCESSOR) has to be set after the project() call. + # because project() might reset CMAKE_SYSTEM_PROCESSOR back to the value of CMAKE_HOST_SYSTEM_PROCESSOR. + # Check if CMAKE_SYSTEM_PROCESSOR is not equal to CMAKE_OSX_ARCHITECTURES + if(NOT CMAKE_OSX_ARCHITECTURES STREQUAL "") + if(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL CMAKE_OSX_ARCHITECTURES) + # Split CMAKE_OSX_ARCHITECTURES into a list + string(REPLACE ";" " " ARCH_LIST ${CMAKE_OSX_ARCHITECTURES}) + separate_arguments(ARCH_LIST UNIX_COMMAND ${ARCH_LIST}) + # Count the number of architectures + list(LENGTH ARCH_LIST ARCH_COUNT) + # Ensure that exactly one architecture is specified + if(NOT ARCH_COUNT EQUAL 1) + message(FATAL_ERROR "CMAKE_OSX_ARCHITECTURES must have exactly one value. Current value: ${CMAKE_OSX_ARCHITECTURES}") + endif() + set(CMAKE_SYSTEM_PROCESSOR ${CMAKE_OSX_ARCHITECTURES}) + message(STATUS "CMAKE_SYSTEM_PROCESSOR is manually set to ${CMAKE_SYSTEM_PROCESSOR}") + endif() + endif() +endif() + if(POLICY CMP0042) cmake_policy(SET CMP0042 NEW) endif()