diff options
-rw-r--r-- | Modules/Platform/Darwin-Initialize.cmake | 79 | ||||
-rw-r--r-- | Source/cmCoreTryCompile.cxx | 3 | ||||
-rw-r--r-- | Source/cmLocalGenerator.cxx | 31 |
3 files changed, 106 insertions, 7 deletions
diff --git a/Modules/Platform/Darwin-Initialize.cmake b/Modules/Platform/Darwin-Initialize.cmake index 1c51ec9..729217c 100644 --- a/Modules/Platform/Darwin-Initialize.cmake +++ b/Modules/Platform/Darwin-Initialize.cmake @@ -133,7 +133,86 @@ function(_apple_resolve_sdk_path sdk_name ret) ) set(${ret} "${_stdout}" PARENT_SCOPE) endfunction() +# Handle multi-arch sysroots. Do this before CMAKE_OSX_SYSROOT is +# transformed into a path, so that we know the sysroot name. +function(_apple_resolve_multi_arch_sysroots) + if(CMAKE_APPLE_ARCH_SYSROOTS) + return() # Already cached + endif() + + list(LENGTH CMAKE_OSX_ARCHITECTURES _num_archs) + if(NOT (_num_archs GREATER 1)) + return() # Only apply to multi-arch + endif() + + if(CMAKE_OSX_SYSROOT STREQUAL "macosx") + # macOS doesn't have a simulator sdk / sysroot, so there is no need to handle per-sdk arches. + return() + endif() + + if(IS_DIRECTORY "${CMAKE_OSX_SYSROOT}") + if(NOT CMAKE_OSX_SYSROOT STREQUAL _CMAKE_OSX_SYSROOT_DEFAULT) + message(WARNING "Can not resolve multi-arch sysroots with CMAKE_OSX_SYSROOT set to path (${CMAKE_OSX_SYSROOT})") + endif() + return() + endif() + + string(REPLACE "os" "simulator" _simulator_sdk ${CMAKE_OSX_SYSROOT}) + set(_sdks "${CMAKE_OSX_SYSROOT};${_simulator_sdk}") + foreach(sdk ${_sdks}) + _apple_resolve_sdk_path(${sdk} _sdk_path) + if(NOT IS_DIRECTORY "${_sdk_path}") + message(WARNING "Failed to resolve SDK path for '${sdk}'") + continue() + endif() + + execute_process( + COMMAND plutil -extract SupportedTargets.${sdk}.Archs json ${_sdk_path}/SDKSettings.plist -o - + OUTPUT_VARIABLE _sdk_archs_json + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_VARIABLE _stderr + RESULT_VARIABLE _failed + ) + if(_failed) + # Failure to extract supported architectures for an SDK means that the installed SDK is old + # and does not provide such information (SDKs that come with Xcode >= 10.x started providing + # the information). In such a case, return early, and handle multi-arch builds the old way + # (no per-sdk arches). + return() + endif() + + # Poor man's JSON decoding + string(REGEX REPLACE "[]\\[\"]" "" _sdk_archs ${_sdk_archs_json}) + string(REPLACE "," ";" _sdk_archs ${_sdk_archs}) + + set(_sdk_archs_${sdk} ${_sdk_archs}) + set(_sdk_path_${sdk} ${_sdk_path}) + endforeach() + + foreach(arch ${CMAKE_OSX_ARCHITECTURES}) + set(_arch_sysroot "") + foreach(sdk ${_sdks}) + list(FIND _sdk_archs_${sdk} ${arch} arch_index) + if(NOT arch_index EQUAL -1) + set(_arch_sysroot ${_sdk_path_${sdk}}) + break() + endif() + endforeach() + if(_arch_sysroot) + list(APPEND _arch_sysroots ${_arch_sysroot}) + else() + message(WARNING "No SDK found for architecture '${arch}'") + list(APPEND _arch_sysroots "") # Placeholder + endif() + endforeach() + + set(CMAKE_APPLE_ARCH_SYSROOTS "${_arch_sysroots}" CACHE INTERNAL + "Architecture dependent sysroots, one per CMAKE_OSX_ARCHITECTURES") +endfunction() + +_apple_resolve_multi_arch_sysroots() +# Transform CMAKE_OSX_SYSROOT to absolute path set(_CMAKE_OSX_SYSROOT_PATH "") if(CMAKE_OSX_SYSROOT) if("x${CMAKE_OSX_SYSROOT}" MATCHES "/") diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 5711cae..4715cfa 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -51,6 +51,8 @@ static std::string const kCMAKE_OSX_ARCHITECTURES = "CMAKE_OSX_ARCHITECTURES"; static std::string const kCMAKE_OSX_DEPLOYMENT_TARGET = "CMAKE_OSX_DEPLOYMENT_TARGET"; static std::string const kCMAKE_OSX_SYSROOT = "CMAKE_OSX_SYSROOT"; +static std::string const kCMAKE_APPLE_ARCH_SYSROOTS = + "CMAKE_APPLE_ARCH_SYSROOTS"; static std::string const kCMAKE_POSITION_INDEPENDENT_CODE = "CMAKE_POSITION_INDEPENDENT_CODE"; static std::string const kCMAKE_SYSROOT = "CMAKE_SYSROOT"; @@ -723,6 +725,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, vars.insert(kCMAKE_OSX_ARCHITECTURES); vars.insert(kCMAKE_OSX_DEPLOYMENT_TARGET); vars.insert(kCMAKE_OSX_SYSROOT); + vars.insert(kCMAKE_APPLE_ARCH_SYSROOTS); vars.insert(kCMAKE_POSITION_INDEPENDENT_CODE); vars.insert(kCMAKE_SYSROOT); vars.insert(kCMAKE_SYSROOT_COMPILE); diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 187e273..303009e 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1771,7 +1771,7 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags, const std::string& lang, const std::string& config) { - // Only add macOS specific flags on Darwin platforms (macOS and iOS): + // Only add Apple specific flags on Apple platforms if (this->Makefile->IsOn("APPLE") && this->EmitUniversalBinaryFlags) { std::vector<std::string> archs; target->GetAppleArchs(config, archs); @@ -1790,11 +1790,29 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags, std::string sysrootFlagVar = std::string("CMAKE_") + lang + "_SYSROOT_FLAG"; const char* sysrootFlag = this->Makefile->GetDefinition(sysrootFlagVar); - if (sysrootFlag && *sysrootFlag && sysroot && *sysroot) { - flags += " "; - flags += sysrootFlag; - flags += " "; - flags += this->ConvertToOutputFormat(sysroot, SHELL); + if (sysrootFlag && *sysrootFlag) { + std::vector<std::string> arch_sysroots; + if (const char* arch_sysroots_str = + this->Makefile->GetDefinition("CMAKE_APPLE_ARCH_SYSROOTS")) { + cmExpandList(std::string(arch_sysroots_str), arch_sysroots, true); + } + if (!arch_sysroots.empty()) { + assert(arch_sysroots.size() == archs.size()); + for (size_t i = 0; i < archs.size(); ++i) { + if (arch_sysroots[i].empty()) { + continue; + } + flags += " -Xarch_" + archs[i] + " "; + // Combine sysroot flag and path to work with -Xarch + std::string arch_sysroot = sysrootFlag + arch_sysroots[i]; + flags += this->ConvertToOutputFormat(arch_sysroot, SHELL); + } + } else if (sysroot && *sysroot) { + flags += " "; + flags += sysrootFlag; + flags += " "; + flags += this->ConvertToOutputFormat(sysroot, SHELL); + } } const char* deploymentTarget = @@ -1803,7 +1821,6 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags, std::string("CMAKE_") + lang + "_OSX_DEPLOYMENT_TARGET_FLAG"; const char* deploymentTargetFlag = this->Makefile->GetDefinition(deploymentTargetFlagVar); - if (deploymentTargetFlag && *deploymentTargetFlag && deploymentTarget && *deploymentTarget) { flags += " "; |