mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-16 14:08:35 +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);
|
||||
this->PopulateInterfaceProperty("TRANSITIVE_LINK_PROPERTIES", target,
|
||||
properties);
|
||||
cmGeneratorTarget::CheckLinkLibrariesSuppressionRAII cllSuppressRAII;
|
||||
std::set<std::string> ifaceProperties;
|
||||
for (std::string const& config : this->Configurations) {
|
||||
for (auto const& i : target->GetCustomTransitiveProperties(
|
||||
|
@@ -99,6 +99,13 @@ public:
|
||||
// Call this after generation is complete.
|
||||
void CheckLinkLibraries() const;
|
||||
|
||||
class CheckLinkLibrariesSuppressionRAII
|
||||
{
|
||||
public:
|
||||
CheckLinkLibrariesSuppressionRAII();
|
||||
~CheckLinkLibrariesSuppressionRAII();
|
||||
};
|
||||
|
||||
cmStateEnums::TargetType GetType() const;
|
||||
const std::string& GetName() const;
|
||||
std::string GetExportName() const;
|
||||
@@ -264,7 +271,6 @@ public:
|
||||
{
|
||||
Compile, // Usage requirements for compiling. Excludes $<LINK_ONLY>.
|
||||
Link, // Usage requirements for linking. Includes $<LINK_ONLY>.
|
||||
LinkInterfaceEval,
|
||||
};
|
||||
|
||||
cmLinkInterfaceLibraries const* GetLinkInterfaceLibraries(
|
||||
|
@@ -54,6 +54,20 @@ const std::string kINTERFACE_LINK_LIBRARIES_DIRECT =
|
||||
"INTERFACE_LINK_LIBRARIES_DIRECT";
|
||||
const std::string kINTERFACE_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
|
||||
@@ -372,7 +386,8 @@ void cmGeneratorTarget::CheckLinkLibraries() const
|
||||
// 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) {
|
||||
if (hmi == hm.end() || !hmi->second.LibrariesDone ||
|
||||
!hmi->second.CheckLinkLibraries) {
|
||||
continue;
|
||||
}
|
||||
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).
|
||||
for (auto const& hmp : this->LinkInterfaceMap) {
|
||||
for (auto const& hmi : hmp.second) {
|
||||
if (!hmi.second.LibrariesDone || hmi.second.LinkOnlyEval) {
|
||||
if (!hmi.second.LibrariesDone || !hmi.second.CheckLinkLibraries) {
|
||||
continue;
|
||||
}
|
||||
for (cmLinkItem const& item : hmi.second.Libraries) {
|
||||
@@ -408,6 +423,18 @@ void cmGeneratorTarget::CheckLinkLibraries() const
|
||||
}
|
||||
}
|
||||
|
||||
cmGeneratorTarget::CheckLinkLibrariesSuppressionRAII::
|
||||
CheckLinkLibrariesSuppressionRAII()
|
||||
{
|
||||
++CheckLinkLibrariesSuppressionRAIICount;
|
||||
}
|
||||
|
||||
cmGeneratorTarget::CheckLinkLibrariesSuppressionRAII::
|
||||
~CheckLinkLibrariesSuppressionRAII()
|
||||
{
|
||||
--CheckLinkLibrariesSuppressionRAIICount;
|
||||
}
|
||||
|
||||
namespace {
|
||||
cm::string_view missingTargetPossibleReasons =
|
||||
"Possible reasons include:\n"
|
||||
@@ -642,7 +669,7 @@ cmLinkInterface const* cmGeneratorTarget::GetLinkInterface(
|
||||
if (secondPass) {
|
||||
iface = cmOptionalLinkInterface();
|
||||
}
|
||||
iface.LinkOnlyEval = false;
|
||||
MaybeEnableCheckLinkLibraries(iface);
|
||||
if (!iface.LibrariesDone) {
|
||||
iface.LibrariesDone = true;
|
||||
this->ComputeLinkInterfaceLibraries(config, iface, head, UseTo::Link);
|
||||
@@ -766,7 +793,7 @@ const cmLinkInterfaceLibraries* cmGeneratorTarget::GetLinkInterfaceLibraries(
|
||||
}
|
||||
|
||||
cmOptionalLinkInterface& iface = hm[head];
|
||||
iface.LinkOnlyEval = (usage == UseTo::LinkInterfaceEval);
|
||||
MaybeEnableCheckLinkLibraries(iface);
|
||||
if (!iface.LibrariesDone) {
|
||||
iface.LibrariesDone = true;
|
||||
this->ComputeLinkInterfaceLibraries(config, iface, head, usage);
|
||||
@@ -1036,7 +1063,7 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
|
||||
if (secondPass) {
|
||||
iface = cmOptionalLinkInterface();
|
||||
}
|
||||
iface.LinkOnlyEval = (usage == UseTo::LinkInterfaceEval);
|
||||
MaybeEnableCheckLinkLibraries(iface);
|
||||
if (!iface.AllDone) {
|
||||
iface.AllDone = true;
|
||||
iface.LibrariesDone = true;
|
||||
@@ -1109,6 +1136,7 @@ const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
|
||||
if (secondPass) {
|
||||
impl = cmOptionalLinkImplementation();
|
||||
}
|
||||
MaybeEnableCheckLinkLibraries(impl);
|
||||
if (!impl.LibrariesDone) {
|
||||
impl.LibrariesDone = true;
|
||||
this->ComputeLinkImplementationLibraries(config, impl, this, usage);
|
||||
@@ -1165,6 +1193,7 @@ cmGeneratorTarget::GetLinkImplementationLibrariesInternal(
|
||||
}
|
||||
|
||||
cmOptionalLinkImplementation& impl = hm[head];
|
||||
MaybeEnableCheckLinkLibraries(impl);
|
||||
if (!impl.LibrariesDone) {
|
||||
impl.LibrariesDone = true;
|
||||
this->ComputeLinkImplementationLibraries(config, impl, head, usage);
|
||||
|
@@ -286,8 +286,7 @@ cmGeneratorTarget::GetCustomTransitiveProperties(std::string const& config,
|
||||
}
|
||||
}
|
||||
};
|
||||
addTransitiveProperties("TRANSITIVE_LINK_PROPERTIES",
|
||||
UseTo::LinkInterfaceEval);
|
||||
addTransitiveProperties("TRANSITIVE_LINK_PROPERTIES", UseTo::Link);
|
||||
addTransitiveProperties("TRANSITIVE_COMPILE_PROPERTIES", UseTo::Compile);
|
||||
i = ctpm.emplace(config, std::move(ctp)).first;
|
||||
}
|
||||
|
@@ -120,11 +120,11 @@ struct cmLinkInterface : public cmLinkInterfaceLibraries
|
||||
|
||||
struct cmOptionalLinkInterface : public cmLinkInterface
|
||||
{
|
||||
bool LinkOnlyEval = false;
|
||||
bool LibrariesDone = false;
|
||||
bool AllDone = false;
|
||||
bool Exists = false;
|
||||
bool Explicit = false;
|
||||
bool CheckLinkLibraries = false;
|
||||
};
|
||||
|
||||
struct cmHeadToLinkInterfaceMap
|
||||
@@ -149,6 +149,7 @@ struct cmOptionalLinkImplementation : public cmLinkImplementation
|
||||
bool LibrariesDone = false;
|
||||
bool LanguagesDone = false;
|
||||
bool HadHeadSensitiveCondition = false;
|
||||
bool CheckLinkLibraries = false;
|
||||
};
|
||||
|
||||
/** Compute the link type to use for the given configuration. */
|
||||
|
Reference in New Issue
Block a user