diff options
author | Marc Chevrier <marc.chevrier@gmail.com> | 2021-11-19 18:08:30 (GMT) |
---|---|---|
committer | Marc Chevrier <marc.chevrier@gmail.com> | 2022-02-08 10:41:04 (GMT) |
commit | 2a6b0415d71db893b6d8edd1c5058d42eb40fca6 (patch) | |
tree | 4bf1015d035518cb818ba6828bdfe0b0d96962d0 | |
parent | 42965799b4747ab1e0afa6546be13444f68c1987 (diff) | |
download | CMake-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.
41 files changed, 383 insertions, 31 deletions
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index b67d479..7c34671 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -1176,12 +1176,20 @@ Output-Related Expressions target_link_libraries(lib3 PRIVATE lib1 lib2) # an error will be raised here because lib1 has two different features + To resolve such incompatibilities, the :prop_tgt:`LINK_LIBRARY_OVERRIDE` + and :prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` target properties can be + used. + .. note:: This expression does not guarantee that the list of specified libraries will be kept grouped. So, constructs like ``start-group`` and ``end-group``, as supported by ``GNU ld``, cannot be used. + ``CMake`` pre-defines some features of general interest: + + .. include:: ../variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt + .. genex:: $<INSTALL_INTERFACE:...> Content of ``...`` when the property is exported using :command:`install(EXPORT)`, diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index f4efd3c..e8048b3 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -308,6 +308,8 @@ Properties on Targets /prop_tgt/LINK_INTERFACE_MULTIPLICITY_CONFIG /prop_tgt/LINK_LIBRARIES /prop_tgt/LINK_LIBRARIES_ONLY_TARGETS + /prop_tgt/LINK_LIBRARY_OVERRIDE + /prop_tgt/LINK_LIBRARY_OVERRIDE_LIBRARY /prop_tgt/LINK_OPTIONS /prop_tgt/LINK_SEARCH_END_STATIC /prop_tgt/LINK_SEARCH_START_STATIC diff --git a/Help/prop_tgt/LINK_LIBRARY_OVERRIDE.rst b/Help/prop_tgt/LINK_LIBRARY_OVERRIDE.rst new file mode 100644 index 0000000..e9c76b0 --- /dev/null +++ b/Help/prop_tgt/LINK_LIBRARY_OVERRIDE.rst @@ -0,0 +1,54 @@ +LINK_LIBRARY_OVERRIDE +--------------------- + +.. versionadded:: 3.24 + +To resolve incompatible features introduced by :genex:`LINK_LIBRARY` generator +expression, this property offers the possibility to override, per ``link-item`` +(``CMake`` target or external library) involved in the link step, any defined +features with a new one. + +This property takes a :ref:`;-list <CMake Language Lists>` of override +declarations which have the following format: + +:: + + feature[,link-item]* + +For the list of ``link-item`` (``CMake`` target or external library) specified, +the feature ``feature`` will be used in place of any declared feature. For +example: + +.. code-block:: cmake + + add_library(lib1 ...) + target_link_libraries(lib1 PUBLIC $<LINK_LIBRARY:feature1,external>) + + add_library(lib2 ...) + target_link_libraries(lib2 PUBLIC $<LINK_LIBRARY:feature2,lib1>) + + add_library(lib3 ...) + target_link_libraries(lib3 PRIVATE lib1 lib2) + # Here, lib1 has two different features which prevents to link lib3 + # So, define LINK_LIBRARY_OVERRIDE property to ensure correct link + set_property(TARGET lib3 PROPERTY LINK_LIBRARY_OVERRIDE "feature2,lib1,external") + # The lib1 and external will be used with FEATURE2 to link lib3 + +It is also possible to override any feature with the pre-defined feature +``DEFAULT`` to get the standard behavior (i.e. no feature): + +.. code-block:: cmake + + set_property(TARGET lib3 PROPERTY LINK_LIBRARY_OVERRIDE "DEFAULT,lib1" + "feature2,external") + # The lib1 will be used without any feature and external will use feature2 to link lib3 + +Contents of ``LINK_LIBRARY_OVERRIDE`` may use +:manual:`generator expressions <cmake-generator-expressions(7)>`. + +See also :prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` target property for +a per linked target oriented approach to override features. + +For more information about features, see +:variable:`CMAKE_<LANG>_LINK_USING_<FEATURE>` +and :variable:`CMAKE_LINK_USING_<FEATURE>` variables. diff --git a/Help/prop_tgt/LINK_LIBRARY_OVERRIDE_LIBRARY.rst b/Help/prop_tgt/LINK_LIBRARY_OVERRIDE_LIBRARY.rst new file mode 100644 index 0000000..58141c9 --- /dev/null +++ b/Help/prop_tgt/LINK_LIBRARY_OVERRIDE_LIBRARY.rst @@ -0,0 +1,45 @@ +LINK_LIBRARY_OVERRIDE_<LIBRARY> +------------------------------- + +.. versionadded:: 3.24 + +To resolve incompatible features introduced by :genex:`LINK_LIBRARY` generator +expression, this property offers the possibility to override, for a +``link-item`` (``CMake`` target or external library) involved in the link step, +any defined features with a new one. + +This property takes a ``feature`` name which will be applied to the +``link-item`` specified by ``<LIBRARY>`` suffix property. For example: + +.. code-block:: cmake + + add_library(lib1 ...) + target_link_libraries(lib1 PUBLIC $<LINK_LIBRARY:feature1,external>) + + add_library(lib2 ...) + target_link_libraries(lib2 PUBLIC $<LINK_LIBRARY:feature2,lib1>) + + add_library(lib3 ...) + target_link_libraries(lib3 PRIVATE lib1 lib2) + # Here, lib1 has two different features which prevents to link lib3 + # So, define LINK_LIBRARY_OVERRIDE_lib1 property to ensure correct link + set_property(TARGET lib3 PROPERTY LINK_LIBRARY_OVERRIDE_lib1 feature2) + # The lib1 will be used with feature2 to link lib3 + +It is also possible to override any feature with the pre-defined feature +``DEFAULT`` to get the standard behavior (i.e. no feature): + +.. code-block:: cmake + + set_property(TARGET lib3 PROPERTY LINK_LIBRARY_OVERRIDE_lib1 DEFAULT) + # The lib1 will be used without any feature to link lib3 + +Contents of ``LINK_LIBRARY_OVERRIDE_<LIBRARY>`` may use +:manual:`generator expressions <cmake-generator-expressions(7)>`. + +This property takes precedence over :prop_tgt:`LINK_LIBRARY_OVERRIDE` +target property. + +For more information about features, see +:variable:`CMAKE_<LANG>_LINK_USING_<FEATURE>` +and :variable:`CMAKE_LINK_USING_<FEATURE>` variables. diff --git a/Help/release/dev/Genex-LINK_LIBRARY.rst b/Help/release/dev/Genex-LINK_LIBRARY.rst index 6b87a4f..3234acb 100644 --- a/Help/release/dev/Genex-LINK_LIBRARY.rst +++ b/Help/release/dev/Genex-LINK_LIBRARY.rst @@ -5,4 +5,7 @@ Genex-LINK_LIBRARY libraries are specified during the link step. The variables :variable:`CMAKE_<LANG>_LINK_USING_<FEATURE>` and :variable:`CMAKE_LINK_USING_<FEATURE>` are used to define features usable by - the :genex:`LINK_LIBRARY` generator expression. + the :genex:`LINK_LIBRARY` generator expression. Moreover, the + :prop_tgt:`LINK_LIBRARY_OVERRIDE` and + :prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` target properties are available + to resolve incompatible features. diff --git a/Help/variable/CMAKE_LANG_LINK_USING_FEATURE.rst b/Help/variable/CMAKE_LANG_LINK_USING_FEATURE.rst index ff8b3d9..9d7f87a 100644 --- a/Help/variable/CMAKE_LANG_LINK_USING_FEATURE.rst +++ b/Help/variable/CMAKE_LANG_LINK_USING_FEATURE.rst @@ -17,3 +17,10 @@ See also the associated variable independent from the link language. .. include:: CMAKE_LINK_USING_FEATURE.txt + +Predefined Features +^^^^^^^^^^^^^^^^^^^ + +``CMake`` pre-defines some features of general interest: + +.. include:: LINK_LIBRARY_PREDEFINED_FEATURES.txt diff --git a/Help/variable/CMAKE_LINK_USING_FEATURE.rst b/Help/variable/CMAKE_LINK_USING_FEATURE.rst index 3d94461..0c9cadc 100644 --- a/Help/variable/CMAKE_LINK_USING_FEATURE.rst +++ b/Help/variable/CMAKE_LINK_USING_FEATURE.rst @@ -21,3 +21,10 @@ for the linker language, the variable :variable:`CMAKE_<LANG>_LINK_USING_<FEATURE>_SUPPORTED` is false or not set. .. include:: CMAKE_LINK_USING_FEATURE.txt + +Predefined Features +^^^^^^^^^^^^^^^^^^^ + +``CMake`` pre-defines some features of general interest: + +.. include:: LINK_LIBRARY_PREDEFINED_FEATURES.txt diff --git a/Help/variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt b/Help/variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt new file mode 100644 index 0000000..dd22e14 --- /dev/null +++ b/Help/variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt @@ -0,0 +1,5 @@ +**Features available in all environments** + +* ``DEFAULT``: This feature enables default link expression. This is mainly + useful with :prop_tgt:`LINK_LIBRARY_OVERRIDE` and + :prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` target properties. diff --git a/Modules/CMakeGenericSystem.cmake b/Modules/CMakeGenericSystem.cmake index 649b6f7..9ae68c4 100644 --- a/Modules/CMakeGenericSystem.cmake +++ b/Modules/CMakeGenericSystem.cmake @@ -24,6 +24,12 @@ set(CMAKE_DL_LIBS "dl") set(CMAKE_FIND_LIBRARY_PREFIXES "lib") set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a") +# Define feature "DEFAULT" as supported. This special feature generates the +# default option to link a library +# This feature is intended to be used in LINK_LIBRARY_OVERRIDE and +# LINK_LIBRARY_OVERRIDE_<LIBRARY> target properties +set(CMAKE_LINK_USING_DEFAULT_SUPPORTED TRUE) + set(CMAKE_AUTOGEN_ORIGIN_DEPENDS ON) set(CMAKE_AUTOMOC_COMPILER_PREDEFINES ON) if(NOT DEFINED CMAKE_AUTOMOC_PATH_PREFIX) 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"); diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h index 02bdf50..64603e0 100644 --- a/Source/cmComputeLinkDepends.h +++ b/Source/cmComputeLinkDepends.h @@ -47,6 +47,8 @@ public: { } + static const std::string DEFAULT; + BT<std::string> Item; cmGeneratorTarget const* Target = nullptr; bool IsSharedDep = false; @@ -54,7 +56,7 @@ public: bool IsObject = false; // The following member is for the management of items specified // through genex $<LINK_LIBRARY:...> - std::string Feature; + std::string Feature = std::string(DEFAULT); }; using EntryVector = std::vector<LinkEntry>; @@ -75,6 +77,10 @@ private: std::string LinkLanguage; std::string Config; EntryVector FinalLinkEntries; + std::map<std::string, std::string> LinkLibraryOverride; + + std::string const& GetCurrentFeature( + std::string const& item, std::string const& defaultFeature) const; std::pair<std::map<cmLinkItem, int>::iterator, bool> AllocateLinkEntry( cmLinkItem const& item); diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 5c3a96d..15e9d60 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -431,6 +431,10 @@ cmComputeLinkInformation::cmComputeLinkInformation( cmComputeLinkInformation::~cmComputeLinkInformation() = default; +namespace { +const std::string& DEFAULT = cmComputeLinkDepends::LinkEntry::DEFAULT; +} + void cmComputeLinkInformation::AppendValues( std::string& result, std::vector<BT<std::string>>& values) { @@ -551,7 +555,7 @@ bool cmComputeLinkInformation::Compute() currentFeature = nullptr; } - if (!linkEntry.Feature.empty() && + if (linkEntry.Feature != DEFAULT && (currentFeature == nullptr || linkEntry.Feature != currentFeature->Name)) { if (!this->AddLibraryFeature(linkEntry.Feature)) { @@ -988,8 +992,9 @@ void cmComputeLinkInformation::AddItem(LinkEntry const& entry) std::string exe = tgt->GetFullPath(config, artifact, true); this->Items.emplace_back( BT<std::string>(exe, item.Backtrace), ItemIsPath::Yes, tgt, - this->FindLibraryFeature( - entry.Feature.empty() ? "__CMAKE_LINK_EXECUTABLE" : entry.Feature)); + this->FindLibraryFeature(entry.Feature == DEFAULT + ? "__CMAKE_LINK_EXECUTABLE" + : entry.Feature)); this->Depends.push_back(std::move(exe)); } else if (tgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) { // Add the interface library as an item so it can be considered as part @@ -1421,7 +1426,7 @@ void cmComputeLinkInformation::AddTargetItem(LinkEntry const& entry) // Now add the full path to the library. this->Items.emplace_back(item, ItemIsPath::Yes, target, - this->FindLibraryFeature(entry.Feature.empty() + this->FindLibraryFeature(entry.Feature == DEFAULT ? "__CMAKE_LINK_LIBRARY" : entry.Feature)); } @@ -1482,7 +1487,7 @@ void cmComputeLinkInformation::AddFullItem(LinkEntry const& entry) this->Items.emplace_back( item, ItemIsPath::Yes, nullptr, this->FindLibraryFeature( - entry.Feature.empty() + entry.Feature == DEFAULT ? (entry.IsObject ? "__CMAKE_LINK_OBJECT" : "__CMAKE_LINK_LIBRARY") : entry.Feature)); } @@ -1650,7 +1655,7 @@ void cmComputeLinkInformation::AddUserItem(LinkEntry const& entry, // Create an option to ask the linker to search for the library. auto out = cmStrCat(this->LibLinkFlag, lib, this->LibLinkSuffix); - if (!entry.Feature.empty()) { + if (entry.Feature != DEFAULT) { auto const& feature = this->GetLibraryFeature(entry.Feature); this->Items.emplace_back( BT<std::string>( diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index d4b02a5..d35d428 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -167,7 +167,7 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkExpression() const cm::string_view property(this->Top()->Property); return property == "LINK_DIRECTORIES"_s || property == "LINK_OPTIONS"_s || - property == "LINK_DEPENDS"_s; + property == "LINK_DEPENDS"_s || property == "LINK_LIBRARY_OVERRIDE"_s; } bool cmGeneratorExpressionDAGChecker::EvaluatingLinkOptionsExpression() const diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/RunCMakeTest.cmake index ab1ac37..d5438b8 100644 --- a/Tests/RunCMake/GenEx-LINK_LIBRARY/RunCMakeTest.cmake +++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/RunCMakeTest.cmake @@ -19,7 +19,16 @@ run_cmake(bad-feature7) run_cmake(feature-not-supported) run_cmake(library-ignored) run_cmake(compatible-features) -run_cmake(incompatible-features) +run_cmake(incompatible-features1) +run_cmake(incompatible-features2) +run_cmake(incompatible-features3) run_cmake(nested-compatible-features) run_cmake(nested-incompatible-features) run_cmake(only-targets) + +# testing target propertes LINK_LIBRARY_OVERRIDE and LINK_LIBRARY_OVERRIDE_<LIBRARY> +run_cmake(override-features1) +run_cmake(override-features2) +run_cmake(override-features3) +run_cmake(override-features4) +run_cmake(override-features5) diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/compatible-features.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/compatible-features.cmake index e79764c..2579a5f 100644 --- a/Tests/RunCMake/GenEx-LINK_LIBRARY/compatible-features.cmake +++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/compatible-features.cmake @@ -11,5 +11,11 @@ add_library(dep1 SHARED empty.c) add_library(dep2 SHARED empty.c) target_link_libraries(dep2 PRIVATE "$<LINK_LIBRARY:feat1,dep1>") -add_library(lib SHARED empty.c) -target_link_libraries(lib PRIVATE "$<LINK_LIBRARY:feat2,dep1,dep2>") +add_library(dep3 SHARED empty.c) +target_link_libraries(dep3 PUBLIC dep2) + +add_library(lib1 SHARED empty.c) +target_link_libraries(lib1 PRIVATE $<LINK_LIBRARY:feat2,dep1,dep2>) + +add_library(lib2 SHARED empty.c) +target_link_libraries(lib2 PRIVATE $<LINK_LIBRARY:DEFAULT,dep2,dep3>) diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features-result.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features1-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features-result.txt +++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features1-result.txt diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features-stderr.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features1-stderr.txt index 22219a2..1b31faa 100644 --- a/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features-stderr.txt +++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features1-stderr.txt @@ -1,4 +1,4 @@ -CMake Error at incompatible-features.cmake:[0-9]+ \(add_library\): +CMake Error at incompatible-features1.cmake:[0-9]+ \(add_library\): Impossible to link target 'lib' because the link item 'dep1', specified with the feature 'feat1', has already occurred with the feature 'feat2', which is not allowed. diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features1.cmake index d96b214..d96b214 100644 --- a/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features.cmake +++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features1.cmake diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features2-result.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features2-stderr.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features2-stderr.txt new file mode 100644 index 0000000..0855481 --- /dev/null +++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features2-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at incompatible-features2.cmake:[0-9]+ \(add_library\): + Impossible to link target 'lib' because the link item 'dep1', specified + without any feature or 'DEFAULT' feature, has already occurred with the + feature 'feat2', which is not allowed. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features2.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features2.cmake new file mode 100644 index 0000000..1845fdb --- /dev/null +++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features2.cmake @@ -0,0 +1,15 @@ +enable_language(C) + +set(CMAKE_C_LINK_USING_feat1_SUPPORTED TRUE) +set(CMAKE_C_LINK_USING_feat1 "<LIBRARY>") + +set(CMAKE_C_LINK_USING_feat2_SUPPORTED TRUE) +set(CMAKE_C_LINK_USING_feat2 "<LIBRARY>") + +add_library(dep1 SHARED empty.c) + +add_library(dep2 SHARED empty.c) +target_link_libraries(dep2 PUBLIC dep1) + +add_library(lib SHARED empty.c) +target_link_libraries(lib PRIVATE $<LINK_LIBRARY:feat2,dep1,dep2>) diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features3-result.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features3-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features3-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features3-stderr.txt b/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features3-stderr.txt new file mode 100644 index 0000000..2f40a1d --- /dev/null +++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features3-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at incompatible-features3.cmake:[0-9]+ \(add_library\): + Impossible to link target 'lib' because the link item 'dep1', specified + with the feature 'feat1', has already occurred without any feature or + 'DEFAULT' feature, which is not allowed. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features3.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features3.cmake new file mode 100644 index 0000000..1198d91 --- /dev/null +++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/incompatible-features3.cmake @@ -0,0 +1,15 @@ +enable_language(C) + +set(CMAKE_C_LINK_USING_feat1_SUPPORTED TRUE) +set(CMAKE_C_LINK_USING_feat1 "<LIBRARY>") + +set(CMAKE_C_LINK_USING_feat2_SUPPORTED TRUE) +set(CMAKE_C_LINK_USING_feat2 "<LIBRARY>") + +add_library(dep1 SHARED empty.c) + +add_library(dep2 SHARED empty.c) +target_link_libraries(dep2 PUBLIC $<LINK_LIBRARY:feat1,dep1>) + +add_library(lib SHARED empty.c) +target_link_libraries(lib PRIVATE dep1 dep2) diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/override-features1.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/override-features1.cmake new file mode 100644 index 0000000..6306c5d --- /dev/null +++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/override-features1.cmake @@ -0,0 +1,4 @@ + +include(incompatible-features1.cmake) + +set_property(TARGET lib PROPERTY LINK_LIBRARY_OVERRIDE "feat1,dep1") diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/override-features2.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/override-features2.cmake new file mode 100644 index 0000000..aa6ee76 --- /dev/null +++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/override-features2.cmake @@ -0,0 +1,4 @@ + +include(incompatible-features1.cmake) + +set_property(TARGET lib PROPERTY LINK_LIBRARY_OVERRIDE "feat2,dep1") diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/override-features3.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/override-features3.cmake new file mode 100644 index 0000000..7f010fd --- /dev/null +++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/override-features3.cmake @@ -0,0 +1,7 @@ + +include(incompatible-features1.cmake) + +set(CMAKE_C_LINK_USING_feat3_SUPPORTED TRUE) +set(CMAKE_C_LINK_USING_feat3 "<LIBRARY>") + +set_property(TARGET lib PROPERTY LINK_LIBRARY_OVERRIDE "feat3,dep1") diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/override-features4.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/override-features4.cmake new file mode 100644 index 0000000..405cc8a --- /dev/null +++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/override-features4.cmake @@ -0,0 +1,9 @@ + +include(incompatible-features1.cmake) + + +set(CMAKE_C_LINK_USING_feat3_SUPPORTED TRUE) +set(CMAKE_C_LINK_USING_feat3 "<LIBRARY>") + +set_property(TARGET lib PROPERTY LINK_LIBRARY_OVERRIDE "feat3,dep1") +set_property(TARGET lib PROPERTY LINK_LIBRARY_OVERRIDE_dep1 feat1) diff --git a/Tests/RunCMake/GenEx-LINK_LIBRARY/override-features5.cmake b/Tests/RunCMake/GenEx-LINK_LIBRARY/override-features5.cmake new file mode 100644 index 0000000..1406d2a --- /dev/null +++ b/Tests/RunCMake/GenEx-LINK_LIBRARY/override-features5.cmake @@ -0,0 +1,7 @@ + +include(incompatible-features1.cmake) + + +set_property(TARGET lib PROPERTY LINK_LIBRARY_OVERRIDE "feat1,dep1") +# next property will be ignored because no feature is specified +set_property(TARGET lib PROPERTY LINK_LIBRARY_OVERRIDE_dep1) diff --git a/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features1-check.cmake b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features1-check.cmake new file mode 100644 index 0000000..a9fba20 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features1-check.cmake @@ -0,0 +1,4 @@ + +if (NOT actual_stdout MATCHES "(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base3${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?${CMAKE_LINK_LIBRARY_FLAG}other1") + set (RunCMake_TEST_FAILED "Not found expected '--LIBFLAG<base3> --LIBFLAG<base1> <other1>'.") +endif() diff --git a/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features1-result.txt b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features1-result.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features1-result.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features2-check.cmake b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features2-check.cmake new file mode 100644 index 0000000..58c117e --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features2-check.cmake @@ -0,0 +1,4 @@ + +if (NOT actual_stdout MATCHES "(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base3${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-PREFIXGROUP\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-LIBGROUPother1${LINK_EXTERN_LIBRARY_SUFFIX}\"? +\"?(/|-)-SUFFIXGROUP") + set (RunCMake_TEST_FAILED "Not found expected '--LIBFLAG<base3> --PREFIXGROUP --LIBGROUP<base1> --LIBGROUP<other1> --SUFFIXGROUP'.") +endif() diff --git a/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features2-result.txt b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features2-result.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features2-result.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features3-check.cmake b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features3-check.cmake new file mode 100644 index 0000000..a9fba20 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features3-check.cmake @@ -0,0 +1,4 @@ + +if (NOT actual_stdout MATCHES "(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base3${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?${CMAKE_LINK_LIBRARY_FLAG}other1") + set (RunCMake_TEST_FAILED "Not found expected '--LIBFLAG<base3> --LIBFLAG<base1> <other1>'.") +endif() diff --git a/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features3-result.txt b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features3-result.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features3-result.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features4-check.cmake b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features4-check.cmake new file mode 100644 index 0000000..58c117e --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features4-check.cmake @@ -0,0 +1,4 @@ + +if (NOT actual_stdout MATCHES "(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base3${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-PREFIXGROUP\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-LIBGROUPother1${LINK_EXTERN_LIBRARY_SUFFIX}\"? +\"?(/|-)-SUFFIXGROUP") + set (RunCMake_TEST_FAILED "Not found expected '--LIBFLAG<base3> --PREFIXGROUP --LIBGROUP<base1> --LIBGROUP<other1> --SUFFIXGROUP'.") +endif() diff --git a/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features4-result.txt b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features4-result.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-features4-result.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-with-DEFAULT-check.cmake b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-with-DEFAULT-check.cmake new file mode 100644 index 0000000..d022f7e --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-with-DEFAULT-check.cmake @@ -0,0 +1,4 @@ + +if (NOT actual_stdout MATCHES "(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base3${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?${CMAKE_LINK_LIBRARY_FLAG}other1${LINK_EXTERN_LIBRARY_SUFFIX}\"?") + set (RunCMake_TEST_FAILED "Not found expected '--LIBFLAG<base3> <base1> <other1>'.") +endif() diff --git a/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-with-DEFAULT-result.txt b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-with-DEFAULT-result.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY-override-with-DEFAULT-result.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY.cmake b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY.cmake index 3223a95..ced689e 100644 --- a/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY.cmake +++ b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/LINK_LIBRARY.cmake @@ -1,4 +1,3 @@ - enable_language(C) # ensure command line is always displayed and do not use any response file @@ -78,4 +77,28 @@ target_link_libraries(LinkLibrary_mix_features2 PRIVATE "$<LINK_LIBRARY:feat2,ba target_link_libraries(base3 INTERFACE other1) add_library(LinkLibrary_mix_features3 SHARED lib.c) -target_link_libraries(LinkLibrary_mix_features3 PRIVATE base2 "$<LINK_LIBRARY:feat2,base1,base3>" other2) +target_link_libraries(LinkLibrary_mix_features3 PRIVATE base2 $<LINK_LIBRARY:feat2,base1,base3> other2) + +# testing LINK_LIBRARY_OVERRIDE property +add_library(LinkLibrary_override_features1 SHARED lib.c) +target_link_libraries(LinkLibrary_override_features1 PRIVATE $<LINK_LIBRARY:feat1,base1,base3>) +set_property(TARGET LinkLibrary_override_features1 PROPERTY LINK_LIBRARY_OVERRIDE "feat1,base1") + +add_library(LinkLibrary_override_features2 SHARED lib.c) +target_link_libraries(LinkLibrary_override_features2 PRIVATE $<LINK_LIBRARY:feat1,base1,base3>) +set_property(TARGET LinkLibrary_override_features2 PROPERTY LINK_LIBRARY_OVERRIDE "feat2,base1,other1") + +add_library(LinkLibrary_override_with_default SHARED lib.c) +target_link_libraries(LinkLibrary_override_with_default PRIVATE $<LINK_LIBRARY:feat1,base1,base3>) +set_property(TARGET LinkLibrary_override_with_default PROPERTY LINK_LIBRARY_OVERRIDE "$<$<LINK_LANGUAGE:C>:DEFAULT,base1,other1>") + +# testing LINK_LIBRARY_OVERRIDE_<LIBRARY> property +add_library(LinkLibrary_override_features3 SHARED lib.c) +target_link_libraries(LinkLibrary_override_features3 PRIVATE $<LINK_LIBRARY:feat1,base1,base3>) +set_property(TARGET LinkLibrary_override_features3 PROPERTY LINK_LIBRARY_OVERRIDE_base1 feat1) + +add_library(LinkLibrary_override_features4 SHARED lib.c) +target_link_libraries(LinkLibrary_override_features4 PRIVATE $<LINK_LIBRARY:feat1,base1,base3>) +set_property(TARGET LinkLibrary_override_features4 PROPERTY LINK_LIBRARY_OVERRIDE "feat3,base1,other1") +set_property(TARGET LinkLibrary_override_features4 PROPERTY LINK_LIBRARY_OVERRIDE_base1 feat2) +set_property(TARGET LinkLibrary_override_features4 PROPERTY LINK_LIBRARY_OVERRIDE_other1 feat2) diff --git a/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/RunCMakeTest.cmake b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/RunCMakeTest.cmake index febada0..9ebbdb7 100644 --- a/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/RunCMakeTest.cmake +++ b/Tests/RunCMake/target_link_libraries-LINK_LIBRARY/RunCMakeTest.cmake @@ -53,6 +53,14 @@ if ((RunCMake_GENERATOR MATCHES "Makefiles|Ninja|Xcode" run_cmake_target(LINK_LIBRARY mix-features2 LinkLibrary_mix_features2) run_cmake_target(LINK_LIBRARY mix-features3 LinkLibrary_mix_features3) + # testing target property LINK_LIBRARY_OVERRIDE + run_cmake_target(LINK_LIBRARY override-features1 LinkLibrary_override_features1) + run_cmake_target(LINK_LIBRARY override-features2 LinkLibrary_override_features2) + run_cmake_target(LINK_LIBRARY override-with-DEFAULT LinkLibrary_override_with_default) + # testing target property LINK_LIBRARY_OVERRIDE_<LIBRARY> + run_cmake_target(LINK_LIBRARY override-features3 LinkLibrary_override_features3) + run_cmake_target(LINK_LIBRARY override-features4 LinkLibrary_override_features4) + run_cmake(imported-target) # tests using features as described in the documentation |