Commit f35be599 authored by Brad King's avatar Brad King
Browse files

Fix transitive usage requirements through same-name imported targets

If two imported targets in different directories have the same name we
should still be able to propagate transitive usage requirements from
both.  Fix the DAG checker to work with target pointers instead of
target names since the pointers will not be duplicated even if the names
are.

Fixes: #18345
parent 1b57f495
......@@ -108,7 +108,7 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
// build type of the makefile
cmGeneratorExpression ge;
cmGeneratorExpressionDAGChecker dagChecker(
target->GetName(), "INTERFACE_LINK_LIBRARIES", nullptr, nullptr);
target, "INTERFACE_LINK_LIBRARIES", nullptr, nullptr);
std::unique_ptr<cmCompiledGeneratorExpression> cge =
ge.Parse(property.second);
std::string evaluated = cge->Evaluate(
......
......@@ -65,8 +65,7 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
cmGeneratorExpression ge;
cmGeneratorExpressionDAGChecker dagChecker(tgt->GetName(), propName, nullptr,
nullptr);
cmGeneratorExpressionDAGChecker dagChecker(tgt, propName, nullptr, nullptr);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
......
......@@ -13,7 +13,6 @@
#include "cmGeneratorExpressionEvaluator.h"
#include "cmGeneratorExpressionLexer.h"
#include "cmGeneratorExpressionParser.h"
#include "cmGeneratorTarget.h"
#include "cmSystemTools.h"
cmGeneratorExpression::cmGeneratorExpression(
......@@ -395,7 +394,7 @@ const std::string& cmGeneratorExpressionInterpreter::Evaluate(
// Specify COMPILE_OPTIONS to DAGchecker, same semantic as COMPILE_FLAGS
cmGeneratorExpressionDAGChecker dagChecker(
this->HeadTarget->GetName(),
this->HeadTarget,
property == "COMPILE_FLAGS" ? "COMPILE_OPTIONS" : property, nullptr,
nullptr);
......
......@@ -14,7 +14,7 @@
#include <utility>
cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
const cmListFileBacktrace& backtrace, const std::string& target,
const cmListFileBacktrace& backtrace, cmGeneratorTarget const* target,
const std::string& property, const GeneratorExpressionContent* content,
cmGeneratorExpressionDAGChecker* parent)
: Parent(parent)
......@@ -28,7 +28,7 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
}
cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
const std::string& target, const std::string& property,
cmGeneratorTarget const* target, const std::string& property,
const GeneratorExpressionContent* content,
cmGeneratorExpressionDAGChecker* parent)
: Parent(parent)
......@@ -58,8 +58,8 @@ void cmGeneratorExpressionDAGChecker::Initialize()
TEST_TRANSITIVE_PROPERTY_METHOD) false)) // NOLINT(clang-tidy)
#undef TEST_TRANSITIVE_PROPERTY_METHOD
{
std::map<std::string, std::set<std::string>>::const_iterator it =
top->Seen.find(this->Target);
std::map<cmGeneratorTarget const*, std::set<std::string>>::const_iterator
it = top->Seen.find(this->Target);
if (it != top->Seen.end()) {
const std::set<std::string>& propSet = it->second;
if (propSet.find(this->Property) != propSet.end()) {
......@@ -166,7 +166,8 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingGenexExpression()
return top->Property == "TARGET_GENEX_EVAL" || top->Property == "GENEX_EVAL";
}
bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(const char* tgt)
bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(
cmGeneratorTarget const* tgt)
{
const cmGeneratorExpressionDAGChecker* top = this;
const cmGeneratorExpressionDAGChecker* parent = this->Parent;
......@@ -189,7 +190,7 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(const char* tgt)
strcmp(prop, "INTERFACE_LINK_LIBRARIES") == 0;
}
std::string cmGeneratorExpressionDAGChecker::TopTarget() const
cmGeneratorTarget const* cmGeneratorExpressionDAGChecker::TopTarget() const
{
const cmGeneratorExpressionDAGChecker* top = this;
const cmGeneratorExpressionDAGChecker* parent = this->Parent;
......
......@@ -13,6 +13,7 @@
struct GeneratorExpressionContent;
struct cmGeneratorExpressionContext;
class cmGeneratorTarget;
#define CM_SELECT_BOTH(F, A1, A2) F(A1, A2)
#define CM_SELECT_FIRST(F, A1, A2) F(A1)
......@@ -41,11 +42,11 @@ struct cmGeneratorExpressionContext;
struct cmGeneratorExpressionDAGChecker
{
cmGeneratorExpressionDAGChecker(const cmListFileBacktrace& backtrace,
const std::string& target,
cmGeneratorTarget const* target,
const std::string& property,
const GeneratorExpressionContent* content,
cmGeneratorExpressionDAGChecker* parent);
cmGeneratorExpressionDAGChecker(const std::string& target,
cmGeneratorExpressionDAGChecker(cmGeneratorTarget const* target,
const std::string& property,
const GeneratorExpressionContent* content,
cmGeneratorExpressionDAGChecker* parent);
......@@ -64,7 +65,7 @@ struct cmGeneratorExpressionDAGChecker
const std::string& expr);
bool EvaluatingGenexExpression();
bool EvaluatingLinkLibraries(const char* tgt = nullptr);
bool EvaluatingLinkLibraries(cmGeneratorTarget const* tgt = nullptr);
#define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) bool METHOD() const;
......@@ -75,7 +76,7 @@ struct cmGeneratorExpressionDAGChecker
bool GetTransitivePropertiesOnly();
void SetTransitivePropertiesOnly() { this->TransitivePropertiesOnly = true; }
std::string TopTarget() const;
cmGeneratorTarget const* TopTarget() const;
private:
Result CheckGraph() const;
......@@ -83,9 +84,9 @@ private:
private:
const cmGeneratorExpressionDAGChecker* const Parent;
const std::string Target;
cmGeneratorTarget const* Target;
const std::string Property;
std::map<std::string, std::set<std::string>> Seen;
std::map<cmGeneratorTarget const*, std::set<std::string>> Seen;
const GeneratorExpressionContent* const Content;
const cmListFileBacktrace Backtrace;
Result CheckResult;
......
......@@ -378,8 +378,8 @@ protected:
{
if (context->HeadTarget) {
cmGeneratorExpressionDAGChecker dagChecker(
context->Backtrace, context->HeadTarget->GetName(), genexOperator,
content, dagCheckerParent);
context->Backtrace, context->HeadTarget, genexOperator, content,
dagCheckerParent);
switch (dagChecker.Check()) {
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE: {
......@@ -1196,9 +1196,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
return target->GetLinkerLanguage(context->Config);
}
cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace,
target->GetName(), propertyName,
content, dagCheckerParent);
cmGeneratorExpressionDAGChecker dagChecker(
context->Backtrace, target, propertyName, content, dagCheckerParent);
switch (dagChecker.Check()) {
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
......@@ -1911,9 +1910,9 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode
return std::string();
}
if (dagChecker &&
(dagChecker->EvaluatingLinkLibraries(name.c_str()) ||
(dagChecker->EvaluatingLinkLibraries(target) ||
(dagChecker->EvaluatingSources() &&
name == dagChecker->TopTarget()))) {
target == dagChecker->TopTarget()))) {
::reportError(context, content->GetOriginalExpression(),
"Expressions which require the linker language may not "
"be used while evaluating link libraries");
......
......@@ -773,7 +773,7 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(
if (iter == this->SystemIncludesCache.end()) {
cmGeneratorExpressionDAGChecker dagChecker(
this->GetName(), "SYSTEM_INCLUDE_DIRECTORIES", nullptr, nullptr);
this, "SYSTEM_INCLUDE_DIRECTORIES", nullptr, nullptr);
bool excludeImported = this->GetPropertyAsBool("NO_SYSTEM_FROM_IMPORTED");
......@@ -964,8 +964,8 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<std::string>& files,
this->DebugSourcesDone = true;
}
cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), "SOURCES",
nullptr, nullptr);
cmGeneratorExpressionDAGChecker dagChecker(this, "SOURCES", nullptr,
nullptr);
std::unordered_set<std::string> uniqueSrcs;
bool contextDependentDirectSources =
......@@ -2078,8 +2078,8 @@ void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string>& result,
}
cmGeneratorExpression ge;
cmGeneratorExpressionDAGChecker dagChecker(
this->GetName(), "AUTOUIC_OPTIONS", nullptr, nullptr);
cmGeneratorExpressionDAGChecker dagChecker(this, "AUTOUIC_OPTIONS", nullptr,
nullptr);
cmSystemTools::ExpandListArgument(
ge.Parse(prop)->Evaluate(this->LocalGenerator, config, false, this,
&dagChecker),
......@@ -2588,8 +2588,8 @@ std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories(
std::vector<std::string> includes;
std::unordered_set<std::string> uniqueIncludes;
cmGeneratorExpressionDAGChecker dagChecker(
this->GetName(), "INCLUDE_DIRECTORIES", nullptr, nullptr);
cmGeneratorExpressionDAGChecker dagChecker(this, "INCLUDE_DIRECTORIES",
nullptr, nullptr);
std::vector<std::string> debugProperties;
const char* debugProp =
......@@ -2710,8 +2710,8 @@ void cmGeneratorTarget::GetCompileOptions(std::vector<std::string>& result,
{
std::unordered_set<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(
this->GetName(), "COMPILE_OPTIONS", nullptr, nullptr);
cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_OPTIONS", nullptr,
nullptr);
std::vector<std::string> debugProperties;
const char* debugProp =
......@@ -2763,8 +2763,8 @@ void cmGeneratorTarget::GetCompileFeatures(std::vector<std::string>& result,
{
std::unordered_set<std::string> uniqueFeatures;
cmGeneratorExpressionDAGChecker dagChecker(
this->GetName(), "COMPILE_FEATURES", nullptr, nullptr);
cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_FEATURES", nullptr,
nullptr);
std::vector<std::string> debugProperties;
const char* debugProp =
......@@ -2814,8 +2814,8 @@ void cmGeneratorTarget::GetCompileDefinitions(
{
std::unordered_set<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(
this->GetName(), "COMPILE_DEFINITIONS", nullptr, nullptr);
cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_DEFINITIONS",
nullptr, nullptr);
std::vector<std::string> debugProperties;
const char* debugProp =
......@@ -2895,8 +2895,8 @@ void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result,
{
std::unordered_set<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), "LINK_OPTIONS",
nullptr, nullptr);
cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_OPTIONS", nullptr,
nullptr);
std::vector<std::string> debugProperties;
const char* debugProp =
......@@ -3043,8 +3043,8 @@ void cmGeneratorTarget::GetStaticLibraryLinkOptions(
std::vector<cmGeneratorTarget::TargetPropertyEntry*> entries;
std::unordered_set<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(
this->GetName(), "STATIC_LIBRARY_OPTIONS", nullptr, nullptr);
cmGeneratorExpressionDAGChecker dagChecker(this, "STATIC_LIBRARY_OPTIONS",
nullptr, nullptr);
if (const char* linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
std::vector<std::string> options;
......@@ -3083,8 +3083,8 @@ void cmGeneratorTarget::GetLinkDepends(std::vector<std::string>& result,
{
std::vector<cmGeneratorTarget::TargetPropertyEntry*> linkDependsEntries;
std::unordered_set<std::string> uniqueOptions;
cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), "LINK_DEPENDS",
nullptr, nullptr);
cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_DEPENDS", nullptr,
nullptr);
if (const char* linkDepends = this->GetProperty("LINK_DEPENDS")) {
std::vector<std::string> depends;
......@@ -4509,8 +4509,7 @@ void cmGeneratorTarget::ExpandLinkItems(
std::vector<cmLinkItem>& items, bool& hadHeadSensitiveCondition) const
{
cmGeneratorExpression ge;
cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), prop, nullptr,
nullptr);
cmGeneratorExpressionDAGChecker dagChecker(this, prop, nullptr, nullptr);
// The $<LINK_ONLY> expression may be in a link interface to specify private
// link dependencies that are otherwise excluded from usage requirements.
if (usage_requirements_only) {
......@@ -5561,8 +5560,8 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
end = entryRange.end();
le != end; ++le, ++btIt) {
std::vector<std::string> llibs;
cmGeneratorExpressionDAGChecker dagChecker(
this->GetName(), "LINK_LIBRARIES", nullptr, nullptr);
cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_LIBRARIES", nullptr,
nullptr);
cmGeneratorExpression ge(*btIt);
std::unique_ptr<cmCompiledGeneratorExpression> const cge = ge.Parse(*le);
std::string const& evaluated =
......
add_library(a STATIC a.c)
target_compile_definitions(a INTERFACE DEF_A)
add_library(sameName INTERFACE IMPORTED)
target_link_libraries(sameName INTERFACE a)
......
add_library(b STATIC b.c)
target_compile_definitions(b INTERFACE DEF_B)
add_library(sameName INTERFACE IMPORTED)
target_link_libraries(sameName INTERFACE b)
......
#ifndef DEF_A
# error "DEF_A not defined"
#endif
#ifndef DEF_B
# error "DEF_B not defined"
#endif
extern void a(void);
extern void b(void);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment