Search code examples
xcodecmakeapple-m1fat-binaries

CMake + Xcode: how to select arm64 vs x86_64 libraries?


We have a CMake based project targeting Xcode, and must include a precompiled 3rd party library which supplies separate arm64 and x86_64 binaries.

What we have working now is to simply attach both binaries like

add_library( someLib INTERFACE )

add_library( someLib_x64 STATIC IMPORTED )
set_target_properties(
  someLib_x64
  PROPERTIES
    IMPORTED_LOCATION_RELEASE "path/to/x64/libsomeLib.a"
)

add_library( someLib_arm STATIC IMPORTED )
set_target_properties(
  someLib_arm
  PROPERTIES
    IMPORTED_LOCATION_RELEASE "path/to/arm/libsomeLib.a"
)

target_link_libraries(
  someLib
  INTERFACE
    someLib_x64
    someLib_arm
)

This seems to result in a valid compilation for both architectures (building for "Any Mac (Apple Silicon, Intel)"), however it causes a bunch of linker warnings as each architecture complains about the other one.

ld: warning: ignoring file /path/to/x64/libsomeLib.a, building for macOS-arm64 but attempting to link with file built for macOS-x86_64

and vice versa.

What is a more accurate way to do this that avoids linker warnings? I couldn't find an applicable generator expression to change the link path?


Solution

  • Edited, I misunderstood this previously. I think you have 3 options

    • suppress error, the error doesn't affect anything in fact, so the simplist way to
    add_link_option("-w")
    

    to ignore it, or just change link option for the target

    • try the latest cmake concept IMPORTED_TARGET, it looks like perfectly fit your demand, but require new cmake version
    • try to compile an universal library from source code, this is some example change flag or cmake official example, but this looks like need another project for source code of the lib

    UPDATE: ACCEPTED ANSWER: Based on the documentation for IMPORTED_TARGET linked here, it revealed that you can use the symbol $(CURRENT_ARCH) in the library path, which is interpreted by Xcode at link time.

    Works perfectly.