CMAKE_OSX_SYSROOT does not guide compiler selection

The documentation for this variable explains:

Specify the location or name of the macOS platform SDK to be used. CMake uses this value to compute the value of the -isysroot flag or equivalent and to help the find_* commands locate files in the SDK.

However, when determining the real path to the compiler, CMakeDetermineCompiler.cmake is using xcrun -find cc (for example) on Apple platforms. This ignores any SDK preference as specified by CMAKE_OSX_SYSROOT. The SDK will have a settings file which directs xcrun to the toolchain to use with that SDK. What the .cmake code should do is include -sdk ${CMAKE_OSX_SYSROOT} when that variable is set.

It’s worth noting further that as result, you get different build behavior/results when using make/Ninja as the generator, versus using Xcode. Xcode follows the SDK settings to find the compiler from the linked toolchain. I noticed an Xcode generator build doesn’t even encode a CMAKE_C_COMPILER in the cache. I guess it leaves it to xcodebuild to drive that?

Usually, I’ve used DEVELOPER_DIR to guide compiler selection and CMAKE_OSX_SYSROOT for which SDK to compile with. I don’t think that the documentation for that variable really has any effect on compiler detection (which rarely (never?) uses find_* anyways).

The Xcode difference is that Xcode has a slot to say “what compiler to use” while CMake needs to generate command lines on its own for make and ninja.

I’ve learned that this is a facet of the internal SDKs we use for development @Apple. There’s a feature built in to the SDK configuration that guides the compiler selection. I found that I could get the correct behavior by updating

 # Look for a make tool provided by Xcode
  if(CMAKE_HOST_APPLE)
    macro(_query_xcrun compiler_name result_var_keyword result_var)
      if(NOT "x${result_var_keyword}" STREQUAL "xRESULT_VAR")
        message(FATAL_ERROR "Bad arguments to macro")
      endif()
      execute_process(COMMAND xcrun --find ${compiler_name}
        OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE
        ERROR_VARIABLE _xcrun_err)

to add -sdk to the xcrun command line when $CMAKE_OSX_SYSROOT is configured. This is in share/cmake/Modules/CMakeDetermineCompiler.cmake.

I know this only affects a small set of users doing development w/ CMake here but it’d be great to figure out a fix that could be upstreamed.

2 Likes

Does adding the flag work with more generally-available toolchains/SDKs? If so, that seems fine. Note that we support some pretty old Xcode versions (I think), so when that flag started becoming available would be of interest as well.

FYI @brad.king

See CMake Issue 19180 that proposes to remove the macOS compiler unwrapping altogether.

In the meantime, I’d be fine with a change to add -sdk to the unwrapping logic. The sysroot selection should be done before that already, IIRC.

Yes, the behavior for existing, public SDKs should be unchanged.

I’ll look into opening a PR. Thanks!