mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-16 22:37:30 +08:00
cmLocalGenerator: Refactor custom command generator construction
Add support for constructing and using multiple generators for one custom command. cmGeneratorTarget contains a code path that needs this behavior when used with Ninja but not other generators, so use virtual dispatch through cmLocalGenerator.
This commit is contained in:
@@ -3079,15 +3079,16 @@ void cmTargetTraceDependencies::CheckCustomCommand(cmCustomCommand const& cc)
|
|||||||
std::set<std::string> depends;
|
std::set<std::string> depends;
|
||||||
for (std::string const& config :
|
for (std::string const& config :
|
||||||
this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig)) {
|
this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig)) {
|
||||||
cmCustomCommandGenerator ccg(cc, config, this->LocalGenerator);
|
for (cmCustomCommandGenerator const& ccg :
|
||||||
|
this->LocalGenerator->MakeCustomCommandGenerators(cc, config)) {
|
||||||
|
// Collect target-level dependencies referenced in command lines.
|
||||||
|
for (auto const& util : ccg.GetUtilities()) {
|
||||||
|
this->GeneratorTarget->Target->AddUtility(util);
|
||||||
|
}
|
||||||
|
|
||||||
// Collect target-level dependencies referenced in command lines.
|
// Collect file-level dependencies referenced in DEPENDS.
|
||||||
for (auto const& util : ccg.GetUtilities()) {
|
depends.insert(ccg.GetDepends().begin(), ccg.GetDepends().end());
|
||||||
this->GeneratorTarget->Target->AddUtility(util);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect file-level dependencies referenced in DEPENDS.
|
|
||||||
depends.insert(ccg.GetDepends().begin(), ccg.GetDepends().end());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Queue file-level dependencies.
|
// Queue file-level dependencies.
|
||||||
|
@@ -4232,6 +4232,15 @@ cmSourceFile* cmLocalGenerator::GetSourceFileWithOutput(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<cmCustomCommandGenerator>
|
||||||
|
cmLocalGenerator::MakeCustomCommandGenerators(cmCustomCommand const& cc,
|
||||||
|
std::string const& config)
|
||||||
|
{
|
||||||
|
std::vector<cmCustomCommandGenerator> ccgs;
|
||||||
|
ccgs.emplace_back(cc, config, this);
|
||||||
|
return ccgs;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> cmLocalGenerator::ExpandCustomCommandOutputPaths(
|
std::vector<std::string> cmLocalGenerator::ExpandCustomCommandOutputPaths(
|
||||||
cmCompiledGeneratorExpression const& cge, std::string const& config)
|
cmCompiledGeneratorExpression const& cge, std::string const& config)
|
||||||
{
|
{
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
class cmCompiledGeneratorExpression;
|
class cmCompiledGeneratorExpression;
|
||||||
class cmComputeLinkInformation;
|
class cmComputeLinkInformation;
|
||||||
|
class cmCustomCommand;
|
||||||
class cmCustomCommandGenerator;
|
class cmCustomCommandGenerator;
|
||||||
class cmCustomCommandLines;
|
class cmCustomCommandLines;
|
||||||
class cmGeneratorTarget;
|
class cmGeneratorTarget;
|
||||||
@@ -363,6 +364,9 @@ public:
|
|||||||
bool command_expand_lists = false, const std::string& job_pool = "",
|
bool command_expand_lists = false, const std::string& job_pool = "",
|
||||||
bool stdPipesUTF8 = false);
|
bool stdPipesUTF8 = false);
|
||||||
|
|
||||||
|
virtual std::vector<cmCustomCommandGenerator> MakeCustomCommandGenerators(
|
||||||
|
cmCustomCommand const& cc, std::string const& config);
|
||||||
|
|
||||||
std::vector<std::string> ExpandCustomCommandOutputPaths(
|
std::vector<std::string> ExpandCustomCommandOutputPaths(
|
||||||
cmCompiledGeneratorExpression const& cge, std::string const& config);
|
cmCompiledGeneratorExpression const& cge, std::string const& config);
|
||||||
std::vector<std::string> ExpandCustomCommandOutputGenex(
|
std::vector<std::string> ExpandCustomCommandOutputGenex(
|
||||||
|
@@ -575,9 +575,95 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (cmCustomCommandGenerator const& ccg :
|
||||||
|
this->MakeCustomCommandGenerators(*cc, config)) {
|
||||||
|
|
||||||
|
const std::vector<std::string>& outputs = ccg.GetOutputs();
|
||||||
|
const std::vector<std::string>& byproducts = ccg.GetByproducts();
|
||||||
|
|
||||||
|
bool symbolic = false;
|
||||||
|
for (std::string const& output : outputs) {
|
||||||
|
if (cmSourceFile* sf = this->Makefile->GetSource(output)) {
|
||||||
|
if (sf->GetPropertyAsBool("SYMBOLIC")) {
|
||||||
|
symbolic = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmNinjaDeps ninjaOutputs(outputs.size() + byproducts.size());
|
||||||
|
std::transform(outputs.begin(), outputs.end(), ninjaOutputs.begin(),
|
||||||
|
gg->MapToNinjaPath());
|
||||||
|
std::transform(byproducts.begin(), byproducts.end(),
|
||||||
|
ninjaOutputs.begin() + outputs.size(),
|
||||||
|
gg->MapToNinjaPath());
|
||||||
|
|
||||||
|
for (std::string const& ninjaOutput : ninjaOutputs) {
|
||||||
|
gg->SeenCustomCommandOutput(ninjaOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmNinjaDeps ninjaDeps;
|
||||||
|
this->AppendCustomCommandDeps(ccg, ninjaDeps, config);
|
||||||
|
|
||||||
|
std::vector<std::string> cmdLines;
|
||||||
|
this->AppendCustomCommandLines(ccg, cmdLines);
|
||||||
|
|
||||||
|
if (cmdLines.empty()) {
|
||||||
|
cmNinjaBuild build("phony");
|
||||||
|
build.Comment = "Phony custom command for " + ninjaOutputs[0];
|
||||||
|
build.Outputs = std::move(ninjaOutputs);
|
||||||
|
build.ExplicitDeps = std::move(ninjaDeps);
|
||||||
|
build.OrderOnlyDeps = orderOnlyDeps;
|
||||||
|
gg->WriteBuild(this->GetImplFileStream(config), build);
|
||||||
|
} else {
|
||||||
|
std::string customStep = cmSystemTools::GetFilenameName(ninjaOutputs[0]);
|
||||||
|
// Hash full path to make unique.
|
||||||
|
customStep += '-';
|
||||||
|
cmCryptoHash hash(cmCryptoHash::AlgoSHA256);
|
||||||
|
customStep += hash.HashString(ninjaOutputs[0]).substr(0, 7);
|
||||||
|
|
||||||
|
std::string depfile = cc->GetDepfile();
|
||||||
|
if (!depfile.empty()) {
|
||||||
|
switch (this->GetPolicyStatus(cmPolicies::CMP0116)) {
|
||||||
|
case cmPolicies::WARN:
|
||||||
|
if (this->GetCurrentBinaryDirectory() !=
|
||||||
|
this->GetBinaryDirectory() ||
|
||||||
|
this->Makefile->PolicyOptionalWarningEnabled(
|
||||||
|
"CMAKE_POLICY_WARNING_CMP0116")) {
|
||||||
|
this->GetCMakeInstance()->IssueMessage(
|
||||||
|
MessageType::AUTHOR_WARNING,
|
||||||
|
cmPolicies::GetPolicyWarning(cmPolicies::CMP0116),
|
||||||
|
cc->GetBacktrace());
|
||||||
|
}
|
||||||
|
CM_FALLTHROUGH;
|
||||||
|
case cmPolicies::OLD:
|
||||||
|
break;
|
||||||
|
case cmPolicies::REQUIRED_IF_USED:
|
||||||
|
case cmPolicies::REQUIRED_ALWAYS:
|
||||||
|
case cmPolicies::NEW:
|
||||||
|
cmSystemTools::MakeDirectory(
|
||||||
|
cmStrCat(this->GetBinaryDirectory(), "/CMakeFiles/d"));
|
||||||
|
depfile = ccg.GetInternalDepfile();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gg->WriteCustomCommandBuild(
|
||||||
|
this->BuildCommandLine(cmdLines, customStep),
|
||||||
|
this->ConstructComment(ccg), "Custom command for " + ninjaOutputs[0],
|
||||||
|
depfile, cc->GetJobPool(), cc->GetUsesTerminal(),
|
||||||
|
/*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, config,
|
||||||
|
ninjaDeps, orderOnlyDeps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<cmCustomCommandGenerator>
|
||||||
|
cmLocalNinjaGenerator::MakeCustomCommandGenerators(cmCustomCommand const& cc,
|
||||||
|
std::string const& config)
|
||||||
|
{
|
||||||
bool transformDepfile = false;
|
bool transformDepfile = false;
|
||||||
auto cmp0116 = this->GetPolicyStatus(cmPolicies::CMP0116);
|
switch (this->GetPolicyStatus(cmPolicies::CMP0116)) {
|
||||||
switch (cmp0116) {
|
|
||||||
case cmPolicies::OLD:
|
case cmPolicies::OLD:
|
||||||
case cmPolicies::WARN:
|
case cmPolicies::WARN:
|
||||||
break;
|
break;
|
||||||
@@ -588,84 +674,9 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmCustomCommandGenerator ccg(*cc, config, this, transformDepfile);
|
std::vector<cmCustomCommandGenerator> ccgs;
|
||||||
|
ccgs.emplace_back(cc, config, this, transformDepfile);
|
||||||
const std::vector<std::string>& outputs = ccg.GetOutputs();
|
return ccgs;
|
||||||
const std::vector<std::string>& byproducts = ccg.GetByproducts();
|
|
||||||
|
|
||||||
bool symbolic = false;
|
|
||||||
for (std::string const& output : outputs) {
|
|
||||||
if (cmSourceFile* sf = this->Makefile->GetSource(output)) {
|
|
||||||
if (sf->GetPropertyAsBool("SYMBOLIC")) {
|
|
||||||
symbolic = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cmNinjaDeps ninjaOutputs(outputs.size() + byproducts.size());
|
|
||||||
std::transform(outputs.begin(), outputs.end(), ninjaOutputs.begin(),
|
|
||||||
gg->MapToNinjaPath());
|
|
||||||
std::transform(byproducts.begin(), byproducts.end(),
|
|
||||||
ninjaOutputs.begin() + outputs.size(), gg->MapToNinjaPath());
|
|
||||||
|
|
||||||
for (std::string const& ninjaOutput : ninjaOutputs) {
|
|
||||||
gg->SeenCustomCommandOutput(ninjaOutput);
|
|
||||||
}
|
|
||||||
|
|
||||||
cmNinjaDeps ninjaDeps;
|
|
||||||
this->AppendCustomCommandDeps(ccg, ninjaDeps, config);
|
|
||||||
|
|
||||||
std::vector<std::string> cmdLines;
|
|
||||||
this->AppendCustomCommandLines(ccg, cmdLines);
|
|
||||||
|
|
||||||
if (cmdLines.empty()) {
|
|
||||||
cmNinjaBuild build("phony");
|
|
||||||
build.Comment = "Phony custom command for " + ninjaOutputs[0];
|
|
||||||
build.Outputs = std::move(ninjaOutputs);
|
|
||||||
build.ExplicitDeps = std::move(ninjaDeps);
|
|
||||||
build.OrderOnlyDeps = orderOnlyDeps;
|
|
||||||
gg->WriteBuild(this->GetImplFileStream(config), build);
|
|
||||||
} else {
|
|
||||||
std::string customStep = cmSystemTools::GetFilenameName(ninjaOutputs[0]);
|
|
||||||
// Hash full path to make unique.
|
|
||||||
customStep += '-';
|
|
||||||
cmCryptoHash hash(cmCryptoHash::AlgoSHA256);
|
|
||||||
customStep += hash.HashString(ninjaOutputs[0]).substr(0, 7);
|
|
||||||
|
|
||||||
std::string depfile = cc->GetDepfile();
|
|
||||||
if (!depfile.empty()) {
|
|
||||||
switch (cmp0116) {
|
|
||||||
case cmPolicies::WARN:
|
|
||||||
if (this->GetCurrentBinaryDirectory() !=
|
|
||||||
this->GetBinaryDirectory() ||
|
|
||||||
this->Makefile->PolicyOptionalWarningEnabled(
|
|
||||||
"CMAKE_POLICY_WARNING_CMP0116")) {
|
|
||||||
this->GetCMakeInstance()->IssueMessage(
|
|
||||||
MessageType::AUTHOR_WARNING,
|
|
||||||
cmPolicies::GetPolicyWarning(cmPolicies::CMP0116),
|
|
||||||
cc->GetBacktrace());
|
|
||||||
}
|
|
||||||
CM_FALLTHROUGH;
|
|
||||||
case cmPolicies::OLD:
|
|
||||||
break;
|
|
||||||
case cmPolicies::REQUIRED_IF_USED:
|
|
||||||
case cmPolicies::REQUIRED_ALWAYS:
|
|
||||||
case cmPolicies::NEW:
|
|
||||||
cmSystemTools::MakeDirectory(
|
|
||||||
cmStrCat(this->GetBinaryDirectory(), "/CMakeFiles/d"));
|
|
||||||
depfile = ccg.GetInternalDepfile();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gg->WriteCustomCommandBuild(
|
|
||||||
this->BuildCommandLine(cmdLines, customStep),
|
|
||||||
this->ConstructComment(ccg), "Custom command for " + ninjaOutputs[0],
|
|
||||||
depfile, cc->GetJobPool(), cc->GetUsesTerminal(),
|
|
||||||
/*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, config,
|
|
||||||
ninjaDeps, orderOnlyDeps);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmLocalNinjaGenerator::AddCustomCommandTarget(cmCustomCommand const* cc,
|
void cmLocalNinjaGenerator::AddCustomCommandTarget(cmCustomCommand const* cc,
|
||||||
|
@@ -70,6 +70,9 @@ public:
|
|||||||
const std::string& fileConfig,
|
const std::string& fileConfig,
|
||||||
cmNinjaTargetDepends depends);
|
cmNinjaTargetDepends depends);
|
||||||
|
|
||||||
|
std::vector<cmCustomCommandGenerator> MakeCustomCommandGenerators(
|
||||||
|
cmCustomCommand const& cc, std::string const& config) override;
|
||||||
|
|
||||||
void AddCustomCommandTarget(cmCustomCommand const* cc,
|
void AddCustomCommandTarget(cmCustomCommand const* cc,
|
||||||
cmGeneratorTarget* target);
|
cmGeneratorTarget* target);
|
||||||
void AppendCustomCommandLines(cmCustomCommandGenerator const& ccg,
|
void AppendCustomCommandLines(cmCustomCommandGenerator const& ccg,
|
||||||
|
Reference in New Issue
Block a user