Skip to content

Xcode: Check for multiple `OSX_ARCHITECTURES` on target

hypernovasun requested to merge hypernovasun/cmake:xcode-universal into master

When determining a given target's object directory, also check for its OSX_ARCHITECTURES before resorting to global defaults. This fixes inconsistent object library references when:

  • CMAKE_OSX_ARCHITECTURES is unset or singular
  • but the object library's OSX_ARCHITECTURES property is set to multiple archs
Example

Given:

cmake_minimum_required(VERSION 3.21)

list(APPEND universal_archs "arm64" "x86_64")

# uncommenting below works
#set(CMAKE_OSX_ARCHITECTURES ${universal_archs} CACHE STRING "" FORCE)

project(UniversalBinary)

set(target_arch ${universal_archs})
# changing to INCLUDE works
list(FILTER target_arch EXCLUDE REGEX ${CMAKE_HOST_SYSTEM_PROCESSOR})

file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/a.cpp "
int x = 42;
")

file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/main.cpp "
#include <iostream>
extern int x;
int main(int argc, char** argv)
{
  std::cout << \"meaning of life is \" << x << std::endl;
  return 0;
}
")

# object library is universal
add_library(objlib OBJECT a.cpp)
set_target_properties(objlib PROPERTIES OSX_ARCHITECTURES "${universal_archs}")

add_executable(life main.cpp)
target_link_libraries(life $<TARGET_OBJECTS:objlib>)
set_target_properties(life PROPERTIES OSX_ARCHITECTURES "${target_arch}")
$ cmake --version
cmake version 3.23.0

Make works as expected:

$ cmake -S . -B make -G"Unix Makefiles"
$ cmake --build make

Ninja works as expected:

$ cmake -S . -B ninja -GNinja
$ cmake --build ninja

Xcode is broken:

$ cmake -S . -B xcode -GXcode
$ cmake --build xcode
...
clang++ -target x86_64-apple-macos12.2   // (building for x86_64 but)
...
  xcode/UniversalBinary.build/Debug/objlib.build/Objects-normal/arm64/a.o
                                                                ^^^^^
                                                   // (is looking at arm64 dir)
...
  -o xcode/Debug/life
...
ld: warning: ignoring file cmake/xcode/UniversalBinary.build/Debug/objlib.build/Objects-normal/arm64/a.o
building for macOS-x86_64 but attempting to link with file built for unknown-arm64
Undefined symbols for architecture x86_64:
  "_x", referenced from:
      _main in main.o
...
** BUILD FAILED **
Edited by Brad King

Merge request reports