diff options
Diffstat (limited to 'Source/cmGlobalXCodeGenerator.cxx')
-rw-r--r-- | Source/cmGlobalXCodeGenerator.cxx | 158 |
1 files changed, 151 insertions, 7 deletions
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 7ee94b2..70aa052 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -503,16 +503,15 @@ cmGlobalXCodeGenerator::GenerateBuildCommand( } } - if (this->XcodeBuildSystem >= BuildSystem::Twelve) { + if ((this->XcodeBuildSystem >= BuildSystem::Twelve) || + (jobs != cmake::NO_BUILD_PARALLEL_LEVEL)) { makeCommand.Add("-parallelizeTargets"); } makeCommand.Add("-configuration", (config.empty() ? "Debug" : config)); - if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) { - makeCommand.Add("-jobs"); - if (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL) { - makeCommand.Add(std::to_string(jobs)); - } + if ((jobs != cmake::NO_BUILD_PARALLEL_LEVEL) && + (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL)) { + makeCommand.Add("-jobs", std::to_string(jobs)); } if (this->XcodeVersion >= 70) { @@ -774,7 +773,9 @@ void cmGlobalXCodeGenerator::ClearXCodeObjects() this->TargetGroup.clear(); this->FileRefs.clear(); this->ExternalLibRefs.clear(); + this->EmbeddedLibRefs.clear(); this->FileRefToBuildFileMap.clear(); + this->FileRefToEmbedBuildFileMap.clear(); this->CommandsVisited.clear(); } @@ -937,6 +938,11 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile( default: break; } + + // Explicitly add the explicit language flag before any other flag + // so user flags can override it. + gtgt->AddExplicitLanguageFlags(flags, *sf); + const std::string COMPILE_FLAGS("COMPILE_FLAGS"); if (cmProp cflags = sf->GetProperty(COMPILE_FLAGS)) { lg->AppendFlags(flags, genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS)); @@ -1198,7 +1204,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath( } } // Make a copy so that we can override it later - std::string path = fullpath; + std::string path = cmSystemTools::CollapseFullPath(fullpath); // Compute the extension without leading '.'. std::string ext = cmSystemTools::GetFilenameLastExtension(path); if (!ext.empty()) { @@ -1643,6 +1649,14 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmGeneratorTarget* gtgt) } } + // Allow empty source file list for iOS Sticker packs + if (const char* productType = GetTargetProductType(gtgt)) { + if (strcmp(productType, + "com.apple.product-type.app-extension.messages-sticker-pack") == + 0) + return; + } + // Add an empty source file to the target that compiles with the // linker language. This should convince Xcode to choose the proper // language. @@ -1794,6 +1808,10 @@ void cmGlobalXCodeGenerator::CreateCustomCommands( if (frameworkBuildPhase) { buildPhases->AddObject(frameworkBuildPhase); } + + // When this build phase is present, it must be last. More build phases may + // be added later for embedding things and they will insert themselves just + // before this last build phase. if (postBuildPhase) { buildPhases->AddObject(postBuildPhase); } @@ -3633,6 +3651,130 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target) } } +void cmGlobalXCodeGenerator::AddEmbeddedFrameworks(cmXCodeObject* target) +{ + cmGeneratorTarget* gt = target->GetTarget(); + if (!gt) { + cmSystemTools::Error("Error no target on xobject\n"); + return; + } + if (!gt->IsInBuildSystem()) { + return; + } + bool isFrameworkTarget = gt->IsFrameworkOnApple(); + bool isBundleTarget = gt->GetPropertyAsBool("MACOSX_BUNDLE"); + bool isCFBundleTarget = gt->IsCFBundleOnApple(); + if (!(isFrameworkTarget || isBundleTarget || isCFBundleTarget)) { + return; + } + cmProp files = gt->GetProperty("XCODE_EMBED_FRAMEWORKS"); + if (!files) { + return; + } + + // Create an "Embedded Frameworks" build phase + auto* copyFilesBuildPhase = + this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase); + std::string copyFilesBuildPhaseName = "Embed Frameworks"; + std::string destinationFrameworks = "10"; + copyFilesBuildPhase->SetComment(copyFilesBuildPhaseName); + copyFilesBuildPhase->AddAttribute("buildActionMask", + this->CreateString("2147483647")); + copyFilesBuildPhase->AddAttribute("dstSubfolderSpec", + this->CreateString(destinationFrameworks)); + copyFilesBuildPhase->AddAttribute( + "name", this->CreateString(copyFilesBuildPhaseName)); + if (cmProp fwEmbedPath = gt->GetProperty("XCODE_EMBED_FRAMEWORKS_PATH")) { + copyFilesBuildPhase->AddAttribute("dstPath", + this->CreateString(*fwEmbedPath)); + } else { + copyFilesBuildPhase->AddAttribute("dstPath", this->CreateString("")); + } + copyFilesBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", + this->CreateString("0")); + cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); + // Collect all embedded frameworks and add them to build phase + std::vector<std::string> relFiles = cmExpandedList(*files); + for (std::string const& relFile : relFiles) { + cmXCodeObject* buildFile{ nullptr }; + std::string filePath = relFile; + auto* genTarget = FindGeneratorTarget(relFile); + if (genTarget) { + // This is a target - get it's product path reference + auto* xcTarget = FindXCodeTarget(genTarget); + if (!xcTarget) { + cmSystemTools::Error("Can not find a target for " + + genTarget->GetName()); + continue; + } + // Add the target output file as a build reference for other targets + // to link against + auto* fileRefObject = xcTarget->GetAttribute("productReference"); + if (!fileRefObject) { + cmSystemTools::Error("Target " + genTarget->GetName() + + " is missing product reference"); + continue; + } + auto it = FileRefToEmbedBuildFileMap.find(fileRefObject); + if (it == FileRefToEmbedBuildFileMap.end()) { + buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile); + buildFile->AddAttribute("fileRef", fileRefObject); + FileRefToEmbedBuildFileMap[fileRefObject] = buildFile; + } else { + buildFile = it->second; + } + } else if (cmSystemTools::IsPathToFramework(relFile)) { + // This is a regular string path - create file reference + auto it = EmbeddedLibRefs.find(relFile); + if (it == EmbeddedLibRefs.end()) { + cmXCodeObject* fileRef = + this->CreateXCodeFileReferenceFromPath(relFile, gt, "", nullptr); + if (fileRef) { + buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile); + buildFile->SetComment(fileRef->GetComment()); + buildFile->AddAttribute("fileRef", + this->CreateObjectReference(fileRef)); + } + if (!buildFile) { + cmSystemTools::Error("Can't create build file for " + relFile); + continue; + } + this->EmbeddedLibRefs.emplace(filePath, buildFile); + } else { + buildFile = it->second; + } + } + if (!buildFile) { + cmSystemTools::Error("Can't find a build file for " + relFile); + continue; + } + // Set build file configuration + cmXCodeObject* settings = + this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP); + cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST); + const auto& rmHeadersProp = + gt->GetSafeProperty("XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY"); + if (cmIsOn(rmHeadersProp)) { + attrs->AddObject(this->CreateString("RemoveHeadersOnCopy")); + } + const auto& codeSignProp = + gt->GetSafeProperty("XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY"); + if (cmIsOn(codeSignProp)) { + attrs->AddObject(this->CreateString("CodeSignOnCopy")); + } + settings->AddAttributeIfNotEmpty("ATTRIBUTES", attrs); + buildFile->AddAttributeIfNotEmpty("settings", settings); + if (!buildFiles->HasObject(buildFile)) { + buildFiles->AddObject(buildFile); + } + } + copyFilesBuildPhase->AddAttribute("files", buildFiles); + auto* buildPhases = target->GetAttribute("buildPhases"); + // Insert embed build phase right before the post-build command + buildPhases->InsertObject(buildPhases->GetObjectCount() - 1, + copyFilesBuildPhase); +} + bool cmGlobalXCodeGenerator::CreateGroups( std::vector<cmLocalGenerator*>& generators) { @@ -4011,7 +4153,9 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects( // loop over all targets and add link and depend info for (auto t : targets) { this->AddDependAndLinkInformation(t); + this->AddEmbeddedFrameworks(t); } + if (this->XcodeBuildSystem == BuildSystem::One) { this->CreateXCodeDependHackMakefile(targets); } |