| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
| file LICENSE.rst or https://cmake.org/licensing for details. */ |
| |
| #include "cmFastbuildUtilityTargetGenerator.h" |
| |
| #include <set> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "cmFastbuildTargetGenerator.h" |
| #include "cmGeneratorTarget.h" |
| #include "cmGlobalFastbuildGenerator.h" |
| #include "cmListFileCache.h" |
| #include "cmMakefile.h" |
| #include "cmStateTypes.h" |
| #include "cmTarget.h" |
| #include "cmTargetDepend.h" |
| |
| cmFastbuildUtilityTargetGenerator::cmFastbuildUtilityTargetGenerator( |
| cmGeneratorTarget* gt, std::string configParam) |
| : cmFastbuildTargetGenerator(gt, std::move(configParam)) |
| { |
| } |
| |
| void cmFastbuildUtilityTargetGenerator::Generate() |
| { |
| std::string targetName = GeneratorTarget->GetName(); |
| |
| if (this->GeneratorTarget->GetType() == cmStateEnums::GLOBAL_TARGET) { |
| targetName = GetGlobalGenerator()->GetTargetName(GeneratorTarget); |
| } |
| |
| FastbuildAliasNode fastbuildTarget; |
| fastbuildTarget.Name = targetName; |
| |
| LogMessage("<-------------->"); |
| LogMessage("Generate Utility target: " + targetName); |
| LogMessage("Config: " + Config); |
| for (auto const& dep : TargetDirectDependencies) { |
| LogMessage("Dep: " + dep->GetName()); |
| } |
| |
| std::vector<std::string> nonImportedUtils; |
| for (BT<std::pair<std::string, bool>> const& util : |
| this->GeneratorTarget->GetUtilities()) { |
| if (util.Value.first == targetName) { |
| continue; |
| } |
| auto const& utilTargetName = |
| this->ConvertToFastbuildPath(util.Value.first); |
| LogMessage("Util: " + utilTargetName); |
| auto* const target = this->Makefile->FindTargetToUse(utilTargetName); |
| if (target && target->IsImported()) { |
| LogMessage("Skipping imported util target: " + utilTargetName); |
| continue; |
| } |
| // Since interface target don't appear in the generated build files, |
| // transitively propagate their deps (if any). |
| // Tested in "ExternalProjectSubdir" test. |
| if (target && target->GetType() == cmStateEnums::INTERFACE_LIBRARY) { |
| for (auto const& dep : target->GetUtilities()) { |
| auto const& depName = this->ConvertToFastbuildPath(dep.Value.first); |
| LogMessage("Transitively propagating iface dep: " + depName + |
| ", is cross: " + std::to_string(dep.Value.second)); |
| nonImportedUtils.emplace_back(depName); |
| fastbuildTarget.PreBuildDependencies.emplace( |
| this->ConvertToFastbuildPath(depName)); |
| } |
| } else { |
| nonImportedUtils.emplace_back(utilTargetName); |
| fastbuildTarget.PreBuildDependencies.emplace(utilTargetName); |
| } |
| } |
| if (this->GetGlobalGenerator()->IsExcluded(this->GetGeneratorTarget())) { |
| LogMessage("Excluding " + targetName + " from ALL"); |
| fastbuildTarget.ExcludeFromAll = true; |
| } |
| auto preBuild = GenerateCommands(FastbuildBuildStep::PRE_BUILD); |
| |
| // Tested in "RunCMake.CPack*" tests. |
| // Utility target "package" has packaging steps as "POST_BUILD". |
| for (auto& exec : GenerateCommands(FastbuildBuildStep::POST_BUILD).Nodes) { |
| fastbuildTarget.PreBuildDependencies.emplace(exec.Name); |
| for (std::string const& util : nonImportedUtils) { |
| LogMessage("Adding: util " + util); |
| exec.PreBuildDependencies.emplace(util); |
| } |
| // So POST_BUILD is executed AFTER PRE_BUILD (tested in "CustomCommand" |
| // test). |
| for (auto const& pre : preBuild.Nodes) { |
| LogMessage("Adding: " + pre.Name); |
| exec.PreBuildDependencies.emplace(pre.Name); |
| } |
| this->GetGlobalGenerator()->AddTarget(std::move(exec)); |
| } |
| |
| for (auto& exec : preBuild.Nodes) { |
| LogMessage("Adding exec " + exec.Name); |
| fastbuildTarget.PreBuildDependencies.emplace(exec.Name); |
| this->GetGlobalGenerator()->AddTarget(std::move(exec)); |
| } |
| |
| for (auto& exec : GenerateCommands(FastbuildBuildStep::REST).Nodes) { |
| fastbuildTarget.PreBuildDependencies.emplace(exec.Name); |
| for (auto const& dep : TargetDirectDependencies) { |
| LogMessage("Direct dep " + dep->GetName() + |
| "-all propagating to CC: " + exec.Name); |
| // All custom commands from within the target must be executed AFTER all |
| // the target's deps. |
| exec.PreBuildDependencies.emplace(dep->GetName()); |
| } |
| this->GetGlobalGenerator()->AddTarget(std::move(exec)); |
| } |
| if (fastbuildTarget.PreBuildDependencies.empty()) { |
| if (fastbuildTarget.ExcludeFromAll) { |
| return; |
| } |
| fastbuildTarget.PreBuildDependencies.emplace(FASTBUILD_NOOP_FILE_NAME); |
| } |
| fastbuildTarget.Hidden = false; |
| this->AdditionalCleanFiles(); |
| this->GetGlobalGenerator()->AddTarget(std::move(fastbuildTarget)); |
| } |