GenEx: Rename cmGeneratorExpressionContext to cm::GenEx::Evaluation

It has grown to hold information about the evaluation itself,
not just the context in which the evaluation occurs.
This commit is contained in:
Brad King
2025-09-21 20:21:32 -04:00
parent d1c780886e
commit 4697f7122b
14 changed files with 749 additions and 841 deletions
+2 -2
View File
@@ -270,9 +270,9 @@ add_library(
cmGccDepfileLexerHelper.h
cmGccDepfileReader.cxx
cmGccDepfileReader.h
cmGenExEvaluation.cxx
cmGenExEvaluation.h
cmGeneratedFileStream.cxx
cmGeneratorExpressionContext.cxx
cmGeneratorExpressionContext.h
cmGeneratorExpressionDAGChecker.cxx
cmGeneratorExpressionDAGChecker.h
cmGeneratorExpressionEvaluationFile.cxx
+8 -8
View File
@@ -5,7 +5,7 @@
#include <unordered_map>
#include <utility>
#include "cmGeneratorExpressionContext.h"
#include "cmGenExEvaluation.h"
#include "cmGeneratorTarget.h"
#include "cmLinkItem.h"
#include "cmList.h"
@@ -64,13 +64,13 @@ void addInterfaceEntry(cmGeneratorTarget const* headTarget,
// Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in our
// caller's property and hand-evaluate it as if it were compiled.
// Create a context as cmCompiledGeneratorExpression::Evaluate does.
cmGeneratorExpressionContext context(
headTarget->GetLocalGenerator(), config, false, headTarget, headTarget,
true, lib.Backtrace, lang);
cmExpandList(lib.Target->EvaluateInterfaceProperty(prop, &context,
dagChecker, usage),
ee.Values);
ee.ContextDependent = context.HadContextSensitiveCondition;
cm::GenEx::Evaluation eval(headTarget->GetLocalGenerator(), config,
false, headTarget, headTarget, true,
lib.Backtrace, lang);
cmExpandList(
lib.Target->EvaluateInterfaceProperty(prop, &eval, dagChecker, usage),
ee.Values);
ee.ContextDependent = eval.HadContextSensitiveCondition;
entries.Entries.emplace_back(std::move(ee));
}
}
@@ -1,14 +1,17 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#include "cmGeneratorExpressionContext.h"
#include "cmGenExEvaluation.h"
#include <utility>
cmGeneratorExpressionContext::cmGeneratorExpressionContext(
cmLocalGenerator const* lg, std::string config, bool quiet,
cmGeneratorTarget const* headTarget, cmGeneratorTarget const* currentTarget,
bool evaluateForBuildsystem, cmListFileBacktrace backtrace,
std::string language)
namespace cm {
namespace GenEx {
Evaluation::Evaluation(cmLocalGenerator const* lg, std::string config,
bool quiet, cmGeneratorTarget const* headTarget,
cmGeneratorTarget const* currentTarget,
bool evaluateForBuildsystem,
cmListFileBacktrace backtrace, std::string language)
: Backtrace(std::move(backtrace))
, LG(lg)
, Config(std::move(config))
@@ -19,3 +22,6 @@ cmGeneratorExpressionContext::cmGeneratorExpressionContext(
, EvaluateForBuildsystem(evaluateForBuildsystem)
{
}
}
}
@@ -11,14 +11,16 @@
class cmGeneratorTarget;
class cmLocalGenerator;
struct cmGeneratorExpressionContext
namespace cm {
namespace GenEx {
struct Evaluation final
{
cmGeneratorExpressionContext(cmLocalGenerator const* lg, std::string config,
bool quiet, cmGeneratorTarget const* headTarget,
cmGeneratorTarget const* currentTarget,
bool evaluateForBuildsystem,
cmListFileBacktrace backtrace,
std::string language);
Evaluation(cmLocalGenerator const* lg, std::string config, bool quiet,
cmGeneratorTarget const* headTarget,
cmGeneratorTarget const* currentTarget,
bool evaluateForBuildsystem, cmListFileBacktrace backtrace,
std::string language);
cmListFileBacktrace Backtrace;
std::set<cmGeneratorTarget*> DependTargets;
@@ -42,3 +44,6 @@ struct cmGeneratorExpressionContext
bool HadLinkLanguageSensitiveCondition = false;
bool EvaluateForBuildsystem;
};
}
}
+17 -17
View File
@@ -12,7 +12,7 @@
#include "cmsys/RegularExpression.hxx"
#include "cmGeneratorExpressionContext.h"
#include "cmGenExEvaluation.h"
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorExpressionEvaluator.h"
#include "cmGeneratorExpressionLexer.h"
@@ -68,10 +68,10 @@ std::string const& cmCompiledGeneratorExpression::Evaluate(
cmGeneratorExpressionDAGChecker* dagChecker,
cmGeneratorTarget const* currentTarget, std::string const& language) const
{
cmGeneratorExpressionContext context(
lg, config, this->Quiet, headTarget,
currentTarget ? currentTarget : headTarget, this->EvaluateForBuildsystem,
this->Backtrace, language);
cm::GenEx::Evaluation eval(lg, config, this->Quiet, headTarget,
currentTarget ? currentTarget : headTarget,
this->EvaluateForBuildsystem, this->Backtrace,
language);
if (!this->NeedsEvaluation) {
return this->Input;
@@ -80,28 +80,28 @@ std::string const& cmCompiledGeneratorExpression::Evaluate(
this->Output.clear();
for (auto const& it : this->Evaluators) {
this->Output += it->Evaluate(&context, dagChecker);
this->Output += it->Evaluate(&eval, dagChecker);
this->SeenTargetProperties.insert(context.SeenTargetProperties.cbegin(),
context.SeenTargetProperties.cend());
if (context.HadError) {
this->SeenTargetProperties.insert(eval.SeenTargetProperties.cbegin(),
eval.SeenTargetProperties.cend());
if (eval.HadError) {
this->Output.clear();
break;
}
}
this->MaxLanguageStandard = context.MaxLanguageStandard;
this->MaxLanguageStandard = eval.MaxLanguageStandard;
if (!context.HadError) {
this->HadContextSensitiveCondition = context.HadContextSensitiveCondition;
this->HadHeadSensitiveCondition = context.HadHeadSensitiveCondition;
if (!eval.HadError) {
this->HadContextSensitiveCondition = eval.HadContextSensitiveCondition;
this->HadHeadSensitiveCondition = eval.HadHeadSensitiveCondition;
this->HadLinkLanguageSensitiveCondition =
context.HadLinkLanguageSensitiveCondition;
this->SourceSensitiveTargets = context.SourceSensitiveTargets;
eval.HadLinkLanguageSensitiveCondition;
this->SourceSensitiveTargets = eval.SourceSensitiveTargets;
}
this->DependTargets = context.DependTargets;
this->AllTargetsSeen = context.AllTargets;
this->DependTargets = eval.DependTargets;
this->AllTargetsSeen = eval.AllTargets;
return this->Output;
}
+12 -12
View File
@@ -9,7 +9,7 @@
#include <cm/string_view>
#include <cmext/string_view>
#include "cmGeneratorExpressionContext.h"
#include "cmGenExEvaluation.h"
#include "cmGeneratorExpressionEvaluator.h"
#include "cmGeneratorTarget.h"
#include "cmLocalGenerator.h"
@@ -62,15 +62,15 @@ cmGeneratorExpressionDAGChecker::Check() const
return this->CheckResult;
}
void cmGeneratorExpressionDAGChecker::ReportError(
cmGeneratorExpressionContext* context, std::string const& expr)
void cmGeneratorExpressionDAGChecker::ReportError(cm::GenEx::Evaluation* eval,
std::string const& expr)
{
if (this->CheckResult == DAG) {
return;
}
context->HadError = true;
if (context->Quiet) {
eval->HadError = true;
if (eval->Quiet) {
return;
}
@@ -80,10 +80,10 @@ void cmGeneratorExpressionDAGChecker::ReportError(
std::ostringstream e;
e << "Error evaluating generator expression:\n"
<< " " << expr << "\n"
<< "Self reference on target \"" << context->HeadTarget->GetName()
<< "Self reference on target \"" << eval->HeadTarget->GetName()
<< "\".\n";
context->LG->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
e.str(), parent->Backtrace);
eval->LG->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
e.str(), parent->Backtrace);
return;
}
@@ -94,8 +94,8 @@ void cmGeneratorExpressionDAGChecker::ReportError(
<< " " << expr << "\n"
<< "Dependency loop found.";
/* clang-format on */
context->LG->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
e.str(), context->Backtrace);
eval->LG->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
e.str(), eval->Backtrace);
}
int loopStep = 1;
@@ -105,8 +105,8 @@ void cmGeneratorExpressionDAGChecker::ReportError(
<< " "
<< (parent->Content ? parent->Content->GetOriginalExpression() : expr)
<< "\n";
context->LG->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
e.str(), parent->Backtrace);
eval->LG->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
e.str(), parent->Backtrace);
parent = parent->Parent;
++loopStep;
}
+7 -3
View File
@@ -10,8 +10,13 @@
#include "cmListFileCache.h"
namespace cm {
namespace GenEx {
struct Evaluation;
}
}
struct GeneratorExpressionContent;
struct cmGeneratorExpressionContext;
class cmGeneratorTarget;
class cmLocalGenerator;
@@ -41,8 +46,7 @@ struct cmGeneratorExpressionDAGChecker
Result Check() const;
void ReportError(cmGeneratorExpressionContext* context,
std::string const& expr);
void ReportError(cm::GenEx::Evaluation* eval, std::string const& expr);
bool EvaluatingTransitiveProperty() const;
bool EvaluatingGenexExpression() const;
+28 -32
View File
@@ -8,7 +8,7 @@
# include <cm3p/json/value.h>
#endif
#include "cmGeneratorExpressionContext.h"
#include "cmGenExEvaluation.h"
#include "cmGeneratorExpressionNode.h"
#include "cmLocalGenerator.h"
#include "cmake.h"
@@ -29,8 +29,7 @@ std::string GeneratorExpressionContent::GetOriginalExpression() const
std::string GeneratorExpressionContent::ProcessArbitraryContent(
cmGeneratorExpressionNode const* node, std::string const& identifier,
cmGeneratorExpressionContext* context,
cmGeneratorExpressionDAGChecker* dagChecker,
cm::GenEx::Evaluation* eval, cmGeneratorExpressionDAGChecker* dagChecker,
std::vector<cmGeneratorExpressionEvaluatorVector>::const_iterator pit) const
{
std::string result;
@@ -40,14 +39,14 @@ std::string GeneratorExpressionContent::ProcessArbitraryContent(
for (auto const& pExprEval : *pit) {
if (node->RequiresLiteralInput()) {
if (pExprEval->GetType() != cmGeneratorExpressionEvaluator::Text) {
reportError(context, this->GetOriginalExpression(),
reportError(eval, this->GetOriginalExpression(),
"$<" + identifier +
"> expression requires literal input.");
return std::string();
}
}
result += pExprEval->Evaluate(context, dagChecker);
if (context->HadError) {
result += pExprEval->Evaluate(eval, dagChecker);
if (eval->HadError) {
return std::string();
}
}
@@ -58,26 +57,25 @@ std::string GeneratorExpressionContent::ProcessArbitraryContent(
if (node->RequiresLiteralInput()) {
std::vector<std::string> parameters;
parameters.push_back(result);
return node->Evaluate(parameters, context, this, dagChecker);
return node->Evaluate(parameters, eval, this, dagChecker);
}
return result;
}
std::string GeneratorExpressionContent::Evaluate(
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
cmGeneratorExpressionDAGChecker* dagChecker) const
{
#ifndef CMAKE_BOOTSTRAP
auto evalProfilingRAII =
context->LG->GetCMakeInstance()->CreateProfilingEntry(
"genex_eval", this->GetOriginalExpression());
auto evalProfilingRAII = eval->LG->GetCMakeInstance()->CreateProfilingEntry(
"genex_eval", this->GetOriginalExpression());
#endif
std::string identifier;
{
for (auto const& pExprEval : this->IdentifierChildren) {
identifier += pExprEval->Evaluate(context, dagChecker);
if (context->HadError) {
identifier += pExprEval->Evaluate(eval, dagChecker);
if (eval->HadError) {
return std::string();
}
}
@@ -87,7 +85,7 @@ std::string GeneratorExpressionContent::Evaluate(
cmGeneratorExpressionNode::GetNode(identifier);
if (!node) {
reportError(context, this->GetOriginalExpression(),
reportError(eval, this->GetOriginalExpression(),
"Expression did not evaluate to a known generator expression");
return std::string();
}
@@ -96,27 +94,26 @@ std::string GeneratorExpressionContent::Evaluate(
if (node->NumExpectedParameters() == 1 &&
node->AcceptsArbitraryContentParameter()) {
if (this->ParamChildren.empty()) {
reportError(context, this->GetOriginalExpression(),
reportError(eval, this->GetOriginalExpression(),
"$<" + identifier + "> expression requires a parameter.");
}
} else {
std::vector<std::string> parameters;
this->EvaluateParameters(node, identifier, context, dagChecker,
parameters);
this->EvaluateParameters(node, identifier, eval, dagChecker, parameters);
}
return std::string();
}
std::vector<std::string> parameters;
this->EvaluateParameters(node, identifier, context, dagChecker, parameters);
if (context->HadError) {
this->EvaluateParameters(node, identifier, eval, dagChecker, parameters);
if (eval->HadError) {
return std::string();
}
{
#ifndef CMAKE_BOOTSTRAP
auto execProfilingRAII =
context->LG->GetCMakeInstance()->CreateProfilingEntry(
eval->LG->GetCMakeInstance()->CreateProfilingEntry(
"genex_exec", identifier, [&parameters]() -> Json::Value {
Json::Value args = Json::objectValue;
if (!parameters.empty()) {
@@ -129,14 +126,13 @@ std::string GeneratorExpressionContent::Evaluate(
});
#endif
return node->Evaluate(parameters, context, this, dagChecker);
return node->Evaluate(parameters, eval, this, dagChecker);
}
}
std::string GeneratorExpressionContent::EvaluateParameters(
cmGeneratorExpressionNode const* node, std::string const& identifier,
cmGeneratorExpressionContext* context,
cmGeneratorExpressionDAGChecker* dagChecker,
cm::GenEx::Evaluation* eval, cmGeneratorExpressionDAGChecker* dagChecker,
std::vector<std::string>& parameters) const
{
int const numExpected = node->NumExpectedParameters();
@@ -149,14 +145,14 @@ std::string GeneratorExpressionContent::EvaluateParameters(
for (; pit != pend; ++pit, ++counter) {
if (acceptsArbitraryContent && counter == numExpected) {
parameters.push_back(this->ProcessArbitraryContent(
node, identifier, context, dagChecker, pit));
node, identifier, eval, dagChecker, pit));
return std::string();
}
std::string parameter;
if (node->ShouldEvaluateNextParameter(parameters, parameter)) {
for (auto const& pExprEval : *pit) {
parameter += pExprEval->Evaluate(context, dagChecker);
if (context->HadError) {
parameter += pExprEval->Evaluate(eval, dagChecker);
if (eval->HadError) {
return std::string();
}
}
@@ -168,10 +164,10 @@ std::string GeneratorExpressionContent::EvaluateParameters(
if ((numExpected > cmGeneratorExpressionNode::DynamicParameters &&
static_cast<unsigned int>(numExpected) != parameters.size())) {
if (numExpected == 0) {
reportError(context, this->GetOriginalExpression(),
reportError(eval, this->GetOriginalExpression(),
"$<" + identifier + "> expression requires no parameters.");
} else if (numExpected == 1) {
reportError(context, this->GetOriginalExpression(),
reportError(eval, this->GetOriginalExpression(),
"$<" + identifier +
"> expression requires "
"exactly one parameter.");
@@ -180,24 +176,24 @@ std::string GeneratorExpressionContent::EvaluateParameters(
e << "$<" + identifier + "> expression requires " << numExpected
<< " comma separated parameters, but got " << parameters.size()
<< " instead.";
reportError(context, this->GetOriginalExpression(), e.str());
reportError(eval, this->GetOriginalExpression(), e.str());
}
return std::string();
}
if (numExpected == cmGeneratorExpressionNode::OneOrMoreParameters &&
parameters.empty()) {
reportError(context, this->GetOriginalExpression(),
reportError(eval, this->GetOriginalExpression(),
"$<" + identifier +
"> expression requires at least one parameter.");
} else if (numExpected == cmGeneratorExpressionNode::TwoOrMoreParameters &&
parameters.size() < 2) {
reportError(context, this->GetOriginalExpression(),
reportError(eval, this->GetOriginalExpression(),
"$<" + identifier +
"> expression requires at least two parameters.");
} else if (numExpected == cmGeneratorExpressionNode::OneOrZeroParameters &&
parameters.size() > 1) {
reportError(context, this->GetOriginalExpression(),
reportError(eval, this->GetOriginalExpression(),
"$<" + identifier +
"> expression requires one or zero parameters.");
}
+11 -7
View File
@@ -10,7 +10,12 @@
#include <utility>
#include <vector>
struct cmGeneratorExpressionContext;
namespace cm {
namespace GenEx {
struct Evaluation;
}
}
struct cmGeneratorExpressionDAGChecker;
struct cmGeneratorExpressionNode;
@@ -32,7 +37,7 @@ struct cmGeneratorExpressionEvaluator
virtual Type GetType() const = 0;
virtual std::string Evaluate(cmGeneratorExpressionContext* context,
virtual std::string Evaluate(cm::GenEx::Evaluation* eval,
cmGeneratorExpressionDAGChecker*) const = 0;
};
@@ -47,7 +52,7 @@ struct TextContent : public cmGeneratorExpressionEvaluator
{
}
std::string Evaluate(cmGeneratorExpressionContext*,
std::string Evaluate(cm::GenEx::Evaluation*,
cmGeneratorExpressionDAGChecker*) const override
{
return std::string(this->Content, this->Length);
@@ -87,7 +92,7 @@ struct GeneratorExpressionContent : public cmGeneratorExpressionEvaluator
return cmGeneratorExpressionEvaluator::Generator;
}
std::string Evaluate(cmGeneratorExpressionContext* context,
std::string Evaluate(cm::GenEx::Evaluation* eval,
cmGeneratorExpressionDAGChecker*) const override;
std::string GetOriginalExpression() const;
@@ -97,14 +102,13 @@ struct GeneratorExpressionContent : public cmGeneratorExpressionEvaluator
private:
std::string EvaluateParameters(cmGeneratorExpressionNode const* node,
std::string const& identifier,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
cmGeneratorExpressionDAGChecker* dagChecker,
std::vector<std::string>& parameters) const;
std::string ProcessArbitraryContent(
cmGeneratorExpressionNode const* node, std::string const& identifier,
cmGeneratorExpressionContext* context,
cmGeneratorExpressionDAGChecker* dagChecker,
cm::GenEx::Evaluation* eval, cmGeneratorExpressionDAGChecker* dagChecker,
std::vector<cmGeneratorExpressionEvaluatorVector>::const_iterator pit)
const;
+595 -702
View File
@@ -27,8 +27,8 @@
#include "cmCMakePath.h"
#include "cmComputeLinkInformation.h"
#include "cmGenExEvaluation.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionContext.h"
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorExpressionEvaluator.h"
#include "cmGeneratorTarget.h"
@@ -52,27 +52,26 @@
#include "cmake.h"
std::string cmGeneratorExpressionNode::EvaluateDependentExpression(
std::string const& prop, cmGeneratorExpressionContext* context,
std::string const& prop, cm::GenEx::Evaluation* eval,
cmGeneratorTarget const* headTarget,
cmGeneratorExpressionDAGChecker* dagChecker,
cmGeneratorTarget const* currentTarget)
{
cmGeneratorExpression ge(*context->LG->GetCMakeInstance(),
context->Backtrace);
cmGeneratorExpression ge(*eval->LG->GetCMakeInstance(), eval->Backtrace);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
cge->SetEvaluateForBuildsystem(context->EvaluateForBuildsystem);
cge->SetQuiet(context->Quiet);
cge->SetEvaluateForBuildsystem(eval->EvaluateForBuildsystem);
cge->SetQuiet(eval->Quiet);
std::string result =
cge->Evaluate(context->LG, context->Config, headTarget, dagChecker,
currentTarget, context->Language);
cge->Evaluate(eval->LG, eval->Config, headTarget, dagChecker,
currentTarget, eval->Language);
if (cge->GetHadContextSensitiveCondition()) {
context->HadContextSensitiveCondition = true;
eval->HadContextSensitiveCondition = true;
}
if (cge->GetHadHeadSensitiveCondition()) {
context->HadHeadSensitiveCondition = true;
eval->HadHeadSensitiveCondition = true;
}
if (cge->GetHadLinkLanguageSensitiveCondition()) {
context->HadLinkLanguageSensitiveCondition = true;
eval->HadLinkLanguageSensitiveCondition = true;
}
return result;
}
@@ -87,7 +86,7 @@ static const struct ZeroNode : public cmGeneratorExpressionNode
std::string Evaluate(
std::vector<std::string> const& /*parameters*/,
cmGeneratorExpressionContext* /*context*/,
cm::GenEx::Evaluation* /*eval*/,
GeneratorExpressionContent const* /*content*/,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
@@ -103,7 +102,7 @@ static const struct OneNode : public cmGeneratorExpressionNode
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* /*context*/,
cm::GenEx::Evaluation* /*eval*/,
GeneratorExpressionContent const* /*content*/,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
@@ -140,7 +139,7 @@ struct BooleanOpNode : public cmGeneratorExpressionNode
}
std::string Evaluate(std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker*) const override
{
@@ -152,7 +151,7 @@ struct BooleanOpNode : public cmGeneratorExpressionNode
std::ostringstream e;
e << "Parameters to $<" << this->op;
e << "> must resolve to either '0' or '1'.";
reportError(context, content->GetOriginalExpression(), e.str());
reportError(eval, content->GetOriginalExpression(), e.str());
return std::string();
}
}
@@ -169,14 +168,13 @@ static const struct NotNode : public cmGeneratorExpressionNode
NotNode() {} // NOLINT(modernize-use-equals-default)
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
if (parameters.front() != "0" && parameters.front() != "1") {
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"$<NOT> parameter must resolve to exactly one '0' or '1' value.");
return std::string();
}
@@ -192,7 +190,7 @@ static const struct BoolNode : public cmGeneratorExpressionNode
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* /*context*/,
cm::GenEx::Evaluation* /*eval*/,
GeneratorExpressionContent const* /*content*/,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
@@ -214,12 +212,12 @@ static const struct IfNode : public cmGeneratorExpressionNode
}
std::string Evaluate(std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker*) const override
{
if (parameters[0] != "1" && parameters[0] != "0") {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"First parameter to $<IF> must resolve to exactly one '0' "
"or '1' value.");
return std::string();
@@ -236,7 +234,7 @@ static const struct StrEqualNode : public cmGeneratorExpressionNode
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* /*context*/,
cm::GenEx::Evaluation* /*eval*/,
GeneratorExpressionContent const* /*content*/,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
@@ -251,15 +249,14 @@ static const struct EqualNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return 2; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
long numbers[2];
for (int i = 0; i < 2; ++i) {
if (!ParameterToLong(parameters[i].c_str(), &numbers[i])) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"$<EQUAL> parameter " + parameters[i] +
" is not a valid integer.");
return {};
@@ -304,15 +301,14 @@ static const struct InListNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return 2; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* /*content*/,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
cmList values;
cmList checkValues;
bool check = false;
switch (context->LG->GetPolicyStatus(cmPolicies::CMP0085)) {
switch (eval->LG->GetPolicyStatus(cmPolicies::CMP0085)) {
case cmPolicies::WARN:
if (parameters.front().empty()) {
check = true;
@@ -326,8 +322,8 @@ static const struct InListNode : public cmGeneratorExpressionNode
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0085)
<< "\nSearch Item:\n \"" << parameters.front()
<< "\"\nList:\n \"" << parameters[1] << "\"\n";
context->LG->GetCMakeInstance()->IssueMessage(
MessageType ::AUTHOR_WARNING, e.str(), context->Backtrace);
eval->LG->GetCMakeInstance()->IssueMessage(
MessageType ::AUTHOR_WARNING, e.str(), eval->Backtrace);
return "0";
}
if (values.empty()) {
@@ -350,20 +346,19 @@ static const struct FilterNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return 3; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
if (parameters.size() != 3) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"$<FILTER:...> expression requires three parameters");
return {};
}
if (parameters[1] != "INCLUDE" && parameters[1] != "EXCLUDE") {
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"$<FILTER:...> second parameter must be either INCLUDE or EXCLUDE");
return {};
}
@@ -375,7 +370,7 @@ static const struct FilterNode : public cmGeneratorExpressionNode
: cmList::FilterMode::INCLUDE)
.to_string();
} catch (std::invalid_argument&) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"$<FILTER:...> failed to compile regex");
return {};
}
@@ -389,14 +384,13 @@ static const struct RemoveDuplicatesNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return 1; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
if (parameters.size() != 1) {
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"$<REMOVE_DUPLICATES:...> expression requires one parameter");
}
@@ -414,13 +408,12 @@ static const struct TargetExistsNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return 1; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
if (parameters.size() != 1) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"$<TARGET_EXISTS:...> expression requires one parameter");
return std::string();
}
@@ -428,13 +421,13 @@ static const struct TargetExistsNode : public cmGeneratorExpressionNode
std::string const& targetName = parameters.front();
if (targetName.empty() ||
!cmGeneratorExpression::IsValidTargetName(targetName)) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"$<TARGET_EXISTS:tgt> expression requires a non-empty "
"valid target name.");
return std::string();
}
return context->LG->GetMakefile()->FindTargetToUse(targetName) ? "1" : "0";
return eval->LG->GetMakefile()->FindTargetToUse(targetName) ? "1" : "0";
}
} targetExistsNode;
@@ -445,13 +438,12 @@ static const struct TargetNameIfExistsNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return 1; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
if (parameters.size() != 1) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"$<TARGET_NAME_IF_EXISTS:...> expression requires one "
"parameter");
return std::string();
@@ -460,13 +452,13 @@ static const struct TargetNameIfExistsNode : public cmGeneratorExpressionNode
std::string const& targetName = parameters.front();
if (targetName.empty() ||
!cmGeneratorExpression::IsValidTargetName(targetName)) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"$<TARGET_NAME_IF_EXISTS:tgt> expression requires a "
"non-empty valid target name.");
return std::string();
}
return context->LG->GetMakefile()->FindTargetToUse(targetName)
return eval->LG->GetMakefile()->FindTargetToUse(targetName)
? targetName
: std::string();
}
@@ -479,24 +471,20 @@ struct GenexEvaluator : public cmGeneratorExpressionNode
protected:
std::string EvaluateExpression(
std::string const& genexOperator, std::string const& expression,
cmGeneratorExpressionContext* context,
GeneratorExpressionContent const* content,
cm::GenEx::Evaluation* eval, GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagCheckerParent) const
{
if (context->HeadTarget) {
if (eval->HeadTarget) {
cmGeneratorExpressionDAGChecker dagChecker{
context->HeadTarget,
genexOperator + ":" + expression,
content,
dagCheckerParent,
context->LG,
context->Config,
context->Backtrace,
eval->HeadTarget, genexOperator + ":" + expression,
content, dagCheckerParent,
eval->LG, eval->Config,
eval->Backtrace,
};
switch (dagChecker.Check()) {
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE: {
dagChecker.ReportError(context, content->GetOriginalExpression());
dagChecker.ReportError(eval, content->GetOriginalExpression());
return std::string();
}
case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
@@ -505,13 +493,12 @@ protected:
}
return this->EvaluateDependentExpression(
expression, context, context->HeadTarget, &dagChecker,
context->CurrentTarget);
expression, eval, eval->HeadTarget, &dagChecker, eval->CurrentTarget);
}
return this->EvaluateDependentExpression(
expression, context, context->HeadTarget, dagCheckerParent,
context->CurrentTarget);
expression, eval, eval->HeadTarget, dagCheckerParent,
eval->CurrentTarget);
}
};
@@ -524,26 +511,25 @@ static const struct TargetGenexEvalNode : public GenexEvaluator
bool AcceptsArbitraryContentParameter() const override { return true; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagCheckerParent) const override
{
std::string const& targetName = parameters.front();
if (targetName.empty() ||
!cmGeneratorExpression::IsValidTargetName(targetName)) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"$<TARGET_GENEX_EVAL:tgt, ...> expression requires a "
"non-empty valid target name.");
return std::string();
}
auto const* target = context->LG->FindGeneratorTargetToUse(targetName);
auto const* target = eval->LG->FindGeneratorTargetToUse(targetName);
if (!target) {
std::ostringstream e;
e << "$<TARGET_GENEX_EVAL:tgt, ...> target \"" << targetName
<< "\" not found.";
reportError(context, content->GetOriginalExpression(), e.str());
reportError(eval, content->GetOriginalExpression(), e.str());
return std::string();
}
@@ -553,12 +539,12 @@ static const struct TargetGenexEvalNode : public GenexEvaluator
}
// Replace the surrounding context with the named target.
cmGeneratorExpressionContext targetContext(
context->LG, context->Config, context->Quiet, target, target,
context->EvaluateForBuildsystem, context->Backtrace, context->Language);
cm::GenEx::Evaluation targetEval(
eval->LG, eval->Config, eval->Quiet, target, target,
eval->EvaluateForBuildsystem, eval->Backtrace, eval->Language);
return this->EvaluateExpression("TARGET_GENEX_EVAL", expression,
&targetContext, content, dagCheckerParent);
&targetEval, content, dagCheckerParent);
}
} targetGenexEvalNode;
@@ -571,8 +557,7 @@ static const struct GenexEvalNode : public GenexEvaluator
bool AcceptsArbitraryContentParameter() const override { return true; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagCheckerParent) const override
{
@@ -581,7 +566,7 @@ static const struct GenexEvalNode : public GenexEvaluator
return expression;
}
return this->EvaluateExpression("GENEX_EVAL", expression, context, content,
return this->EvaluateExpression("GENEX_EVAL", expression, eval, content,
dagCheckerParent);
}
} genexEvalNode;
@@ -594,7 +579,7 @@ static const struct LowerCaseNode : public cmGeneratorExpressionNode
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* /*context*/,
cm::GenEx::Evaluation* /*eval*/,
GeneratorExpressionContent const* /*content*/,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
@@ -610,7 +595,7 @@ static const struct UpperCaseNode : public cmGeneratorExpressionNode
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* /*context*/,
cm::GenEx::Evaluation* /*eval*/,
GeneratorExpressionContent const* /*content*/,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
@@ -659,7 +644,7 @@ public:
using Arguments = Range<std::vector<std::string>>;
bool CheckGenExParameters(cmGeneratorExpressionContext* ctx,
bool CheckGenExParameters(cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* cnt,
cm::string_view genex, cm::string_view option,
std::size_t count, int required = 1,
@@ -684,7 +669,7 @@ bool CheckGenExParameters(cmGeneratorExpressionContext* ctx,
default:
nbParameters = cmStrCat(required, " parameters");
}
reportError(ctx, cnt->GetOriginalExpression(),
reportError(eval, cnt->GetOriginalExpression(),
cmStrCat("$<", genex, ':', option, "> expression requires ",
(exactly ? "exactly" : "at least"), ' ', nbParameters,
'.'));
@@ -693,20 +678,20 @@ bool CheckGenExParameters(cmGeneratorExpressionContext* ctx,
return true;
};
bool CheckPathParametersEx(cmGeneratorExpressionContext* ctx,
bool CheckPathParametersEx(cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* cnt,
cm::string_view option, std::size_t count,
int required = 1, bool exactly = true)
{
return CheckGenExParameters(ctx, cnt, "PATH"_s, option, count, required,
return CheckGenExParameters(eval, cnt, "PATH"_s, option, count, required,
exactly);
}
bool CheckPathParameters(cmGeneratorExpressionContext* ctx,
bool CheckPathParameters(cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* cnt,
cm::string_view option, Arguments args,
int required = 1)
{
return CheckPathParametersEx(ctx, cnt, option, args.size(), required);
return CheckPathParametersEx(eval, cnt, option, args.size(), required);
};
std::string ToString(bool isTrue)
@@ -724,8 +709,7 @@ static const struct PathNode : public cmGeneratorExpressionNode
bool AcceptsArbitraryContentParameter() const override { return true; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
@@ -739,15 +723,14 @@ static const struct PathNode : public cmGeneratorExpressionNode
static std::unordered_map<
cm::string_view,
std::function<std::string(cmGeneratorExpressionContext*,
std::function<std::string(cm::GenEx::Evaluation*,
GeneratorExpressionContent const*,
Arguments&)>>
pathCommands{
{ "GET_ROOT_NAME"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckPathParameters(ctx, cnt, "GET_ROOT_NAME"_s, args) &&
if (CheckPathParameters(ev, cnt, "GET_ROOT_NAME"_s, args) &&
!args.front().empty()) {
return processList(args.front(), [](std::string& value) {
value = cmCMakePath{ value }.GetRootName().String();
@@ -756,10 +739,9 @@ static const struct PathNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "GET_ROOT_DIRECTORY"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckPathParameters(ctx, cnt, "GET_ROOT_DIRECTORY"_s, args) &&
if (CheckPathParameters(ev, cnt, "GET_ROOT_DIRECTORY"_s, args) &&
!args.front().empty()) {
return processList(args.front(), [](std::string& value) {
value = cmCMakePath{ value }.GetRootDirectory().String();
@@ -768,10 +750,9 @@ static const struct PathNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "GET_ROOT_PATH"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckPathParameters(ctx, cnt, "GET_ROOT_PATH"_s, args) &&
if (CheckPathParameters(ev, cnt, "GET_ROOT_PATH"_s, args) &&
!args.front().empty()) {
return processList(args.front(), [](std::string& value) {
value = cmCMakePath{ value }.GetRootPath().String();
@@ -780,10 +761,9 @@ static const struct PathNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "GET_FILENAME"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckPathParameters(ctx, cnt, "GET_FILENAME"_s, args) &&
if (CheckPathParameters(ev, cnt, "GET_FILENAME"_s, args) &&
!args.front().empty()) {
return processList(args.front(), [](std::string& value) {
value = cmCMakePath{ value }.GetFileName().String();
@@ -792,14 +772,13 @@ static const struct PathNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "GET_EXTENSION"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
bool lastOnly = args.front() == "LAST_ONLY"_s;
if (lastOnly) {
args.advance(1);
}
if (CheckPathParametersEx(ctx, cnt,
if (CheckPathParametersEx(ev, cnt,
lastOnly ? "GET_EXTENSION,LAST_ONLY"_s
: "GET_EXTENSION"_s,
args.size())) {
@@ -818,15 +797,14 @@ static const struct PathNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "GET_STEM"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
bool lastOnly = args.front() == "LAST_ONLY"_s;
if (lastOnly) {
args.advance(1);
}
if (CheckPathParametersEx(
ctx, cnt, lastOnly ? "GET_STEM,LAST_ONLY"_s : "GET_STEM"_s,
ev, cnt, lastOnly ? "GET_STEM,LAST_ONLY"_s : "GET_STEM"_s,
args.size())) {
if (args.front().empty()) {
return std::string{};
@@ -843,10 +821,9 @@ static const struct PathNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "GET_RELATIVE_PART"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckPathParameters(ctx, cnt, "GET_RELATIVE_PART"_s, args) &&
if (CheckPathParameters(ev, cnt, "GET_RELATIVE_PART"_s, args) &&
!args.front().empty()) {
return processList(args.front(), [](std::string& value) {
value = cmCMakePath{ value }.GetRelativePath().String();
@@ -855,10 +832,9 @@ static const struct PathNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "GET_PARENT_PATH"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckPathParameters(ctx, cnt, "GET_PARENT_PATH"_s, args)) {
if (CheckPathParameters(ev, cnt, "GET_PARENT_PATH"_s, args)) {
return processList(args.front(), [](std::string& value) {
value = cmCMakePath{ value }.GetParentPath().String();
});
@@ -866,98 +842,86 @@ static const struct PathNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "HAS_ROOT_NAME"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
return CheckPathParameters(ctx, cnt, "HAS_ROOT_NAME"_s, args)
return CheckPathParameters(ev, cnt, "HAS_ROOT_NAME"_s, args)
? ToString(cmCMakePath{ args.front() }.HasRootName())
: std::string{ "0" };
} },
{ "HAS_ROOT_DIRECTORY"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
return CheckPathParameters(ctx, cnt, "HAS_ROOT_DIRECTORY"_s, args)
return CheckPathParameters(ev, cnt, "HAS_ROOT_DIRECTORY"_s, args)
? ToString(cmCMakePath{ args.front() }.HasRootDirectory())
: std::string{ "0" };
} },
{ "HAS_ROOT_PATH"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
return CheckPathParameters(ctx, cnt, "HAS_ROOT_PATH"_s, args)
return CheckPathParameters(ev, cnt, "HAS_ROOT_PATH"_s, args)
? ToString(cmCMakePath{ args.front() }.HasRootPath())
: std::string{ "0" };
} },
{ "HAS_FILENAME"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
return CheckPathParameters(ctx, cnt, "HAS_FILENAME"_s, args)
return CheckPathParameters(ev, cnt, "HAS_FILENAME"_s, args)
? ToString(cmCMakePath{ args.front() }.HasFileName())
: std::string{ "0" };
} },
{ "HAS_EXTENSION"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
return CheckPathParameters(ctx, cnt, "HAS_EXTENSION"_s, args) &&
return CheckPathParameters(ev, cnt, "HAS_EXTENSION"_s, args) &&
!args.front().empty()
? ToString(cmCMakePath{ args.front() }.HasExtension())
: std::string{ "0" };
} },
{ "HAS_STEM"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
return CheckPathParameters(ctx, cnt, "HAS_STEM"_s, args)
return CheckPathParameters(ev, cnt, "HAS_STEM"_s, args)
? ToString(cmCMakePath{ args.front() }.HasStem())
: std::string{ "0" };
} },
{ "HAS_RELATIVE_PART"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
return CheckPathParameters(ctx, cnt, "HAS_RELATIVE_PART"_s, args)
return CheckPathParameters(ev, cnt, "HAS_RELATIVE_PART"_s, args)
? ToString(cmCMakePath{ args.front() }.HasRelativePath())
: std::string{ "0" };
} },
{ "HAS_PARENT_PATH"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
return CheckPathParameters(ctx, cnt, "HAS_PARENT_PATH"_s, args)
return CheckPathParameters(ev, cnt, "HAS_PARENT_PATH"_s, args)
? ToString(cmCMakePath{ args.front() }.HasParentPath())
: std::string{ "0" };
} },
{ "IS_ABSOLUTE"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
return CheckPathParameters(ctx, cnt, "IS_ABSOLUTE"_s, args)
return CheckPathParameters(ev, cnt, "IS_ABSOLUTE"_s, args)
? ToString(cmCMakePath{ args.front() }.IsAbsolute())
: std::string{ "0" };
} },
{ "IS_RELATIVE"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
return CheckPathParameters(ctx, cnt, "IS_RELATIVE"_s, args)
return CheckPathParameters(ev, cnt, "IS_RELATIVE"_s, args)
? ToString(cmCMakePath{ args.front() }.IsRelative())
: std::string{ "0" };
} },
{ "IS_PREFIX"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
bool normalize = args.front() == "NORMALIZE"_s;
if (normalize) {
args.advance(1);
}
if (CheckPathParametersEx(ctx, cnt,
normalize ? "IS_PREFIX,NORMALIZE"_s
: "IS_PREFIX"_s,
args.size(), 2)) {
if (CheckPathParametersEx(
ev, cnt, normalize ? "IS_PREFIX,NORMALIZE"_s : "IS_PREFIX"_s,
args.size(), 2)) {
if (normalize) {
return ToString(cmCMakePath{ args[0] }.Normal().IsPrefix(
cmCMakePath{ args[1] }.Normal()));
@@ -968,14 +932,13 @@ static const struct PathNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "CMAKE_PATH"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
bool normalize = args.front() == "NORMALIZE"_s;
if (normalize) {
args.advance(1);
}
if (CheckPathParametersEx(ctx, cnt,
if (CheckPathParametersEx(ev, cnt,
normalize ? "CMAKE_PATH,NORMALIZE"_s
: "CMAKE_PATH"_s,
args.size(), 1)) {
@@ -989,14 +952,13 @@ static const struct PathNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "NATIVE_PATH"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
bool normalize = args.front() == "NORMALIZE"_s;
if (normalize) {
args.advance(1);
}
if (CheckPathParametersEx(ctx, cnt,
if (CheckPathParametersEx(ev, cnt,
normalize ? "NATIVE_PATH,NORMALIZE"_s
: "NATIVE_PATH"_s,
args.size(), 1)) {
@@ -1010,10 +972,9 @@ static const struct PathNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "APPEND"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckPathParametersEx(ctx, cnt, "APPEND"_s, args.size(), 1,
if (CheckPathParametersEx(ev, cnt, "APPEND"_s, args.size(), 1,
false)) {
auto const& list = args.front();
args.advance(1);
@@ -1029,10 +990,9 @@ static const struct PathNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "REMOVE_FILENAME"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckPathParameters(ctx, cnt, "REMOVE_FILENAME"_s, args) &&
if (CheckPathParameters(ev, cnt, "REMOVE_FILENAME"_s, args) &&
!args.front().empty()) {
return processList(args.front(), [](std::string& value) {
value = cmCMakePath{ value }.RemoveFileName().String();
@@ -1041,10 +1001,9 @@ static const struct PathNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "REPLACE_FILENAME"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckPathParameters(ctx, cnt, "REPLACE_FILENAME"_s, args, 2)) {
if (CheckPathParameters(ev, cnt, "REPLACE_FILENAME"_s, args, 2)) {
return processList(args.front(), [&args](std::string& value) {
value = cmCMakePath{ value }
.ReplaceFileName(cmCMakePath{ args[1] })
@@ -1054,14 +1013,13 @@ static const struct PathNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "REMOVE_EXTENSION"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
bool lastOnly = args.front() == "LAST_ONLY"_s;
if (lastOnly) {
args.advance(1);
}
if (CheckPathParametersEx(ctx, cnt,
if (CheckPathParametersEx(ev, cnt,
lastOnly ? "REMOVE_EXTENSION,LAST_ONLY"_s
: "REMOVE_EXTENSION"_s,
args.size())) {
@@ -1080,14 +1038,13 @@ static const struct PathNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "REPLACE_EXTENSION"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
bool lastOnly = args.front() == "LAST_ONLY"_s;
if (lastOnly) {
args.advance(1);
}
if (CheckPathParametersEx(ctx, cnt,
if (CheckPathParametersEx(ev, cnt,
lastOnly
? "REPLACE_EXTENSION,LAST_ONLY"_s
: "REPLACE_EXTENSION"_s,
@@ -1108,10 +1065,9 @@ static const struct PathNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "NORMAL_PATH"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckPathParameters(ctx, cnt, "NORMAL_PATH"_s, args) &&
if (CheckPathParameters(ev, cnt, "NORMAL_PATH"_s, args) &&
!args.front().empty()) {
return processList(args.front(), [](std::string& value) {
value = cmCMakePath{ value }.Normal().String();
@@ -1120,10 +1076,9 @@ static const struct PathNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "RELATIVE_PATH"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckPathParameters(ctx, cnt, "RELATIVE_PATH"_s, args, 2)) {
if (CheckPathParameters(ev, cnt, "RELATIVE_PATH"_s, args, 2)) {
return processList(args.front(), [&args](std::string& value) {
value = cmCMakePath{ value }.Relative(args[1]).String();
});
@@ -1131,14 +1086,13 @@ static const struct PathNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "ABSOLUTE_PATH"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
bool normalize = args.front() == "NORMALIZE"_s;
if (normalize) {
args.advance(1);
}
if (CheckPathParametersEx(ctx, cnt,
if (CheckPathParametersEx(ev, cnt,
normalize ? "ABSOLUTE_PATH,NORMALIZE"_s
: "ABSOLUTE_PATH"_s,
args.size(), 2)) {
@@ -1154,10 +1108,10 @@ static const struct PathNode : public cmGeneratorExpressionNode
if (cm::contains(pathCommands, parameters.front())) {
auto args = Arguments{ parameters }.advance(1);
return pathCommands[parameters.front()](context, content, args);
return pathCommands[parameters.front()](eval, content, args);
}
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
cmStrCat(parameters.front(), ": invalid option."));
return std::string{};
}
@@ -1171,7 +1125,7 @@ static const struct PathEqualNode : public cmGeneratorExpressionNode
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* /*context*/,
cm::GenEx::Evaluation* /*eval*/,
GeneratorExpressionContent const* /*content*/,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
@@ -1181,20 +1135,20 @@ static const struct PathEqualNode : public cmGeneratorExpressionNode
} pathEqualNode;
namespace {
inline bool CheckListParametersEx(cmGeneratorExpressionContext* ctx,
inline bool CheckListParametersEx(cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* cnt,
cm::string_view option, std::size_t count,
int required = 1, bool exactly = true)
{
return CheckGenExParameters(ctx, cnt, "LIST"_s, option, count, required,
return CheckGenExParameters(eval, cnt, "LIST"_s, option, count, required,
exactly);
}
inline bool CheckListParameters(cmGeneratorExpressionContext* ctx,
inline bool CheckListParameters(cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* cnt,
cm::string_view option, Arguments args,
int required = 1)
{
return CheckListParametersEx(ctx, cnt, option, args.size(), required);
return CheckListParametersEx(eval, cnt, option, args.size(), required);
};
inline cmList GetList(std::string const& list)
@@ -1225,7 +1179,7 @@ bool GetNumericArgument(std::string const& arg, cmList::index_type& value)
}
bool GetNumericArguments(
cmGeneratorExpressionContext* ctx, GeneratorExpressionContent const* cnt,
cm::GenEx::Evaluation* eval, GeneratorExpressionContent const* cnt,
Arguments args, std::vector<cmList::index_type>& indexes,
cmList::ExpandElements expandElements = cmList::ExpandElements::No)
{
@@ -1240,7 +1194,7 @@ bool GetNumericArguments(
for (auto const& value : arguments) {
cmList::index_type index;
if (!GetNumericArgument(value, index)) {
reportError(ctx, cnt->GetOriginalExpression(),
reportError(eval, cnt->GetOriginalExpression(),
cmStrCat("index: \"", value, "\" is not a valid index"));
return false;
}
@@ -1259,41 +1213,38 @@ static const struct ListNode : public cmGeneratorExpressionNode
bool AcceptsArbitraryContentParameter() const override { return true; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
static std::unordered_map<
cm::string_view,
std::function<std::string(cmGeneratorExpressionContext*,
std::function<std::string(cm::GenEx::Evaluation*,
GeneratorExpressionContent const*,
Arguments&)>>
listCommands{
{ "LENGTH"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckListParameters(ctx, cnt, "LENGTH"_s, args)) {
if (CheckListParameters(ev, cnt, "LENGTH"_s, args)) {
return std::to_string(GetList(args.front()).size());
}
return std::string{};
} },
{ "GET"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckListParametersEx(ctx, cnt, "GET"_s, args.size(), 2,
if (CheckListParametersEx(ev, cnt, "GET"_s, args.size(), 2,
false)) {
auto list = GetList(args.front());
if (list.empty()) {
reportError(ctx, cnt->GetOriginalExpression(),
reportError(ev, cnt->GetOriginalExpression(),
"given empty list");
return std::string{};
}
std::vector<cmList::index_type> indexes;
if (!GetNumericArguments(ctx, cnt, args.advance(1), indexes,
if (!GetNumericArguments(ev, cnt, args.advance(1), indexes,
cmList::ExpandElements::Yes)) {
return std::string{};
}
@@ -1301,41 +1252,39 @@ static const struct ListNode : public cmGeneratorExpressionNode
return list.get_items(indexes.begin(), indexes.end())
.to_string();
} catch (std::out_of_range& e) {
reportError(ctx, cnt->GetOriginalExpression(), e.what());
reportError(ev, cnt->GetOriginalExpression(), e.what());
return std::string{};
}
}
return std::string{};
} },
{ "JOIN"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckListParameters(ctx, cnt, "JOIN"_s, args, 2)) {
if (CheckListParameters(ev, cnt, "JOIN"_s, args, 2)) {
return GetList(args.front()).join(args[1]);
}
return std::string{};
} },
{ "SUBLIST"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckListParameters(ctx, cnt, "SUBLIST"_s, args, 3)) {
if (CheckListParameters(ev, cnt, "SUBLIST"_s, args, 3)) {
auto list = GetList(args.front());
if (!list.empty()) {
std::vector<cmList::index_type> indexes;
if (!GetNumericArguments(ctx, cnt, args.advance(1), indexes)) {
if (!GetNumericArguments(ev, cnt, args.advance(1), indexes)) {
return std::string{};
}
if (indexes[0] < 0) {
reportError(ctx, cnt->GetOriginalExpression(),
reportError(ev, cnt->GetOriginalExpression(),
cmStrCat("begin index: ", indexes[0],
" is out of range 0 - ",
list.size() - 1));
return std::string{};
}
if (indexes[1] < -1) {
reportError(ctx, cnt->GetOriginalExpression(),
reportError(ev, cnt->GetOriginalExpression(),
cmStrCat("length: ", indexes[1],
" should be -1 or greater"));
return std::string{};
@@ -1346,7 +1295,7 @@ static const struct ListNode : public cmGeneratorExpressionNode
static_cast<cmList::size_type>(indexes[1]))
.to_string();
} catch (std::out_of_range& e) {
reportError(ctx, cnt->GetOriginalExpression(), e.what());
reportError(ev, cnt->GetOriginalExpression(), e.what());
return std::string{};
}
}
@@ -1354,10 +1303,9 @@ static const struct ListNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "FIND"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckListParameters(ctx, cnt, "FIND"_s, args, 2)) {
if (CheckListParameters(ev, cnt, "FIND"_s, args, 2)) {
auto list = GetList(args.front());
auto index = list.find(args[1]);
return index == cmList::npos ? "-1" : std::to_string(index);
@@ -1365,10 +1313,9 @@ static const struct ListNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "APPEND"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckListParametersEx(ctx, cnt, "APPEND"_s, args.size(), 2,
if (CheckListParametersEx(ev, cnt, "APPEND"_s, args.size(), 2,
false)) {
auto list = args.front();
args.advance(1);
@@ -1377,10 +1324,9 @@ static const struct ListNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "PREPEND"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckListParametersEx(ctx, cnt, "PREPEND"_s, args.size(), 2,
if (CheckListParametersEx(ev, cnt, "PREPEND"_s, args.size(), 2,
false)) {
auto list = args.front();
args.advance(1);
@@ -1389,15 +1335,14 @@ static const struct ListNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "INSERT"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckListParametersEx(ctx, cnt, "INSERT"_s, args.size(), 3,
if (CheckListParametersEx(ev, cnt, "INSERT"_s, args.size(), 3,
false)) {
cmList::index_type index;
if (!GetNumericArgument(args[1], index)) {
reportError(
ctx, cnt->GetOriginalExpression(),
ev, cnt->GetOriginalExpression(),
cmStrCat("index: \"", args[1], "\" is not a valid index"));
return std::string{};
}
@@ -1409,17 +1354,16 @@ static const struct ListNode : public cmGeneratorExpressionNode
cmList::EmptyElements::Yes);
return list.to_string();
} catch (std::out_of_range& e) {
reportError(ctx, cnt->GetOriginalExpression(), e.what());
reportError(ev, cnt->GetOriginalExpression(), e.what());
return std::string{};
}
}
return std::string{};
} },
{ "POP_BACK"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckListParameters(ctx, cnt, "POP_BACK"_s, args)) {
if (CheckListParameters(ev, cnt, "POP_BACK"_s, args)) {
auto list = GetList(args.front());
if (!list.empty()) {
list.pop_back();
@@ -1429,10 +1373,9 @@ static const struct ListNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "POP_FRONT"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckListParameters(ctx, cnt, "POP_FRONT"_s, args)) {
if (CheckListParameters(ev, cnt, "POP_FRONT"_s, args)) {
auto list = GetList(args.front());
if (!list.empty()) {
list.pop_front();
@@ -1442,20 +1385,18 @@ static const struct ListNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "REMOVE_DUPLICATES"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckListParameters(ctx, cnt, "REMOVE_DUPLICATES"_s, args)) {
if (CheckListParameters(ev, cnt, "REMOVE_DUPLICATES"_s, args)) {
return GetList(args.front()).remove_duplicates().to_string();
}
return std::string{};
} },
{ "REMOVE_ITEM"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckListParametersEx(ctx, cnt, "REMOVE_ITEM"_s, args.size(),
2, false)) {
if (CheckListParametersEx(ev, cnt, "REMOVE_ITEM"_s, args.size(), 2,
false)) {
auto list = GetList(args.front());
args.advance(1);
cmList items{ args.begin(), args.end(),
@@ -1465,14 +1406,13 @@ static const struct ListNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "REMOVE_AT"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckListParametersEx(ctx, cnt, "REMOVE_AT"_s, args.size(), 2,
if (CheckListParametersEx(ev, cnt, "REMOVE_AT"_s, args.size(), 2,
false)) {
auto list = GetList(args.front());
std::vector<cmList::index_type> indexes;
if (!GetNumericArguments(ctx, cnt, args.advance(1), indexes,
if (!GetNumericArguments(ev, cnt, args.advance(1), indexes,
cmList::ExpandElements::Yes)) {
return std::string{};
}
@@ -1480,21 +1420,20 @@ static const struct ListNode : public cmGeneratorExpressionNode
return list.remove_items(indexes.begin(), indexes.end())
.to_string();
} catch (std::out_of_range& e) {
reportError(ctx, cnt->GetOriginalExpression(), e.what());
reportError(ev, cnt->GetOriginalExpression(), e.what());
return std::string{};
}
}
return std::string{};
} },
{ "FILTER"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckListParameters(ctx, cnt, "FILTER"_s, args, 3)) {
if (CheckListParameters(ev, cnt, "FILTER"_s, args, 3)) {
auto const& op = args[1];
if (op != "INCLUDE"_s && op != "EXCLUDE"_s) {
reportError(
ctx, cnt->GetOriginalExpression(),
ev, cnt->GetOriginalExpression(),
cmStrCat("sub-command FILTER does not recognize operator \"",
op, "\". It must be either INCLUDE or EXCLUDE."));
return std::string{};
@@ -1507,7 +1446,7 @@ static const struct ListNode : public cmGeneratorExpressionNode
.to_string();
} catch (std::invalid_argument&) {
reportError(
ctx, cnt->GetOriginalExpression(),
ev, cnt->GetOriginalExpression(),
cmStrCat("sub-command FILTER, failed to compile regex \"",
args[2], "\"."));
return std::string{};
@@ -1516,10 +1455,9 @@ static const struct ListNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "TRANSFORM"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckListParametersEx(ctx, cnt, "TRANSFORM"_s, args.size(), 2,
if (CheckListParametersEx(ev, cnt, "TRANSFORM"_s, args.size(), 2,
false)) {
auto list = GetList(args.front());
if (!list.empty()) {
@@ -1561,7 +1499,7 @@ static const struct ListNode : public cmGeneratorExpressionNode
auto descriptor = descriptors.find(args.advance(1).front());
if (descriptor == descriptors.end()) {
reportError(ctx, cnt->GetOriginalExpression(),
reportError(ev, cnt->GetOriginalExpression(),
cmStrCat(" sub-command TRANSFORM, ",
args.front(), " invalid action."));
return std::string{};
@@ -1570,7 +1508,7 @@ static const struct ListNode : public cmGeneratorExpressionNode
// Action arguments
args.advance(1);
if (args.size() < descriptor->Arity) {
reportError(ctx, cnt->GetOriginalExpression(),
reportError(ev, cnt->GetOriginalExpression(),
cmStrCat("sub-command TRANSFORM, action ",
descriptor->Name, " expects ",
descriptor->Arity, " argument(s)."));
@@ -1594,7 +1532,7 @@ static const struct ListNode : public cmGeneratorExpressionNode
if ((args.front() == REGEX || args.front() == AT ||
args.front() == FOR) &&
selector) {
reportError(ctx, cnt->GetOriginalExpression(),
reportError(ev, cnt->GetOriginalExpression(),
cmStrCat("sub-command TRANSFORM, selector "
"already specified (",
selector->GetTag(), ")."));
@@ -1606,7 +1544,7 @@ static const struct ListNode : public cmGeneratorExpressionNode
if (args.front() == REGEX) {
if (args.advance(1).empty()) {
reportError(
ctx, cnt->GetOriginalExpression(),
ev, cnt->GetOriginalExpression(),
"sub-command TRANSFORM, selector REGEX expects "
"'regular expression' argument.");
return std::string{};
@@ -1632,7 +1570,7 @@ static const struct ListNode : public cmGeneratorExpressionNode
if (!GetNumericArgument(index, value)) {
// this is not a number, stop processing
reportError(
ctx, cnt->GetOriginalExpression(),
ev, cnt->GetOriginalExpression(),
cmStrCat("sub-command TRANSFORM, selector AT: '",
index, "': unexpected argument."));
return std::string{};
@@ -1643,7 +1581,7 @@ static const struct ListNode : public cmGeneratorExpressionNode
}
if (indexes.empty()) {
reportError(ctx, cnt->GetOriginalExpression(),
reportError(ev, cnt->GetOriginalExpression(),
"sub-command TRANSFORM, selector AT "
"expects at least one "
"numeric value.");
@@ -1659,7 +1597,7 @@ static const struct ListNode : public cmGeneratorExpressionNode
// FOR selector
if (args.front() == FOR) {
if (args.advance(1).size() < 2) {
reportError(ctx, cnt->GetOriginalExpression(),
reportError(ev, cnt->GetOriginalExpression(),
"sub-command TRANSFORM, selector FOR "
"expects, at least,"
" two arguments.");
@@ -1678,7 +1616,7 @@ static const struct ListNode : public cmGeneratorExpressionNode
if (!valid) {
reportError(
ctx, cnt->GetOriginalExpression(),
ev, cnt->GetOriginalExpression(),
"sub-command TRANSFORM, selector FOR expects, "
"at least, two numeric values.");
return std::string{};
@@ -1694,7 +1632,7 @@ static const struct ListNode : public cmGeneratorExpressionNode
if (step <= 0) {
reportError(
ctx, cnt->GetOriginalExpression(),
ev, cnt->GetOriginalExpression(),
"sub-command TRANSFORM, selector FOR expects "
"positive numeric value for <step>.");
return std::string{};
@@ -1705,7 +1643,7 @@ static const struct ListNode : public cmGeneratorExpressionNode
continue;
}
reportError(ctx, cnt->GetOriginalExpression(),
reportError(ev, cnt->GetOriginalExpression(),
cmStrCat("sub-command TRANSFORM, '",
cmJoin(args, ", "),
"': unexpected argument(s)."));
@@ -1715,14 +1653,14 @@ static const struct ListNode : public cmGeneratorExpressionNode
if (!selector) {
selector = cmList::TransformSelector::New();
}
selector->Makefile = ctx->LG->GetMakefile();
selector->Makefile = ev->LG->GetMakefile();
return list
.transform(descriptor->Action, arguments,
std::move(selector))
.to_string();
} catch (cmList::transform_error& e) {
reportError(ctx, cnt->GetOriginalExpression(), e.what());
reportError(ev, cnt->GetOriginalExpression(), e.what());
return std::string{};
}
}
@@ -1730,19 +1668,17 @@ static const struct ListNode : public cmGeneratorExpressionNode
return std::string{};
} },
{ "REVERSE"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckListParameters(ctx, cnt, "REVERSE"_s, args)) {
if (CheckListParameters(ev, cnt, "REVERSE"_s, args)) {
return GetList(args.front()).reverse().to_string();
}
return std::string{};
} },
{ "SORT"_s,
[](cmGeneratorExpressionContext* ctx,
GeneratorExpressionContent const* cnt,
[](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
Arguments& args) -> std::string {
if (CheckListParametersEx(ctx, cnt, "SORT"_s, args.size(), 1,
if (CheckListParametersEx(ev, cnt, "SORT"_s, args.size(), 1,
false)) {
auto list = GetList(args.front());
args.advance(1);
@@ -1755,7 +1691,7 @@ static const struct ListNode : public cmGeneratorExpressionNode
if (cmHasPrefix(arg, COMPARE)) {
if (sortConfig.Compare !=
SortConfig::CompareMethod::DEFAULT) {
reportError(ctx, cnt->GetOriginalExpression(),
reportError(ev, cnt->GetOriginalExpression(),
"sub-command SORT, COMPARE option has been "
"specified multiple times.");
return std::string{};
@@ -1776,7 +1712,7 @@ static const struct ListNode : public cmGeneratorExpressionNode
continue;
}
reportError(
ctx, cnt->GetOriginalExpression(),
ev, cnt->GetOriginalExpression(),
cmStrCat(
"sub-command SORT, an invalid COMPARE option has been "
"specified: \"",
@@ -1786,7 +1722,7 @@ static const struct ListNode : public cmGeneratorExpressionNode
if (cmHasPrefix(arg, CASE)) {
if (sortConfig.Case !=
SortConfig::CaseSensitivity::DEFAULT) {
reportError(ctx, cnt->GetOriginalExpression(),
reportError(ev, cnt->GetOriginalExpression(),
"sub-command SORT, CASE option has been "
"specified multiple times.");
return std::string{};
@@ -1801,7 +1737,7 @@ static const struct ListNode : public cmGeneratorExpressionNode
continue;
}
reportError(
ctx, cnt->GetOriginalExpression(),
ev, cnt->GetOriginalExpression(),
cmStrCat(
"sub-command SORT, an invalid CASE option has been "
"specified: \"",
@@ -1810,7 +1746,7 @@ static const struct ListNode : public cmGeneratorExpressionNode
}
if (cmHasPrefix(arg, ORDER)) {
if (sortConfig.Order != SortConfig::OrderMode::DEFAULT) {
reportError(ctx, cnt->GetOriginalExpression(),
reportError(ev, cnt->GetOriginalExpression(),
"sub-command SORT, ORDER option has been "
"specified multiple times.");
return std::string{};
@@ -1826,14 +1762,14 @@ static const struct ListNode : public cmGeneratorExpressionNode
continue;
}
reportError(
ctx, cnt->GetOriginalExpression(),
ev, cnt->GetOriginalExpression(),
cmStrCat(
"sub-command SORT, an invalid ORDER option has been "
"specified: \"",
option, "\"."));
return std::string{};
}
reportError(ctx, cnt->GetOriginalExpression(),
reportError(ev, cnt->GetOriginalExpression(),
cmStrCat("sub-command SORT, option \"", arg,
"\" is invalid."));
return std::string{};
@@ -1847,10 +1783,10 @@ static const struct ListNode : public cmGeneratorExpressionNode
if (cm::contains(listCommands, parameters.front())) {
auto args = Arguments{ parameters }.advance(1);
return listCommands[parameters.front()](context, content, args);
return listCommands[parameters.front()](eval, content, args);
}
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
cmStrCat(parameters.front(), ": invalid option."));
return std::string{};
}
@@ -1864,7 +1800,7 @@ static const struct MakeCIdentifierNode : public cmGeneratorExpressionNode
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* /*context*/,
cm::GenEx::Evaluation* /*eval*/,
GeneratorExpressionContent const* /*content*/,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
@@ -1881,7 +1817,7 @@ struct CharacterNode : public cmGeneratorExpressionNode
std::string Evaluate(
std::vector<std::string> const& /*parameters*/,
cmGeneratorExpressionContext* /*context*/,
cm::GenEx::Evaluation* /*eval*/,
GeneratorExpressionContent const* /*content*/,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
@@ -1903,32 +1839,30 @@ struct CompilerIdNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagChecker) const override
{
if (!context->HeadTarget) {
if (!eval->HeadTarget) {
std::ostringstream e;
e << "$<" << this->CompilerLanguage
<< "_COMPILER_ID> may only be used with binary targets. It may "
"not be used with add_custom_command or add_custom_target.";
reportError(context, content->GetOriginalExpression(), e.str());
reportError(eval, content->GetOriginalExpression(), e.str());
return {};
}
return this->EvaluateWithLanguage(parameters, context, content, dagChecker,
return this->EvaluateWithLanguage(parameters, eval, content, dagChecker,
this->CompilerLanguage);
}
std::string EvaluateWithLanguage(std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* /*unused*/,
std::string const& lang) const
{
std::string const& compilerId =
context->LG->GetMakefile()->GetSafeDefinition("CMAKE_" + lang +
"_COMPILER_ID");
std::string const& compilerId = eval->LG->GetMakefile()->GetSafeDefinition(
"CMAKE_" + lang + "_COMPILER_ID");
if (parameters.empty()) {
return compilerId;
}
@@ -1939,7 +1873,7 @@ struct CompilerIdNode : public cmGeneratorExpressionNode
for (auto const& param : parameters) {
if (!compilerIdValidator.find(param)) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"Expression syntax not recognized.");
return std::string();
}
@@ -1969,39 +1903,38 @@ struct CompilerVersionNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return OneOrZeroParameters; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagChecker) const override
{
if (!context->HeadTarget) {
if (!eval->HeadTarget) {
std::ostringstream e;
e << "$<" << this->CompilerLanguage
<< "_COMPILER_VERSION> may only be used with binary targets. It "
"may not be used with add_custom_command or add_custom_target.";
reportError(context, content->GetOriginalExpression(), e.str());
reportError(eval, content->GetOriginalExpression(), e.str());
return {};
}
return this->EvaluateWithLanguage(parameters, context, content, dagChecker,
return this->EvaluateWithLanguage(parameters, eval, content, dagChecker,
this->CompilerLanguage);
}
std::string EvaluateWithLanguage(std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* /*unused*/,
std::string const& lang) const
{
std::string const& compilerVersion =
context->LG->GetMakefile()->GetSafeDefinition("CMAKE_" + lang +
"_COMPILER_VERSION");
eval->LG->GetMakefile()->GetSafeDefinition("CMAKE_" + lang +
"_COMPILER_VERSION");
if (parameters.empty()) {
return compilerVersion;
}
static cmsys::RegularExpression compilerIdValidator("^[0-9\\.]*$");
if (!compilerIdValidator.find(parameters.front())) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"Expression syntax not recognized.");
return {};
}
@@ -2034,32 +1967,31 @@ struct CompilerFrontendVariantNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagChecker) const override
{
if (!context->HeadTarget) {
if (!eval->HeadTarget) {
std::ostringstream e;
e << "$<" << this->CompilerLanguage
<< "_COMPILER_FRONTEND_VARIANT> may only be used with binary targets. "
" It may not be used with add_custom_command or add_custom_target.";
reportError(context, content->GetOriginalExpression(), e.str());
reportError(eval, content->GetOriginalExpression(), e.str());
return {};
}
return this->EvaluateWithLanguage(parameters, context, content, dagChecker,
return this->EvaluateWithLanguage(parameters, eval, content, dagChecker,
this->CompilerLanguage);
}
std::string EvaluateWithLanguage(std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* /*unused*/,
std::string const& lang) const
{
std::string const& compilerFrontendVariant =
context->LG->GetMakefile()->GetSafeDefinition(
"CMAKE_" + lang + "_COMPILER_FRONTEND_VARIANT");
eval->LG->GetMakefile()->GetSafeDefinition("CMAKE_" + lang +
"_COMPILER_FRONTEND_VARIANT");
if (parameters.empty()) {
return compilerFrontendVariant;
}
@@ -2071,7 +2003,7 @@ struct CompilerFrontendVariantNode : public cmGeneratorExpressionNode
for (auto const& param : parameters) {
if (!compilerFrontendVariantValidator.find(param)) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"Expression syntax not recognized.");
return {};
}
@@ -2101,13 +2033,12 @@ struct PlatformIdNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* /*content*/,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
std::string const& platformId =
context->LG->GetMakefile()->GetSafeDefinition("CMAKE_SYSTEM_NAME");
eval->LG->GetMakefile()->GetSafeDefinition("CMAKE_SYSTEM_NAME");
if (parameters.empty()) {
return platformId;
}
@@ -2135,7 +2066,7 @@ struct VersionNode : public cmGeneratorExpressionNode
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* /*context*/,
cm::GenEx::Evaluation* /*eval*/,
GeneratorExpressionContent const* /*content*/,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
@@ -2156,13 +2087,12 @@ static const struct CompileOnlyNode : public cmGeneratorExpressionNode
CompileOnlyNode() {} // NOLINT(modernize-use-equals-default)
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagChecker) const override
{
if (!dagChecker) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"$<COMPILE_ONLY:...> may only be used for linking");
return std::string();
}
@@ -2178,13 +2108,12 @@ static const struct LinkOnlyNode : public cmGeneratorExpressionNode
LinkOnlyNode() {} // NOLINT(modernize-use-equals-default)
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagChecker) const override
{
if (!dagChecker) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"$<LINK_ONLY:...> may only be used for linking");
return std::string();
}
@@ -2203,12 +2132,11 @@ static const struct ConfigurationNode : public cmGeneratorExpressionNode
std::string Evaluate(
std::vector<std::string> const& /*parameters*/,
cmGeneratorExpressionContext* context,
GeneratorExpressionContent const* /*content*/,
cm::GenEx::Evaluation* eval, GeneratorExpressionContent const* /*content*/,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
context->HadContextSensitiveCondition = true;
return context->Config;
eval->HadContextSensitiveCondition = true;
return eval->Config;
}
} configurationNode;
@@ -2219,16 +2147,15 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
if (parameters.empty()) {
return configurationNode.Evaluate(parameters, context, content, nullptr);
return configurationNode.Evaluate(parameters, eval, content, nullptr);
}
context->HadContextSensitiveCondition = true;
eval->HadContextSensitiveCondition = true;
// First, validate our arguments.
static cmsys::RegularExpression configValidator("^[A-Za-z0-9_]*$");
@@ -2236,7 +2163,7 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
for (auto const& param : parameters) {
if (!configValidator.find(param)) {
if (firstParam) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"Expression syntax not recognized.");
return std::string();
}
@@ -2248,8 +2175,8 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
<< " " << content->GetOriginalExpression() << "\n"
<< "The config name of \"" << param << "\" is invalid";
/* clang-format on */
context->LG->GetCMakeInstance()->IssueMessage(
MessageType::WARNING, e.str(), context->Backtrace);
eval->LG->GetCMakeInstance()->IssueMessage(MessageType::WARNING,
e.str(), eval->Backtrace);
}
firstParam = false;
}
@@ -2265,32 +2192,32 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
// below), then finally based on the selected configuration of the imported
// target.
bool const targetIsImported =
(context->CurrentTarget && context->CurrentTarget->IsImported());
(eval->CurrentTarget && eval->CurrentTarget->IsImported());
bool const oldPolicy = [&] {
if (!targetIsImported) {
// For non-imported targets, there is no behavior difference between
// the OLD and NEW policy.
return false;
}
cmTarget const* const t = context->CurrentTarget->Target;
cmTarget const* const t = eval->CurrentTarget->Target;
if (t->GetOrigin() == cmTarget::Origin::Cps) {
// Generator expressions appearing on targets imported from CPS should
// always be evaluated according to the selected configuration of the
// imported target, i.e. the NEW policy.
return false;
}
switch (context->HeadTarget->GetPolicyStatusCMP0199()) {
switch (eval->HeadTarget->GetPolicyStatusCMP0199()) {
case cmPolicies::WARN:
if (context->LG->GetMakefile()->PolicyOptionalWarningEnabled(
if (eval->LG->GetMakefile()->PolicyOptionalWarningEnabled(
"CMAKE_POLICY_WARNING_CMP0199")) {
std::string const err =
cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0199),
"\nEvaluation of $<CONFIG> for imported target \"",
context->CurrentTarget->GetName(), "\", used by \"",
context->HeadTarget->GetName(),
eval->CurrentTarget->GetName(), "\", used by \"",
eval->HeadTarget->GetName(),
"\", may match multiple configurations.\n");
context->LG->GetCMakeInstance()->IssueMessage(
MessageType ::AUTHOR_WARNING, err, context->Backtrace);
eval->LG->GetCMakeInstance()->IssueMessage(
MessageType ::AUTHOR_WARNING, err, eval->Backtrace);
}
CM_FALLTHROUGH;
case cmPolicies::OLD:
@@ -2307,12 +2234,12 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
if (!targetIsImported || oldPolicy) {
// Does the consuming target's configuration match any of the arguments?
for (auto const& param : parameters) {
if (context->Config.empty()) {
if (eval->Config.empty()) {
if (param.empty()) {
return "1";
}
} else if (cmsysString_strcasecmp(param.c_str(),
context->Config.c_str()) == 0) {
eval->Config.c_str()) == 0) {
return "1";
}
}
@@ -2322,8 +2249,8 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
cmValue loc = nullptr;
cmValue imp = nullptr;
std::string suffix;
if (context->CurrentTarget->Target->GetMappedConfig(context->Config, loc,
imp, suffix)) {
if (eval->CurrentTarget->Target->GetMappedConfig(eval->Config, loc, imp,
suffix)) {
if (oldPolicy) {
// If the target has a MAP_IMPORTED_CONFIG_<CONFIG> property for the
// consumer's <CONFIG>, match *any* config in that list, regardless
@@ -2333,9 +2260,8 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
// long time, and... Hyrum's Law.
cmList mappedConfigs;
std::string mapProp = cmStrCat(
"MAP_IMPORTED_CONFIG_", cmSystemTools::UpperCase(context->Config));
if (cmValue mapValue =
context->CurrentTarget->GetProperty(mapProp)) {
"MAP_IMPORTED_CONFIG_", cmSystemTools::UpperCase(eval->Config));
if (cmValue mapValue = eval->CurrentTarget->GetProperty(mapProp)) {
mappedConfigs.assign(cmSystemTools::UpperCase(*mapValue));
for (auto const& param : parameters) {
@@ -2377,7 +2303,7 @@ static const struct JoinNode : public cmGeneratorExpressionNode
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* /*context*/,
cm::GenEx::Evaluation* /*eval*/,
GeneratorExpressionContent const* /*content*/,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
@@ -2392,22 +2318,21 @@ static const struct CompileLanguageNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagChecker) const override
{
if (context->Language.empty() &&
if (eval->Language.empty() &&
(!dagChecker || !dagChecker->EvaluatingCompileExpression())) {
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"$<COMPILE_LANGUAGE:...> may only be used to specify include "
"directories, compile definitions, compile options, and to evaluate "
"components of the file(GENERATE) command.");
return std::string();
}
cmGlobalGenerator const* gg = context->LG->GetGlobalGenerator();
cmGlobalGenerator const* gg = eval->LG->GetGlobalGenerator();
std::string genName = gg->GetName();
if (genName.find("Makefiles") == std::string::npos &&
genName.find("Ninja") == std::string::npos &&
@@ -2416,16 +2341,16 @@ static const struct CompileLanguageNode : public cmGeneratorExpressionNode
genName.find("Watcom WMake") == std::string::npos &&
genName.find("FASTBuild") == std::string::npos &&
genName.find("Green Hills MULTI") == std::string::npos) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"$<COMPILE_LANGUAGE:...> not supported for this generator.");
return std::string();
}
if (parameters.empty()) {
return context->Language;
return eval->Language;
}
for (auto const& param : parameters) {
if (context->Language == param) {
if (eval->Language == param) {
return "1";
}
}
@@ -2440,17 +2365,16 @@ static const struct CompileLanguageAndIdNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return TwoOrMoreParameters; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagChecker) const override
{
if (!context->HeadTarget ||
(context->Language.empty() &&
if (!eval->HeadTarget ||
(eval->Language.empty() &&
(!dagChecker || !dagChecker->EvaluatingCompileExpression()))) {
// reportError(context, content->GetOriginalExpression(), "");
// reportError(eval, content->GetOriginalExpression(), "");
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"$<COMPILE_LANG_AND_ID:lang,id> may only be used with binary "
"targets "
"to specify include directories, compile definitions, and compile "
@@ -2458,7 +2382,7 @@ static const struct CompileLanguageAndIdNode : public cmGeneratorExpressionNode
"add_custom_target, or file(GENERATE) commands.");
return std::string();
}
cmGlobalGenerator const* gg = context->LG->GetGlobalGenerator();
cmGlobalGenerator const* gg = eval->LG->GetGlobalGenerator();
std::string genName = gg->GetName();
if (genName.find("Makefiles") == std::string::npos &&
genName.find("Ninja") == std::string::npos &&
@@ -2468,17 +2392,17 @@ static const struct CompileLanguageAndIdNode : public cmGeneratorExpressionNode
genName.find("Watcom WMake") == std::string::npos &&
genName.find("Green Hills MULTI") == std::string::npos) {
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"$<COMPILE_LANG_AND_ID:lang,id> not supported for this generator.");
return std::string();
}
std::string const& lang = context->Language;
std::string const& lang = eval->Language;
if (lang == parameters.front()) {
std::vector<std::string> idParameter((parameters.cbegin() + 1),
parameters.cend());
return CompilerIdNode{ lang.c_str() }.EvaluateWithLanguage(
idParameter, context, content, dagChecker, lang);
idParameter, eval, content, dagChecker, lang);
}
return "0";
}
@@ -2491,16 +2415,15 @@ static const struct LinkLanguageNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagChecker) const override
{
if (!context->HeadTarget || !dagChecker ||
if (!eval->HeadTarget || !dagChecker ||
!(dagChecker->EvaluatingLinkExpression() ||
dagChecker->EvaluatingLinkLibraries() ||
dagChecker->EvaluatingLinkerLauncher())) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"$<LINK_LANGUAGE:...> may only be used with binary targets "
"to specify link libraries, link directories, link options "
"and link depends.");
@@ -2508,12 +2431,12 @@ static const struct LinkLanguageNode : public cmGeneratorExpressionNode
}
if (dagChecker->EvaluatingLinkLibraries() && parameters.empty()) {
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"$<LINK_LANGUAGE> is not supported in link libraries expression.");
return std::string();
}
cmGlobalGenerator const* gg = context->LG->GetGlobalGenerator();
cmGlobalGenerator const* gg = eval->LG->GetGlobalGenerator();
std::string genName = gg->GetName();
if (genName.find("Makefiles") == std::string::npos &&
genName.find("Ninja") == std::string::npos &&
@@ -2522,22 +2445,22 @@ static const struct LinkLanguageNode : public cmGeneratorExpressionNode
genName.find("Xcode") == std::string::npos &&
genName.find("Watcom WMake") == std::string::npos &&
genName.find("Green Hills MULTI") == std::string::npos) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"$<LINK_LANGUAGE:...> not supported for this generator.");
return std::string();
}
if (dagChecker->EvaluatingLinkLibraries()) {
context->HadHeadSensitiveCondition = true;
context->HadLinkLanguageSensitiveCondition = true;
eval->HadHeadSensitiveCondition = true;
eval->HadLinkLanguageSensitiveCondition = true;
}
if (parameters.empty()) {
return context->Language;
return eval->Language;
}
for (auto const& param : parameters) {
if (context->Language == param) {
if (eval->Language == param) {
return "1";
}
}
@@ -2549,13 +2472,12 @@ namespace {
struct LinkerId
{
static std::string Evaluate(std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
std::string const& lang)
{
std::string const& linkerId =
context->LG->GetMakefile()->GetSafeDefinition("CMAKE_" + lang +
"_COMPILER_ID");
std::string const& linkerId = eval->LG->GetMakefile()->GetSafeDefinition(
"CMAKE_" + lang + "_COMPILER_ID");
if (parameters.empty()) {
return linkerId;
}
@@ -2566,7 +2488,7 @@ struct LinkerId
for (auto const& param : parameters) {
if (!linkerIdValidator.find(param)) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"Expression syntax not recognized.");
return std::string();
}
@@ -2587,17 +2509,16 @@ static const struct LinkLanguageAndIdNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return TwoOrMoreParameters; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagChecker) const override
{
if (!context->HeadTarget || !dagChecker ||
if (!eval->HeadTarget || !dagChecker ||
!(dagChecker->EvaluatingLinkExpression() ||
dagChecker->EvaluatingLinkLibraries() ||
dagChecker->EvaluatingLinkerLauncher())) {
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets "
"to specify link libraries, link directories, link options, and "
"link "
@@ -2605,7 +2526,7 @@ static const struct LinkLanguageAndIdNode : public cmGeneratorExpressionNode
return std::string();
}
cmGlobalGenerator const* gg = context->LG->GetGlobalGenerator();
cmGlobalGenerator const* gg = eval->LG->GetGlobalGenerator();
std::string genName = gg->GetName();
if (genName.find("Makefiles") == std::string::npos &&
genName.find("Ninja") == std::string::npos &&
@@ -2615,21 +2536,21 @@ static const struct LinkLanguageAndIdNode : public cmGeneratorExpressionNode
genName.find("Watcom WMake") == std::string::npos &&
genName.find("Green Hills MULTI") == std::string::npos) {
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"$<LINK_LANG_AND_ID:lang,id> not supported for this generator.");
return std::string();
}
if (dagChecker->EvaluatingLinkLibraries()) {
context->HadHeadSensitiveCondition = true;
context->HadLinkLanguageSensitiveCondition = true;
eval->HadHeadSensitiveCondition = true;
eval->HadLinkLanguageSensitiveCondition = true;
}
std::string const& lang = context->Language;
std::string const& lang = eval->Language;
if (lang == parameters.front()) {
std::vector<std::string> idParameter((parameters.cbegin() + 1),
parameters.cend());
return LinkerId::Evaluate(idParameter, context, content, lang);
return LinkerId::Evaluate(idParameter, eval, content, lang);
}
return "0";
}
@@ -2645,32 +2566,31 @@ struct CompilerLinkerIdNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagChecker) const override
{
if (!context->HeadTarget) {
if (!eval->HeadTarget) {
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
cmStrCat(
"$<", this->Language,
"_COMPILER_LINKER_ID> may only be used with binary targets. It may "
"not be used with add_custom_command or add_custom_target."));
return {};
}
return this->EvaluateWithLanguage(parameters, context, content, dagChecker,
return this->EvaluateWithLanguage(parameters, eval, content, dagChecker,
this->Language);
}
std::string EvaluateWithLanguage(std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* /*unused*/,
std::string const& lang) const
{
std::string const& compilerLinkerId =
context->LG->GetMakefile()->GetSafeDefinition(
eval->LG->GetMakefile()->GetSafeDefinition(
cmStrCat("CMAKE_", lang, "_COMPILER_LINKER_ID"));
if (parameters.empty()) {
return compilerLinkerId;
@@ -2683,7 +2603,7 @@ struct CompilerLinkerIdNode : public cmGeneratorExpressionNode
for (auto const& param : parameters) {
if (!compilerLinkerIdValidator.find(param)) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"Expression syntax not recognized.");
return std::string();
}
@@ -2713,14 +2633,13 @@ struct CompilerLinkerFrontendVariantNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagChecker) const override
{
if (!context->HeadTarget) {
if (!eval->HeadTarget) {
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
cmStrCat(
"$<", this->Language,
"_COMPILER_LINKER_FRONTEND_VARIANT> may only be used with binary "
@@ -2728,18 +2647,18 @@ struct CompilerLinkerFrontendVariantNode : public cmGeneratorExpressionNode
"add_custom_target."));
return {};
}
return this->EvaluateWithLanguage(parameters, context, content, dagChecker,
return this->EvaluateWithLanguage(parameters, eval, content, dagChecker,
this->Language);
}
std::string EvaluateWithLanguage(std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* /*unused*/,
std::string const& lang) const
{
std::string const& compilerLinkerFrontendVariant =
context->LG->GetMakefile()->GetSafeDefinition(
eval->LG->GetMakefile()->GetSafeDefinition(
cmStrCat("CMAKE_", lang, "_COMPILER_LINKER_FRONTEND_VARIANT"));
if (parameters.empty()) {
return compilerLinkerFrontendVariant;
@@ -2752,7 +2671,7 @@ struct CompilerLinkerFrontendVariantNode : public cmGeneratorExpressionNode
for (auto const& param : parameters) {
if (!compilerLinkerFrontendVariantValidator.find(param)) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"Expression syntax not recognized.");
return {};
}
@@ -2782,17 +2701,16 @@ static const struct LinkLibraryNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return OneOrMoreParameters; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagChecker) const override
{
using ForGenex = cmGeneratorExpressionDAGChecker::ForGenex;
if (!context->HeadTarget || !dagChecker ||
if (!eval->HeadTarget || !dagChecker ||
!dagChecker->EvaluatingLinkLibraries(nullptr,
ForGenex::LINK_LIBRARY)) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"$<LINK_LIBRARY:...> may only be used with binary targets "
"to specify link libraries through 'LINK_LIBRARIES', "
"'INTERFACE_LINK_LIBRARIES', and "
@@ -2803,7 +2721,7 @@ static const struct LinkLibraryNode : public cmGeneratorExpressionNode
cmList list{ parameters.begin(), parameters.end() };
if (list.empty()) {
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"$<LINK_LIBRARY:...> expects a feature name as first argument.");
return std::string();
}
@@ -2815,7 +2733,7 @@ static const struct LinkLibraryNode : public cmGeneratorExpressionNode
static cmsys::RegularExpression featureNameValidator("^[A-Za-z0-9_]+$");
auto const& feature = list.front();
if (!featureNameValidator.find(feature)) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
cmStrCat("The feature name '", feature,
"' contains invalid characters."));
return std::string();
@@ -2837,7 +2755,7 @@ static const struct LinkLibraryNode : public cmGeneratorExpressionNode
});
if (it != list.cend()) {
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"$<LINK_LIBRARY:...> with different features cannot be nested.");
return std::string();
}
@@ -2847,7 +2765,7 @@ static const struct LinkLibraryNode : public cmGeneratorExpressionNode
return cmHasPrefix(item, "<LINK_GROUP:"_s);
});
if (it != list.cend()) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"$<LINK_GROUP:...> cannot be nested inside a "
"$<LINK_LIBRARY:...> expression.");
return std::string();
@@ -2867,17 +2785,16 @@ static const struct LinkGroupNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return OneOrMoreParameters; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagChecker) const override
{
using ForGenex = cmGeneratorExpressionDAGChecker::ForGenex;
if (!context->HeadTarget || !dagChecker ||
if (!eval->HeadTarget || !dagChecker ||
!dagChecker->EvaluatingLinkLibraries(nullptr, ForGenex::LINK_GROUP)) {
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"$<LINK_GROUP:...> may only be used with binary targets "
"to specify group of link libraries through 'LINK_LIBRARIES', "
"'INTERFACE_LINK_LIBRARIES', and "
@@ -2888,7 +2805,7 @@ static const struct LinkGroupNode : public cmGeneratorExpressionNode
cmList list{ parameters.begin(), parameters.end() };
if (list.empty()) {
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"$<LINK_GROUP:...> expects a feature name as first argument.");
return std::string();
}
@@ -2897,7 +2814,7 @@ static const struct LinkGroupNode : public cmGeneratorExpressionNode
[](std::string const& item) -> bool {
return cmHasPrefix(item, "<LINK_GROUP"_s);
}) != list.cend()) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"$<LINK_GROUP:...> cannot be nested.");
return std::string();
}
@@ -2909,7 +2826,7 @@ static const struct LinkGroupNode : public cmGeneratorExpressionNode
static cmsys::RegularExpression featureNameValidator("^[A-Za-z0-9_]+$");
auto const& feature = list.front();
if (!featureNameValidator.find(feature)) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
cmStrCat("The feature name '", feature,
"' contains invalid characters."));
return std::string();
@@ -2936,21 +2853,20 @@ static const struct HostLinkNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagChecker) const override
{
if (!context->HeadTarget || !dagChecker ||
if (!eval->HeadTarget || !dagChecker ||
!dagChecker->EvaluatingLinkOptionsExpression()) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"$<HOST_LINK:...> may only be used with binary targets "
"to specify link options.");
return std::string();
}
return context->HeadTarget->IsDeviceLink() ? std::string()
: cmList::to_string(parameters);
return eval->HeadTarget->IsDeviceLink() ? std::string()
: cmList::to_string(parameters);
}
} hostLinkNode;
@@ -2961,20 +2877,19 @@ static const struct DeviceLinkNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagChecker) const override
{
if (!context->HeadTarget || !dagChecker ||
if (!eval->HeadTarget || !dagChecker ||
!dagChecker->EvaluatingLinkOptionsExpression()) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"$<DEVICE_LINK:...> may only be used with binary targets "
"to specify link options.");
return std::string();
}
if (context->HeadTarget->IsDeviceLink()) {
if (eval->HeadTarget->IsDeviceLink()) {
cmList list{ parameters.begin(), parameters.end() };
auto const DL_BEGIN = "<DEVICE_LINK>"_s;
auto const DL_END = "</DEVICE_LINK>"_s;
@@ -2994,24 +2909,23 @@ static const struct DeviceLinkNode : public cmGeneratorExpressionNode
static std::string getLinkedTargetsContent(
cmGeneratorTarget const* target, std::string const& prop,
cmGeneratorExpressionContext* context,
cmGeneratorExpressionDAGChecker* dagChecker, cmGeneratorTarget::UseTo usage)
cm::GenEx::Evaluation* eval, cmGeneratorExpressionDAGChecker* dagChecker,
cmGeneratorTarget::UseTo usage)
{
std::string result;
if (cmLinkImplementationLibraries const* impl =
target->GetLinkImplementationLibraries(
context->Config, cmGeneratorTarget::UseTo::Compile)) {
eval->Config, cmGeneratorTarget::UseTo::Compile)) {
for (cmLinkImplItem const& lib : impl->Libraries) {
if (lib.Target) {
// Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in our
// caller's property and hand-evaluate it as if it were compiled.
// Create a context as cmCompiledGeneratorExpression::Evaluate does.
cmGeneratorExpressionContext libContext(
target->GetLocalGenerator(), context->Config, context->Quiet, target,
target, context->EvaluateForBuildsystem, lib.Backtrace,
context->Language);
cm::GenEx::Evaluation libEval(
target->GetLocalGenerator(), eval->Config, eval->Quiet, target,
target, eval->EvaluateForBuildsystem, lib.Backtrace, eval->Language);
std::string libResult = lib.Target->EvaluateInterfaceProperty(
prop, &libContext, dagChecker, usage);
prop, &libEval, dagChecker, usage);
if (!libResult.empty()) {
if (result.empty()) {
result = std::move(libResult);
@@ -3056,8 +2970,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
}
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagCheckerParent) const override
{
@@ -3072,53 +2985,52 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
propertyName = parameters[1];
if (char const* e = GetErrorText(targetName, propertyName)) {
reportError(context, content->GetOriginalExpression(), e);
reportError(eval, content->GetOriginalExpression(), e);
return std::string();
}
if (propertyName == "ALIASED_TARGET"_s) {
if (context->LG->GetMakefile()->IsAlias(targetName)) {
if (eval->LG->GetMakefile()->IsAlias(targetName)) {
if (cmGeneratorTarget* tgt =
context->LG->FindGeneratorTargetToUse(targetName)) {
eval->LG->FindGeneratorTargetToUse(targetName)) {
return tgt->GetName();
}
}
return std::string();
}
if (propertyName == "ALIAS_GLOBAL"_s) {
if (context->LG->GetMakefile()->IsAlias(targetName)) {
return context->LG->GetGlobalGenerator()->IsAlias(targetName)
? "TRUE"
: "FALSE";
if (eval->LG->GetMakefile()->IsAlias(targetName)) {
return eval->LG->GetGlobalGenerator()->IsAlias(targetName) ? "TRUE"
: "FALSE";
}
return std::string();
}
cmLocalGenerator const* lg = context->CurrentTarget
? context->CurrentTarget->GetLocalGenerator()
: context->LG;
cmLocalGenerator const* lg = eval->CurrentTarget
? eval->CurrentTarget->GetLocalGenerator()
: eval->LG;
target = lg->FindGeneratorTargetToUse(targetName);
if (!target) {
std::ostringstream e;
e << "Target \"" << targetName << "\" not found.";
reportError(context, content->GetOriginalExpression(), e.str());
reportError(eval, content->GetOriginalExpression(), e.str());
return std::string();
}
context->AllTargets.insert(target);
eval->AllTargets.insert(target);
} else if (parameters.size() == 1) {
target = context->HeadTarget;
target = eval->HeadTarget;
propertyName = parameters[0];
// Keep track of the properties seen while processing.
// The evaluation of the LINK_LIBRARIES generator expressions
// will check this to ensure that properties have one consistent
// value for all evaluations.
context->SeenTargetProperties.insert(propertyName);
eval->SeenTargetProperties.insert(propertyName);
context->HadHeadSensitiveCondition = true;
eval->HadHeadSensitiveCondition = true;
if (!target) {
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"$<TARGET_PROPERTY:prop> may only be used with binary targets. "
"It may not be used with add_custom_command or add_custom_target. "
" "
@@ -3129,25 +3041,25 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
}
} else {
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"$<TARGET_PROPERTY:...> expression requires one or two parameters");
return std::string();
}
if (propertyName == "SOURCES") {
context->SourceSensitiveTargets.insert(target);
eval->SourceSensitiveTargets.insert(target);
}
if (propertyName.empty()) {
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"$<TARGET_PROPERTY:...> expression requires a non-empty property "
"name.");
return std::string();
}
if (!propertyNameValidator.find(propertyName)) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"Property name not supported.");
return std::string();
}
@@ -3159,12 +3071,12 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
(dagCheckerParent->EvaluatingLinkLibraries() ||
dagCheckerParent->EvaluatingSources())) {
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"LINKER_LANGUAGE target property can not be used while evaluating "
"link libraries for a static library");
return std::string();
}
return target->GetLinkerLanguage(context->Config);
return target->GetLinkerLanguage(eval->Config);
}
bool const evaluatingLinkLibraries =
@@ -3175,8 +3087,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
cmGeneratorTarget::UseTo usage = cmGeneratorTarget::UseTo::Compile;
if (cm::optional<cmGeneratorTarget::TransitiveProperty> transitiveProp =
target->IsTransitiveProperty(propertyName, context->LG,
context->Config, dagCheckerParent)) {
target->IsTransitiveProperty(propertyName, eval->LG, eval->Config,
dagCheckerParent)) {
interfacePropertyName = std::string(transitiveProp->InterfaceName);
isInterfaceProperty = transitiveProp->InterfaceName == propertyName;
usage = transitiveProp->Usage;
@@ -3193,7 +3105,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
} else if (evaluatingLinkLibraries) {
if (!interfacePropertyName.empty()) {
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"$<TARGET_PROPERTY:...> expression in link libraries "
"evaluation depends on target property which is transitive "
"over the link libraries, creating a recursion.");
@@ -3206,23 +3118,18 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
if (isInterfaceProperty) {
return cmGeneratorExpression::StripEmptyListElements(
target->EvaluateInterfaceProperty(propertyName, context,
dagCheckerParent, usage));
target->EvaluateInterfaceProperty(propertyName, eval, dagCheckerParent,
usage));
}
cmGeneratorExpressionDAGChecker dagChecker{
target,
propertyName,
content,
dagCheckerParent,
context->LG,
context->Config,
context->Backtrace,
target, propertyName, content, dagCheckerParent,
eval->LG, eval->Config, eval->Backtrace,
};
switch (dagChecker.Check()) {
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
dagChecker.ReportError(context, content->GetOriginalExpression());
dagChecker.ReportError(eval, content->GetOriginalExpression());
return std::string();
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
// No error. We just skip cyclic references.
@@ -3258,37 +3165,37 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
// from this target and the transitive link closure to get the max or min.
if (!haveProp && !target->IsImported()) {
if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
context->Config)) {
context->HadContextSensitiveCondition = true;
eval->Config)) {
eval->HadContextSensitiveCondition = true;
return target->GetLinkInterfaceDependentBoolProperty(propertyName,
context->Config)
eval->Config)
? "1"
: "0";
}
if (target->IsLinkInterfaceDependentStringProperty(propertyName,
context->Config)) {
context->HadContextSensitiveCondition = true;
eval->Config)) {
eval->HadContextSensitiveCondition = true;
char const* propContent =
target->GetLinkInterfaceDependentStringProperty(propertyName,
context->Config);
eval->Config);
return propContent ? propContent : "";
}
}
if (!evaluatingLinkLibraries && !target->IsImported()) {
if (target->IsLinkInterfaceDependentNumberMinProperty(propertyName,
context->Config)) {
context->HadContextSensitiveCondition = true;
eval->Config)) {
eval->HadContextSensitiveCondition = true;
char const* propContent =
target->GetLinkInterfaceDependentNumberMinProperty(propertyName,
context->Config);
eval->Config);
return propContent ? propContent : "";
}
if (target->IsLinkInterfaceDependentNumberMaxProperty(propertyName,
context->Config)) {
context->HadContextSensitiveCondition = true;
eval->Config)) {
eval->HadContextSensitiveCondition = true;
char const* propContent =
target->GetLinkInterfaceDependentNumberMaxProperty(propertyName,
context->Config);
eval->Config);
return propContent ? propContent : "";
}
}
@@ -3297,10 +3204,10 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
// transitive link closure as an ordered list.
if (!interfacePropertyName.empty()) {
result = cmGeneratorExpression::StripEmptyListElements(
this->EvaluateDependentExpression(result, context, target, &dagChecker,
this->EvaluateDependentExpression(result, eval, target, &dagChecker,
target));
std::string linkedTargetsContent = getLinkedTargetsContent(
target, interfacePropertyName, context, &dagChecker, usage);
target, interfacePropertyName, eval, &dagChecker, usage);
if (!linkedTargetsContent.empty()) {
result += (result.empty() ? "" : ";") + linkedTargetsContent;
}
@@ -3320,7 +3227,7 @@ static const struct TargetNameNode : public cmGeneratorExpressionNode
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* /*context*/,
cm::GenEx::Evaluation* /*eval*/,
GeneratorExpressionContent const* /*content*/,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
@@ -3336,18 +3243,17 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
TargetObjectsNode() {} // NOLINT(modernize-use-equals-default)
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
std::string const& tgtName = parameters.front();
cmGeneratorTarget* gt = context->LG->FindGeneratorTargetToUse(tgtName);
cmGeneratorTarget* gt = eval->LG->FindGeneratorTargetToUse(tgtName);
if (!gt) {
std::ostringstream e;
e << "Objects of target \"" << tgtName
<< "\" referenced but no such target exists.";
reportError(context, content->GetOriginalExpression(), e.str());
reportError(eval, content->GetOriginalExpression(), e.str());
return std::string();
}
cmStateEnums::TargetType type = gt->GetType();
@@ -3360,13 +3266,13 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
e << "Objects of target \"" << tgtName
<< "\" referenced but is not one of the allowed target types "
<< "(EXECUTABLE, STATIC, SHARED, MODULE, OBJECT).";
reportError(context, content->GetOriginalExpression(), e.str());
reportError(eval, content->GetOriginalExpression(), e.str());
return std::string();
}
cmGlobalGenerator const* gg = context->LG->GetGlobalGenerator();
cmGlobalGenerator const* gg = eval->LG->GetGlobalGenerator();
{
std::string reason;
if (!context->EvaluateForBuildsystem &&
if (!eval->EvaluateForBuildsystem &&
!gt->Target->HasKnownObjectFileLocation(&reason)) {
std::ostringstream e;
e << "The evaluation of the TARGET_OBJECTS generator expression "
@@ -3374,7 +3280,7 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
<< reason
<< "). "
"It is not suitable for writing out elsewhere.";
reportError(context, content->GetOriginalExpression(), e.str());
reportError(eval, content->GetOriginalExpression(), e.str());
return std::string();
}
}
@@ -3385,23 +3291,22 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
cmValue loc = nullptr;
cmValue imp = nullptr;
std::string suffix;
if (gt->Target->GetMappedConfig(context->Config, loc, imp, suffix)) {
if (gt->Target->GetMappedConfig(eval->Config, loc, imp, suffix)) {
objects.assign(*loc);
}
context->HadContextSensitiveCondition = true;
eval->HadContextSensitiveCondition = true;
} else {
gt->GetTargetObjectNames(context->Config, objects);
gt->GetTargetObjectNames(eval->Config, objects);
std::string obj_dir;
if (context->EvaluateForBuildsystem && !gg->SupportsCrossConfigs()) {
if (eval->EvaluateForBuildsystem && !gg->SupportsCrossConfigs()) {
// Use object file directory with buildsystem placeholder.
obj_dir = gt->ObjectDirectory;
context->HadContextSensitiveCondition =
gt->HasContextDependentSources();
eval->HadContextSensitiveCondition = gt->HasContextDependentSources();
} else {
// Use object file directory with per-config location.
obj_dir = gt->GetObjectDirectory(context->Config);
context->HadContextSensitiveCondition = true;
obj_dir = gt->GetObjectDirectory(eval->Config);
eval->HadContextSensitiveCondition = true;
}
for (auto& o : objects) {
@@ -3410,7 +3315,7 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
}
// Create the cmSourceFile instances in the referencing directory.
cmMakefile* mf = context->LG->GetMakefile();
cmMakefile* mf = eval->LG->GetMakefile();
for (std::string const& o : objects) {
mf->AddTargetObject(tgtName, o);
}
@@ -3422,17 +3327,16 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
struct TargetRuntimeDllsBaseNode : public cmGeneratorExpressionNode
{
std::vector<std::string> CollectDlls(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content) const
{
std::string const& tgtName = parameters.front();
cmGeneratorTarget* gt = context->LG->FindGeneratorTargetToUse(tgtName);
cmGeneratorTarget* gt = eval->LG->FindGeneratorTargetToUse(tgtName);
if (!gt) {
std::ostringstream e;
e << "Objects of target \"" << tgtName
<< "\" referenced but no such target exists.";
reportError(context, content->GetOriginalExpression(), e.str());
reportError(eval, content->GetOriginalExpression(), e.str());
return std::vector<std::string>();
}
cmStateEnums::TargetType type = gt->GetType();
@@ -3443,16 +3347,16 @@ struct TargetRuntimeDllsBaseNode : public cmGeneratorExpressionNode
e << "Objects of target \"" << tgtName
<< "\" referenced but is not one of the allowed target types "
<< "(EXECUTABLE, SHARED, MODULE).";
reportError(context, content->GetOriginalExpression(), e.str());
reportError(eval, content->GetOriginalExpression(), e.str());
return std::vector<std::string>();
}
if (auto* cli = gt->GetLinkInformation(context->Config)) {
if (auto* cli = gt->GetLinkInformation(eval->Config)) {
std::vector<std::string> dllPaths;
auto const& dlls = cli->GetRuntimeDLLs();
for (auto const& dll : dlls) {
if (auto loc = dll->MaybeGetLocation(context->Config)) {
if (auto loc = dll->MaybeGetLocation(eval->Config)) {
dllPaths.emplace_back(*loc);
}
}
@@ -3469,12 +3373,11 @@ static const struct TargetRuntimeDllsNode : public TargetRuntimeDllsBaseNode
TargetRuntimeDllsNode() {} // NOLINT(modernize-use-equals-default)
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
std::vector<std::string> dlls = CollectDlls(parameters, context, content);
std::vector<std::string> dlls = CollectDlls(parameters, eval, content);
return cmList::to_string(dlls);
}
} targetRuntimeDllsNode;
@@ -3484,12 +3387,11 @@ static const struct TargetRuntimeDllDirsNode : public TargetRuntimeDllsBaseNode
TargetRuntimeDllDirsNode() {} // NOLINT(modernize-use-equals-default)
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
std::vector<std::string> dlls = CollectDlls(parameters, context, content);
std::vector<std::string> dlls = CollectDlls(parameters, eval, content);
std::vector<std::string> dllDirs;
for (std::string const& dll : dlls) {
std::string directory = cmSystemTools::GetFilenamePath(dll);
@@ -3509,32 +3411,31 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return OneOrMoreParameters; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagChecker) const override
{
cmGeneratorTarget const* target = context->HeadTarget;
cmGeneratorTarget const* target = eval->HeadTarget;
if (!target) {
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"$<COMPILE_FEATURE> may only be used with binary targets. It may "
"not be used with add_custom_command or add_custom_target.");
return std::string();
}
context->HadHeadSensitiveCondition = true;
eval->HadHeadSensitiveCondition = true;
using LangMap = std::map<std::string, cmList>;
static LangMap availableFeatures;
LangMap testedFeatures;
cmStandardLevelResolver standardResolver(context->LG->GetMakefile());
cmStandardLevelResolver standardResolver(eval->LG->GetMakefile());
for (std::string const& p : parameters) {
std::string error;
std::string lang;
if (!standardResolver.CompileFeatureKnown(
context->HeadTarget->Target->GetName(), p, lang, &error)) {
reportError(context, content->GetOriginalExpression(), error);
eval->HeadTarget->Target->GetName(), p, lang, &error)) {
reportError(eval, content->GetOriginalExpression(), error);
return std::string();
}
testedFeatures[lang].push_back(p);
@@ -3543,7 +3444,7 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
cmValue featuresKnown =
standardResolver.CompileFeaturesAvailable(lang, &error);
if (!featuresKnown) {
reportError(context, content->GetOriginalExpression(), error);
reportError(eval, content->GetOriginalExpression(), error);
return std::string();
}
availableFeatures[lang].assign(featuresKnown);
@@ -3555,7 +3456,7 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
for (auto const& lit : testedFeatures) {
std::vector<std::string> const& langAvailable =
availableFeatures[lit.first];
cmValue standardDefault = context->LG->GetMakefile()->GetDefinition(
cmValue standardDefault = eval->LG->GetMakefile()->GetDefinition(
"CMAKE_" + lit.first + "_STANDARD_DEFAULT");
for (std::string const& it : lit.second) {
if (!cm::contains(langAvailable, it)) {
@@ -3567,15 +3468,14 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
continue;
}
if (!standardResolver.HaveStandardAvailable(target, lit.first,
context->Config, it)) {
eval->Config, it)) {
if (evalLL) {
cmValue l =
target->GetLanguageStandard(lit.first, context->Config);
cmValue l = target->GetLanguageStandard(lit.first, eval->Config);
if (!l) {
l = standardDefault;
}
assert(l);
context->MaxLanguageStandard[target][lit.first] = *l;
eval->MaxLanguageStandard[target][lit.first] = *l;
} else {
return "0";
}
@@ -3633,27 +3533,26 @@ static const struct TargetPolicyNode : public cmGeneratorExpressionNode
int NumExpectedParameters() const override { return 1; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
if (!context->HeadTarget) {
if (!eval->HeadTarget) {
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"$<TARGET_POLICY:prop> may only be used with binary targets. It "
"may not be used with add_custom_command or add_custom_target.");
return std::string();
}
context->HadContextSensitiveCondition = true;
context->HadHeadSensitiveCondition = true;
eval->HadContextSensitiveCondition = true;
eval->HadHeadSensitiveCondition = true;
for (size_t i = 1; i < cm::size(targetPolicyWhitelist); ++i) {
char const* policy = targetPolicyWhitelist[i];
if (parameters.front() == policy) {
cmLocalGenerator* lg = context->HeadTarget->GetLocalGenerator();
switch (statusForTarget(context->HeadTarget, policy)) {
cmLocalGenerator* lg = eval->HeadTarget->GetLocalGenerator();
switch (statusForTarget(eval->HeadTarget, policy)) {
case cmPolicies::WARN:
lg->IssueMessage(
MessageType::AUTHOR_WARNING,
@@ -3667,7 +3566,7 @@ static const struct TargetPolicyNode : public cmGeneratorExpressionNode
}
}
reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"$<TARGET_POLICY:prop> may only be used with a limited number of "
"policies. Currently it may be used with the following policies:\n"
@@ -3694,11 +3593,10 @@ static const struct InstallPrefixNode : public cmGeneratorExpressionNode
std::string Evaluate(
std::vector<std::string> const& /*parameters*/,
cmGeneratorExpressionContext* context,
GeneratorExpressionContent const* content,
cm::GenEx::Evaluation* eval, GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"INSTALL_PREFIX is a marker for install(EXPORT) only. It "
"should never be evaluated.");
return std::string();
@@ -3724,20 +3622,20 @@ template <typename ArtifactT, typename ComponentT>
struct TargetFilesystemArtifactDependency
{
static void AddDependency(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context)
cm::GenEx::Evaluation* eval)
{
context->DependTargets.insert(target);
context->AllTargets.insert(target);
eval->DependTargets.insert(target);
eval->AllTargets.insert(target);
}
};
struct TargetFilesystemArtifactDependencyCMP0112
{
static void AddDependency(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context)
cm::GenEx::Evaluation* eval)
{
context->AllTargets.insert(target);
cmLocalGenerator const* lg = context->LG;
eval->AllTargets.insert(target);
cmLocalGenerator const* lg = eval->LG;
switch (target->GetPolicyStatusCMP0112()) {
case cmPolicies::WARN:
if (lg->GetMakefile()->PolicyOptionalWarningEnabled(
@@ -3747,11 +3645,11 @@ struct TargetFilesystemArtifactDependencyCMP0112
"\nDependency being added to target:\n \"",
target->GetName(), "\"\n");
lg->GetCMakeInstance()->IssueMessage(MessageType ::AUTHOR_WARNING,
err, context->Backtrace);
err, eval->Backtrace);
}
CM_FALLTHROUGH;
case cmPolicies::OLD:
context->DependTargets.insert(target);
eval->DependTargets.insert(target);
break;
case cmPolicies::NEW:
break;
@@ -3792,7 +3690,7 @@ template <typename ArtifactT>
struct TargetFilesystemArtifactResultCreator
{
static std::string Create(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content);
};
@@ -3800,30 +3698,30 @@ template <>
struct TargetFilesystemArtifactResultCreator<ArtifactSonameTag>
{
static std::string Create(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content)
{
// The target soname file (.so.1).
if (target->IsDLLPlatform()) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"TARGET_SONAME_FILE is not allowed "
"for DLL target platforms.");
return std::string();
}
if (target->GetType() != cmStateEnums::SHARED_LIBRARY) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"TARGET_SONAME_FILE is allowed only for "
"SHARED libraries.");
return std::string();
}
if (target->IsArchivedAIXSharedLibrary()) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"TARGET_SONAME_FILE is not allowed for "
"AIX_SHARED_LIBRARY_ARCHIVE libraries.");
return std::string();
}
std::string result = cmStrCat(target->GetDirectory(context->Config), '/',
target->GetSOName(context->Config));
std::string result = cmStrCat(target->GetDirectory(eval->Config), '/',
target->GetSOName(eval->Config));
return result;
}
};
@@ -3832,35 +3730,35 @@ template <>
struct TargetFilesystemArtifactResultCreator<ArtifactSonameImportTag>
{
static std::string Create(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content)
{
// The target soname file (.so.1).
if (target->IsDLLPlatform()) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"TARGET_SONAME_IMPORT_FILE is not allowed "
"for DLL target platforms.");
return std::string();
}
if (target->GetType() != cmStateEnums::SHARED_LIBRARY) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"TARGET_SONAME_IMPORT_FILE is allowed only for "
"SHARED libraries.");
return std::string();
}
if (target->IsArchivedAIXSharedLibrary()) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"TARGET_SONAME_IMPORT_FILE is not allowed for "
"AIX_SHARED_LIBRARY_ARCHIVE libraries.");
return std::string();
}
if (target->HasImportLibrary(context->Config)) {
return cmStrCat(target->GetDirectory(
context->Config, cmStateEnums::ImportLibraryArtifact),
'/',
target->GetSOName(context->Config,
cmStateEnums::ImportLibraryArtifact));
if (target->HasImportLibrary(eval->Config)) {
return cmStrCat(
target->GetDirectory(eval->Config,
cmStateEnums::ImportLibraryArtifact),
'/',
target->GetSOName(eval->Config, cmStateEnums::ImportLibraryArtifact));
}
return std::string{};
}
@@ -3870,21 +3768,21 @@ template <>
struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag>
{
static std::string Create(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content)
{
if (target->IsImported()) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"TARGET_PDB_FILE not allowed for IMPORTED targets.");
return std::string();
}
std::string language = target->GetLinkerLanguage(context->Config);
std::string language = target->GetLinkerLanguage(eval->Config);
std::string pdbSupportVar = "CMAKE_" + language + "_LINKER_SUPPORTS_PDB";
if (!context->LG->GetMakefile()->IsOn(pdbSupportVar)) {
::reportError(context, content->GetOriginalExpression(),
if (!eval->LG->GetMakefile()->IsOn(pdbSupportVar)) {
::reportError(eval, content->GetOriginalExpression(),
"TARGET_PDB_FILE is not supported by the target linker.");
return std::string();
}
@@ -3894,14 +3792,14 @@ struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag>
if (targetType != cmStateEnums::SHARED_LIBRARY &&
targetType != cmStateEnums::MODULE_LIBRARY &&
targetType != cmStateEnums::EXECUTABLE) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"TARGET_PDB_FILE is allowed only for "
"targets with linker created artifacts.");
return std::string();
}
std::string result = cmStrCat(target->GetPDBDirectory(context->Config),
'/', target->GetPDBName(context->Config));
std::string result = cmStrCat(target->GetPDBDirectory(eval->Config), '/',
target->GetPDBName(eval->Config));
return result;
}
};
@@ -3910,22 +3808,22 @@ template <>
struct TargetFilesystemArtifactResultCreator<ArtifactLinkerTag>
{
static std::string Create(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content)
{
// The file used to link to the target (.so, .lib, .a) or import file
// (.lib, .tbd).
if (!target->IsLinkable()) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"TARGET_LINKER_FILE is allowed only for libraries and "
"executables with ENABLE_EXPORTS.");
return std::string();
}
cmStateEnums::ArtifactType artifact =
target->HasImportLibrary(context->Config)
target->HasImportLibrary(eval->Config)
? cmStateEnums::ImportLibraryArtifact
: cmStateEnums::RuntimeBinaryArtifact;
return target->GetFullPath(context->Config, artifact);
return target->GetFullPath(eval->Config, artifact);
}
};
@@ -3933,13 +3831,13 @@ template <>
struct TargetFilesystemArtifactResultCreator<ArtifactLinkerLibraryTag>
{
static std::string Create(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content)
{
// The file used to link to the target (.dylib, .so, .a).
if (!target->IsLinkable() ||
target->GetType() == cmStateEnums::EXECUTABLE) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"TARGET_LINKER_LIBRARY_FILE is allowed only for libraries "
"with ENABLE_EXPORTS.");
return std::string();
@@ -3947,7 +3845,7 @@ struct TargetFilesystemArtifactResultCreator<ArtifactLinkerLibraryTag>
if (!target->IsDLLPlatform() ||
target->GetType() == cmStateEnums::STATIC_LIBRARY) {
return target->GetFullPath(context->Config,
return target->GetFullPath(eval->Config,
cmStateEnums::RuntimeBinaryArtifact);
}
return std::string{};
@@ -3958,20 +3856,20 @@ template <>
struct TargetFilesystemArtifactResultCreator<ArtifactLinkerImportTag>
{
static std::string Create(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content)
{
// The file used to link to the target (.lib, .tbd).
if (!target->IsLinkable()) {
::reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"TARGET_LINKER_IMPORT_FILE is allowed only for libraries and "
"executables with ENABLE_EXPORTS.");
return std::string();
}
if (target->HasImportLibrary(context->Config)) {
return target->GetFullPath(context->Config,
if (target->HasImportLibrary(eval->Config)) {
return target->GetFullPath(eval->Config,
cmStateEnums::ImportLibraryArtifact);
}
return std::string{};
@@ -3982,22 +3880,22 @@ template <>
struct TargetFilesystemArtifactResultCreator<ArtifactBundleDirTag>
{
static std::string Create(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content)
{
if (target->IsImported()) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"TARGET_BUNDLE_DIR not allowed for IMPORTED targets.");
return std::string();
}
if (!target->IsBundleOnApple()) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"TARGET_BUNDLE_DIR is allowed only for Bundle targets.");
return std::string();
}
std::string outpath = target->GetDirectory(context->Config) + '/';
return target->BuildBundleDirectory(outpath, context->Config,
std::string outpath = target->GetDirectory(eval->Config) + '/';
return target->BuildBundleDirectory(outpath, eval->Config,
cmGeneratorTarget::BundleDirLevel);
}
};
@@ -4006,24 +3904,24 @@ template <>
struct TargetFilesystemArtifactResultCreator<ArtifactBundleDirNameTag>
{
static std::string Create(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content)
{
if (target->IsImported()) {
::reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"TARGET_BUNDLE_DIR_NAME not allowed for IMPORTED targets.");
return std::string();
}
if (!target->IsBundleOnApple()) {
::reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"TARGET_BUNDLE_DIR_NAME is allowed only for Bundle targets.");
return std::string();
}
auto level = cmGeneratorTarget::BundleDirLevel;
auto config = context->Config;
auto config = eval->Config;
if (target->IsAppBundleOnApple()) {
return target->GetAppBundleDirectory(config, level);
}
@@ -4041,24 +3939,24 @@ template <>
struct TargetFilesystemArtifactResultCreator<ArtifactBundleContentDirTag>
{
static std::string Create(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content)
{
if (target->IsImported()) {
::reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"TARGET_BUNDLE_CONTENT_DIR not allowed for IMPORTED targets.");
return std::string();
}
if (!target->IsBundleOnApple()) {
::reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"TARGET_BUNDLE_CONTENT_DIR is allowed only for Bundle targets.");
return std::string();
}
std::string outpath = target->GetDirectory(context->Config) + '/';
return target->BuildBundleDirectory(outpath, context->Config,
std::string outpath = target->GetDirectory(eval->Config) + '/';
return target->BuildBundleDirectory(outpath, eval->Config,
cmGeneratorTarget::ContentLevel);
}
};
@@ -4067,10 +3965,10 @@ template <>
struct TargetFilesystemArtifactResultCreator<ArtifactNameTag>
{
static std::string Create(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* /*unused*/)
{
return target->GetFullPath(context->Config,
return target->GetFullPath(eval->Config,
cmStateEnums::RuntimeBinaryArtifact, true);
}
};
@@ -4079,11 +3977,11 @@ template <>
struct TargetFilesystemArtifactResultCreator<ArtifactImportTag>
{
static std::string Create(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* /*unused*/)
{
if (target->HasImportLibrary(context->Config)) {
return target->GetFullPath(context->Config,
if (target->HasImportLibrary(eval->Config)) {
return target->GetFullPath(eval->Config,
cmStateEnums::ImportLibraryArtifact, true);
}
return std::string{};
@@ -4126,8 +4024,7 @@ struct TargetArtifactBase : public cmGeneratorExpressionNode
protected:
cmGeneratorTarget* GetTarget(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagChecker) const
{
@@ -4135,19 +4032,19 @@ protected:
std::string const& name = parameters.front();
if (!cmGeneratorExpression::IsValidTargetName(name)) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"Expression syntax not recognized.");
return nullptr;
}
cmGeneratorTarget* target = context->LG->FindGeneratorTargetToUse(name);
cmGeneratorTarget* target = eval->LG->FindGeneratorTargetToUse(name);
if (!target) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"No target \"" + name + "\"");
return nullptr;
}
if (target->GetType() >= cmStateEnums::OBJECT_LIBRARY &&
target->GetType() != cmStateEnums::UNKNOWN_LIBRARY) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"Target \"" + name +
"\" is not an executable or library.");
return nullptr;
@@ -4156,7 +4053,7 @@ protected:
(dagChecker->EvaluatingLinkLibraries(target) ||
(dagChecker->EvaluatingSources() &&
target == dagChecker->TopTarget()))) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"Expressions which require the linker language may not "
"be used while evaluating link libraries");
return nullptr;
@@ -4174,13 +4071,12 @@ struct TargetFilesystemArtifact : public TargetArtifactBase
int NumExpectedParameters() const override { return 1; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagChecker) const override
{
cmGeneratorTarget* target =
this->GetTarget(parameters, context, content, dagChecker);
this->GetTarget(parameters, eval, content, dagChecker);
if (!target) {
return std::string();
}
@@ -4188,12 +4084,12 @@ struct TargetFilesystemArtifact : public TargetArtifactBase
// ArtifactNameTag, ArtifactBundleDirTag, ArtifactBundleDirNameTag,
// and ArtifactBundleContentDirTag
TargetFilesystemArtifactDependency<ArtifactT, ComponentT>::AddDependency(
target, context);
target, eval);
std::string result =
TargetFilesystemArtifactResultCreator<ArtifactT>::Create(target, context,
TargetFilesystemArtifactResultCreator<ArtifactT>::Create(target, eval,
content);
if (context->HadError) {
if (eval->HadError) {
return std::string();
}
return TargetFilesystemArtifactResultGetter<ComponentT>::Get(result);
@@ -4253,7 +4149,7 @@ template <typename ArtifactT>
struct TargetOutputNameArtifactResultGetter
{
static std::string Get(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content);
};
@@ -4261,12 +4157,12 @@ template <>
struct TargetOutputNameArtifactResultGetter<ArtifactNameTag>
{
static std::string Get(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* /*unused*/)
{
return target->GetOutputName(context->Config,
return target->GetOutputName(eval->Config,
cmStateEnums::RuntimeBinaryArtifact) +
target->GetFilePostfix(context->Config);
target->GetFilePostfix(eval->Config);
}
};
@@ -4274,13 +4170,13 @@ template <>
struct TargetOutputNameArtifactResultGetter<ArtifactImportTag>
{
static std::string Get(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* /*unused*/)
{
if (target->HasImportLibrary(context->Config)) {
return target->GetOutputName(context->Config,
if (target->HasImportLibrary(eval->Config)) {
return target->GetOutputName(eval->Config,
cmStateEnums::ImportLibraryArtifact) +
target->GetFilePostfix(context->Config);
target->GetFilePostfix(eval->Config);
}
return std::string{};
}
@@ -4290,23 +4186,23 @@ template <>
struct TargetOutputNameArtifactResultGetter<ArtifactLinkerTag>
{
static std::string Get(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content)
{
// The library file used to link to the target (.so, .lib, .a) or import
// file (.lin, .tbd).
if (!target->IsLinkable()) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"TARGET_LINKER_FILE_BASE_NAME is allowed only for "
"libraries and executables with ENABLE_EXPORTS.");
return std::string();
}
cmStateEnums::ArtifactType artifact =
target->HasImportLibrary(context->Config)
target->HasImportLibrary(eval->Config)
? cmStateEnums::ImportLibraryArtifact
: cmStateEnums::RuntimeBinaryArtifact;
return target->GetOutputName(context->Config, artifact) +
target->GetFilePostfix(context->Config);
return target->GetOutputName(eval->Config, artifact) +
target->GetFilePostfix(eval->Config);
}
};
@@ -4314,13 +4210,13 @@ template <>
struct TargetOutputNameArtifactResultGetter<ArtifactLinkerLibraryTag>
{
static std::string Get(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content)
{
// The library file used to link to the target (.so, .lib, .a).
if (!target->IsLinkable() ||
target->GetType() == cmStateEnums::EXECUTABLE) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"TARGET_LINKER_LIBRARY_FILE_BASE_NAME is allowed only for "
"libraries with ENABLE_EXPORTS.");
return std::string();
@@ -4328,9 +4224,9 @@ struct TargetOutputNameArtifactResultGetter<ArtifactLinkerLibraryTag>
if (!target->IsDLLPlatform() ||
target->GetType() == cmStateEnums::STATIC_LIBRARY) {
return target->GetOutputName(context->Config,
return target->GetOutputName(eval->Config,
cmStateEnums::ImportLibraryArtifact) +
target->GetFilePostfix(context->Config);
target->GetFilePostfix(eval->Config);
}
return std::string{};
}
@@ -4340,21 +4236,21 @@ template <>
struct TargetOutputNameArtifactResultGetter<ArtifactLinkerImportTag>
{
static std::string Get(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content)
{
// The import file used to link to the target (.lib, .tbd).
if (!target->IsLinkable()) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"TARGET_LINKER_IMPORT_FILE_BASE_NAME is allowed only for "
"libraries and executables with ENABLE_EXPORTS.");
return std::string();
}
if (target->HasImportLibrary(context->Config)) {
return target->GetOutputName(context->Config,
if (target->HasImportLibrary(eval->Config)) {
return target->GetOutputName(eval->Config,
cmStateEnums::ImportLibraryArtifact) +
target->GetFilePostfix(context->Config);
target->GetFilePostfix(eval->Config);
}
return std::string{};
}
@@ -4364,23 +4260,23 @@ template <>
struct TargetOutputNameArtifactResultGetter<ArtifactPdbTag>
{
static std::string Get(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content)
{
if (target->IsImported()) {
::reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"TARGET_PDB_FILE_BASE_NAME not allowed for IMPORTED targets.");
return std::string();
}
std::string language = target->GetLinkerLanguage(context->Config);
std::string language = target->GetLinkerLanguage(eval->Config);
std::string pdbSupportVar = "CMAKE_" + language + "_LINKER_SUPPORTS_PDB";
if (!context->LG->GetMakefile()->IsOn(pdbSupportVar)) {
if (!eval->LG->GetMakefile()->IsOn(pdbSupportVar)) {
::reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"TARGET_PDB_FILE_BASE_NAME is not supported by the target linker.");
return std::string();
}
@@ -4390,13 +4286,13 @@ struct TargetOutputNameArtifactResultGetter<ArtifactPdbTag>
if (targetType != cmStateEnums::SHARED_LIBRARY &&
targetType != cmStateEnums::MODULE_LIBRARY &&
targetType != cmStateEnums::EXECUTABLE) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"TARGET_PDB_FILE_BASE_NAME is allowed only for "
"targets with linker created artifacts.");
return std::string();
}
return target->GetPDBOutputName(context->Config);
return target->GetPDBOutputName(eval->Config);
}
};
@@ -4408,20 +4304,19 @@ struct TargetFileBaseNameArtifact : public TargetArtifactBase
int NumExpectedParameters() const override { return 1; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagChecker) const override
{
cmGeneratorTarget* target =
this->GetTarget(parameters, context, content, dagChecker);
this->GetTarget(parameters, eval, content, dagChecker);
if (!target) {
return std::string();
}
std::string result = TargetOutputNameArtifactResultGetter<ArtifactT>::Get(
target, context, content);
if (context->HadError) {
target, eval, content);
if (eval->HadError) {
return std::string();
}
return result;
@@ -4456,7 +4351,7 @@ template <typename ArtifactT>
struct TargetFileArtifactResultGetter
{
static std::string Get(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content);
};
@@ -4464,21 +4359,21 @@ template <>
struct TargetFileArtifactResultGetter<ArtifactFilePrefixTag>
{
static std::string Get(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const*)
{
return target->GetFilePrefix(context->Config);
return target->GetFilePrefix(eval->Config);
}
};
template <>
struct TargetFileArtifactResultGetter<ArtifactImportFilePrefixTag>
{
static std::string Get(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const*)
{
if (target->HasImportLibrary(context->Config)) {
return target->GetFilePrefix(context->Config,
if (target->HasImportLibrary(eval->Config)) {
return target->GetFilePrefix(eval->Config,
cmStateEnums::ImportLibraryArtifact);
}
return std::string{};
@@ -4488,36 +4383,36 @@ template <>
struct TargetFileArtifactResultGetter<ArtifactLinkerFilePrefixTag>
{
static std::string Get(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content)
{
if (!target->IsLinkable()) {
::reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"TARGET_LINKER_FILE_PREFIX is allowed only for libraries and "
"executables with ENABLE_EXPORTS.");
return std::string();
}
cmStateEnums::ArtifactType artifact =
target->HasImportLibrary(context->Config)
target->HasImportLibrary(eval->Config)
? cmStateEnums::ImportLibraryArtifact
: cmStateEnums::RuntimeBinaryArtifact;
return target->GetFilePrefix(context->Config, artifact);
return target->GetFilePrefix(eval->Config, artifact);
}
};
template <>
struct TargetFileArtifactResultGetter<ArtifactLinkerLibraryFilePrefixTag>
{
static std::string Get(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content)
{
if (!target->IsLinkable() ||
target->GetType() == cmStateEnums::EXECUTABLE) {
::reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"TARGET_LINKER_LIBRARY_FILE_PREFIX is allowed only for libraries "
"with ENABLE_EXPORTS.");
return std::string();
@@ -4525,7 +4420,7 @@ struct TargetFileArtifactResultGetter<ArtifactLinkerLibraryFilePrefixTag>
if (!target->IsDLLPlatform() ||
target->GetType() == cmStateEnums::STATIC_LIBRARY) {
return target->GetFilePrefix(context->Config,
return target->GetFilePrefix(eval->Config,
cmStateEnums::RuntimeBinaryArtifact);
}
return std::string{};
@@ -4535,19 +4430,19 @@ template <>
struct TargetFileArtifactResultGetter<ArtifactLinkerImportFilePrefixTag>
{
static std::string Get(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content)
{
if (!target->IsLinkable()) {
::reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"TARGET_LINKER_IMPORT_FILE_PREFIX is allowed only for libraries and "
"executables with ENABLE_EXPORTS.");
return std::string();
}
if (target->HasImportLibrary(context->Config)) {
return target->GetFilePrefix(context->Config,
if (target->HasImportLibrary(eval->Config)) {
return target->GetFilePrefix(eval->Config,
cmStateEnums::ImportLibraryArtifact);
}
return std::string{};
@@ -4557,21 +4452,21 @@ template <>
struct TargetFileArtifactResultGetter<ArtifactFileSuffixTag>
{
static std::string Get(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const*)
{
return target->GetFileSuffix(context->Config);
return target->GetFileSuffix(eval->Config);
}
};
template <>
struct TargetFileArtifactResultGetter<ArtifactImportFileSuffixTag>
{
static std::string Get(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const*)
{
if (target->HasImportLibrary(context->Config)) {
return target->GetFileSuffix(context->Config,
if (target->HasImportLibrary(eval->Config)) {
return target->GetFileSuffix(eval->Config,
cmStateEnums::ImportLibraryArtifact);
}
return std::string{};
@@ -4581,35 +4476,35 @@ template <>
struct TargetFileArtifactResultGetter<ArtifactLinkerFileSuffixTag>
{
static std::string Get(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content)
{
if (!target->IsLinkable()) {
::reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"TARGET_LINKER_FILE_SUFFIX is allowed only for libraries and "
"executables with ENABLE_EXPORTS.");
return std::string();
}
cmStateEnums::ArtifactType artifact =
target->HasImportLibrary(context->Config)
target->HasImportLibrary(eval->Config)
? cmStateEnums::ImportLibraryArtifact
: cmStateEnums::RuntimeBinaryArtifact;
return target->GetFileSuffix(context->Config, artifact);
return target->GetFileSuffix(eval->Config, artifact);
}
};
template <>
struct TargetFileArtifactResultGetter<ArtifactLinkerLibraryFileSuffixTag>
{
static std::string Get(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content)
{
if (!target->IsLinkable() ||
target->GetType() == cmStateEnums::STATIC_LIBRARY) {
::reportError(context, content->GetOriginalExpression(),
::reportError(eval, content->GetOriginalExpression(),
"TARGET_LINKER_LIBRARY_FILE_SUFFIX is allowed only for "
"libraries with ENABLE_EXPORTS.");
return std::string();
@@ -4617,7 +4512,7 @@ struct TargetFileArtifactResultGetter<ArtifactLinkerLibraryFileSuffixTag>
if (!target->IsDLLPlatform() ||
target->GetType() == cmStateEnums::STATIC_LIBRARY) {
return target->GetFileSuffix(context->Config,
return target->GetFileSuffix(eval->Config,
cmStateEnums::RuntimeBinaryArtifact);
}
return std::string{};
@@ -4627,19 +4522,19 @@ template <>
struct TargetFileArtifactResultGetter<ArtifactLinkerImportFileSuffixTag>
{
static std::string Get(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content)
{
if (!target->IsLinkable()) {
::reportError(
context, content->GetOriginalExpression(),
eval, content->GetOriginalExpression(),
"TARGET_LINKER_IMPORT_FILE_SUFFIX is allowed only for libraries and "
"executables with ENABLE_EXPORTS.");
return std::string();
}
if (target->HasImportLibrary(context->Config)) {
return target->GetFileSuffix(context->Config,
if (target->HasImportLibrary(eval->Config)) {
return target->GetFileSuffix(eval->Config,
cmStateEnums::ImportLibraryArtifact);
}
return std::string{};
@@ -4654,20 +4549,19 @@ struct TargetFileArtifact : public TargetArtifactBase
int NumExpectedParameters() const override { return 1; }
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagChecker) const override
{
cmGeneratorTarget* target =
this->GetTarget(parameters, context, content, dagChecker);
this->GetTarget(parameters, eval, content, dagChecker);
if (!target) {
return std::string();
}
std::string result =
TargetFileArtifactResultGetter<ArtifactT>::Get(target, context, content);
if (context->HadError) {
TargetFileArtifactResultGetter<ArtifactT>::Get(target, eval, content);
if (eval->HadError) {
return std::string();
}
return result;
@@ -4698,25 +4592,24 @@ static const struct ShellPathNode : public cmGeneratorExpressionNode
ShellPathNode() {} // NOLINT(modernize-use-equals-default)
std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
cmList list_in{ parameters.front() };
if (list_in.empty()) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"\"\" is not an absolute path.");
return std::string();
}
cmStateSnapshot snapshot = context->LG->GetStateSnapshot();
cmStateSnapshot snapshot = eval->LG->GetStateSnapshot();
cmOutputConverter converter(snapshot);
char const* separator = snapshot.GetState()->UseWindowsShell() ? ";" : ":";
std::vector<std::string> list_out;
list_out.reserve(list_in.size());
for (auto const& in : list_in) {
if (!cmSystemTools::FileIsFullPath(in)) {
reportError(context, content->GetOriginalExpression(),
reportError(eval, content->GetOriginalExpression(),
"\"" + in + "\" is not an absolute path.");
return std::string();
}
@@ -4892,11 +4785,11 @@ cmGeneratorExpressionNode const* cmGeneratorExpressionNode::GetNode(
return nullptr;
}
void reportError(cmGeneratorExpressionContext* context,
std::string const& expr, std::string const& result)
void reportError(cm::GenEx::Evaluation* eval, std::string const& expr,
std::string const& result)
{
context->HadError = true;
if (context->Quiet) {
eval->HadError = true;
if (eval->Quiet) {
return;
}
@@ -4906,6 +4799,6 @@ void reportError(cmGeneratorExpressionContext* context,
<< " " << expr << "\n"
<< result;
/* clang-format on */
context->LG->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
e.str(), context->Backtrace);
eval->LG->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str(),
eval->Backtrace);
}
+10 -6
View File
@@ -7,9 +7,14 @@
#include <string>
#include <vector>
namespace cm {
namespace GenEx {
struct Evaluation;
}
}
class cmGeneratorTarget;
struct GeneratorExpressionContent;
struct cmGeneratorExpressionContext;
struct cmGeneratorExpressionDAGChecker;
struct cmGeneratorExpressionNode
@@ -39,13 +44,12 @@ struct cmGeneratorExpressionNode
}
virtual std::string Evaluate(
std::vector<std::string> const& parameters,
cmGeneratorExpressionContext* context,
std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
GeneratorExpressionContent const* content,
cmGeneratorExpressionDAGChecker* dagChecker) const = 0;
static std::string EvaluateDependentExpression(
std::string const& prop, cmGeneratorExpressionContext* context,
std::string const& prop, cm::GenEx::Evaluation* eval,
cmGeneratorTarget const* headTarget,
cmGeneratorExpressionDAGChecker* dagChecker,
cmGeneratorTarget const* currentTarget);
@@ -54,5 +58,5 @@ struct cmGeneratorExpressionNode
std::string const& identifier);
};
void reportError(cmGeneratorExpressionContext* context,
std::string const& expr, std::string const& result);
void reportError(cm::GenEx::Evaluation* eval, std::string const& expr,
std::string const& result);
+8 -3
View File
@@ -27,6 +27,12 @@
#include "cmStateTypes.h"
#include "cmValue.h"
namespace cm {
namespace GenEx {
struct Evaluation;
}
}
class cmake;
enum class cmBuildStep;
class cmCompiledGeneratorExpression;
@@ -40,7 +46,6 @@ class cmSourceFile;
struct cmSyntheticTargetCache;
class cmTarget;
struct cmGeneratorExpressionContext;
struct cmGeneratorExpressionDAGChecker;
class cmGeneratorTarget
@@ -1006,7 +1011,7 @@ public:
class TargetPropertyEntry;
std::string EvaluateInterfaceProperty(
std::string const& prop, cmGeneratorExpressionContext* context,
std::string const& prop, cm::GenEx::Evaluation* eval,
cmGeneratorExpressionDAGChecker* dagCheckerParent, UseTo usage) const;
struct TransitiveProperty
@@ -1316,7 +1321,7 @@ private:
mutable std::unordered_map<std::string, bool> MaybeInterfacePropertyExists;
bool MaybeHaveInterfaceProperty(std::string const& prop,
cmGeneratorExpressionContext* context,
cm::GenEx::Evaluation* eval,
UseTo usage) const;
using TargetPropertyEntryVector =
+26 -35
View File
@@ -15,8 +15,8 @@
#include <cm/string_view>
#include <cmext/string_view>
#include "cmGenExEvaluation.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionContext.h"
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorExpressionNode.h"
#include "cmLinkItem.h"
@@ -54,11 +54,11 @@ std::map<cm::string_view, TransitiveProperty> const
{ "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES"_s, UseTo::Compile } },
};
bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
std::string const& prop, cmGeneratorExpressionContext* context,
UseTo usage) const
bool cmGeneratorTarget::MaybeHaveInterfaceProperty(std::string const& prop,
cm::GenEx::Evaluation* eval,
UseTo usage) const
{
std::string const key = prop + '@' + context->Config;
std::string const key = prop + '@' + eval->Config;
auto i = this->MaybeInterfacePropertyExists.find(key);
if (i == this->MaybeInterfacePropertyExists.end()) {
// Insert an entry now in case there is a cycle.
@@ -71,10 +71,9 @@ bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
// Otherwise, recurse to interface dependencies.
if (!maybeInterfaceProp) {
cmGeneratorTarget const* headTarget =
context->HeadTarget ? context->HeadTarget : this;
eval->HeadTarget ? eval->HeadTarget : this;
if (cmLinkInterfaceLibraries const* iface =
this->GetLinkInterfaceLibraries(context->Config, headTarget,
usage)) {
this->GetLinkInterfaceLibraries(eval->Config, headTarget, usage)) {
if (iface->HadHeadSensitiveCondition) {
// With a different head target we may get to a library with
// this interface property.
@@ -84,7 +83,7 @@ bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
// head target, so we can follow them.
for (cmLinkItem const& lib : iface->Libraries) {
if (lib.Target &&
lib.Target->MaybeHaveInterfaceProperty(prop, context, usage)) {
lib.Target->MaybeHaveInterfaceProperty(prop, eval, usage)) {
maybeInterfaceProp = true;
break;
}
@@ -97,13 +96,13 @@ bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
}
std::string cmGeneratorTarget::EvaluateInterfaceProperty(
std::string const& prop, cmGeneratorExpressionContext* context,
std::string const& prop, cm::GenEx::Evaluation* eval,
cmGeneratorExpressionDAGChecker* dagCheckerParent, UseTo usage) const
{
std::string result;
// If the property does not appear transitively at all, we are done.
if (!this->MaybeHaveInterfaceProperty(prop, context, usage)) {
if (!this->MaybeHaveInterfaceProperty(prop, eval, usage)) {
return result;
}
@@ -111,18 +110,13 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
// a subset of TargetPropertyNode::Evaluate without stringify/parse steps
// but sufficient for transitive interface properties.
cmGeneratorExpressionDAGChecker dagChecker{
this,
prop,
nullptr,
dagCheckerParent,
context->LG,
context->Config,
context->Backtrace,
this, prop, nullptr, dagCheckerParent,
eval->LG, eval->Config, eval->Backtrace,
};
switch (dagChecker.Check()) {
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
dagChecker.ReportError(
context, "$<TARGET_PROPERTY:" + this->GetName() + "," + prop + ">");
eval, "$<TARGET_PROPERTY:" + this->GetName() + "," + prop + ">");
return result;
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
// No error. We just skip cyclic references.
@@ -134,17 +128,16 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
}
cmGeneratorTarget const* headTarget =
context->HeadTarget ? context->HeadTarget : this;
eval->HeadTarget ? eval->HeadTarget : this;
if (cmValue p = this->GetProperty(prop)) {
result = cmGeneratorExpressionNode::EvaluateDependentExpression(
*p, context, headTarget, &dagChecker, this);
*p, eval, headTarget, &dagChecker, this);
}
if (cmLinkInterfaceLibraries const* iface =
this->GetLinkInterfaceLibraries(context->Config, headTarget, usage)) {
context->HadContextSensitiveCondition =
context->HadContextSensitiveCondition ||
this->GetLinkInterfaceLibraries(eval->Config, headTarget, usage)) {
eval->HadContextSensitiveCondition = eval->HadContextSensitiveCondition ||
iface->HadContextSensitiveCondition;
for (cmLinkItem const& lib : iface->Libraries) {
// Broken code can have a target in its own link interface.
@@ -154,12 +147,11 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
// Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in the
// above property and hand-evaluate it as if it were compiled.
// Create a context as cmCompiledGeneratorExpression::Evaluate does.
cmGeneratorExpressionContext libContext(
context->LG, context->Config, context->Quiet, headTarget, this,
context->EvaluateForBuildsystem, context->Backtrace,
context->Language);
cm::GenEx::Evaluation libEval(
eval->LG, eval->Config, eval->Quiet, headTarget, this,
eval->EvaluateForBuildsystem, eval->Backtrace, eval->Language);
std::string libResult = cmGeneratorExpression::StripEmptyListElements(
lib.Target->EvaluateInterfaceProperty(prop, &libContext, &dagChecker,
lib.Target->EvaluateInterfaceProperty(prop, &libEval, &dagChecker,
usage));
if (!libResult.empty()) {
if (result.empty()) {
@@ -170,12 +162,11 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
result += libResult;
}
}
context->HadContextSensitiveCondition =
context->HadContextSensitiveCondition ||
libContext.HadContextSensitiveCondition;
context->HadHeadSensitiveCondition =
context->HadHeadSensitiveCondition ||
libContext.HadHeadSensitiveCondition;
eval->HadContextSensitiveCondition =
eval->HadContextSensitiveCondition ||
libEval.HadContextSensitiveCondition;
eval->HadHeadSensitiveCondition =
eval->HadHeadSensitiveCondition || libEval.HadHeadSensitiveCondition;
}
}
}
+1 -1
View File
@@ -375,8 +375,8 @@ CMAKE_CXX_SOURCES="\
cmFunctionCommand \
cmFSPermissions \
cmGeneratedFileStream \
cmGenExEvaluation \
cmGeneratorExpression \
cmGeneratorExpressionContext \
cmGeneratorExpressionDAGChecker \
cmGeneratorExpressionEvaluationFile \
cmGeneratorExpressionEvaluator \