Xcode: Configuring with '-DCMAKE_OSX_ARCHITECTURES=$(ARCHS_STANDARD)' fails to link object libraries into an executable
cmake_minimum_required(VERSION 3.16)
project(app LANGUAGES CXX)
set(source_my_obj_lib "${CMAKE_BINARY_DIR}/source_my_obj_lib.cpp")
file(GENERATE OUTPUT "${source_my_obj_lib}" CONTENT "void bar() {}")
add_library(actual_my_obj_lib OBJECT ${source_my_obj_lib})
set(app_cpp "${CMAKE_BINARY_DIR}/main.cpp")
file(GENERATE OUTPUT "${app_cpp}" CONTENT "int main() { return 0; }")
add_executable(app ${app_cpp})
target_link_libraries(app PRIVATE "$<TARGET_OBJECTS:actual_my_obj_lib>")
When configuring the project above with
cmake -GXcode .. '-DCMAKE_OSX_ARCHITECTURES=$(ARCHS_STANDARD)'
the application linking step will fail with:
$ xcodebuild
...
Ld /build/app.build/Debug/app.build/Objects-normal/arm64/Binary/app normal arm64 (in target 'app' from project 'app')
cd
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -target arm64-apple-macos10.15 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk -L/build/Debug -F/build/Debug -filelist /build/app.build/Debug/app.build/Objects-normal/arm64/app.LinkFileList -Xlinker -object_path_lto -Xlinker /build/app.build/Debug/app.build/Objects-normal/arm64/app_lto.o -Xlinker -no_deduplicate -Wl,-search_paths_first -Wl,-headerpad_max_install_names /build/app.build/Debug/actual_my_obj_lib.build/Objects-normal/arm64 x86_64/source_my_obj_lib.o -Xlinker -no_adhoc_codesign -Xlinker -dependency_info -Xlinker /build/app.build/Debug/app.build/Objects-normal/arm64/app_dependency_info.dat -o /build/app.build/Debug/app.build/Objects-normal/arm64/Binary/app
clang: error: no such file or directory: 'x86_64/source_my_obj_lib.o'
Note the space in /build/app.build/Debug/actual_my_obj_lib.build/Objects-normal/arm64 x86_64/source_my_obj_lib.o
I believe that happens here https://gitlab.kitware.com/cmake/cmake/-/blob/master/Source/cmGlobalXCodeGenerator.cxx#L4499
because $(ARCHS_STANDARD)
is interpreted as a single architecture value by CMake, and then it expands into a space separated list.
The value of ARCHS_STANDARD
can be seen by running
$ xcodebuild -showBuildSettings | grep ARCHS_STANDARD
ARCHS_STANDARD = arm64 x86_64
When configuring with
cmake -GXcode .. '-DCMAKE_OSX_ARCHITECTURES=x86_64;arm64'
the executable links successfully, because the object files are referred to using $(CURRENT_ARCH)
instead.