From 2f708f5d65557ecbfe4ebe7c14b02dbba6bf0ffe Mon Sep 17 00:00:00 2001 From: Brad King <brad.king@kitware.com> Date: Fri, 7 Sep 2018 10:56:17 -0400 Subject: Make internal TARGET_PROPERTY generator expressions more robust While collecting usage requirements from the `INTERFACE_*` properties of directly linked targets, we internally generate `TARGET_PROPERTY:` and `TARGET_OBJECTS:` generator expressions to refer to those properties on those targets. At the point we generate these expressions we already have a pointer to an exact `cmGeneratorTarget` instance. Switch from using the target name in these generator expressions to using an internal unique name generated for each `cmGeneratorTarget` instance to be referenced. This avoids depending on the user-facing target name to find the same target we already have. --- Source/cmGeneratorExpressionNode.cxx | 4 +++- Source/cmGeneratorTarget.cxx | 10 ++++++++-- Source/cmGlobalGenerator.cxx | 18 ++++++++++++++++++ Source/cmGlobalGenerator.h | 4 ++++ 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 1e51f09..16ac88c 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -1054,7 +1054,9 @@ std::string getLinkedTargetsContent( // Don't follow such link interface entries so as not to create a // self-referencing loop. if (l.Target && l.Target != target) { - depString += sep + "$<TARGET_PROPERTY:" + l.Target->GetName() + "," + + std::string uniqueName = + target->GetGlobalGenerator()->IndexGeneratorTargetUniquely(l.Target); + depString += sep + "$<TARGET_PROPERTY:" + std::move(uniqueName) + "," + interfacePropertyName + ">"; sep = ";"; } diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index e8e7b90..40ee01e 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -819,8 +819,11 @@ static void AddInterfaceEntries( thisTarget->GetLinkImplementationLibraries(config)) { for (cmLinkImplItem const& lib : impl->Libraries) { if (lib.Target) { + std::string uniqueName = + thisTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely( + lib.Target); std::string genex = - "$<TARGET_PROPERTY:" + lib.AsStr() + "," + prop + ">"; + "$<TARGET_PROPERTY:" + std::move(uniqueName) + "," + prop + ">"; cmGeneratorExpression ge(lib.Backtrace); std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex); cge->SetEvaluateForBuildsystem(true); @@ -840,7 +843,10 @@ static void AddObjectEntries( for (cmLinkImplItem const& lib : impl->Libraries) { if (lib.Target && lib.Target->GetType() == cmStateEnums::OBJECT_LIBRARY) { - std::string genex = "$<TARGET_OBJECTS:" + lib.AsStr() + ">"; + std::string uniqueName = + thisTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely( + lib.Target); + std::string genex = "$<TARGET_OBJECTS:" + std::move(uniqueName) + ">"; cmGeneratorExpression ge(lib.Backtrace); std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex); cge->SetEvaluateForBuildsystem(true); diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 207d492..0aba67c 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -2155,6 +2155,24 @@ void cmGlobalGenerator::IndexGeneratorTarget(cmGeneratorTarget* gt) } } +std::string cmGlobalGenerator::IndexGeneratorTargetUniquely( + cmGeneratorTarget const* gt) +{ + // Use the pointer value to uniquely identify the target instance. + // Use a "T" prefix to indicate that this identifier is for a target. + // We must satisfy cmGeneratorExpression::IsValidTargetName so use no + // other special characters. + char buf[64]; + sprintf(buf, "::T%p", + static_cast<void const*>(gt)); // cast avoids format warning + std::string id = gt->GetName() + buf; + // We internally index pointers to non-const generator targets + // but our callers only have pointers to const generator targets. + // They will give up non-const privileges when looking up anyway. + this->GeneratorTargetSearchIndex[id] = const_cast<cmGeneratorTarget*>(gt); + return id; +} + void cmGlobalGenerator::IndexMakefile(cmMakefile* mf) { // FIXME: add_subdirectory supports multiple build directories diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 720938d..6b972eb 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -303,6 +303,10 @@ public: void IndexTarget(cmTarget* t); void IndexGeneratorTarget(cmGeneratorTarget* gt); + // Index the target using a name that is unique to that target + // even if other targets have the same name. + std::string IndexGeneratorTargetUniquely(cmGeneratorTarget const* gt); + static bool IsReservedTarget(std::string const& name); virtual const char* GetAllTargetName() const { return "ALL_BUILD"; } -- cgit v0.12