From cc9f88af53b6dd95d3fc1786166dd05599e2ba91 Mon Sep 17 00:00:00 2001 From: Marc Chevrier Date: Tue, 26 Jun 2018 16:21:05 +0200 Subject: LINK_DEPENDS: add support for property INTERFACE_LINK_DEPENDS Fixes: #17997 --- Help/manual/cmake-properties.7.rst | 2 ++ Help/prop_tgt/INTERFACE_LINK_DEPENDS.rst | 31 +++++++++++++++++++ Help/prop_tgt/LINK_DEPENDS.rst | 4 +-- .../dev/INTERFACE_LINK_DEPENDS-property.rst | 4 +++ Source/cmExportBuildFileGenerator.cxx | 3 ++ Source/cmExportFileGenerator.cxx | 31 +++++++++++++++++++ Source/cmExportFileGenerator.h | 4 +++ Source/cmExportInstallFileGenerator.cxx | 2 ++ Source/cmGeneratorExpressionDAGChecker.h | 3 +- Source/cmGeneratorTarget.cxx | 36 ++++++++++++++++++++++ Source/cmGeneratorTarget.h | 4 +++ Source/cmMakefileExecutableTargetGenerator.cxx | 22 ++++++------- Source/cmMakefileLibraryTargetGenerator.cxx | 22 ++++++------- Source/cmMakefileTargetGenerator.cxx | 8 ++--- Source/cmMakefileTargetGenerator.h | 3 +- Source/cmNinjaNormalTargetGenerator.cxx | 4 +-- Source/cmNinjaTargetGenerator.cxx | 15 +++++---- Source/cmNinjaTargetGenerator.h | 2 +- Tests/BuildDepends/CMakeLists.txt | 11 +++++++ Tests/BuildDepends/Project/CMakeLists.txt | 5 +++ Tests/ExportImport/Export/CMakeLists.txt | 14 +++++++++ Tests/ExportImport/Import/A/CMakeLists.txt | 7 +++++ 22 files changed, 195 insertions(+), 42 deletions(-) create mode 100644 Help/prop_tgt/INTERFACE_LINK_DEPENDS.rst create mode 100644 Help/release/dev/INTERFACE_LINK_DEPENDS-property.rst diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 03a6a27..9c2ac03 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -198,6 +198,7 @@ Properties on Targets /prop_tgt/IMPORTED_LIBNAME_CONFIG /prop_tgt/IMPORTED_LIBNAME /prop_tgt/IMPORTED_LINK_DEPENDENT_LIBRARIES_CONFIG + /prop_tgt/IMPORTED_LINK_DEPENDENT_LIBRARIES_CONFIG /prop_tgt/IMPORTED_LINK_DEPENDENT_LIBRARIES /prop_tgt/IMPORTED_LINK_INTERFACE_LANGUAGES_CONFIG /prop_tgt/IMPORTED_LINK_INTERFACE_LANGUAGES @@ -225,6 +226,7 @@ Properties on Targets /prop_tgt/INTERFACE_COMPILE_FEATURES /prop_tgt/INTERFACE_COMPILE_OPTIONS /prop_tgt/INTERFACE_INCLUDE_DIRECTORIES + /prop_tgt/INTERFACE_LINK_DEPENDS /prop_tgt/INTERFACE_LINK_LIBRARIES /prop_tgt/INTERFACE_LINK_OPTIONS /prop_tgt/INTERFACE_POSITION_INDEPENDENT_CODE diff --git a/Help/prop_tgt/INTERFACE_LINK_DEPENDS.rst b/Help/prop_tgt/INTERFACE_LINK_DEPENDS.rst new file mode 100644 index 0000000..d07f8ea --- /dev/null +++ b/Help/prop_tgt/INTERFACE_LINK_DEPENDS.rst @@ -0,0 +1,31 @@ +INTERFACE_LINK_DEPENDS +---------------------- + +Additional public interface files on which a target binary depends for linking. + +This property is supported only by Makefile and Ninja generators. It is +intended to specify dependencies on "linker scripts" for custom Makefile link +rules. + +When target dependencies are specified using :command:`target_link_libraries`, +CMake will read this property from all target dependencies to determine the +build properties of the consumer. + +Contents of ``INTERFACE_LINK_DEPENDS`` may use "generator expressions" +with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` +manual for available expressions. See the :manual:`cmake-buildsystem(7)` +-manual for more on defining buildsystem properties. + +Link dependency files usage requirements commonly differ between the build-tree +and the install-tree. The ``BUILD_INTERFACE`` and ``INSTALL_INTERFACE`` +generator expressions can be used to describe separate usage requirements +based on the usage location. Relative paths are allowed within the +``INSTALL_INTERFACE`` expression and are interpreted relative to the +installation prefix. For example: + +.. code-block:: cmake + + set_property(TARGET mylib PROPERTY INTERFACE_LINK_DEPENDS + $ + $ # /mylinkscript + ) diff --git a/Help/prop_tgt/LINK_DEPENDS.rst b/Help/prop_tgt/LINK_DEPENDS.rst index 5576b85..bc83393 100644 --- a/Help/prop_tgt/LINK_DEPENDS.rst +++ b/Help/prop_tgt/LINK_DEPENDS.rst @@ -7,6 +7,6 @@ Specifies a semicolon-separated list of full-paths to files on which the link rule for this target depends. The target binary will be linked if any of the named files is newer than it. -This property is ignored by non-Makefile generators. It is intended -to specify dependencies on "linker scripts" for custom Makefile link +This property is supported only by Makefile and Ninja generators. It is +intended to specify dependencies on "linker scripts" for custom Makefile link rules. diff --git a/Help/release/dev/INTERFACE_LINK_DEPENDS-property.rst b/Help/release/dev/INTERFACE_LINK_DEPENDS-property.rst new file mode 100644 index 0000000..9527c97 --- /dev/null +++ b/Help/release/dev/INTERFACE_LINK_DEPENDS-property.rst @@ -0,0 +1,4 @@ +INTERFACE_LINK_DEPENDS-property +------------------------------- + +* Binary targets gained new :prop_tgt:`INTERFACE_LINK_DEPENDS` property. diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index 9f2e01d..7f42035 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -98,6 +98,9 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) this->PopulateInterfaceProperty("INTERFACE_LINK_OPTIONS", gte, cmGeneratorExpression::BuildInterface, properties, missingTargets); + this->PopulateInterfaceProperty("INTERFACE_LINK_DEPENDS", gte, + cmGeneratorExpression::BuildInterface, + properties, missingTargets); this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", gte, properties); diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 5f61571..ec68fce 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -420,6 +420,37 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface( } } +void cmExportFileGenerator::PopulateLinkDependsInterface( + cmTargetExport* tei, cmGeneratorExpression::PreprocessContext preprocessRule, + ImportPropertyMap& properties, std::vector& missingTargets) +{ + cmGeneratorTarget* gt = tei->Target; + assert(preprocessRule == cmGeneratorExpression::InstallInterface); + + const char* propName = "INTERFACE_LINK_DEPENDS"; + const char* input = gt->GetProperty(propName); + + if (!input) { + return; + } + + if (!*input) { + properties[propName].clear(); + return; + } + + std::string prepro = + cmGeneratorExpression::Preprocess(input, preprocessRule, true); + if (!prepro.empty()) { + this->ResolveTargetsInGeneratorExpressions(prepro, gt, missingTargets); + + if (!checkInterfaceDirs(prepro, gt, propName)) { + return; + } + properties[propName] = prepro; + } +} + void cmExportFileGenerator::PopulateInterfaceProperty( const std::string& propName, cmGeneratorTarget* target, cmGeneratorExpression::PreprocessContext preprocessRule, diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index 954e6c5..6ca2e07 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -147,6 +147,10 @@ protected: cmTargetExport* target, cmGeneratorExpression::PreprocessContext preprocessRule, ImportPropertyMap& properties, std::vector& missingTargets); + void PopulateLinkDependsInterface( + cmTargetExport* target, + cmGeneratorExpression::PreprocessContext preprocessRule, + ImportPropertyMap& properties, std::vector& missingTargets); void SetImportLinkInterface( const std::string& config, std::string const& suffix, diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 1db76ac..3595708 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -106,6 +106,8 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) this->PopulateInterfaceProperty("INTERFACE_LINK_OPTIONS", gt, cmGeneratorExpression::InstallInterface, properties, missingTargets); + this->PopulateLinkDependsInterface( + te, cmGeneratorExpression::InstallInterface, properties, missingTargets); std::string errorMessage; if (!this->PopulateExportProperties(gt, properties, errorMessage)) { diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h index cfe31f1..cd23904 100644 --- a/Source/cmGeneratorExpressionDAGChecker.h +++ b/Source/cmGeneratorExpressionDAGChecker.h @@ -26,7 +26,8 @@ struct cmGeneratorExpressionContext; SELECT(F, EvaluatingAutoUicOptions, AUTOUIC_OPTIONS) \ SELECT(F, EvaluatingSources, SOURCES) \ SELECT(F, EvaluatingCompileFeatures, COMPILE_FEATURES) \ - SELECT(F, EvaluatingLinkOptions, LINK_OPTIONS) + SELECT(F, EvaluatingLinkOptions, LINK_OPTIONS) \ + SELECT(F, EvaluatingLinkDepends, LINK_DEPENDS) #define CM_FOR_EACH_TRANSITIVE_PROPERTY(F) \ CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_BOTH) diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 41e55a5..d4686c2 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -3008,6 +3008,42 @@ void cmGeneratorTarget::GetLinkOptions(std::vector& result, } } +namespace { +void processLinkDepends( + cmGeneratorTarget const* tgt, + const std::vector& entries, + std::vector& options, + std::unordered_set& uniqueOptions, + cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config, + std::string const& language) +{ + processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker, + config, false, "link depends", language, + OptionsParse::None); +} +} + +void cmGeneratorTarget::GetLinkDepends(std::vector& result, + const std::string& config, + const std::string& language) const +{ + if (const char* linkDepends = this->GetProperty("LINK_DEPENDS")) { + cmSystemTools::ExpandListArgument(linkDepends, result); + } + + std::unordered_set uniqueOptions; + std::vector linkDependsEntries; + cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), "LINK_DEPENDS", + nullptr, nullptr); + + AddInterfaceEntries(this, config, "INTERFACE_LINK_DEPENDS", + linkDependsEntries); + processLinkDepends(this, linkDependsEntries, result, uniqueOptions, + &dagChecker, config, language); + + cmDeleteAll(linkDependsEntries); +} + void cmGeneratorTarget::ComputeTargetManifest(const std::string& config) const { if (this->IsImported()) { diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index aa36823..4cc0aac 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -422,6 +422,10 @@ public: const std::string& config, const std::string& language) const; + void GetLinkDepends(std::vector& result, + const std::string& config, + const std::string& language) const; + bool IsSystemIncludeDirectory(const std::string& dir, const std::string& config, const std::string& language) const; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 82f4683..b9845ba 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -97,15 +97,15 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( std::vector commands; - // Build list of dependencies. - std::vector depends; - this->AppendLinkDepends(depends); - // Get the language to use for linking this library. std::string linkLanguage = "CUDA"; std::string const objExt = this->Makefile->GetSafeDefinition("CMAKE_CUDA_OUTPUT_EXTENSION"); + // Build list of dependencies. + std::vector depends; + this->AppendLinkDepends(depends, linkLanguage); + // Get the name of the device object to generate. std::string const targetOutputReal = this->GeneratorTarget->ObjectDirectory + "cmake_device_link" + objExt; @@ -294,13 +294,6 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) { std::vector commands; - // Build list of dependencies. - std::vector depends; - this->AppendLinkDepends(depends); - if (!this->DeviceLinkObject.empty()) { - depends.push_back(this->DeviceLinkObject); - } - // Get the name of the executable to generate. std::string targetName; std::string targetNameReal; @@ -378,6 +371,13 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) return; } + // Build list of dependencies. + std::vector depends; + this->AppendLinkDepends(depends, linkLanguage); + if (!this->DeviceLinkObject.empty()) { + depends.push_back(this->DeviceLinkObject); + } + this->NumberOfProgressActions++; if (!this->NoRuleMessages) { cmLocalUnixMakefileGenerator3::EchoProgress progress; diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 036acc7..571e74b 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -260,15 +260,15 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( // code duplication. std::vector commands; - // Build list of dependencies. - std::vector depends; - this->AppendLinkDepends(depends); - // Get the language to use for linking this library. std::string linkLanguage = "CUDA"; std::string const objExt = this->Makefile->GetSafeDefinition("CMAKE_CUDA_OUTPUT_EXTENSION"); + // Build list of dependencies. + std::vector depends; + this->AppendLinkDepends(depends, linkLanguage); + // Create set of linking flags. std::string linkFlags; this->GetTargetLinkFlags(linkFlags, linkLanguage); @@ -444,13 +444,6 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( // code duplication. std::vector commands; - // Build list of dependencies. - std::vector depends; - this->AppendLinkDepends(depends); - if (!this->DeviceLinkObject.empty()) { - depends.push_back(this->DeviceLinkObject); - } - // Get the language to use for linking this library. std::string linkLanguage = this->GeneratorTarget->GetLinkerLanguage(this->ConfigName); @@ -462,6 +455,13 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( return; } + // Build list of dependencies. + std::vector depends; + this->AppendLinkDepends(depends, linkLanguage); + if (!this->DeviceLinkObject.empty()) { + depends.push_back(this->DeviceLinkObject); + } + // Create set of linking flags. std::string linkFlags; this->LocalGenerator->AppendFlags(linkFlags, extraFlags); diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 08fcd8f..7cae305 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -1387,7 +1387,7 @@ void cmMakefileTargetGenerator::AppendObjectDepends( } void cmMakefileTargetGenerator::AppendLinkDepends( - std::vector& depends) + std::vector& depends, const std::string& linkLanguage) { this->AppendObjectDepends(depends); @@ -1411,10 +1411,8 @@ void cmMakefileTargetGenerator::AppendLinkDepends( } // Add user-specified dependencies. - if (const char* linkDepends = - this->GeneratorTarget->GetProperty("LINK_DEPENDS")) { - cmSystemTools::ExpandListArgument(linkDepends, depends); - } + this->GeneratorTarget->GetLinkDepends(depends, this->ConfigName, + linkLanguage); } std::string cmMakefileTargetGenerator::GetLinkRule( diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index 4d1c9ec..f21362a 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -128,7 +128,8 @@ protected: void AppendObjectDepends(std::vector& depends); // Append link rule dependencies (objects, etc.). - void AppendLinkDepends(std::vector& depends); + void AppendLinkDepends(std::vector& depends, + const std::string& linkLanguage); // Lookup the link rule for this target. std::string GetLinkRule(const std::string& linkRuleVar); diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 7394188..f94e5bc 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -625,7 +625,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement() outputs.push_back(targetOutputReal); // Compute specific libraries to link with. cmNinjaDeps explicitDeps = this->GetObjects(); - cmNinjaDeps implicitDeps = this->ComputeLinkDeps(); + cmNinjaDeps implicitDeps = this->ComputeLinkDeps(this->TargetLinkLanguage); std::string frameworkPath; std::string linkPath; @@ -794,7 +794,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() // Compute specific libraries to link with. cmNinjaDeps explicitDeps = this->GetObjects(); - cmNinjaDeps implicitDeps = this->ComputeLinkDeps(); + cmNinjaDeps implicitDeps = this->ComputeLinkDeps(this->TargetLinkLanguage); if (!this->DeviceLinkObject.empty()) { explicitDeps.push_back(this->DeviceLinkObject); diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 9d41948..df32f40 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -235,7 +235,8 @@ std::string cmNinjaTargetGenerator::ComputeIncludes( return includesString; } -cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const +cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps( + const std::string& linkLanguage) const { // Static libraries never depend on other targets for linking. if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY || @@ -270,13 +271,11 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const } // Add user-specified dependencies. - if (const char* linkDepends = - this->GeneratorTarget->GetProperty("LINK_DEPENDS")) { - std::vector linkDeps; - cmSystemTools::ExpandListArgument(linkDepends, linkDeps); - std::transform(linkDeps.begin(), linkDeps.end(), - std::back_inserter(result), MapToNinjaPath()); - } + std::vector linkDeps; + this->GeneratorTarget->GetLinkDepends(linkDeps, this->ConfigName, + linkLanguage); + std::transform(linkDeps.begin(), linkDeps.end(), std::back_inserter(result), + MapToNinjaPath()); return result; } diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index 4660a3a..e58a8a0 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -95,7 +95,7 @@ protected: } /// @return the list of link dependency for the given target @a target. - cmNinjaDeps ComputeLinkDeps() const; + cmNinjaDeps ComputeLinkDeps(const std::string& linkLanguage) const; /// @return the source file path for the given @a source. std::string GetSourceFilePath(cmSourceFile const* source) const; diff --git a/Tests/BuildDepends/CMakeLists.txt b/Tests/BuildDepends/CMakeLists.txt index 3b4ff60..39a5131 100644 --- a/Tests/BuildDepends/CMakeLists.txt +++ b/Tests/BuildDepends/CMakeLists.txt @@ -345,6 +345,17 @@ is not newer than dependency ${TEST_LINK_DEPENDS} ") endif() + + set(linkdep2 ${BuildDepends_BINARY_DIR}/Project/linkdep2${CMAKE_EXECUTABLE_SUFFIX}) + if(${linkdep2} IS_NEWER_THAN ${TEST_LINK_DEPENDS}) + message("INTERFACE_LINK_DEPENDS worked") + else() + message(SEND_ERROR "INTERFACE_LINK_DEPENDS failed. Executable + ${linkdep2} +is not newer than dependency + ${TEST_LINK_DEPENDS} +") + endif() endif() if(EXISTS "${link_depends_no_shared_check_txt}") diff --git a/Tests/BuildDepends/Project/CMakeLists.txt b/Tests/BuildDepends/Project/CMakeLists.txt index 127b365..09be3ea 100644 --- a/Tests/BuildDepends/Project/CMakeLists.txt +++ b/Tests/BuildDepends/Project/CMakeLists.txt @@ -107,6 +107,11 @@ set_property( if(TEST_LINK_DEPENDS) add_executable(linkdep linkdep.cxx) set_property(TARGET linkdep PROPERTY LINK_DEPENDS ${TEST_LINK_DEPENDS}) + + add_library(foo_interface INTERFACE) + set_property(TARGET foo_interface PROPERTY INTERFACE_LINK_DEPENDS $<1:${TEST_LINK_DEPENDS}>) + add_executable(linkdep2 linkdep.cxx) + target_link_libraries(linkdep2 PRIVATE foo_interface) endif() add_library(link_depends_no_shared_lib SHARED link_depends_no_shared_lib.c diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt index a1c4993..470a5bd 100644 --- a/Tests/ExportImport/Export/CMakeLists.txt +++ b/Tests/ExportImport/Export/CMakeLists.txt @@ -607,3 +607,17 @@ target_link_options(testLinkOptions INTERFACE INTERFACE_FLAG) install(TARGETS testLinkOptions EXPORT RequiredExp DESTINATION lib) export(TARGETS testLinkOptions NAMESPACE bld_ APPEND FILE ExportBuildTree.cmake) + + +#------------------------------------------------------------------------------ +# test export of INTERFACE_LINK_DEPENDS +if(CMAKE_GENERATOR MATCHES "Make|Ninja") + add_library(testLinkDepends INTERFACE) + set_property(TARGET testLinkDepends PROPERTY INTERFACE_LINK_DEPENDS + $ + $) + + install(TARGETS testLinkDepends + EXPORT RequiredExp DESTINATION lib) + export(TARGETS testLinkDepends NAMESPACE bld_ APPEND FILE ExportBuildTree.cmake) +endif() diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt index f8eb721..7510d7e 100644 --- a/Tests/ExportImport/Import/A/CMakeLists.txt +++ b/Tests/ExportImport/Import/A/CMakeLists.txt @@ -477,3 +477,10 @@ endif() # check that imported libraries have the expected INTERFACE_LINK_OPTIONS property checkForProperty(bld_testLinkOptions "INTERFACE_LINK_OPTIONS" "INTERFACE_FLAG") checkForProperty(Req::testLinkOptions "INTERFACE_LINK_OPTIONS" "INTERFACE_FLAG") + +#--------------------------------------------------------------------------------- +# check that imported libraries have the expected INTERFACE_LINK_DEPENDS property +if(CMAKE_GENERATOR MATCHES "Make|Ninja") + checkForProperty(bld_testLinkDepends "INTERFACE_LINK_DEPENDS" "BUILD_LINK_DEPENDS") + checkForProperty(Req::testLinkDepends "INTERFACE_LINK_DEPENDS" "${CMAKE_INSTALL_PREFIX}/INSTALL_LINK_DEPENDS") +endif() -- cgit v0.12 From 724bd7790e1a28826b5457c0b28edbfff9af4d15 Mon Sep 17 00:00:00 2001 From: Marc Chevrier Date: Wed, 27 Jun 2018 18:36:47 +0200 Subject: LINK_DEPENDS: add support of 'generator expressions' --- Help/prop_tgt/LINK_DEPENDS.rst | 5 +++++ Help/release/dev/LINK_DEPENDS-property.rst | 5 +++++ Source/cmGeneratorTarget.cxx | 16 +++++++++++----- Tests/BuildDepends/Project/CMakeLists.txt | 2 +- 4 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 Help/release/dev/LINK_DEPENDS-property.rst diff --git a/Help/prop_tgt/LINK_DEPENDS.rst b/Help/prop_tgt/LINK_DEPENDS.rst index bc83393..3ab8658 100644 --- a/Help/prop_tgt/LINK_DEPENDS.rst +++ b/Help/prop_tgt/LINK_DEPENDS.rst @@ -10,3 +10,8 @@ linked if any of the named files is newer than it. This property is supported only by Makefile and Ninja generators. It is intended to specify dependencies on "linker scripts" for custom Makefile link rules. + +Contents of ``LINK_DEPENDS`` may use "generator expressions" with +the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` +manual for available expressions. See the :manual:`cmake-buildsystem(7)` +manual for more on defining buildsystem properties. diff --git a/Help/release/dev/LINK_DEPENDS-property.rst b/Help/release/dev/LINK_DEPENDS-property.rst new file mode 100644 index 0000000..83beba8 --- /dev/null +++ b/Help/release/dev/LINK_DEPENDS-property.rst @@ -0,0 +1,5 @@ +LINK_DEPENDS-property +--------------------- + +* The :prop_tgt:`LINK_DEPENDS` target property learned to support + :manual:`generator expressions `. diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index d4686c2..e07ccd9 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -3027,15 +3027,21 @@ void cmGeneratorTarget::GetLinkDepends(std::vector& result, const std::string& config, const std::string& language) const { - if (const char* linkDepends = this->GetProperty("LINK_DEPENDS")) { - cmSystemTools::ExpandListArgument(linkDepends, result); - } - - std::unordered_set uniqueOptions; std::vector linkDependsEntries; + std::unordered_set uniqueOptions; cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), "LINK_DEPENDS", nullptr, nullptr); + if (const char* linkDepends = this->GetProperty("LINK_DEPENDS")) { + std::vector depends; + cmGeneratorExpression ge; + cmSystemTools::ExpandListArgument(linkDepends, depends); + for (const auto& depend : depends) { + std::unique_ptr cge = ge.Parse(depend); + linkDependsEntries.push_back( + new cmGeneratorTarget::TargetPropertyEntry(std::move(cge))); + } + } AddInterfaceEntries(this, config, "INTERFACE_LINK_DEPENDS", linkDependsEntries); processLinkDepends(this, linkDependsEntries, result, uniqueOptions, diff --git a/Tests/BuildDepends/Project/CMakeLists.txt b/Tests/BuildDepends/Project/CMakeLists.txt index 09be3ea..3f41b26 100644 --- a/Tests/BuildDepends/Project/CMakeLists.txt +++ b/Tests/BuildDepends/Project/CMakeLists.txt @@ -106,7 +106,7 @@ set_property( if(TEST_LINK_DEPENDS) add_executable(linkdep linkdep.cxx) - set_property(TARGET linkdep PROPERTY LINK_DEPENDS ${TEST_LINK_DEPENDS}) + set_property(TARGET linkdep PROPERTY LINK_DEPENDS $<1:${TEST_LINK_DEPENDS}>) add_library(foo_interface INTERFACE) set_property(TARGET foo_interface PROPERTY INTERFACE_LINK_DEPENDS $<1:${TEST_LINK_DEPENDS}>) -- cgit v0.12