diff options
author | Brad King <brad.king@kitware.com> | 2019-09-27 18:54:39 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2019-09-27 18:54:58 (GMT) |
commit | f30f1625c25afb44861eff1f69ca4fa966077c73 (patch) | |
tree | a3aa65e72e65d20bb40cc9ab0b879fd1c0ee63d3 /Source | |
parent | 0672647e123670342d68827354610c747fe98004 (diff) | |
parent | 5a06efda05feda02511592c76134ee8ed3e8b650 (diff) | |
download | CMake-f30f1625c25afb44861eff1f69ca4fa966077c73.zip CMake-f30f1625c25afb44861eff1f69ca4fa966077c73.tar.gz CMake-f30f1625c25afb44861eff1f69ca4fa966077c73.tar.bz2 |
Merge topic 'decompose-custom-command-creation'
5a06efda05 cmMakefile: Remove AddUtilityCommand overload without byproducts
ea1bed34b2 cmMakefile: Extract utilities used for creation of custom commands
91abf9f3c4 cmCustomCommand: Move custom commands
f151a57705 cmMakefile: Move enumerations into new header
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !3846
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Source/cmAddCustomCommandCommand.cxx | 10 | ||||
-rw-r--r-- | Source/cmAddCustomTargetCommand.cxx | 3 | ||||
-rw-r--r-- | Source/cmCPluginAPI.cxx | 14 | ||||
-rw-r--r-- | Source/cmCustomCommandTypes.h | 39 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.cxx | 2 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudio8Generator.cxx | 20 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudioGenerator.cxx | 7 | ||||
-rw-r--r-- | Source/cmGlobalXCodeGenerator.cxx | 23 | ||||
-rw-r--r-- | Source/cmLocalGenerator.cxx | 3 | ||||
-rw-r--r-- | Source/cmMakefile.cxx | 298 | ||||
-rw-r--r-- | Source/cmMakefile.h | 85 | ||||
-rw-r--r-- | Source/cmQtAutoGenGlobalInitializer.cxx | 3 | ||||
-rw-r--r-- | Source/cmQtAutoGenInitializer.cxx | 10 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 15 | ||||
-rw-r--r-- | Source/cmTarget.h | 10 |
16 files changed, 313 insertions, 230 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 71a7dbd..0c1f3b1 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -195,6 +195,7 @@ set(SRCS cmCustomCommandGenerator.h cmCustomCommandLines.cxx cmCustomCommandLines.h + cmCustomCommandTypes.h cmDefinitions.cxx cmDefinitions.h cmDepends.cxx diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx index 94de851..6e04ce5 100644 --- a/Source/cmAddCustomCommandCommand.cxx +++ b/Source/cmAddCustomCommandCommand.cxx @@ -8,6 +8,7 @@ #include "cmCheckCustomOutputs.h" #include "cmCustomCommand.h" #include "cmCustomCommandLines.h" +#include "cmCustomCommandTypes.h" #include "cmExecutionStatus.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" @@ -15,7 +16,6 @@ #include "cmPolicies.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -#include "cmTarget.h" bool cmAddCustomCommandCommand(std::vector<std::string> const& args, cmExecutionStatus& status) @@ -55,7 +55,7 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args, // Save all command lines. cmCustomCommandLines commandLines; - cmTarget::CustomCommandType cctype = cmTarget::POST_BUILD; + cmCustomCommandType cctype = cmCustomCommandType::POST_BUILD; enum tdoing { @@ -139,11 +139,11 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args, currentLine.clear(); } } else if (copy == keyPRE_BUILD) { - cctype = cmTarget::PRE_BUILD; + cctype = cmCustomCommandType::PRE_BUILD; } else if (copy == keyPRE_LINK) { - cctype = cmTarget::PRE_LINK; + cctype = cmCustomCommandType::PRE_LINK; } else if (copy == keyPOST_BUILD) { - cctype = cmTarget::POST_BUILD; + cctype = cmCustomCommandType::POST_BUILD; } else if (copy == keyVERBATIM) { verbatim = true; } else if (copy == keyAPPEND) { diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx index b580c43..e27b126 100644 --- a/Source/cmAddCustomTargetCommand.cxx +++ b/Source/cmAddCustomTargetCommand.cxx @@ -6,6 +6,7 @@ #include "cmCheckCustomOutputs.h" #include "cmCustomCommandLines.h" +#include "cmCustomCommandTypes.h" #include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" @@ -214,7 +215,7 @@ bool cmAddCustomTargetCommand(std::vector<std::string> const& args, // Add the utility target to the makefile. bool escapeOldStyle = !verbatim; cmTarget* target = mf.AddUtilityCommand( - targetName, cmMakefile::TargetOrigin::Project, excludeFromAll, + targetName, cmCommandOrigin::Project, excludeFromAll, working_directory.c_str(), byproducts, depends, commandLines, escapeOldStyle, comment, uses_terminal, command_expand_lists, job_pool); diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx index 1eaf48b..78a232e 100644 --- a/Source/cmCPluginAPI.cxx +++ b/Source/cmCPluginAPI.cxx @@ -220,8 +220,10 @@ void CCONV cmAddUtilityCommand(void* arg, const char* utilityName, } // Pass the call to the makefile instance. - mf->AddUtilityCommand(utilityName, cmMakefile::TargetOrigin::Project, - (all ? false : true), nullptr, depends2, commandLines); + std::vector<std::string> no_byproducts; + mf->AddUtilityCommand(utilityName, cmCommandOrigin::Project, + (all ? false : true), nullptr, no_byproducts, depends2, + commandLines); } void CCONV cmAddCustomCommand(void* arg, const char* source, const char* command, int numArgs, @@ -319,16 +321,16 @@ void CCONV cmAddCustomCommandToTarget(void* arg, const char* target, commandLines.push_back(commandLine); // Select the command type. - cmTarget::CustomCommandType cctype = cmTarget::POST_BUILD; + cmCustomCommandType cctype = cmCustomCommandType::POST_BUILD; switch (commandType) { case CM_PRE_BUILD: - cctype = cmTarget::PRE_BUILD; + cctype = cmCustomCommandType::PRE_BUILD; break; case CM_PRE_LINK: - cctype = cmTarget::PRE_LINK; + cctype = cmCustomCommandType::PRE_LINK; break; case CM_POST_BUILD: - cctype = cmTarget::POST_BUILD; + cctype = cmCustomCommandType::POST_BUILD; break; } diff --git a/Source/cmCustomCommandTypes.h b/Source/cmCustomCommandTypes.h new file mode 100644 index 0000000..d4bf1f9 --- /dev/null +++ b/Source/cmCustomCommandTypes.h @@ -0,0 +1,39 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmCustomCommandTypes_h +#define cmCustomCommandTypes_h + +#include "cmConfigure.h" // IWYU pragma: keep + +#include <string> + +/** Target custom command type */ +enum class cmCustomCommandType +{ + PRE_BUILD, + PRE_LINK, + POST_BUILD +}; + +/** Where the command originated from. */ +enum class cmCommandOrigin +{ + Project, + Generator +}; + +/** How to handle custom commands for object libraries */ +enum class cmObjectLibraryCommands +{ + Reject, + Accept +}; + +/** Utility target output source file name. */ +struct cmUtilityOutput +{ + std::string Name; + std::string NameCMP0049; +}; + +#endif diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 2273c50..c4974f3 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -2582,7 +2582,7 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget(GlobalTargetInfo const& gti, cmCustomCommand cc(nullptr, no_outputs, no_byproducts, no_depends, gti.CommandLines, nullptr, gti.WorkingDir.c_str()); cc.SetUsesTerminal(gti.UsesTerminal); - target.AddPostBuildCommand(cc); + target.AddPostBuildCommand(std::move(cc)); if (!gti.Message.empty()) { target.SetProperty("EchoString", gti.Message.c_str()); } diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index f25d2e2..8e6125b 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -96,17 +96,18 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() return false; } - const char* no_working_directory = nullptr; - std::vector<std::string> no_depends; std::vector<cmLocalGenerator*> const& generators = this->LocalGenerators; cmLocalVisualStudio7Generator* lg = static_cast<cmLocalVisualStudio7Generator*>(generators[0]); cmMakefile* mf = lg->GetMakefile(); - cmCustomCommandLines noCommandLines; + const char* no_working_directory = nullptr; + std::vector<std::string> no_byproducts; + std::vector<std::string> no_depends; + cmCustomCommandLines no_commands; cmTarget* tgt = mf->AddUtilityCommand( - CMAKE_CHECK_BUILD_SYSTEM_TARGET, cmMakefile::TargetOrigin::Generator, - false, no_working_directory, no_depends, noCommandLines); + CMAKE_CHECK_BUILD_SYSTEM_TARGET, cmCommandOrigin::Generator, false, + no_working_directory, no_byproducts, no_depends, no_commands); cmGeneratorTarget* gt = new cmGeneratorTarget(tgt, lg); lg->AddGeneratorTarget(gt); @@ -152,10 +153,10 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() std::vector<std::string> byproducts; byproducts.push_back(cm->GetGlobVerifyStamp()); - mf->AddCustomCommandToTarget(CMAKE_CHECK_BUILD_SYSTEM_TARGET, byproducts, - no_depends, verifyCommandLines, - cmTarget::PRE_BUILD, "Checking File Globs", - no_working_directory, false); + mf->AddCustomCommandToTarget( + CMAKE_CHECK_BUILD_SYSTEM_TARGET, byproducts, no_depends, + verifyCommandLines, cmCustomCommandType::PRE_BUILD, + "Checking File Globs", no_working_directory, false); // Ensure ZERO_CHECK always runs in Visual Studio using MSBuild, // otherwise the prebuild command will not be run. @@ -182,7 +183,6 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() // file as the main dependency because it would get // overwritten by the CreateVCProjBuildRule. // (this could be avoided with per-target source files) - std::vector<std::string> no_byproducts; std::string no_main_dependency; cmImplicitDependsList no_implicit_depends; if (cmSourceFile* file = mf->AddCustomCommandToOutput( diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index 7a564ed..0bc08a5 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -183,7 +183,8 @@ void cmGlobalVisualStudioGenerator::AddExtraIDETargets() { // Add a special target that depends on ALL projects for easy build // of one configuration only. - const char* no_working_dir = 0; + const char* no_working_dir = nullptr; + std::vector<std::string> no_byproducts; std::vector<std::string> no_depends; cmCustomCommandLines no_commands; for (auto const& it : this->ProjectMap) { @@ -193,8 +194,8 @@ void cmGlobalVisualStudioGenerator::AddExtraIDETargets() // Use no actual command lines so that the target itself is not // considered always out of date. cmTarget* allBuild = gen[0]->GetMakefile()->AddUtilityCommand( - "ALL_BUILD", cmMakefile::TargetOrigin::Generator, true, no_working_dir, - no_depends, no_commands, false, "Build all projects"); + "ALL_BUILD", cmCommandOrigin::Generator, true, no_working_dir, + no_byproducts, no_depends, no_commands, false, "Build all projects"); cmGeneratorTarget* gt = new cmGeneratorTarget(allBuild, gen[0]); gen[0]->AddGeneratorTarget(gt); diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 2c3d3ad..4202175 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -497,12 +497,14 @@ void cmGlobalXCodeGenerator::AddExtraTargets( { cmMakefile* mf = root->GetMakefile(); - // Add ALL_BUILD const char* no_working_directory = nullptr; + std::vector<std::string> no_byproducts; std::vector<std::string> no_depends; + + // Add ALL_BUILD cmTarget* allbuild = mf->AddUtilityCommand( - "ALL_BUILD", cmMakefile::TargetOrigin::Generator, true, - no_working_directory, no_depends, + "ALL_BUILD", cmCommandOrigin::Generator, true, no_working_directory, + no_byproducts, no_depends, cmMakeSingleCommandLine({ "echo", "Build all projects" })); cmGeneratorTarget* allBuildGt = new cmGeneratorTarget(allbuild, root); @@ -526,8 +528,8 @@ void cmGlobalXCodeGenerator::AddExtraTargets( this->ConvertToRelativeForMake(this->CurrentReRunCMakeMakefile); cmSystemTools::ReplaceString(file, "\\ ", " "); cmTarget* check = mf->AddUtilityCommand( - CMAKE_CHECK_BUILD_SYSTEM_TARGET, cmMakefile::TargetOrigin::Generator, - true, no_working_directory, no_depends, + CMAKE_CHECK_BUILD_SYSTEM_TARGET, cmCommandOrigin::Generator, true, + no_working_directory, no_byproducts, no_depends, cmMakeSingleCommandLine({ "make", "-f", file })); cmGeneratorTarget* checkGt = new cmGeneratorTarget(check, root); @@ -542,9 +544,8 @@ void cmGlobalXCodeGenerator::AddExtraTargets( continue; } - std::string targetName = target->GetName(); - - if (regenerate && (targetName != CMAKE_CHECK_BUILD_SYSTEM_TARGET)) { + if (regenerate && + (target->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET)) { target->Target->AddUtility(CMAKE_CHECK_BUILD_SYSTEM_TARGET); } @@ -555,11 +556,11 @@ void cmGlobalXCodeGenerator::AddExtraTargets( if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) { commandLines.front().back() = // fill placeholder this->PostBuildMakeTarget(target->GetName(), "$(CONFIGURATION)"); - std::vector<std::string> no_byproducts; gen->GetMakefile()->AddCustomCommandToTarget( target->GetName(), no_byproducts, no_depends, commandLines, - cmTarget::POST_BUILD, "Depend check for xcode", dir.c_str(), true, - false, "", "", false, cmMakefile::AcceptObjectLibraryCommands); + cmCustomCommandType::POST_BUILD, "Depend check for xcode", + dir.c_str(), true, false, "", "", false, + cmObjectLibraryCommands::Accept); } if (!this->IsExcluded(target)) { diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 93e074d..7af3da5 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -7,6 +7,7 @@ #include "cmCustomCommand.h" #include "cmCustomCommandGenerator.h" #include "cmCustomCommandLines.h" +#include "cmCustomCommandTypes.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorExpression.h" #include "cmGeneratorExpressionEvaluationFile.h" @@ -2356,7 +2357,7 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target, if (this->GetGlobalGenerator()->IsMultiConfig()) { this->Makefile->AddCustomCommandToTarget( target->GetName(), outputs, no_deps, commandLines, - cmTarget::PRE_BUILD, no_message, no_current_dir); + cmCustomCommandType::PRE_BUILD, no_message, no_current_dir); } else { cmImplicitDependsList no_implicit_depends; cmSourceFile* copy_rule = this->Makefile->AddCustomCommandToOutput( diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 34081ed..a528fc6 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -39,6 +39,7 @@ #include "cmStateDirectory.h" #include "cmStateTypes.h" #include "cmSystemTools.h" +#include "cmTarget.h" #include "cmTargetLinkLibraryType.h" #include "cmTest.h" #include "cmTestGenerator.h" // IWYU pragma: keep @@ -837,13 +838,8 @@ bool cmMakefile::ValidateCustomCommand( return true; } -cmTarget* cmMakefile::AddCustomCommandToTarget( - const std::string& target, const std::vector<std::string>& byproducts, - const std::vector<std::string>& depends, - const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType type, - const char* comment, const char* workingDir, bool escapeOldStyle, - bool uses_terminal, const std::string& depfile, const std::string& job_pool, - bool command_expand_lists, ObjectLibraryCommands objLibraryCommands) +cmTarget* cmMakefile::GetCustomCommandTarget( + const std::string& target, cmObjectLibraryCommands objLibCommands) const { // Find the target to which to add the custom command. auto ti = this->Targets.find(target); @@ -884,7 +880,7 @@ cmTarget* cmMakefile::AddCustomCommandToTarget( } cmTarget* t = &ti->second; - if (objLibraryCommands == RejectObjectLibraryCommands && + if (objLibCommands == cmObjectLibraryCommands::Reject && t->GetType() == cmStateEnums::OBJECT_LIBRARY) { std::ostringstream e; e << "Target \"" << target @@ -902,8 +898,21 @@ cmTarget* cmMakefile::AddCustomCommandToTarget( return nullptr; } + return t; +} + +cmTarget* cmMakefile::AddCustomCommandToTarget( + const std::string& target, const std::vector<std::string>& byproducts, + const std::vector<std::string>& depends, + const cmCustomCommandLines& commandLines, cmCustomCommandType type, + const char* comment, const char* workingDir, bool escapeOldStyle, + bool uses_terminal, const std::string& depfile, const std::string& job_pool, + bool command_expand_lists, cmObjectLibraryCommands objLibCommands) +{ + cmTarget* t = this->GetCustomCommandTarget(target, objLibCommands); + // Validate custom commands. - if (!this->ValidateCustomCommand(commandLines)) { + if (!t || !this->ValidateCustomCommand(commandLines)) { return t; } @@ -920,7 +929,7 @@ cmTarget* cmMakefile::AddCustomCommandToTarget( void cmMakefile::CommitCustomCommandToTarget( cmTarget* target, const std::vector<std::string>& byproducts, const std::vector<std::string>& depends, - const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType type, + const cmCustomCommandLines& commandLines, cmCustomCommandType type, const char* comment, const char* workingDir, bool escapeOldStyle, bool uses_terminal, const std::string& depfile, const std::string& job_pool, bool command_expand_lists) @@ -936,47 +945,18 @@ void cmMakefile::CommitCustomCommandToTarget( cc.SetDepfile(depfile); cc.SetJobPool(job_pool); switch (type) { - case cmTarget::PRE_BUILD: - target->AddPreBuildCommand(cc); + case cmCustomCommandType::PRE_BUILD: + target->AddPreBuildCommand(std::move(cc)); break; - case cmTarget::PRE_LINK: - target->AddPreLinkCommand(cc); + case cmCustomCommandType::PRE_LINK: + target->AddPreLinkCommand(std::move(cc)); break; - case cmTarget::POST_BUILD: - target->AddPostBuildCommand(cc); + case cmCustomCommandType::POST_BUILD: + target->AddPostBuildCommand(std::move(cc)); break; } - this->UpdateOutputToSourceMap(byproducts, target); -} - -void cmMakefile::UpdateOutputToSourceMap( - std::vector<std::string> const& byproducts, cmTarget* target) -{ - for (std::string const& o : byproducts) { - this->UpdateOutputToSourceMap(o, target); - } -} - -void cmMakefile::UpdateOutputToSourceMap(std::string const& byproduct, - cmTarget* target) -{ - SourceEntry entry; - entry.Sources.Target = target; - auto pr = this->OutputToSource.emplace(byproduct, entry); - if (!pr.second) { - SourceEntry& current = pr.first->second; - // Has the target already been set? - if (!current.Sources.Target) { - current.Sources.Target = target; - } else { - // Multiple custom commands/targets produce the same output (source file - // or target). See also comment in other UpdateOutputToSourceMap - // overload. - // - // TODO: Warn the user about this case. - } - } + this->AddTargetByproducts(target, byproducts); } cmSourceFile* cmMakefile::AddCustomCommandToOutput( @@ -1102,47 +1082,10 @@ cmSourceFile* cmMakefile::CommitCustomCommandToOutput( cc->SetDepfile(depfile); cc->SetJobPool(job_pool); file->SetCustomCommand(std::move(cc)); - this->UpdateOutputToSourceMap(outputs, file, false); - this->UpdateOutputToSourceMap(byproducts, file, true); - } - return file; -} - -void cmMakefile::UpdateOutputToSourceMap( - std::vector<std::string> const& outputs, cmSourceFile* source, - bool byproduct) -{ - for (std::string const& o : outputs) { - this->UpdateOutputToSourceMap(o, source, byproduct); - } -} - -void cmMakefile::UpdateOutputToSourceMap(std::string const& output, - cmSourceFile* source, bool byproduct) -{ - SourceEntry entry; - entry.Sources.Source = source; - entry.Sources.SourceIsByproduct = byproduct; - auto pr = this->OutputToSource.emplace(output, entry); - if (!pr.second) { - SourceEntry& current = pr.first->second; - // Outputs take precedence over byproducts - if (!current.Sources.Source || - (current.Sources.SourceIsByproduct && !byproduct)) { - current.Sources.Source = source; - current.Sources.SourceIsByproduct = false; - } else { - // Multiple custom commands produce the same output but may - // be attached to a different source file (MAIN_DEPENDENCY). - // LinearGetSourceFileWithOutput would return the first one, - // so keep the mapping for the first one. - // - // TODO: Warn the user about this case. However, the VS 8 generator - // triggers it for separate generate.stamp rules in ZERO_CHECK and - // individual targets. - } + this->AddSourceOutputs(file, outputs, byproducts); } + return file; } void cmMakefile::AddCustomCommandOldStyle( @@ -1157,9 +1100,9 @@ void cmMakefile::AddCustomCommandOldStyle( // same then it added a post-build rule to the target. Preserve // this behavior. std::vector<std::string> no_byproducts; - this->AddCustomCommandToTarget(target, no_byproducts, depends, - commandLines, cmTarget::POST_BUILD, comment, - nullptr); + this->AddCustomCommandToTarget( + target, no_byproducts, depends, commandLines, + cmCustomCommandType::POST_BUILD, comment, nullptr); return; } @@ -1247,85 +1190,73 @@ void cmMakefile::CommitAppendCustomCommandToOutput( } } -cmTarget* cmMakefile::AddUtilityCommand( - const std::string& utilityName, TargetOrigin origin, bool excludeFromAll, - const char* workingDirectory, const std::vector<std::string>& depends, - const cmCustomCommandLines& commandLines, bool escapeOldStyle, - const char* comment, bool uses_terminal, bool command_expand_lists, - const std::string& job_pool) +cmUtilityOutput cmMakefile::GetUtilityOutput(cmTarget* target) { - std::vector<std::string> no_byproducts; - return this->AddUtilityCommand( - utilityName, origin, excludeFromAll, workingDirectory, no_byproducts, - depends, commandLines, escapeOldStyle, comment, uses_terminal, - command_expand_lists, job_pool); + std::string force = cmStrCat(this->GetCurrentBinaryDirectory(), + "/CMakeFiles/", target->GetName()); + std::string forceCMP0049 = target->GetSourceCMP0049(force); + { + cmSourceFile* sf = nullptr; + if (!forceCMP0049.empty()) { + sf = this->GetOrCreateSource(forceCMP0049, false, + cmSourceFileLocationKind::Known); + } + // The output is not actually created so mark it symbolic. + if (sf) { + sf->SetProperty("SYMBOLIC", "1"); + } else { + cmSystemTools::Error("Could not get source file entry for " + force); + } + } + return { std::move(force), std::move(forceCMP0049) }; } cmTarget* cmMakefile::AddUtilityCommand( - const std::string& utilityName, TargetOrigin origin, bool excludeFromAll, + const std::string& utilityName, cmCommandOrigin origin, bool excludeFromAll, const char* workingDirectory, const std::vector<std::string>& byproducts, const std::vector<std::string>& depends, const cmCustomCommandLines& commandLines, bool escapeOldStyle, const char* comment, bool uses_terminal, bool command_expand_lists, const std::string& job_pool) { - // Create a target instance for this utility. - cmTarget* target = this->AddNewTarget(cmStateEnums::UTILITY, utilityName); - target->SetIsGeneratorProvided(origin == TargetOrigin::Generator); - if (excludeFromAll || this->GetPropertyAsBool("EXCLUDE_FROM_ALL")) { - target->SetProperty("EXCLUDE_FROM_ALL", "TRUE"); - } + cmTarget* target = + this->AddNewUtilityTarget(utilityName, origin, excludeFromAll); // Validate custom commands. - if (!this->ValidateCustomCommand(commandLines) || - (commandLines.empty() && depends.empty())) { + if ((commandLines.empty() && depends.empty()) || + !this->ValidateCustomCommand(commandLines)) { return target; } + // Get the output name of the utility target and mark it generated. + cmUtilityOutput force = this->GetUtilityOutput(target); + this->GetOrCreateGeneratedSource(force.Name); + // Always create the byproduct sources and mark them generated. this->CreateGeneratedSources(byproducts); - std::string force = - cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/", utilityName); - this->CreateGeneratedSource(force); - std::string forceCMP0049 = target->GetSourceCMP0049(force); - { - cmSourceFile* sf = nullptr; - if (!forceCMP0049.empty()) { - sf = this->GetOrCreateSource(forceCMP0049, false, - cmSourceFileLocationKind::Known); - } - // The output is not actually created so mark it symbolic. - if (sf) { - sf->SetProperty("SYMBOLIC", "1"); - } else { - cmSystemTools::Error("Could not get source file entry for " + force); - } - } - if (!comment) { // Use an empty comment to avoid generation of default comment. comment = ""; } - this->CommitUtilityCommand(target, force, forceCMP0049, workingDirectory, - byproducts, depends, commandLines, escapeOldStyle, - comment, uses_terminal, command_expand_lists, - job_pool); + this->CommitUtilityCommand(target, force, workingDirectory, byproducts, + depends, commandLines, escapeOldStyle, comment, + uses_terminal, command_expand_lists, job_pool); return target; } void cmMakefile::CommitUtilityCommand( - cmTarget* target, const std::string& force, const std::string& forceCMP0049, - const char* workingDirectory, const std::vector<std::string>& byproducts, + cmTarget* target, const cmUtilityOutput& force, const char* workingDirectory, + const std::vector<std::string>& byproducts, const std::vector<std::string>& depends, const cmCustomCommandLines& commandLines, bool escapeOldStyle, const char* comment, bool uses_terminal, bool command_expand_lists, const std::string& job_pool) { std::vector<std::string> forced; - forced.push_back(force); + forced.push_back(force.Name); std::string no_main_dependency; cmImplicitDependsList no_implicit_depends; bool no_replace = false; @@ -1333,11 +1264,11 @@ void cmMakefile::CommitUtilityCommand( forced, byproducts, depends, no_main_dependency, no_implicit_depends, commandLines, comment, workingDirectory, no_replace, escapeOldStyle, uses_terminal, command_expand_lists, /*depfile=*/"", job_pool); - if (!forceCMP0049.empty()) { - target->AddSource(forceCMP0049); + if (!force.NameCMP0049.empty()) { + target->AddSource(force.NameCMP0049); } if (sf) { - this->UpdateOutputToSourceMap(byproducts, target); + this->AddTargetByproducts(target, byproducts); } } @@ -2156,6 +2087,18 @@ cmTarget* cmMakefile::AddNewTarget(cmStateEnums::TargetType type, return &it->second; } +cmTarget* cmMakefile::AddNewUtilityTarget(const std::string& utilityName, + cmCommandOrigin origin, + bool excludeFromAll) +{ + cmTarget* target = this->AddNewTarget(cmStateEnums::UTILITY, utilityName); + target->SetIsGeneratorProvided(origin == cmCommandOrigin::Generator); + if (excludeFromAll || this->GetPropertyAsBool("EXCLUDE_FROM_ALL")) { + target->SetProperty("EXCLUDE_FROM_ALL", "TRUE"); + } + return target; +} + namespace { bool AnyOutputMatches(const std::string& name, const std::vector<std::string>& outputs) @@ -2286,6 +2229,76 @@ bool cmMakefile::MightHaveCustomCommand(const std::string& name) const return false; } +void cmMakefile::AddTargetByproducts( + cmTarget* target, const std::vector<std::string>& byproducts) +{ + for (std::string const& o : byproducts) { + this->UpdateOutputToSourceMap(o, target); + } +} + +void cmMakefile::AddSourceOutputs(cmSourceFile* source, + const std::vector<std::string>& outputs, + const std::vector<std::string>& byproducts) +{ + for (std::string const& o : outputs) { + this->UpdateOutputToSourceMap(o, source, false); + } + for (std::string const& o : byproducts) { + this->UpdateOutputToSourceMap(o, source, true); + } +} + +void cmMakefile::UpdateOutputToSourceMap(std::string const& byproduct, + cmTarget* target) +{ + SourceEntry entry; + entry.Sources.Target = target; + + auto pr = this->OutputToSource.emplace(byproduct, entry); + if (!pr.second) { + SourceEntry& current = pr.first->second; + // Has the target already been set? + if (!current.Sources.Target) { + current.Sources.Target = target; + } else { + // Multiple custom commands/targets produce the same output (source file + // or target). See also comment in other UpdateOutputToSourceMap + // overload. + // + // TODO: Warn the user about this case. + } + } +} + +void cmMakefile::UpdateOutputToSourceMap(std::string const& output, + cmSourceFile* source, bool byproduct) +{ + SourceEntry entry; + entry.Sources.Source = source; + entry.Sources.SourceIsByproduct = byproduct; + + auto pr = this->OutputToSource.emplace(output, entry); + if (!pr.second) { + SourceEntry& current = pr.first->second; + // Outputs take precedence over byproducts + if (!current.Sources.Source || + (current.Sources.SourceIsByproduct && !byproduct)) { + current.Sources.Source = source; + current.Sources.SourceIsByproduct = false; + } else { + // Multiple custom commands produce the same output but may + // be attached to a different source file (MAIN_DEPENDENCY). + // LinearGetSourceFileWithOutput would return the first one, + // so keep the mapping for the first one. + // + // TODO: Warn the user about this case. However, the VS 8 generator + // triggers it for separate generate.stamp rules in ZERO_CHECK and + // individual targets. + } + } +} + #if !defined(CMAKE_BOOTSTRAP) cmSourceGroup* cmMakefile::GetSourceGroup( const std::vector<std::string>& name) const @@ -3530,19 +3543,20 @@ cmSourceFile* cmMakefile::GetOrCreateSource(const std::string& sourceName, return this->CreateSource(sourceName, generated, kind); } -void cmMakefile::CreateGeneratedSource(const std::string& output) +cmSourceFile* cmMakefile::GetOrCreateGeneratedSource( + const std::string& sourceName) { - if (cmSourceFile* out = this->GetOrCreateSource( - output, true, cmSourceFileLocationKind::Known)) { - out->SetProperty("GENERATED", "1"); - } + cmSourceFile* sf = + this->GetOrCreateSource(sourceName, true, cmSourceFileLocationKind::Known); + sf->SetProperty("GENERATED", "1"); + return sf; } void cmMakefile::CreateGeneratedSources( const std::vector<std::string>& outputs) { for (std::string const& output : outputs) { - this->CreateGeneratedSource(output); + this->GetOrCreateGeneratedSource(output); } } diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index db37477..bb88bed 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -20,6 +20,7 @@ #include <cm/string_view> #include "cmAlgorithms.h" +#include "cmCustomCommandTypes.h" #include "cmListFileCache.h" #include "cmMessageType.h" #include "cmNewLineStyle.h" @@ -28,7 +29,10 @@ #include "cmStateSnapshot.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" -#include "cmTarget.h" + +// IWYU does not see that 'std::unordered_map<std::string, cmTarget>' +// will not compile without the complete type. +#include "cmTarget.h" // IWYU pragma: keep #if !defined(CMAKE_BOOTSTRAP) # include "cmSourceGroup.h" @@ -164,22 +168,21 @@ public: */ void FinalPass(); - /** How to handle custom commands for object libraries */ - enum ObjectLibraryCommands - { - RejectObjectLibraryCommands, - AcceptObjectLibraryCommands - }; + /** + * Get the target for PRE_BUILD, PRE_LINK, or POST_BUILD commands. + */ + cmTarget* GetCustomCommandTarget( + const std::string& target, cmObjectLibraryCommands objLibCommands) const; /** Add a custom command to the build. */ cmTarget* AddCustomCommandToTarget( const std::string& target, const std::vector<std::string>& byproducts, const std::vector<std::string>& depends, - const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType type, + const cmCustomCommandLines& commandLines, cmCustomCommandType type, const char* comment, const char* workingDir, bool escapeOldStyle = true, bool uses_terminal = false, const std::string& depfile = "", const std::string& job_pool = "", bool command_expand_lists = false, - ObjectLibraryCommands objLibraryCommands = RejectObjectLibraryCommands); + cmObjectLibraryCommands objLibCommands = cmObjectLibraryCommands::Reject); cmSourceFile* AddCustomCommandToOutput( const std::string& output, const std::vector<std::string>& depends, const std::string& main_dependency, @@ -209,6 +212,19 @@ public: const cmCustomCommandLines& commandLines); /** + * Add target byproducts. + */ + void AddTargetByproducts(cmTarget* target, + const std::vector<std::string>& byproducts); + + /** + * Add source file outputs. + */ + void AddSourceOutputs(cmSourceFile* source, + const std::vector<std::string>& outputs, + const std::vector<std::string>& byproducts); + + /** * Add a define flag to the build. */ void AddDefineFlag(std::string const& definition); @@ -225,6 +241,10 @@ public: cmTarget* AddNewTarget(cmStateEnums::TargetType type, const std::string& name); + /** Create a target instance for the utility. */ + cmTarget* AddNewUtilityTarget(const std::string& utilityName, + cmCommandOrigin origin, bool excludeFromAll); + /** * Add an executable to the build. */ @@ -232,26 +252,19 @@ public: const std::vector<std::string>& srcs, bool excludeFromAll = false); - /** Where the target originated from. */ - enum class TargetOrigin - { - Project, - Generator - }; + /** + * Return the utility target output source file name and the CMP0049 name. + */ + cmUtilityOutput GetUtilityOutput(cmTarget* target); /** * Add a utility to the build. A utility target is a command that * is run every time the target is built. */ cmTarget* AddUtilityCommand( - const std::string& utilityName, TargetOrigin origin, bool excludeFromAll, - const char* workingDirectory, const std::vector<std::string>& depends, - const cmCustomCommandLines& commandLines, bool escapeOldStyle = true, - const char* comment = nullptr, bool uses_terminal = false, - bool command_expand_lists = false, const std::string& job_pool = ""); - cmTarget* AddUtilityCommand( - const std::string& utilityName, TargetOrigin origin, bool excludeFromAll, - const char* workingDirectory, const std::vector<std::string>& byproducts, + const std::string& utilityName, cmCommandOrigin origin, + bool excludeFromAll, const char* workingDirectory, + const std::vector<std::string>& byproducts, const std::vector<std::string>& depends, const cmCustomCommandLines& commandLines, bool escapeOldStyle = true, const char* comment = nullptr, bool uses_terminal = false, @@ -455,6 +468,12 @@ public: const std::string& sourceName, bool generated = false, cmSourceFileLocationKind kind = cmSourceFileLocationKind::Ambiguous); + /** Get a cmSourceFile pointer for a given source name and always mark the + * file as generated, if the name is not found, then create the source file + * and return it. + */ + cmSourceFile* GetOrCreateGeneratedSource(const std::string& sourceName); + void AddTargetObject(std::string const& tgtName, std::string const& objFile); /** @@ -1036,13 +1055,12 @@ private: friend bool cmCMakePolicyCommand(std::vector<std::string> const& args, cmExecutionStatus& status); class IncludeScope; - friend class IncludeScope; - class ListFileScope; + class ListFileScope; friend class ListFileScope; - class BuildsystemFileScope; + class BuildsystemFileScope; friend class BuildsystemFileScope; // CMP0053 == old @@ -1061,10 +1079,12 @@ private: bool ValidateCustomCommand(const cmCustomCommandLines& commandLines) const; + void CreateGeneratedSources(const std::vector<std::string>& outputs); + void CommitCustomCommandToTarget( cmTarget* target, const std::vector<std::string>& byproducts, const std::vector<std::string>& depends, - const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType type, + const cmCustomCommandLines& commandLines, cmCustomCommandType type, const char* comment, const char* workingDir, bool escapeOldStyle, bool uses_terminal, const std::string& depfile, const std::string& job_pool, bool command_expand_lists); @@ -1083,8 +1103,7 @@ private: const cmImplicitDependsList& implicit_depends, const cmCustomCommandLines& commandLines); - void CommitUtilityCommand(cmTarget* target, const std::string& force, - const std::string& forceCMP0049, + void CommitUtilityCommand(cmTarget* target, const cmUtilityOutput& force, const char* workingDirectory, const std::vector<std::string>& byproducts, const std::vector<std::string>& depends, @@ -1093,9 +1112,6 @@ private: bool uses_terminal, bool command_expand_lists, const std::string& job_pool); - void CreateGeneratedSource(const std::string& output); - void CreateGeneratedSources(const std::vector<std::string>& outputs); - /** * See LinearGetSourceFileWithOutput for background information */ @@ -1120,12 +1136,7 @@ private: using OutputToSourceMap = std::unordered_map<std::string, SourceEntry>; OutputToSourceMap OutputToSource; - void UpdateOutputToSourceMap(std::vector<std::string> const& byproducts, - cmTarget* target); void UpdateOutputToSourceMap(std::string const& byproduct, cmTarget* target); - - void UpdateOutputToSourceMap(std::vector<std::string> const& outputs, - cmSourceFile* source, bool byproduct); void UpdateOutputToSourceMap(std::string const& output, cmSourceFile* source, bool byproduct); diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx index 576a034..751ad50 100644 --- a/Source/cmQtAutoGenGlobalInitializer.cxx +++ b/Source/cmQtAutoGenGlobalInitializer.cxx @@ -3,6 +3,7 @@ #include "cmQtAutoGenGlobalInitializer.h" #include "cmCustomCommandLines.h" +#include "cmCustomCommandTypes.h" #include "cmDuration.h" #include "cmGeneratorTarget.h" #include "cmLocalGenerator.h" @@ -154,7 +155,7 @@ void cmQtAutoGenGlobalInitializer::GetOrCreateGlobalTarget( // Create utility target cmTarget* target = makefile->AddUtilityCommand( - name, cmMakefile::TargetOrigin::Generator, true, + name, cmCommandOrigin::Generator, true, makefile->GetHomeOutputDirectory().c_str() /*work dir*/, std::vector<std::string>() /*output*/, std::vector<std::string>() /*depends*/, cmCustomCommandLines(), false, diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index 0d56fe1..d7b9fa2 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -8,6 +8,7 @@ #include "cmAlgorithms.h" #include "cmCustomCommand.h" #include "cmCustomCommandLines.h" +#include "cmCustomCommandTypes.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" @@ -1085,7 +1086,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() this->Dir.Work.c_str()); cc.SetEscapeOldStyle(false); cc.SetEscapeAllowMakeVars(true); - this->GenTarget->Target->AddPreBuildCommand(cc); + this->GenTarget->Target->AddPreBuildCommand(std::move(cc)); } else { // Add link library target dependencies to the autogen target @@ -1117,7 +1118,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() // Create autogen target cmTarget* autogenTarget = this->Makefile->AddUtilityCommand( - this->AutogenTarget.Name, cmMakefile::TargetOrigin::Generator, true, + this->AutogenTarget.Name, cmCommandOrigin::Generator, true, this->Dir.Work.c_str(), /*byproducts=*/autogenProvides, std::vector<std::string>(this->AutogenTarget.DependFiles.begin(), this->AutogenTarget.DependFiles.end()), @@ -1199,9 +1200,8 @@ bool cmQtAutoGenInitializer::InitRccTargets() } cmTarget* autoRccTarget = this->Makefile->AddUtilityCommand( - ccName, cmMakefile::TargetOrigin::Generator, true, - this->Dir.Work.c_str(), ccOutput, ccDepends, commandLines, false, - ccComment.c_str()); + ccName, cmCommandOrigin::Generator, true, this->Dir.Work.c_str(), + ccOutput, ccDepends, commandLines, false, ccComment.c_str()); // Create autogen generator target this->LocalGen->AddGeneratorTarget( diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 1b88db6..ae77d9e 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -604,6 +604,11 @@ void cmTarget::AddPreBuildCommand(cmCustomCommand const& cmd) impl->PreBuildCommands.push_back(cmd); } +void cmTarget::AddPreBuildCommand(cmCustomCommand&& cmd) +{ + impl->PreBuildCommands.push_back(std::move(cmd)); +} + std::vector<cmCustomCommand> const& cmTarget::GetPreLinkCommands() const { return impl->PreLinkCommands; @@ -614,6 +619,11 @@ void cmTarget::AddPreLinkCommand(cmCustomCommand const& cmd) impl->PreLinkCommands.push_back(cmd); } +void cmTarget::AddPreLinkCommand(cmCustomCommand&& cmd) +{ + impl->PreLinkCommands.push_back(std::move(cmd)); +} + std::vector<cmCustomCommand> const& cmTarget::GetPostBuildCommands() const { return impl->PostBuildCommands; @@ -624,6 +634,11 @@ void cmTarget::AddPostBuildCommand(cmCustomCommand const& cmd) impl->PostBuildCommands.push_back(cmd); } +void cmTarget::AddPostBuildCommand(cmCustomCommand&& cmd) +{ + impl->PostBuildCommands.push_back(std::move(cmd)); +} + void cmTarget::AddTracedSources(std::vector<std::string> const& srcs) { if (!srcs.empty()) { diff --git a/Source/cmTarget.h b/Source/cmTarget.h index f4726d3..65a1ce3 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -43,13 +43,6 @@ public: VisibilityImportedGlobally }; - enum CustomCommandType - { - PRE_BUILD, - PRE_LINK, - POST_BUILD - }; - cmTarget(std::string const& name, cmStateEnums::TargetType type, Visibility vis, cmMakefile* mf); @@ -91,14 +84,17 @@ public: //! Get the list of the PRE_BUILD custom commands for this target std::vector<cmCustomCommand> const& GetPreBuildCommands() const; void AddPreBuildCommand(cmCustomCommand const& cmd); + void AddPreBuildCommand(cmCustomCommand&& cmd); //! Get the list of the PRE_LINK custom commands for this target std::vector<cmCustomCommand> const& GetPreLinkCommands() const; void AddPreLinkCommand(cmCustomCommand const& cmd); + void AddPreLinkCommand(cmCustomCommand&& cmd); //! Get the list of the POST_BUILD custom commands for this target std::vector<cmCustomCommand> const& GetPostBuildCommands() const; void AddPostBuildCommand(cmCustomCommand const& cmd); + void AddPostBuildCommand(cmCustomCommand&& cmd); //! Add sources to the target. void AddSources(std::vector<std::string> const& srcs); |