summaryrefslogtreecommitdiffstats
path: root/Source/cmComputeLinkDepends.cxx
diff options
context:
space:
mode:
authorMarc Chevrier <marc.chevrier@gmail.com>2021-11-19 18:08:30 (GMT)
committerMarc Chevrier <marc.chevrier@gmail.com>2022-02-08 10:41:04 (GMT)
commit2a6b0415d71db893b6d8edd1c5058d42eb40fca6 (patch)
tree4bf1015d035518cb818ba6828bdfe0b0d96962d0 /Source/cmComputeLinkDepends.cxx
parent42965799b4747ab1e0afa6546be13444f68c1987 (diff)
downloadCMake-2a6b0415d71db893b6d8edd1c5058d42eb40fca6.zip
CMake-2a6b0415d71db893b6d8edd1c5058d42eb40fca6.tar.gz
CMake-2a6b0415d71db893b6d8edd1c5058d42eb40fca6.tar.bz2
$<LINK_LIBRARY>: Add LINK_LIBRARY_OVERRIDE target property
To enable the management of incompatible $<LINK_LIBRARY> declarations, add LINK_LIBRARY_OVERRIDE and LINK_LIBRARY_OVERRIDE_<LIBRARY> target properties.
Diffstat (limited to 'Source/cmComputeLinkDepends.cxx')
-rw-r--r--Source/cmComputeLinkDepends.cxx90
1 files changed, 74 insertions, 16 deletions
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index c3367ac..e6073cb 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -11,9 +11,12 @@
#include <utility>
#include <cm/memory>
+#include <cm/string_view>
#include <cmext/string_view>
#include "cmComputeComponentGraph.h"
+#include "cmGeneratorExpression.h"
+#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmListFileCache.h"
@@ -200,6 +203,8 @@ bool IsFeatureSupported(cmMakefile* makefile, std::string const& linkLanguage,
}
}
+const std::string cmComputeLinkDepends::LinkEntry::DEFAULT = "DEFAULT";
+
cmComputeLinkDepends::cmComputeLinkDepends(const cmGeneratorTarget* target,
const std::string& config,
const std::string& linkLanguage)
@@ -212,6 +217,49 @@ cmComputeLinkDepends::cmComputeLinkDepends(const cmGeneratorTarget* target,
this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance();
this->LinkLanguage = linkLanguage;
+ // target oriented feature override property takes precedence over
+ // global override property
+ cm::string_view lloPrefix = "LINK_LIBRARY_OVERRIDE_"_s;
+ auto const& keys = this->Target->GetPropertyKeys();
+ std::for_each(
+ keys.cbegin(), keys.cend(),
+ [this, &lloPrefix, &config, &linkLanguage](std::string const& key) {
+ if (cmHasPrefix(key, lloPrefix)) {
+ if (cmValue feature = this->Target->GetProperty(key)) {
+ if (!feature->empty() && key.length() > lloPrefix.length()) {
+ auto item = key.substr(lloPrefix.length());
+ cmGeneratorExpressionDAGChecker dag{ this->Target->GetBacktrace(),
+ this->Target,
+ "LINK_LIBRARY_OVERRIDE",
+ nullptr, nullptr };
+ auto overrideFeature = cmGeneratorExpression::Evaluate(
+ feature, this->Target->GetLocalGenerator(), config, this->Target,
+ &dag, this->Target, linkLanguage);
+ this->LinkLibraryOverride.emplace(item, overrideFeature);
+ }
+ }
+ }
+ });
+ // global override property
+ if (cmValue linkLibraryOverride =
+ this->Target->GetProperty("LINK_LIBRARY_OVERRIDE")) {
+ cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
+ "LINK_LIBRARY_OVERRIDE", nullptr,
+ nullptr };
+ auto overrideValue = cmGeneratorExpression::Evaluate(
+ linkLibraryOverride, target->GetLocalGenerator(), config, target, &dag,
+ target, linkLanguage);
+
+ auto overrideList = cmTokenize(overrideValue, ","_s);
+ if (overrideList.size() >= 2) {
+ auto const& feature = overrideList.front();
+ for_each(overrideList.cbegin() + 1, overrideList.cend(),
+ [this, &feature](std::string const& item) {
+ this->LinkLibraryOverride.emplace(item, feature);
+ });
+ }
+ }
+
// The configuration being linked.
this->HasConfig = !config.empty();
this->Config = (this->HasConfig) ? config : std::string();
@@ -309,6 +357,13 @@ cmComputeLinkDepends::Compute()
return this->FinalLinkEntries;
}
+std::string const& cmComputeLinkDepends::GetCurrentFeature(
+ std::string const& item, std::string const& defaultFeature) const
+{
+ auto it = this->LinkLibraryOverride.find(item);
+ return it == this->LinkLibraryOverride.end() ? defaultFeature : it->second;
+}
+
std::pair<std::map<cmLinkItem, int>::iterator, bool>
cmComputeLinkDepends::AllocateLinkEntry(cmLinkItem const& item)
{
@@ -568,7 +623,7 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index,
{
// Track inferred dependency sets implied by this list.
std::map<int, DependSet> dependSets;
- std::string feature;
+ std::string feature = LinkEntry::DEFAULT;
// Loop over the libraries linked directly by the depender.
for (T const& l : libs) {
@@ -604,7 +659,7 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index,
continue;
}
if (cmHasPrefix(item.AsStr(), LL_END) && cmHasSuffix(item.AsStr(), '>')) {
- feature.clear();
+ feature = LinkEntry::DEFAULT;
continue;
}
@@ -612,7 +667,9 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index,
auto ale = this->AddLinkEntry(item);
int dependee_index = ale.first;
LinkEntry& entry = this->EntryList[dependee_index];
- if (!feature.empty()) {
+ auto const& itemFeature =
+ this->GetCurrentFeature(entry.Item.Value, feature);
+ if (itemFeature != LinkEntry::DEFAULT) {
if (ale.second) {
// current item not yet defined
if (entry.Target != nullptr &&
@@ -633,7 +690,7 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index,
" library '", entry.Item.Value, "'."),
this->Target->GetBacktrace());
} else {
- entry.Feature = feature;
+ entry.Feature = itemFeature;
}
}
}
@@ -642,20 +699,21 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index,
(entry.Target->GetType() != cmStateEnums::TargetType::OBJECT_LIBRARY &&
entry.Target->GetType() != cmStateEnums::TargetType::INTERFACE_LIBRARY);
- if (supportedItem && entry.Feature != feature) {
+ if (supportedItem && entry.Feature != itemFeature) {
// incompatibles features occurred
this->CMakeInstance->IssueMessage(
MessageType::FATAL_ERROR,
- cmStrCat(
- "Impossible to link target '", this->Target->GetName(),
- "' because the link item '", entry.Item.Value, "', specified ",
- (feature.empty() ? "without any feature"
- : cmStrCat("with the feature '", feature, '\'')),
- ", has already occurred ",
- (entry.Feature.empty()
- ? "without any feature"
- : cmStrCat("with the feature '", entry.Feature, '\'')),
- ", which is not allowed."),
+ cmStrCat("Impossible to link target '", this->Target->GetName(),
+ "' because the link item '", entry.Item.Value,
+ "', specified ",
+ (itemFeature == LinkEntry::DEFAULT
+ ? "without any feature or 'DEFAULT' feature"
+ : cmStrCat("with the feature '", itemFeature, '\'')),
+ ", has already occurred ",
+ (entry.Feature == LinkEntry::DEFAULT
+ ? "without any feature or 'DEFAULT' feature"
+ : cmStrCat("with the feature '", entry.Feature, '\'')),
+ ", which is not allowed."),
this->Target->GetBacktrace());
}
@@ -978,7 +1036,7 @@ void cmComputeLinkDepends::DisplayFinalEntries()
} else {
fprintf(stderr, " item [%s]", lei.Item.Value.c_str());
}
- if (!lei.Feature.empty()) {
+ if (lei.Feature != LinkEntry::DEFAULT) {
fprintf(stderr, ", feature [%s]", lei.Feature.c_str());
}
fprintf(stderr, "\n");