diff options
author | Marc Chevrier <marc.chevrier@gmail.com> | 2018-09-14 15:48:20 (GMT) |
---|---|---|
committer | Craig Scott <craig.scott@crascit.com> | 2018-09-25 13:59:58 (GMT) |
commit | a71caab46b205c2b0367c2b11c12a9b55b09bcca (patch) | |
tree | b19ad25b6e8b87bc0e35eb7c93df8afcb6fde594 /Source/cmGeneratorTarget.cxx | |
parent | 5ca130e22394978814a9e59418529a7a3e1a61bd (diff) | |
download | CMake-a71caab46b205c2b0367c2b11c12a9b55b09bcca.zip CMake-a71caab46b205c2b0367c2b11c12a9b55b09bcca.tar.gz CMake-a71caab46b205c2b0367c2b11c12a9b55b09bcca.tar.bz2 |
LINK_DIRECTORIES: Add new properties and commands
These new capabilities enable to manage link directories
Two new properties:
* target properties: LINK_DIRECTORIES and INTERFACE_LINK_DIRECTORIES
One new command
* target_link_directories(): to populate target properties
Fixes: #17215
Diffstat (limited to 'Source/cmGeneratorTarget.cxx')
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 107 |
1 files changed, 102 insertions, 5 deletions
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index a58d3cb..012d77a 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -103,6 +103,7 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg) , DebugCompileFeaturesDone(false) , DebugCompileDefinitionsDone(false) , DebugLinkOptionsDone(false) + , DebugLinkDirectoriesDone(false) , DebugSourcesDone(false) , LinkImplementationLanguageIsContextDependent(true) , UtilityItemsDone(false) @@ -133,6 +134,10 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg) t->GetLinkOptionsBacktraces(), this->LinkOptionsEntries); + CreatePropertyGeneratorExpressions(t->GetLinkDirectoriesEntries(), + t->GetLinkDirectoriesBacktraces(), + this->LinkDirectoriesEntries); + CreatePropertyGeneratorExpressions(t->GetSourceEntries(), t->GetSourceBacktraces(), this->SourceEntries, true); @@ -150,6 +155,7 @@ cmGeneratorTarget::~cmGeneratorTarget() cmDeleteAll(this->CompileFeaturesEntries); cmDeleteAll(this->CompileDefinitionsEntries); cmDeleteAll(this->LinkOptionsEntries); + cmDeleteAll(this->LinkDirectoriesEntries); cmDeleteAll(this->SourceEntries); cmDeleteAll(this->LinkInformation); } @@ -1704,11 +1710,6 @@ cmListFileBacktrace cmGeneratorTarget::GetBacktrace() const return this->Target->GetBacktrace(); } -const std::vector<std::string>& cmGeneratorTarget::GetLinkDirectories() const -{ - return this->Target->GetLinkDirectories(); -} - const std::set<std::string>& cmGeneratorTarget::GetUtilities() const { return this->Target->GetUtilities(); @@ -3068,6 +3069,102 @@ void cmGeneratorTarget::GetStaticLibraryLinkOptions( } namespace { +void processLinkDirectories( + cmGeneratorTarget const* tgt, + const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, + std::vector<std::string>& directories, + std::unordered_set<std::string>& uniqueDirectories, + cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config, + bool debugDirectories, std::string const& language) +{ + for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) { + cmLinkImplItem const& item = entry->LinkImplItem; + std::string const& targetName = item.AsStr(); + + std::vector<std::string> entryDirectories; + cmSystemTools::ExpandListArgument( + entry->ge->Evaluate(tgt->GetLocalGenerator(), config, false, tgt, + dagChecker, language), + entryDirectories); + + std::string usedDirectories; + for (std::string& entryDirectory : entryDirectories) { + if (!cmSystemTools::FileIsFullPath(entryDirectory)) { + std::ostringstream e; + if (!targetName.empty()) { + /* clang-format off */ + e << "Target \"" << targetName << "\" contains relative " + "path in its INTERFACE_LINK_DIRECTORIES:\n" + " \"" << entryDirectory << "\""; + /* clang-format on */ + tgt->GetLocalGenerator()->IssueMessage(cmake::FATAL_ERROR, e.str()); + return; + } + } + + // Sanitize the path the same way the link_directories command does + // in case projects set the LINK_DIRECTORIES property directly. + cmSystemTools::ConvertToUnixSlashes(entryDirectory); + if (uniqueDirectories.insert(entryDirectory).second) { + directories.push_back(entryDirectory); + if (debugDirectories) { + usedDirectories += " * " + entryDirectory + "\n"; + } + } + } + if (!usedDirectories.empty()) { + tgt->GetLocalGenerator()->GetCMakeInstance()->IssueMessage( + cmake::LOG, + std::string("Used link directories for target ") + tgt->GetName() + + ":\n" + usedDirectories, + entry->ge->GetBacktrace()); + } + } +} +} + +void cmGeneratorTarget::GetLinkDirectories(std::vector<std::string>& result, + const std::string& config, + const std::string& language) const +{ + std::unordered_set<std::string> uniqueDirectories; + + cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_DIRECTORIES", nullptr, + nullptr); + + std::vector<std::string> debugProperties; + const char* debugProp = + this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); + if (debugProp) { + cmSystemTools::ExpandListArgument(debugProp, debugProperties); + } + + bool debugDirectories = !this->DebugLinkDirectoriesDone && + std::find(debugProperties.begin(), debugProperties.end(), + "LINK_DIRECTORIES") != debugProperties.end(); + + if (this->GlobalGenerator->GetConfigureDoneCMP0026()) { + this->DebugLinkDirectoriesDone = true; + } + + processLinkDirectories(this, this->LinkDirectoriesEntries, result, + uniqueDirectories, &dagChecker, config, + debugDirectories, language); + + std::vector<cmGeneratorTarget::TargetPropertyEntry*> + linkInterfaceLinkDirectoriesEntries; + + AddInterfaceEntries(this, config, "INTERFACE_LINK_DIRECTORIES", + linkInterfaceLinkDirectoriesEntries); + + processLinkDirectories(this, linkInterfaceLinkDirectoriesEntries, result, + uniqueDirectories, &dagChecker, config, + debugDirectories, language); + + cmDeleteAll(linkInterfaceLinkDirectoriesEntries); +} + +namespace { void processLinkDepends( cmGeneratorTarget const* tgt, const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, |