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
This commit is contained in:
Brad King
2019-09-27 18:54:39 +00:00
committed by Kitware Robot
16 changed files with 323 additions and 240 deletions

View File

@@ -195,6 +195,7 @@ set(SRCS
cmCustomCommandGenerator.h
cmCustomCommandLines.cxx
cmCustomCommandLines.h
cmCustomCommandTypes.h
cmDefinitions.cxx
cmDefinitions.h
cmDepends.cxx

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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());
}

View File

@@ -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(

View File

@@ -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);

View File

@@ -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)) {

View File

@@ -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(

View File

@@ -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,49 +1082,12 @@ 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);
this->AddSourceOutputs(file, outputs, byproducts);
}
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.
}
}
}
void cmMakefile::AddCustomCommandOldStyle(
const std::string& target, const std::vector<std::string>& outputs,
const std::vector<std::string>& depends, const std::string& source,
@@ -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,47 +1190,10 @@ 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);
}
cmTarget* cmMakefile::AddUtilityCommand(
const std::string& utilityName, TargetOrigin 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");
}
// Validate custom commands.
if (!this->ValidateCustomCommand(commandLines) ||
(commandLines.empty() && depends.empty())) {
return target;
}
// 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 force = cmStrCat(this->GetCurrentBinaryDirectory(),
"/CMakeFiles/", target->GetName());
std::string forceCMP0049 = target->GetSourceCMP0049(force);
{
cmSourceFile* sf = nullptr;
@@ -1302,30 +1208,55 @@ cmTarget* cmMakefile::AddUtilityCommand(
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);
return target;
return { std::move(force), std::move(forceCMP0049) };
}
void cmMakefile::CommitUtilityCommand(
cmTarget* target, const std::string& force, const std::string& forceCMP0049,
cmTarget* cmMakefile::AddUtilityCommand(
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)
{
cmTarget* target =
this->AddNewUtilityTarget(utilityName, origin, excludeFromAll);
// Validate custom commands.
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);
if (!comment) {
// Use an empty comment to avoid generation of default comment.
comment = "";
}
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 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);
}
}

View File

@@ -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,
@@ -208,6 +211,19 @@ public:
const cmImplicitDependsList& implicit_depends,
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.
*/
@@ -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;
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);

View File

@@ -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,

View File

@@ -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(

View File

@@ -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()) {

View File

@@ -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);