Apple: Fix mapping CMAKE_APPLE_ARCH_SYSROOTS to custom OSX_ARCHITECTURES

The `CMAKE_OSX_ARCHITECTURES` value is not used directly by generators.
It is used to initialize a per-target `OSX_ARCHITECTURES` property, but
that property can also be set explicitly by project code to a subset of
the full list of architectures.  In order to handle this case, construct
a mapping from each `CMAKE_OSX_ARCHITECTURES` entry to the corresponding
`CMAKE_APPLE_ARCH_SYSROOTS` entry by name.  Use the mapping to find the
sysroot for each entry in `OSX_ARCHITECTURES` for a given target.

If `CMAKE_APPLE_ARCH_SYSROOTS` does not have the same length as
`CMAKE_OSX_ARCHITECTURES`, error out early rather than risking a crash
or assertion failure.

Fixes: #20534
This commit is contained in:
Brad King
2020-04-08 11:35:32 -04:00
parent 45fa9b32ca
commit 84a1e67380
2 changed files with 29 additions and 11 deletions

View File

@@ -131,6 +131,28 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile)
this->LinkerSysroot = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT");
}
if (std::string const* appleArchSysroots =
this->Makefile->GetDef("CMAKE_APPLE_ARCH_SYSROOTS")) {
std::string const& appleArchs =
this->Makefile->GetSafeDefinition("CMAKE_OSX_ARCHITECTURES");
std::vector<std::string> archs;
std::vector<std::string> sysroots;
cmExpandList(appleArchs, archs);
cmExpandList(*appleArchSysroots, sysroots, true);
if (archs.size() == sysroots.size()) {
for (size_t i = 0; i < archs.size(); ++i) {
this->AppleArchSysroots[archs[i]] = sysroots[i];
}
} else {
std::string const e =
cmStrCat("CMAKE_APPLE_ARCH_SYSROOTS:\n ", *appleArchSysroots,
"\n"
"is not the same length as CMAKE_OSX_ARCHITECTURES:\n ",
appleArchs);
this->IssueMessage(MessageType::FATAL_ERROR, e);
}
}
for (std::string const& lang : enabledLanguages) {
if (lang == "NONE") {
continue;
@@ -1792,20 +1814,15 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
std::string("CMAKE_") + lang + "_SYSROOT_FLAG";
const char* sysrootFlag = this->Makefile->GetDefinition(sysrootFlagVar);
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 (cmIsOff(arch_sysroots[i])) {
if (!this->AppleArchSysroots.empty()) {
for (std::string const& arch : archs) {
std::string const& archSysroot = this->AppleArchSysroots[arch];
if (cmIsOff(archSysroot)) {
continue;
}
flags += " -Xarch_" + archs[i] + " ";
flags += " -Xarch_" + arch + " ";
// Combine sysroot flag and path to work with -Xarch
std::string arch_sysroot = sysrootFlag + arch_sysroots[i];
std::string arch_sysroot = sysrootFlag + archSysroot;
flags += this->ConvertToOutputFormat(arch_sysroot, SHELL);
}
} else if (sysroot && *sysroot) {

View File

@@ -513,6 +513,7 @@ protected:
std::map<std::string, std::string> VariableMappings;
std::string CompilerSysroot;
std::string LinkerSysroot;
std::unordered_map<std::string, std::string> AppleArchSysroots;
bool EmitUniversalBinaryFlags;