summaryrefslogtreecommitdiff
path: root/Source/cmGeneratorTarget.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2021-12-16 12:42:29 -0500
committerBrad King <brad.king@kitware.com>2021-12-16 16:43:17 -0500
commitea050286e7f4b659518bf5b6c4adbddefa3cc9a6 (patch)
tree90849ed084ad953d03d0b84eb812c5383140db55 /Source/cmGeneratorTarget.cxx
parenta97c92e46eff516eb4642776dcf85bd646e63763 (diff)
downloadcmake-ea050286e7f4b659518bf5b6c4adbddefa3cc9a6.tar.gz
CMP0028: Report the target whose link interface has an offending item
Previously items linked via the link interface of a dependency were reported in CMP0028 messages as if directly linked by a target. Clarify the messages to indicate that an offending item is actually in the link interface of a given target, regardless of its consumer. Move the check to the end of generation and look through the final set of link implementations and link interfaces that were used for generation. This avoids repeating messages on link interfaces that have multiple consumers.
Diffstat (limited to 'Source/cmGeneratorTarget.cxx')
-rw-r--r--Source/cmGeneratorTarget.cxx114
1 files changed, 78 insertions, 36 deletions
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 0e17839106..e370472323 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;