diff options
author | Brad King <brad.king@kitware.com> | 2018-07-20 11:40:27 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2018-07-20 11:40:35 (GMT) |
commit | 01c04e429717fb7a6a157ce1baeb2114724ec055 (patch) | |
tree | 2a6d95e422972809c898c7ba21d55e89496298f7 | |
parent | 56148cb98f546a3a38bb6f9b191e753f8c8dd9df (diff) | |
parent | fb45559e0924467523bd372a3c037861d8b11c51 (diff) | |
download | CMake-01c04e429717fb7a6a157ce1baeb2114724ec055.zip CMake-01c04e429717fb7a6a157ce1baeb2114724ec055.tar.gz CMake-01c04e429717fb7a6a157ce1baeb2114724ec055.tar.bz2 |
Merge topic 'xcode-target-order'
fb45559e09 Xcode: Process targets in depth-first order during generation
0bad9eba46 Xcode: Refactor storage of ordered list of targets
d0de296e50 Xcode: Factor target generation loop body into helper method
30e27b4110 Xcode: Compute global order index for targets
e3469a5920 Xcode: Remove loop over local generators that has no effect
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !2224
-rw-r--r-- | Source/cmGlobalXCodeGenerator.cxx | 514 | ||||
-rw-r--r-- | Source/cmGlobalXCodeGenerator.h | 5 |
2 files changed, 279 insertions, 240 deletions
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 02297d5..042ce41 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -386,12 +386,46 @@ void cmGlobalXCodeGenerator::AddExtraIDETargets() } } +void cmGlobalXCodeGenerator::ComputeTargetOrder() +{ + size_t index = 0; + auto const& lgens = this->GetLocalGenerators(); + for (cmLocalGenerator* lgen : lgens) { + auto const& targets = lgen->GetGeneratorTargets(); + for (cmGeneratorTarget const* gt : targets) { + this->ComputeTargetOrder(gt, index); + } + } + assert(index == this->TargetOrderIndex.size()); +} + +void cmGlobalXCodeGenerator::ComputeTargetOrder(cmGeneratorTarget const* gt, + size_t& index) +{ + std::map<cmGeneratorTarget const*, size_t>::value_type value(gt, 0); + auto insertion = this->TargetOrderIndex.insert(value); + if (!insertion.second) { + return; + } + auto entry = insertion.first; + + auto& deps = this->GetTargetDirectDepends(gt); + for (auto& d : deps) { + this->ComputeTargetOrder(d, index); + } + + entry->second = index++; +} + void cmGlobalXCodeGenerator::Generate() { this->cmGlobalGenerator::Generate(); if (cmSystemTools::GetErrorOccuredFlag()) { return; } + + this->ComputeTargetOrder(); + for (auto keyVal : this->ProjectMap) { cmLocalGenerator* root = keyVal.second[0]; @@ -1031,15 +1065,17 @@ struct cmSourceFilePathCompare struct cmCompareTargets { - bool operator()(std::string const& a, std::string const& b) const + bool operator()(cmXCodeObject* l, cmXCodeObject* r) const { + std::string const& a = l->GetTarget()->GetName(); + std::string const& b = r->GetTarget()->GetName(); if (a == "ALL_BUILD") { return true; } if (b == "ALL_BUILD") { return false; } - return strcmp(a.c_str(), b.c_str()) < 0; + return a < b; } }; @@ -1047,274 +1083,279 @@ bool cmGlobalXCodeGenerator::CreateXCodeTargets( cmLocalGenerator* gen, std::vector<cmXCodeObject*>& targets) { this->SetCurrentLocalGenerator(gen); - typedef std::map<std::string, cmGeneratorTarget*, cmCompareTargets> - cmSortedTargets; - cmSortedTargets sortedTargets; - for (auto tgt : this->CurrentLocalGenerator->GetGeneratorTargets()) { - sortedTargets[tgt->GetName()] = tgt; + std::vector<cmGeneratorTarget*> gts = + this->CurrentLocalGenerator->GetGeneratorTargets(); + std::sort(gts.begin(), gts.end(), + [this](cmGeneratorTarget const* l, cmGeneratorTarget const* r) { + return this->TargetOrderIndex[l] < this->TargetOrderIndex[r]; + }); + for (auto gtgt : gts) { + if (!this->CreateXCodeTarget(gtgt, targets)) { + return false; + } } - for (auto& sortedTarget : sortedTargets) { - cmGeneratorTarget* gtgt = sortedTarget.second; - - std::string targetName = gtgt->GetName(); + std::sort(targets.begin(), targets.end(), cmCompareTargets()); + return true; +} - // make sure ALL_BUILD, INSTALL, etc are only done once - if (this->SpecialTargetEmitted(targetName)) { - continue; - } +bool cmGlobalXCodeGenerator::CreateXCodeTarget( + cmGeneratorTarget* gtgt, std::vector<cmXCodeObject*>& targets) +{ + std::string targetName = gtgt->GetName(); - if (gtgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) { - continue; - } + // make sure ALL_BUILD, INSTALL, etc are only done once + if (this->SpecialTargetEmitted(targetName)) { + return true; + } - if (gtgt->GetType() == cmStateEnums::UTILITY || - gtgt->GetType() == cmStateEnums::GLOBAL_TARGET) { - cmXCodeObject* t = this->CreateUtilityTarget(gtgt); - if (!t) { - return false; - } - targets.push_back(t); - continue; - } + if (gtgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) { + return true; + } - // organize the sources - std::vector<cmSourceFile*> classes; - if (!gtgt->GetConfigCommonSourceFiles(classes)) { + if (gtgt->GetType() == cmStateEnums::UTILITY || + gtgt->GetType() == cmStateEnums::GLOBAL_TARGET) { + cmXCodeObject* t = this->CreateUtilityTarget(gtgt); + if (!t) { return false; } + targets.push_back(t); + return true; + } - // Add CMakeLists.txt file for user convenience. - this->AddXCodeProjBuildRule(gtgt, classes); + // organize the sources + std::vector<cmSourceFile*> classes; + if (!gtgt->GetConfigCommonSourceFiles(classes)) { + return false; + } - std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare()); + // Add CMakeLists.txt file for user convenience. + this->AddXCodeProjBuildRule(gtgt, classes); - gtgt->ComputeObjectMapping(); + std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare()); - std::vector<cmXCodeObject*> externalObjFiles; - std::vector<cmXCodeObject*> headerFiles; - std::vector<cmXCodeObject*> resourceFiles; - std::vector<cmXCodeObject*> sourceFiles; - for (auto sourceFile : classes) { - cmXCodeObject* xsf = this->CreateXCodeSourceFile( - this->CurrentLocalGenerator, sourceFile, gtgt); - cmXCodeObject* fr = xsf->GetObject("fileRef"); - cmXCodeObject* filetype = fr->GetObject()->GetObject("explicitFileType"); + gtgt->ComputeObjectMapping(); - cmGeneratorTarget::SourceFileFlags tsFlags = - gtgt->GetTargetSourceFileFlags(sourceFile); + std::vector<cmXCodeObject*> externalObjFiles; + std::vector<cmXCodeObject*> headerFiles; + std::vector<cmXCodeObject*> resourceFiles; + std::vector<cmXCodeObject*> sourceFiles; + for (auto sourceFile : classes) { + cmXCodeObject* xsf = this->CreateXCodeSourceFile( + this->CurrentLocalGenerator, sourceFile, gtgt); + cmXCodeObject* fr = xsf->GetObject("fileRef"); + cmXCodeObject* filetype = fr->GetObject()->GetObject("explicitFileType"); - if (filetype && filetype->GetString() == "compiled.mach-o.objfile") { - if (sourceFile->GetObjectLibrary().empty()) { - externalObjFiles.push_back(xsf); - } - } else if (this->IsHeaderFile(sourceFile) || - (tsFlags.Type == - cmGeneratorTarget::SourceFileTypePrivateHeader) || - (tsFlags.Type == - cmGeneratorTarget::SourceFileTypePublicHeader)) { - headerFiles.push_back(xsf); - } else if (tsFlags.Type == cmGeneratorTarget::SourceFileTypeResource) { - resourceFiles.push_back(xsf); - } else if (!sourceFile->GetPropertyAsBool("HEADER_FILE_ONLY")) { - // Include this file in the build if it has a known language - // and has not been listed as an ignored extension for this - // generator. - if (!this->CurrentLocalGenerator->GetSourceFileLanguage(*sourceFile) - .empty() && - !this->IgnoreFile(sourceFile->GetExtension().c_str())) { - sourceFiles.push_back(xsf); - } - } - } + cmGeneratorTarget::SourceFileFlags tsFlags = + gtgt->GetTargetSourceFileFlags(sourceFile); - if (this->XcodeVersion < 50) { - // Add object library contents as external objects. (Equivalent to - // the externalObjFiles above, except each one is not a cmSourceFile - // within the target.) - std::vector<cmSourceFile const*> objs; - gtgt->GetExternalObjects(objs, ""); - for (auto sourceFile : objs) { - if (sourceFile->GetObjectLibrary().empty()) { - continue; - } - std::string const& obj = sourceFile->GetFullPath(); - cmXCodeObject* xsf = - this->CreateXCodeSourceFileFromPath(obj, gtgt, "", nullptr); + if (filetype && filetype->GetString() == "compiled.mach-o.objfile") { + if (sourceFile->GetObjectLibrary().empty()) { externalObjFiles.push_back(xsf); } - } - - // some build phases only apply to bundles and/or frameworks - bool isFrameworkTarget = gtgt->IsFrameworkOnApple(); - bool isBundleTarget = gtgt->GetPropertyAsBool("MACOSX_BUNDLE"); - bool isCFBundleTarget = gtgt->IsCFBundleOnApple(); - - cmXCodeObject* buildFiles = nullptr; - - // create source build phase - cmXCodeObject* sourceBuildPhase = nullptr; - if (!sourceFiles.empty()) { - sourceBuildPhase = - this->CreateObject(cmXCodeObject::PBXSourcesBuildPhase); - sourceBuildPhase->SetComment("Sources"); - sourceBuildPhase->AddAttribute("buildActionMask", - this->CreateString("2147483647")); - buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); - for (auto& sourceFile : sourceFiles) { - buildFiles->AddObject(sourceFile); + } else if (this->IsHeaderFile(sourceFile) || + (tsFlags.Type == + cmGeneratorTarget::SourceFileTypePrivateHeader) || + (tsFlags.Type == + cmGeneratorTarget::SourceFileTypePublicHeader)) { + headerFiles.push_back(xsf); + } else if (tsFlags.Type == cmGeneratorTarget::SourceFileTypeResource) { + resourceFiles.push_back(xsf); + } else if (!sourceFile->GetPropertyAsBool("HEADER_FILE_ONLY")) { + // Include this file in the build if it has a known language + // and has not been listed as an ignored extension for this + // generator. + if (!this->CurrentLocalGenerator->GetSourceFileLanguage(*sourceFile) + .empty() && + !this->IgnoreFile(sourceFile->GetExtension().c_str())) { + sourceFiles.push_back(xsf); } - sourceBuildPhase->AddAttribute("files", buildFiles); - sourceBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", - this->CreateString("0")); } + } - // create header build phase - only for framework targets - cmXCodeObject* headerBuildPhase = nullptr; - if (!headerFiles.empty() && isFrameworkTarget) { - headerBuildPhase = - this->CreateObject(cmXCodeObject::PBXHeadersBuildPhase); - headerBuildPhase->SetComment("Headers"); - headerBuildPhase->AddAttribute("buildActionMask", - this->CreateString("2147483647")); - buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); - for (auto& headerFile : headerFiles) { - buildFiles->AddObject(headerFile); + if (this->XcodeVersion < 50) { + // Add object library contents as external objects. (Equivalent to + // the externalObjFiles above, except each one is not a cmSourceFile + // within the target.) + std::vector<cmSourceFile const*> objs; + gtgt->GetExternalObjects(objs, ""); + for (auto sourceFile : objs) { + if (sourceFile->GetObjectLibrary().empty()) { + continue; } - headerBuildPhase->AddAttribute("files", buildFiles); - headerBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", - this->CreateString("0")); + std::string const& obj = sourceFile->GetFullPath(); + cmXCodeObject* xsf = + this->CreateXCodeSourceFileFromPath(obj, gtgt, "", nullptr); + externalObjFiles.push_back(xsf); + } + } + + // some build phases only apply to bundles and/or frameworks + bool isFrameworkTarget = gtgt->IsFrameworkOnApple(); + bool isBundleTarget = gtgt->GetPropertyAsBool("MACOSX_BUNDLE"); + bool isCFBundleTarget = gtgt->IsCFBundleOnApple(); + + cmXCodeObject* buildFiles = nullptr; + + // create source build phase + cmXCodeObject* sourceBuildPhase = nullptr; + if (!sourceFiles.empty()) { + sourceBuildPhase = this->CreateObject(cmXCodeObject::PBXSourcesBuildPhase); + sourceBuildPhase->SetComment("Sources"); + sourceBuildPhase->AddAttribute("buildActionMask", + this->CreateString("2147483647")); + buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); + for (auto& sourceFile : sourceFiles) { + buildFiles->AddObject(sourceFile); + } + sourceBuildPhase->AddAttribute("files", buildFiles); + sourceBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", + this->CreateString("0")); + } + + // create header build phase - only for framework targets + cmXCodeObject* headerBuildPhase = nullptr; + if (!headerFiles.empty() && isFrameworkTarget) { + headerBuildPhase = this->CreateObject(cmXCodeObject::PBXHeadersBuildPhase); + headerBuildPhase->SetComment("Headers"); + headerBuildPhase->AddAttribute("buildActionMask", + this->CreateString("2147483647")); + buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); + for (auto& headerFile : headerFiles) { + buildFiles->AddObject(headerFile); + } + headerBuildPhase->AddAttribute("files", buildFiles); + headerBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", + this->CreateString("0")); + } + + // create resource build phase - only for framework or bundle targets + cmXCodeObject* resourceBuildPhase = nullptr; + if (!resourceFiles.empty() && + (isFrameworkTarget || isBundleTarget || isCFBundleTarget)) { + resourceBuildPhase = + this->CreateObject(cmXCodeObject::PBXResourcesBuildPhase); + resourceBuildPhase->SetComment("Resources"); + resourceBuildPhase->AddAttribute("buildActionMask", + this->CreateString("2147483647")); + buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); + for (auto& resourceFile : resourceFiles) { + buildFiles->AddObject(resourceFile); } + resourceBuildPhase->AddAttribute("files", buildFiles); + resourceBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", + this->CreateString("0")); + } - // create resource build phase - only for framework or bundle targets - cmXCodeObject* resourceBuildPhase = nullptr; - if (!resourceFiles.empty() && - (isFrameworkTarget || isBundleTarget || isCFBundleTarget)) { - resourceBuildPhase = - this->CreateObject(cmXCodeObject::PBXResourcesBuildPhase); - resourceBuildPhase->SetComment("Resources"); - resourceBuildPhase->AddAttribute("buildActionMask", - this->CreateString("2147483647")); - buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); - for (auto& resourceFile : resourceFiles) { - buildFiles->AddObject(resourceFile); - } - resourceBuildPhase->AddAttribute("files", buildFiles); - resourceBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", - this->CreateString("0")); - } - - // create vector of "non-resource content file" build phases - only for - // framework or bundle targets - std::vector<cmXCodeObject*> contentBuildPhases; - if (isFrameworkTarget || isBundleTarget || isCFBundleTarget) { - typedef std::map<std::string, std::vector<cmSourceFile*>> - mapOfVectorOfSourceFiles; - mapOfVectorOfSourceFiles bundleFiles; - for (auto sourceFile : classes) { - cmGeneratorTarget::SourceFileFlags tsFlags = - gtgt->GetTargetSourceFileFlags(sourceFile); - if (tsFlags.Type == cmGeneratorTarget::SourceFileTypeMacContent) { - bundleFiles[tsFlags.MacFolder].push_back(sourceFile); - } + // create vector of "non-resource content file" build phases - only for + // framework or bundle targets + std::vector<cmXCodeObject*> contentBuildPhases; + if (isFrameworkTarget || isBundleTarget || isCFBundleTarget) { + typedef std::map<std::string, std::vector<cmSourceFile*>> + mapOfVectorOfSourceFiles; + mapOfVectorOfSourceFiles bundleFiles; + for (auto sourceFile : classes) { + cmGeneratorTarget::SourceFileFlags tsFlags = + gtgt->GetTargetSourceFileFlags(sourceFile); + if (tsFlags.Type == cmGeneratorTarget::SourceFileTypeMacContent) { + bundleFiles[tsFlags.MacFolder].push_back(sourceFile); } - for (auto keySources : bundleFiles) { - cmXCodeObject* copyFilesBuildPhase = - this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase); - copyFilesBuildPhase->SetComment("Copy files"); - copyFilesBuildPhase->AddAttribute("buildActionMask", - this->CreateString("2147483647")); - copyFilesBuildPhase->AddAttribute("dstSubfolderSpec", - this->CreateString("6")); - std::ostringstream ostr; - if (gtgt->IsFrameworkOnApple()) { - // dstPath in frameworks is relative to Versions/<version> + } + for (auto keySources : bundleFiles) { + cmXCodeObject* copyFilesBuildPhase = + this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase); + copyFilesBuildPhase->SetComment("Copy files"); + copyFilesBuildPhase->AddAttribute("buildActionMask", + this->CreateString("2147483647")); + copyFilesBuildPhase->AddAttribute("dstSubfolderSpec", + this->CreateString("6")); + std::ostringstream ostr; + if (gtgt->IsFrameworkOnApple()) { + // dstPath in frameworks is relative to Versions/<version> + ostr << keySources.first; + } else if (keySources.first != "MacOS") { + if (gtgt->Target->GetMakefile()->PlatformIsAppleEmbedded()) { ostr << keySources.first; - } else if (keySources.first != "MacOS") { - if (gtgt->Target->GetMakefile()->PlatformIsAppleEmbedded()) { - ostr << keySources.first; - } else { - // dstPath in bundles is relative to Contents/MacOS - ostr << "../" << keySources.first; - } - } - copyFilesBuildPhase->AddAttribute("dstPath", - this->CreateString(ostr.str())); - copyFilesBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", - this->CreateString("0")); - buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); - copyFilesBuildPhase->AddAttribute("files", buildFiles); - for (auto sourceFile : keySources.second) { - cmXCodeObject* xsf = this->CreateXCodeSourceFile( - this->CurrentLocalGenerator, sourceFile, gtgt); - buildFiles->AddObject(xsf); + } else { + // dstPath in bundles is relative to Contents/MacOS + ostr << "../" << keySources.first; } - contentBuildPhases.push_back(copyFilesBuildPhase); } + copyFilesBuildPhase->AddAttribute("dstPath", + this->CreateString(ostr.str())); + copyFilesBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", + this->CreateString("0")); + buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); + copyFilesBuildPhase->AddAttribute("files", buildFiles); + for (auto sourceFile : keySources.second) { + cmXCodeObject* xsf = this->CreateXCodeSourceFile( + this->CurrentLocalGenerator, sourceFile, gtgt); + buildFiles->AddObject(xsf); + } + contentBuildPhases.push_back(copyFilesBuildPhase); } + } - // create vector of "resource content file" build phases - only for - // framework or bundle targets - if (isFrameworkTarget || isBundleTarget || isCFBundleTarget) { - typedef std::map<std::string, std::vector<cmSourceFile*>> - mapOfVectorOfSourceFiles; - mapOfVectorOfSourceFiles bundleFiles; - for (auto sourceFile : classes) { - cmGeneratorTarget::SourceFileFlags tsFlags = - gtgt->GetTargetSourceFileFlags(sourceFile); - if (tsFlags.Type == cmGeneratorTarget::SourceFileTypeDeepResource) { - bundleFiles[tsFlags.MacFolder].push_back(sourceFile); - } - } - for (auto keySources : bundleFiles) { - cmXCodeObject* copyFilesBuildPhase = - this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase); - copyFilesBuildPhase->SetComment("Copy files"); - copyFilesBuildPhase->AddAttribute("buildActionMask", - this->CreateString("2147483647")); - copyFilesBuildPhase->AddAttribute("dstSubfolderSpec", - this->CreateString("7")); - copyFilesBuildPhase->AddAttribute( - "dstPath", this->CreateString(keySources.first)); - copyFilesBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", - this->CreateString("0")); - buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); - copyFilesBuildPhase->AddAttribute("files", buildFiles); - for (auto sourceFile : keySources.second) { - cmXCodeObject* xsf = this->CreateXCodeSourceFile( - this->CurrentLocalGenerator, sourceFile, gtgt); - buildFiles->AddObject(xsf); - } - contentBuildPhases.push_back(copyFilesBuildPhase); + // create vector of "resource content file" build phases - only for + // framework or bundle targets + if (isFrameworkTarget || isBundleTarget || isCFBundleTarget) { + typedef std::map<std::string, std::vector<cmSourceFile*>> + mapOfVectorOfSourceFiles; + mapOfVectorOfSourceFiles bundleFiles; + for (auto sourceFile : classes) { + cmGeneratorTarget::SourceFileFlags tsFlags = + gtgt->GetTargetSourceFileFlags(sourceFile); + if (tsFlags.Type == cmGeneratorTarget::SourceFileTypeDeepResource) { + bundleFiles[tsFlags.MacFolder].push_back(sourceFile); } } - - // create framework build phase - cmXCodeObject* frameworkBuildPhase = nullptr; - if (!externalObjFiles.empty()) { - frameworkBuildPhase = - this->CreateObject(cmXCodeObject::PBXFrameworksBuildPhase); - frameworkBuildPhase->SetComment("Frameworks"); - frameworkBuildPhase->AddAttribute("buildActionMask", + for (auto keySources : bundleFiles) { + cmXCodeObject* copyFilesBuildPhase = + this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase); + copyFilesBuildPhase->SetComment("Copy files"); + copyFilesBuildPhase->AddAttribute("buildActionMask", this->CreateString("2147483647")); + copyFilesBuildPhase->AddAttribute("dstSubfolderSpec", + this->CreateString("7")); + copyFilesBuildPhase->AddAttribute("dstPath", + this->CreateString(keySources.first)); + copyFilesBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", + this->CreateString("0")); buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); - frameworkBuildPhase->AddAttribute("files", buildFiles); - for (auto& externalObjFile : externalObjFiles) { - buildFiles->AddObject(externalObjFile); + copyFilesBuildPhase->AddAttribute("files", buildFiles); + for (auto sourceFile : keySources.second) { + cmXCodeObject* xsf = this->CreateXCodeSourceFile( + this->CurrentLocalGenerator, sourceFile, gtgt); + buildFiles->AddObject(xsf); } - frameworkBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", - this->CreateString("0")); + contentBuildPhases.push_back(copyFilesBuildPhase); + } + } + + // create framework build phase + cmXCodeObject* frameworkBuildPhase = nullptr; + if (!externalObjFiles.empty()) { + frameworkBuildPhase = + this->CreateObject(cmXCodeObject::PBXFrameworksBuildPhase); + frameworkBuildPhase->SetComment("Frameworks"); + frameworkBuildPhase->AddAttribute("buildActionMask", + this->CreateString("2147483647")); + buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); + frameworkBuildPhase->AddAttribute("files", buildFiles); + for (auto& externalObjFile : externalObjFiles) { + buildFiles->AddObject(externalObjFile); } + frameworkBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", + this->CreateString("0")); + } - // create list of build phases and create the Xcode target - cmXCodeObject* buildPhases = - this->CreateObject(cmXCodeObject::OBJECT_LIST); + // create list of build phases and create the Xcode target + cmXCodeObject* buildPhases = this->CreateObject(cmXCodeObject::OBJECT_LIST); - this->CreateCustomCommands(buildPhases, sourceBuildPhase, headerBuildPhase, - resourceBuildPhase, contentBuildPhases, - frameworkBuildPhase, gtgt); + this->CreateCustomCommands(buildPhases, sourceBuildPhase, headerBuildPhase, + resourceBuildPhase, contentBuildPhases, + frameworkBuildPhase, gtgt); - targets.push_back(this->CreateXCodeTarget(gtgt, buildPhases)); - } + targets.push_back(this->CreateXCodeTarget(gtgt, buildPhases)); return true; } @@ -3319,13 +3360,6 @@ void cmGlobalXCodeGenerator::OutputXCodeProject( if (generators.empty()) { return; } - // Skip local generators that are excluded from this project. - for (auto generator : generators) { - if (this->IsExcluded(root, generator)) { - continue; - } - } - if (!this->CreateXCodeObjects(root, generators)) { return; } diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index ccef6e2..f7bca13 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -109,6 +109,8 @@ public: protected: void AddExtraIDETargets() override; + void ComputeTargetOrder(); + void ComputeTargetOrder(cmGeneratorTarget const* gt, size_t& index); void Generate() override; private: @@ -204,6 +206,8 @@ private: void AddXCodeProjBuildRule(cmGeneratorTarget* target, std::vector<cmSourceFile*>& sources) const; bool CreateXCodeTargets(cmLocalGenerator* gen, std::vector<cmXCodeObject*>&); + bool CreateXCodeTarget(cmGeneratorTarget* gtgt, + std::vector<cmXCodeObject*>&); bool IsHeaderFile(cmSourceFile*); void AddDependTarget(cmXCodeObject* target, cmXCodeObject* dependTarget); void CreateXCodeDependHackTarget(std::vector<cmXCodeObject*>& targets); @@ -286,6 +290,7 @@ private: std::string ObjectDirArchDefault; std::string ObjectDirArch; std::string GeneratorToolset; + std::map<cmGeneratorTarget const*, size_t> TargetOrderIndex; }; #endif |