add_custom_command: Target-dependent generator expression support

OUTPUT variant with a TARGET given to allow resolving target-based generator
expressions wouldn't work because OUTPUT is resolved before generator targets
are created, i.e. FindGeneratorTargetToUse() returns nullptr.
This is a known limitation, see #21364.

Implements #21336.
This commit is contained in:
Raul Tambre
2020-12-19 14:14:18 +02:00
parent 7676e11943
commit 1cb4f592a0
9 changed files with 65 additions and 7 deletions
+10
View File
@@ -150,3 +150,13 @@ void cmCustomCommand::SetCMP0116Status(cmPolicies::PolicyStatus cmp0116)
{
this->CMP0116Status = cmp0116;
}
const std::string& cmCustomCommand::GetTarget() const
{
return this->Target;
}
void cmCustomCommand::SetTarget(const std::string& target)
{
this->Target = target;
}
+5
View File
@@ -100,6 +100,10 @@ public:
cmPolicies::PolicyStatus GetCMP0116Status() const;
void SetCMP0116Status(cmPolicies::PolicyStatus cmp0116);
/** Set/Get the associated target */
const std::string& GetTarget() const;
void SetTarget(const std::string& target);
private:
std::vector<std::string> Outputs;
std::vector<std::string> Byproducts;
@@ -107,6 +111,7 @@ private:
cmCustomCommandLines CommandLines;
cmListFileBacktrace Backtrace;
cmImplicitDependsList ImplicitDepends;
std::string Target;
std::string Comment;
std::string WorkingDirectory;
std::string Depfile;
+11 -7
View File
@@ -29,7 +29,7 @@ namespace {
std::string EvaluateSplitConfigGenex(
cm::string_view input, cmGeneratorExpression const& ge, cmLocalGenerator* lg,
bool useOutputConfig, std::string const& outputConfig,
std::string const& commandConfig,
std::string const& commandConfig, cmGeneratorTarget const* target,
std::set<BT<std::pair<std::string, bool>>>* utils = nullptr)
{
std::string result;
@@ -87,7 +87,7 @@ std::string EvaluateSplitConfigGenex(
// Evaluate this genex in the selected configuration.
std::unique_ptr<cmCompiledGeneratorExpression> cge =
ge.Parse(std::string(genex));
result += cge->Evaluate(lg, *config);
result += cge->Evaluate(lg, *config, target);
// Record targets referenced by the genex.
if (utils) {
@@ -114,7 +114,8 @@ std::vector<std::string> EvaluateDepends(std::vector<std::string> const& paths,
std::string const& ep =
EvaluateSplitConfigGenex(p, ge, lg, /*useOutputConfig=*/true,
/*outputConfig=*/outputConfig,
/*commandConfig=*/commandConfig);
/*commandConfig=*/commandConfig,
/*target=*/nullptr);
cm::append(depends, cmExpandedList(ep));
}
for (std::string& p : depends) {
@@ -157,6 +158,7 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(
: CC(&cc)
, OutputConfig(crossConfig ? *crossConfig : config)
, CommandConfig(std::move(config))
, Target(cc.GetTarget())
, LG(lg)
, OldStyle(cc.GetEscapeOldStyle())
, MakeVars(cc.GetEscapeAllowMakeVars())
@@ -171,6 +173,8 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(
}
cmGeneratorExpression ge(cc.GetBacktrace());
cmGeneratorTarget const* target{ lg->FindGeneratorTargetToUse(
this->Target) };
const cmCustomCommandLines& cmdlines = this->CC->GetCommandLines();
for (cmCustomCommandLine const& cmdline : cmdlines) {
@@ -180,7 +184,7 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(
for (std::string const& clarg : cmdline) {
std::string parsed_arg = EvaluateSplitConfigGenex(
clarg, ge, this->LG, useOutputConfig, this->OutputConfig,
this->CommandConfig, &this->Utilities);
this->CommandConfig, target, &this->Utilities);
if (this->CC->GetCommandExpandLists()) {
cm::append(argv, cmExpandedList(parsed_arg));
} else {
@@ -249,9 +253,9 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(
const std::string& workingdirectory = this->CC->GetWorkingDirectory();
if (!workingdirectory.empty()) {
this->WorkingDirectory =
EvaluateSplitConfigGenex(workingdirectory, ge, this->LG, true,
this->OutputConfig, this->CommandConfig);
this->WorkingDirectory = EvaluateSplitConfigGenex(
workingdirectory, ge, this->LG, true, this->OutputConfig,
this->CommandConfig, target);
// Convert working directory to a full path.
if (!this->WorkingDirectory.empty()) {
std::string const& build_dir = this->LG->GetCurrentBinaryDirectory();
+1
View File
@@ -25,6 +25,7 @@ class cmCustomCommandGenerator
cmCustomCommand const* CC;
std::string OutputConfig;
std::string CommandConfig;
std::string Target;
cmLocalGenerator* LG;
bool OldStyle;
bool MakeVars;
+1
View File
@@ -4096,6 +4096,7 @@ void AddCustomCommandToTarget(cmLocalGenerator& lg,
cc.SetDepfile(depfile);
cc.SetJobPool(job_pool);
cc.SetCMP0116Status(cmp0116);
cc.SetTarget(target->GetName());
switch (type) {
case cmCustomCommandType::PRE_BUILD:
target->AddPreBuildCommand(std::move(cc));