speedb-io / speedb

A RocksDB compliant high performance scalable embedded key-value store
https://www.speedb.io/
Apache License 2.0
856 stars 63 forks source link

Workaround for a Cmake bug that happens when cross-compiling using Cmake on macOS x86_64 CPUs with target CPU arm64 #822

Open shpala opened 5 months ago

shpala commented 5 months ago

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

Cross-compilation of a project that is linked to SpeeDB on an x86_64 CPU with target CPU as arm64 fails after SpeeDB was built using the following command: cmake -G "Unix Makefiles" -DCMAKE_SYSTEM_PROCESSOR=arm64 .. The SpeeDB build itself succeeds, but executable linking with it will return a linking error. This specific issue only happens when cross-compiling on an macOS machine due to a possible Cmake bug that causes CMAKE_SYSTEM_PROCESSOR to be equal to CMAKE_HOST_SYSTEM_PROCESSOR regardless of the value of CMAKE_OSX_ARCHITECTURES, which in turn causes an issue in SpeeDBs own CMakeLists.txt. In my case the issue happened when I was building SpeeDB on x86_64 with a CMAKE_OSX_ARCHITECTURES set to "arm64". Even after manually setting CMAKE_SYSTEM_PROCESSOR with "-DCMAKE_SYSTEM_PROCESSOR=arm64" or even when setting it manually at the top of CMakeLists.txt using set(CMAKE_SYSTEM_PROCESSOR arm64), immediately after the project() call, the CMAKE_SYSTEM_PROCESSOR was reset back to x86_64. The linking error happens, because due to wrong CMAKE_SYSTEM_PROCESSOR, the variable HAS_ARMV8_CRC gets the wrong value. This in turn causes Cmake to skip the source append command of "util/crc32c_arm64.cc".

Expected behavior Successfully compiled executable.

Actual behavior The following linking error: Undefined symbols for architecture arm64: "crc32c_arm64(unsigned int, unsigned char const, unsigned long)", referenced from: speedb::crc32c::ExtendARMImpl(unsigned int, char const, unsigned long) in libspeedb.a(crc32c.cc.o) "crc32c_runtime_check()", referenced from: speedb::crc32c::IsFastCrc32Supported() in libspeedb.a(crc32c.cc.o) GLOBALsub_I_crc32c.cc in libspeedb.a(crc32c.cc.o) "crc32c_pmull_runtime_check()", referenced from: speedb::crc32c::IsFastCrc32Supported() in libspeedb.a(crc32c.cc.o) GLOBALsub_I_crc32c.cc in libspeedb.a(crc32c.cc.o)

nm -C libspeedb.a returns the following: crc32c.cc.o: 0000000000000dfc s GCC_except_table1 0000000000000e20 s GCC_except_table21 0000000000000e4c s GLOBALsub_I_crc32c.cc U __Unwind_Resume U crc32c_arm64(unsigned int, unsigned char const, unsigned long) U crc32c_runtime_check() U crc32c_pmull_runtime_check() 0000000000000860 T speedb::DecodeFixed32(char const)"

Steps to reproduce the behavior Cross-compile a project that is linked to SpeeDB on an x86_64 CPU with target CPU as arm64. cmake -G "Unix Makefiles" -DCMAKE_SYSTEM_PROCESSOR=arm64 ..