diff options
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 114 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.h | 11 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.cxx | 15 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.h | 1 | ||||
-rw-r--r-- | Source/cmLocalGenerator.h | 5 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0028/CMP0028-NEW-iface-stderr.txt | 12 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0028/CMP0028-NEW-stderr.txt | 12 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0028/CMP0028-WARN-iface-stderr.txt | 12 | ||||
-rw-r--r-- | Tests/RunCMake/CMP0028/CMP0028-WARN-stderr.txt | 12 | ||||
-rw-r--r-- | Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus-stderr.txt | 12 | ||||
-rw-r--r-- | Tests/RunCMake/target_link_libraries/ConfigCase-stderr.txt | 28 |
11 files changed, 175 insertions, 59 deletions
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 0e17839..e370472 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -2687,7 +2687,6 @@ public: : Config(std::move(config)) , Languages(languages) , HeadTarget(head) - , Target(target) , SecondPass(secondPass) { this->Visited.insert(target); @@ -2696,40 +2695,6 @@ public: void Visit(cmLinkItem const& item) { if (!item.Target) { - if (item.AsStr().find("::") != std::string::npos) { - bool noMessage = false; - MessageType messageType = MessageType::FATAL_ERROR; - std::ostringstream e; - switch (this->Target->GetLocalGenerator()->GetPolicyStatus( - cmPolicies::CMP0028)) { - case cmPolicies::WARN: { - e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0028) << "\n"; - messageType = MessageType::AUTHOR_WARNING; - } break; - case cmPolicies::OLD: - noMessage = true; - break; - case cmPolicies::REQUIRED_IF_USED: - case cmPolicies::REQUIRED_ALWAYS: - case cmPolicies::NEW: - // Issue the fatal message. - break; - } - - if (!noMessage) { - e << "Target \"" << this->Target->GetName() - << "\" links to target \"" << item.AsStr() - << "\" but the target was not found. Perhaps a find_package() " - "call is missing for an IMPORTED target, or an ALIAS target is " - "missing?"; - cmListFileBacktrace backtrace = item.Backtrace; - if (backtrace.Empty()) { - backtrace = this->Target->GetBacktrace(); - } - this->Target->GetLocalGenerator()->GetCMakeInstance()->IssueMessage( - messageType, e.str(), backtrace); - } - } return; } if (!this->Visited.insert(item.Target).second) { @@ -2762,7 +2727,6 @@ private: std::string Config; std::unordered_set<std::string>& Languages; cmGeneratorTarget const* HeadTarget; - const cmGeneratorTarget* Target; std::set<cmGeneratorTarget const*> Visited; bool SecondPass; bool HadLinkLanguageSensitiveCondition = false; @@ -6281,6 +6245,84 @@ cmComputeLinkInformation* cmGeneratorTarget::GetLinkInformation( return i->second.get(); } +void cmGeneratorTarget::CheckLinkLibraries() const +{ + // Check link the implementation for each generated configuration. + for (auto const& hmp : this->LinkImplMap) { + HeadToLinkImplementationMap const& hm = hmp.second; + // There could be several entries used when computing the pre-CMP0022 + // default link interface. Check only the entry for our own link impl. + auto const hmi = hm.find(this); + if (hmi == hm.end() || !hmi->second.LibrariesDone) { + continue; + } + for (cmLinkImplItem const& item : hmi->second.Libraries) { + if (!this->VerifyLinkItemColons(LinkItemRole::Implementation, item)) { + return; + } + } + } + + // Check link the interface for each generated combination of + // configuration and consuming head target. We should not need to + // consider LinkInterfaceUsageRequirementsOnlyMap because its entries + // should be a subset of LinkInterfaceMap (with LINK_ONLY left out). + for (auto const& hmp : this->LinkInterfaceMap) { + for (auto const& hmi : hmp.second) { + if (!hmi.second.LibrariesDone) { + continue; + } + for (cmLinkItem const& item : hmi.second.Libraries) { + if (!this->VerifyLinkItemColons(LinkItemRole::Interface, item)) { + return; + } + } + } + } +} + +bool cmGeneratorTarget::VerifyLinkItemColons(LinkItemRole role, + cmLinkItem const& item) const +{ + if (item.Target || item.AsStr().find("::") == std::string::npos) { + return true; + } + MessageType messageType = MessageType::FATAL_ERROR; + std::string e; + switch (this->GetLocalGenerator()->GetPolicyStatus(cmPolicies::CMP0028)) { + case cmPolicies::WARN: { + e = cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0028), "\n"); + messageType = MessageType::AUTHOR_WARNING; + } break; + case cmPolicies::OLD: + return true; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::NEW: + // Issue the fatal message. + break; + } + + if (role == LinkItemRole::Implementation) { + e = cmStrCat(e, "Target \"", this->GetName(), "\" links to"); + } else { + e = cmStrCat(e, "The link interface of target \"", this->GetName(), + "\" contains"); + } + e = cmStrCat(e, ":\n ", item.AsStr(), "\n", + "but the target was not found. Possible reasons include:\n" + " * There is a typo in the target name.\n" + " * A find_package call is missing for an IMPORTED target.\n" + " * An ALIAS target is missing.\n"); + cmListFileBacktrace backtrace = item.Backtrace; + if (backtrace.Empty()) { + backtrace = this->GetBacktrace(); + } + this->GetLocalGenerator()->GetCMakeInstance()->IssueMessage(messageType, e, + backtrace); + return false; +} + void cmGeneratorTarget::GetTargetVersion(int& major, int& minor) const { int patch; diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 110af43..096e2ea 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -84,6 +84,10 @@ public: cmComputeLinkInformation* GetLinkInformation( const std::string& config) const; + // Perform validation checks on memoized link structures. + // Call this after generation is complete. + void CheckLinkLibraries() const; + cmStateEnums::TargetType GetType() const; const std::string& GetName() const; std::string GetExportName() const; @@ -973,6 +977,13 @@ private: cmLinkImplementation const* GetLinkImplementation(const std::string& config, bool secondPass) const; + enum class LinkItemRole + { + Implementation, + Interface, + }; + bool VerifyLinkItemColons(LinkItemRole role, cmLinkItem const& item) const; + // Cache import information from properties for each configuration. struct ImportInfo { diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 0a2e7b5..6433681 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -328,6 +328,18 @@ bool cmGlobalGenerator::CheckTargetsForMissingSources() const return failed; } +void cmGlobalGenerator::CheckTargetLinkLibraries() const +{ + for (const auto& generator : this->LocalGenerators) { + for (const auto& gt : generator->GetGeneratorTargets()) { + gt->CheckLinkLibraries(); + } + for (const auto& gt : generator->GetOwnedImportedGeneratorTargets()) { + gt->CheckLinkLibraries(); + } + } +} + bool cmGlobalGenerator::CheckTargetsForType() const { if (!this->GetLanguageEnabled("Swift")) { @@ -1606,6 +1618,9 @@ void cmGlobalGenerator::Generate() this->ExtraGenerator->Generate(); } + // Perform validation checks on memoized link structures. + this->CheckTargetLinkLibraries(); + if (!this->CMP0042WarnTargets.empty()) { std::ostringstream w; w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0042) << "\n"; diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 96696aa..2406798 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -684,6 +684,7 @@ private: virtual void ForceLinkerLanguages(); + void CheckTargetLinkLibraries() const; bool CheckTargetsForMissingSources() const; bool CheckTargetsForType() const; bool CheckTargetsForPchCompilePdb() const; diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index c73cd62..115a54a 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -193,6 +193,11 @@ public: return this->GeneratorTargets; } + const GeneratorTargetVector& GetOwnedImportedGeneratorTargets() const + { + return this->OwnedImportedGeneratorTargets; + } + void AddGeneratorTarget(std::unique_ptr<cmGeneratorTarget> gt); void AddImportedGeneratorTarget(cmGeneratorTarget* gt); void AddOwnedImportedGeneratorTarget(std::unique_ptr<cmGeneratorTarget> gt); diff --git a/Tests/RunCMake/CMP0028/CMP0028-NEW-iface-stderr.txt b/Tests/RunCMake/CMP0028/CMP0028-NEW-iface-stderr.txt index 2f264a1..111d1f0 100644 --- a/Tests/RunCMake/CMP0028/CMP0028-NEW-iface-stderr.txt +++ b/Tests/RunCMake/CMP0028/CMP0028-NEW-iface-stderr.txt @@ -1,6 +1,12 @@ CMake Error at CMP0028-NEW-iface\.cmake:5 \(target_link_libraries\): - Target "foo" links to target "External::Library" but the target was not - found. Perhaps a find_package\(\) call is missing for an IMPORTED target, or - an ALIAS target is missing\? + The link interface of target "iface" contains: + + External::Library + + but the target was not found. Possible reasons include: +( + \*[^ +]+)* + Call Stack \(most recent call first\): CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/CMP0028/CMP0028-NEW-stderr.txt b/Tests/RunCMake/CMP0028/CMP0028-NEW-stderr.txt index 7abf318..17b25de 100644 --- a/Tests/RunCMake/CMP0028/CMP0028-NEW-stderr.txt +++ b/Tests/RunCMake/CMP0028/CMP0028-NEW-stderr.txt @@ -1,6 +1,12 @@ CMake Error at CMP0028-NEW\.cmake:5 \(target_link_libraries\): - Target "foo" links to target "External::Library" but the target was not - found. Perhaps a find_package\(\) call is missing for an IMPORTED target, or - an ALIAS target is missing\? + Target "foo" links to: + + External::Library + + but the target was not found. Possible reasons include: +( + \*[^ +]+)* + Call Stack \(most recent call first\): CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/CMP0028/CMP0028-WARN-iface-stderr.txt b/Tests/RunCMake/CMP0028/CMP0028-WARN-iface-stderr.txt index e865d48..bb6a16e 100644 --- a/Tests/RunCMake/CMP0028/CMP0028-WARN-iface-stderr.txt +++ b/Tests/RunCMake/CMP0028/CMP0028-WARN-iface-stderr.txt @@ -3,9 +3,15 @@ CMake Warning \(dev\) at CMP0028-WARN-iface\.cmake:3 \(target_link_libraries\): IMPORTED target. Run "cmake --help-policy CMP0028" for policy details. Use the cmake_policy command to set the policy and suppress this warning. - Target "foo" links to target "External::Library" but the target was not - found. Perhaps a find_package\(\) call is missing for an IMPORTED target, or - an ALIAS target is missing\? + The link interface of target "iface" contains: + + External::Library + + but the target was not found. Possible reasons include: +( + \*[^ +]+)* + Call Stack \(most recent call first\): CMakeLists\.txt:[0-9]+ \(include\) This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CMP0028/CMP0028-WARN-stderr.txt b/Tests/RunCMake/CMP0028/CMP0028-WARN-stderr.txt index 533cba3..c0cb5b0 100644 --- a/Tests/RunCMake/CMP0028/CMP0028-WARN-stderr.txt +++ b/Tests/RunCMake/CMP0028/CMP0028-WARN-stderr.txt @@ -3,9 +3,15 @@ CMake Warning \(dev\) at CMP0028-WARN\.cmake:3 \(target_link_libraries\): IMPORTED target. Run "cmake --help-policy CMP0028" for policy details. Use the cmake_policy command to set the policy and suppress this warning. - Target "foo" links to target "External::Library" but the target was not - found. Perhaps a find_package\(\) call is missing for an IMPORTED target, or - an ALIAS target is missing\? + Target "foo" links to: + + External::Library + + but the target was not found. Possible reasons include: +( + \*[^ +]+)* + Call Stack \(most recent call first\): CMakeLists\.txt:[0-9]+ \(include\) This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus-stderr.txt b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus-stderr.txt index 644674f..488ae8d 100644 --- a/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus-stderr.txt +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus-stderr.txt @@ -1,6 +1,12 @@ ^CMake Error at CMP0079-link-NEW-bogus\.cmake:6 \(set_property\): - Target "top" links to target "::@\(0xdeadbeef\)" but the target was not - found. Perhaps a find_package\(\) call is missing for an IMPORTED target, or - an ALIAS target is missing\? + Target "top" links to: + + ::@\(0xdeadbeef\) + + but the target was not found. Possible reasons include: +( + \*[^ +]+)* + Call Stack \(most recent call first\): CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/target_link_libraries/ConfigCase-stderr.txt b/Tests/RunCMake/target_link_libraries/ConfigCase-stderr.txt index ea078b5..ad48fd0 100644 --- a/Tests/RunCMake/target_link_libraries/ConfigCase-stderr.txt +++ b/Tests/RunCMake/target_link_libraries/ConfigCase-stderr.txt @@ -1,13 +1,25 @@ -^CMake Error at ConfigCase\.cmake:6 \(target_link_libraries\): - Target "impl" links to target "config::impl-Debug" but the target was not - found. Perhaps a find_package\(\) call is missing for an IMPORTED target, or - an ALIAS target is missing\? +^CMake Error at ConfigCase\.cmake:4 \(target_link_libraries\): + The link interface of target "iface" contains: + + config::iface-Debug + + but the target was not found. Possible reasons include: +( + \*[^ +]+)* + Call Stack \(most recent call first\): CMakeLists\.txt:[0-9]+ \(include\) + -CMake Error at ConfigCase\.cmake:4 \(target_link_libraries\): - Target "impl" links to target "config::iface-Debug" but the target was not - found. Perhaps a find_package\(\) call is missing for an IMPORTED target, or - an ALIAS target is missing\? +CMake Error at ConfigCase\.cmake:6 \(target_link_libraries\): + Target "impl" links to: + + config::impl-Debug + + but the target was not found. Possible reasons include: +( + \*[^ +]+)* + Call Stack \(most recent call first\): CMakeLists\.txt:[0-9]+ \(include\) |