mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-09 23:30:35 -06:00
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
This commit is contained in:
@@ -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 =
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
add_library(a STATIC a.c)
|
||||
target_compile_definitions(a INTERFACE DEF_A)
|
||||
|
||||
add_library(sameName INTERFACE IMPORTED)
|
||||
target_link_libraries(sameName INTERFACE a)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
add_library(b STATIC b.c)
|
||||
target_compile_definitions(b INTERFACE DEF_B)
|
||||
|
||||
add_library(sameName INTERFACE IMPORTED)
|
||||
target_link_libraries(sameName INTERFACE b)
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user