Skip to content

Pass the macOS deployment target to swiftc in Metal builds - #1264

Open
Slymaster wants to merge 1 commit into
lightvector:masterfrom
Slymaster:metal-swift-deployment-target
Open

Slymaster wants to merge 1 commit into
lightvector:masterfrom
Slymaster:metal-swift-deployment-target

Conversation

@Slymaster

Copy link
Copy Markdown

I bundle a Metal build of KataGo in a small macOS app and noticed the binary needed macOS 26, the version of my build Mac, even though CMakeLists.txt sets CMAKE_OSX_DEPLOYMENT_TARGET to 13.0.

The C++ files do get -mmacosx-version-min=13.0, but CMake passes nothing to swiftc, and swiftc is what links katago, so it falls back to the host's version. Passing -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 on the command line doesn't help either.

This adds -target <arch>-apple-macosx13.0 to the Swift flags, unless a -target is already in CMAKE_Swift_FLAGS.

Tested on Apple Silicon only (M2 Max, macOS 26.6.2, Xcode 27.0, CMake 4.4.3), checking minos with otool -l katago:

  • current master: 26.0
  • with this change: 13.0
  • with this change and -DCMAKE_Swift_FLAGS="-target arm64-apple-macosx14.0": 14.0

The 13.0 build runs fine (katago version reports the Metal backend, and katago benchmark works).

CMake gives swiftc no -target, and swiftc links katago, so the binary's minimum macOS was the build machine's version instead of 13.0.
@ChinChangYang

Copy link
Copy Markdown
Contributor

Thanks — I can confirm the diagnosis. CMake (4.4.4 here) has no deployment-target flag for Swift, and swiftc is the link driver, so minos followed the build host.

Tested on M3 Max, macOS 27.2, Xcode 27, CMake 4.4.4, Ninja:

master this PR
minos of katago 27.2 13.0
katago benchmark (b18c384nbt, 8 threads) 192–194 visits/s 186–197 visits/s

Builds cleanly, the Metal backend works, and there's no performance difference.

One gap: add_subdirectory(external/katagocoreml) comes before set(CMAKE_OSX_DEPLOYMENT_TARGET 13.0), so katagocoreml's C++ objects get no -mmacosx-version-min and target the host OS. With this PR, the link shows 44 warnings like:

ld: warning: object file (libkatagocoreml.a(MILBuilder.cpp.o)) was built for newer 'macOS' version (27.2) than being linked (13.0)

So minos reads 13.0, but part of the binary was compiled for 27.2. Moving the subdirectory below the new block fixes it (0 warnings, benchmark unchanged):

@@ -804,7 +804,6 @@ elseif(USE_BACKEND STREQUAL "METAL")
   if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
     message(FATAL_ERROR "Project requires building with AppleClang. Have ${CMAKE_CXX_COMPILER_ID}")
   endif()
-  add_subdirectory(external/katagocoreml)
   list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/external/macos/cmake/modules")
 
   if (NOT CMAKE_OSX_SYSROOT)
@@ -818,6 +817,7 @@ elseif(USE_BACKEND STREQUAL "METAL")
   if(NOT CMAKE_Swift_FLAGS MATCHES "-target ")
     string(APPEND CMAKE_Swift_FLAGS " -target ${CMAKE_SYSTEM_PROCESSOR}-apple-macosx${CMAKE_OSX_DEPLOYMENT_TARGET}")
   endif()
+  add_subdirectory(external/katagocoreml)
   set(NEURALNET_BACKEND_SOURCES
     neuralnet/metalbackend.cpp
     )

Two notes, not blocking:

  • Homebrew dependencies. katago also links Homebrew's protobuf, abseil and libzip from /opt/homebrew, and those dylibs have minos 27.0 here (83 ld warnings). For an app that runs on older macOS, you'll need to bundle builds of these with a deployment target of 13.0 or lower. This PR can't fix that.
  • Target arch. The arch in the target triple comes from CMAKE_SYSTEM_PROCESSOR, which is the host. With -DCMAKE_OSX_ARCHITECTURES=x86_64 on Apple Silicon, C++ gets -arch x86_64 but Swift gets -target arm64-apple-macosx13.0. master already has this mismatch, so it's not a regression. Using CMAKE_OSX_ARCHITECTURES when it holds a single value would cover it. I've only checked this at configure time, not with a full build.

I haven't run the binary on an actual macOS 13 machine.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants