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 10:26:12 -04:00
parent d1c780886e
commit 4697f7122b
14 changed files with 749 additions and 841 deletions

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

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

View File

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

View File

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

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

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

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;

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.");
}

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;

File diff suppressed because it is too large Load Diff

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

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 =

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

View File

@@ -375,8 +375,8 @@ CMAKE_CXX_SOURCES="\
cmFunctionCommand \
cmFSPermissions \
cmGeneratedFileStream \
cmGenExEvaluation \
cmGeneratorExpression \
cmGeneratorExpressionContext \
cmGeneratorExpressionDAGChecker \
cmGeneratorExpressionEvaluationFile \
cmGeneratorExpressionEvaluator \