mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-18 17:31:57 +08:00
Restore support for exporting INTERFACE with missing dependencies
Since commitc16acd35b3
(GenEx: Add support for custom transitive link properties, 2024-05-09, v3.30.0-rc1~82^2) evaluation of `TRANSITIVE_LINK_PROPERTIES` by `install(EXPORT)` enables discovery of missing dependencies on INTERFACE libraries that we did not previously diagnose. This regressed existing projects that relied on such non-diagnosis. Although commit2fc9e482a9
(Evaluation of TRANSITIVE_LINK_PROPERTIES isn't considered a usage, 2024-07-05) fixed this, it also made a significant change to the `UseTo` infrastructure that may have other subtle effects. Replace the fix with an approach that explicitly models suppression of the relevant diagnostics. Fixes: #26108
This commit is contained in:
@@ -613,6 +613,7 @@ void cmExportFileGenerator::PopulateCustomTransitiveInterfaceProperties(
|
|||||||
properties);
|
properties);
|
||||||
this->PopulateInterfaceProperty("TRANSITIVE_LINK_PROPERTIES", target,
|
this->PopulateInterfaceProperty("TRANSITIVE_LINK_PROPERTIES", target,
|
||||||
properties);
|
properties);
|
||||||
|
cmGeneratorTarget::CheckLinkLibrariesSuppressionRAII cllSuppressRAII;
|
||||||
std::set<std::string> ifaceProperties;
|
std::set<std::string> ifaceProperties;
|
||||||
for (std::string const& config : this->Configurations) {
|
for (std::string const& config : this->Configurations) {
|
||||||
for (auto const& i : target->GetCustomTransitiveProperties(
|
for (auto const& i : target->GetCustomTransitiveProperties(
|
||||||
|
@@ -99,6 +99,13 @@ public:
|
|||||||
// Call this after generation is complete.
|
// Call this after generation is complete.
|
||||||
void CheckLinkLibraries() const;
|
void CheckLinkLibraries() const;
|
||||||
|
|
||||||
|
class CheckLinkLibrariesSuppressionRAII
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CheckLinkLibrariesSuppressionRAII();
|
||||||
|
~CheckLinkLibrariesSuppressionRAII();
|
||||||
|
};
|
||||||
|
|
||||||
cmStateEnums::TargetType GetType() const;
|
cmStateEnums::TargetType GetType() const;
|
||||||
const std::string& GetName() const;
|
const std::string& GetName() const;
|
||||||
std::string GetExportName() const;
|
std::string GetExportName() const;
|
||||||
@@ -264,7 +271,6 @@ public:
|
|||||||
{
|
{
|
||||||
Compile, // Usage requirements for compiling. Excludes $<LINK_ONLY>.
|
Compile, // Usage requirements for compiling. Excludes $<LINK_ONLY>.
|
||||||
Link, // Usage requirements for linking. Includes $<LINK_ONLY>.
|
Link, // Usage requirements for linking. Includes $<LINK_ONLY>.
|
||||||
LinkInterfaceEval,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
cmLinkInterfaceLibraries const* GetLinkInterfaceLibraries(
|
cmLinkInterfaceLibraries const* GetLinkInterfaceLibraries(
|
||||||
|
@@ -54,6 +54,20 @@ const std::string kINTERFACE_LINK_LIBRARIES_DIRECT =
|
|||||||
"INTERFACE_LINK_LIBRARIES_DIRECT";
|
"INTERFACE_LINK_LIBRARIES_DIRECT";
|
||||||
const std::string kINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE =
|
const std::string kINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE =
|
||||||
"INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE";
|
"INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE";
|
||||||
|
|
||||||
|
unsigned int CheckLinkLibrariesSuppressionRAIICount;
|
||||||
|
void MaybeEnableCheckLinkLibraries(cmOptionalLinkImplementation& impl)
|
||||||
|
{
|
||||||
|
if (CheckLinkLibrariesSuppressionRAIICount == 0) {
|
||||||
|
impl.CheckLinkLibraries = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void MaybeEnableCheckLinkLibraries(cmOptionalLinkInterface& iface)
|
||||||
|
{
|
||||||
|
if (CheckLinkLibrariesSuppressionRAIICount == 0) {
|
||||||
|
iface.CheckLinkLibraries = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class cmTargetCollectLinkLanguages
|
class cmTargetCollectLinkLanguages
|
||||||
@@ -372,7 +386,8 @@ void cmGeneratorTarget::CheckLinkLibraries() const
|
|||||||
// There could be several entries used when computing the pre-CMP0022
|
// There could be several entries used when computing the pre-CMP0022
|
||||||
// default link interface. Check only the entry for our own link impl.
|
// default link interface. Check only the entry for our own link impl.
|
||||||
auto const hmi = hm.find(this);
|
auto const hmi = hm.find(this);
|
||||||
if (hmi == hm.end() || !hmi->second.LibrariesDone) {
|
if (hmi == hm.end() || !hmi->second.LibrariesDone ||
|
||||||
|
!hmi->second.CheckLinkLibraries) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (cmLinkImplItem const& item : hmi->second.Libraries) {
|
for (cmLinkImplItem const& item : hmi->second.Libraries) {
|
||||||
@@ -392,7 +407,7 @@ void cmGeneratorTarget::CheckLinkLibraries() const
|
|||||||
// should be a subset of LinkInterfaceMap (with LINK_ONLY left out).
|
// should be a subset of LinkInterfaceMap (with LINK_ONLY left out).
|
||||||
for (auto const& hmp : this->LinkInterfaceMap) {
|
for (auto const& hmp : this->LinkInterfaceMap) {
|
||||||
for (auto const& hmi : hmp.second) {
|
for (auto const& hmi : hmp.second) {
|
||||||
if (!hmi.second.LibrariesDone || hmi.second.LinkOnlyEval) {
|
if (!hmi.second.LibrariesDone || !hmi.second.CheckLinkLibraries) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (cmLinkItem const& item : hmi.second.Libraries) {
|
for (cmLinkItem const& item : hmi.second.Libraries) {
|
||||||
@@ -408,6 +423,18 @@ void cmGeneratorTarget::CheckLinkLibraries() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmGeneratorTarget::CheckLinkLibrariesSuppressionRAII::
|
||||||
|
CheckLinkLibrariesSuppressionRAII()
|
||||||
|
{
|
||||||
|
++CheckLinkLibrariesSuppressionRAIICount;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmGeneratorTarget::CheckLinkLibrariesSuppressionRAII::
|
||||||
|
~CheckLinkLibrariesSuppressionRAII()
|
||||||
|
{
|
||||||
|
--CheckLinkLibrariesSuppressionRAIICount;
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
cm::string_view missingTargetPossibleReasons =
|
cm::string_view missingTargetPossibleReasons =
|
||||||
"Possible reasons include:\n"
|
"Possible reasons include:\n"
|
||||||
@@ -642,7 +669,7 @@ cmLinkInterface const* cmGeneratorTarget::GetLinkInterface(
|
|||||||
if (secondPass) {
|
if (secondPass) {
|
||||||
iface = cmOptionalLinkInterface();
|
iface = cmOptionalLinkInterface();
|
||||||
}
|
}
|
||||||
iface.LinkOnlyEval = false;
|
MaybeEnableCheckLinkLibraries(iface);
|
||||||
if (!iface.LibrariesDone) {
|
if (!iface.LibrariesDone) {
|
||||||
iface.LibrariesDone = true;
|
iface.LibrariesDone = true;
|
||||||
this->ComputeLinkInterfaceLibraries(config, iface, head, UseTo::Link);
|
this->ComputeLinkInterfaceLibraries(config, iface, head, UseTo::Link);
|
||||||
@@ -766,7 +793,7 @@ const cmLinkInterfaceLibraries* cmGeneratorTarget::GetLinkInterfaceLibraries(
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmOptionalLinkInterface& iface = hm[head];
|
cmOptionalLinkInterface& iface = hm[head];
|
||||||
iface.LinkOnlyEval = (usage == UseTo::LinkInterfaceEval);
|
MaybeEnableCheckLinkLibraries(iface);
|
||||||
if (!iface.LibrariesDone) {
|
if (!iface.LibrariesDone) {
|
||||||
iface.LibrariesDone = true;
|
iface.LibrariesDone = true;
|
||||||
this->ComputeLinkInterfaceLibraries(config, iface, head, usage);
|
this->ComputeLinkInterfaceLibraries(config, iface, head, usage);
|
||||||
@@ -1036,7 +1063,7 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
|
|||||||
if (secondPass) {
|
if (secondPass) {
|
||||||
iface = cmOptionalLinkInterface();
|
iface = cmOptionalLinkInterface();
|
||||||
}
|
}
|
||||||
iface.LinkOnlyEval = (usage == UseTo::LinkInterfaceEval);
|
MaybeEnableCheckLinkLibraries(iface);
|
||||||
if (!iface.AllDone) {
|
if (!iface.AllDone) {
|
||||||
iface.AllDone = true;
|
iface.AllDone = true;
|
||||||
iface.LibrariesDone = true;
|
iface.LibrariesDone = true;
|
||||||
@@ -1109,6 +1136,7 @@ const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
|
|||||||
if (secondPass) {
|
if (secondPass) {
|
||||||
impl = cmOptionalLinkImplementation();
|
impl = cmOptionalLinkImplementation();
|
||||||
}
|
}
|
||||||
|
MaybeEnableCheckLinkLibraries(impl);
|
||||||
if (!impl.LibrariesDone) {
|
if (!impl.LibrariesDone) {
|
||||||
impl.LibrariesDone = true;
|
impl.LibrariesDone = true;
|
||||||
this->ComputeLinkImplementationLibraries(config, impl, this, usage);
|
this->ComputeLinkImplementationLibraries(config, impl, this, usage);
|
||||||
@@ -1165,6 +1193,7 @@ cmGeneratorTarget::GetLinkImplementationLibrariesInternal(
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmOptionalLinkImplementation& impl = hm[head];
|
cmOptionalLinkImplementation& impl = hm[head];
|
||||||
|
MaybeEnableCheckLinkLibraries(impl);
|
||||||
if (!impl.LibrariesDone) {
|
if (!impl.LibrariesDone) {
|
||||||
impl.LibrariesDone = true;
|
impl.LibrariesDone = true;
|
||||||
this->ComputeLinkImplementationLibraries(config, impl, head, usage);
|
this->ComputeLinkImplementationLibraries(config, impl, head, usage);
|
||||||
|
@@ -286,8 +286,7 @@ cmGeneratorTarget::GetCustomTransitiveProperties(std::string const& config,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
addTransitiveProperties("TRANSITIVE_LINK_PROPERTIES",
|
addTransitiveProperties("TRANSITIVE_LINK_PROPERTIES", UseTo::Link);
|
||||||
UseTo::LinkInterfaceEval);
|
|
||||||
addTransitiveProperties("TRANSITIVE_COMPILE_PROPERTIES", UseTo::Compile);
|
addTransitiveProperties("TRANSITIVE_COMPILE_PROPERTIES", UseTo::Compile);
|
||||||
i = ctpm.emplace(config, std::move(ctp)).first;
|
i = ctpm.emplace(config, std::move(ctp)).first;
|
||||||
}
|
}
|
||||||
|
@@ -120,11 +120,11 @@ struct cmLinkInterface : public cmLinkInterfaceLibraries
|
|||||||
|
|
||||||
struct cmOptionalLinkInterface : public cmLinkInterface
|
struct cmOptionalLinkInterface : public cmLinkInterface
|
||||||
{
|
{
|
||||||
bool LinkOnlyEval = false;
|
|
||||||
bool LibrariesDone = false;
|
bool LibrariesDone = false;
|
||||||
bool AllDone = false;
|
bool AllDone = false;
|
||||||
bool Exists = false;
|
bool Exists = false;
|
||||||
bool Explicit = false;
|
bool Explicit = false;
|
||||||
|
bool CheckLinkLibraries = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cmHeadToLinkInterfaceMap
|
struct cmHeadToLinkInterfaceMap
|
||||||
@@ -149,6 +149,7 @@ struct cmOptionalLinkImplementation : public cmLinkImplementation
|
|||||||
bool LibrariesDone = false;
|
bool LibrariesDone = false;
|
||||||
bool LanguagesDone = false;
|
bool LanguagesDone = false;
|
||||||
bool HadHeadSensitiveCondition = false;
|
bool HadHeadSensitiveCondition = false;
|
||||||
|
bool CheckLinkLibraries = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Compute the link type to use for the given configuration. */
|
/** Compute the link type to use for the given configuration. */
|
||||||
|
Reference in New Issue
Block a user