diff options
author | Kyle Edwards <kyle.edwards@kitware.com> | 2021-02-19 14:27:48 (GMT) |
---|---|---|
committer | Kyle Edwards <kyle.edwards@kitware.com> | 2021-02-24 19:55:17 (GMT) |
commit | d34d28e688c9ac5f1e5e446bb1131b3018721053 (patch) | |
tree | c3a5c931025e51ad264211303e050c507aaae2c9 /Source | |
parent | e742cf2c1737ececad51f193a81447dce9790cb2 (diff) | |
download | CMake-d34d28e688c9ac5f1e5e446bb1131b3018721053.zip CMake-d34d28e688c9ac5f1e5e446bb1131b3018721053.tar.gz CMake-d34d28e688c9ac5f1e5e446bb1131b3018721053.tar.bz2 |
Genex: Add TARGET_RUNTIME_DLLS genex
Co-Authored-by: Brad King <brad.king@kitware.com>
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmComputeLinkInformation.cxx | 19 | ||||
-rw-r--r-- | Source/cmComputeLinkInformation.h | 6 | ||||
-rw-r--r-- | Source/cmGeneratorExpressionNode.cxx | 51 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 14 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.h | 5 |
5 files changed, 95 insertions, 0 deletions
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 6225a4a..5473316 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -701,6 +701,10 @@ void cmComputeLinkInformation::AddItem(BT<std::string> const& item, this->AddTargetItem(lib, tgt); this->AddLibraryRuntimeInfo(lib.Value, tgt); + if (tgt && tgt->GetType() == cmStateEnums::SHARED_LIBRARY && + this->Target->IsDLLPlatform()) { + this->AddRuntimeDLL(tgt); + } } } else { // This is not a CMake target. Use the name given. @@ -728,6 +732,13 @@ void cmComputeLinkInformation::AddItem(BT<std::string> const& item, void cmComputeLinkInformation::AddSharedDepItem(BT<std::string> const& item, const cmGeneratorTarget* tgt) { + // Record dependencies on DLLs. + if (tgt && tgt->GetType() == cmStateEnums::SHARED_LIBRARY && + this->Target->IsDLLPlatform() && + this->SharedDependencyMode != SharedDepModeLink) { + this->AddRuntimeDLL(tgt); + } + // If dropping shared library dependencies, ignore them. if (this->SharedDependencyMode == SharedDepModeNone) { return; @@ -799,6 +810,14 @@ void cmComputeLinkInformation::AddSharedDepItem(BT<std::string> const& item, } } +void cmComputeLinkInformation::AddRuntimeDLL(cmGeneratorTarget const* tgt) +{ + if (std::find(this->RuntimeDLLs.begin(), this->RuntimeDLLs.end(), tgt) == + this->RuntimeDLLs.end()) { + this->RuntimeDLLs.emplace_back(tgt); + } +} + void cmComputeLinkInformation::ComputeLinkTypeInfo() { // Check whether archives may actually be shared libraries. diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h index 9fec702..4acb99f 100644 --- a/Source/cmComputeLinkInformation.h +++ b/Source/cmComputeLinkInformation.h @@ -64,6 +64,10 @@ public: std::string GetRPathString(bool for_install) const; std::string GetChrpathString() const; std::set<cmGeneratorTarget const*> const& GetSharedLibrariesLinked() const; + std::vector<cmGeneratorTarget const*> const& GetRuntimeDLLs() const + { + return this->RuntimeDLLs; + } std::string const& GetLibLinkFileFlag() const { @@ -81,6 +85,7 @@ private: void AddItem(BT<std::string> const& item, const cmGeneratorTarget* tgt); void AddSharedDepItem(BT<std::string> const& item, cmGeneratorTarget const* tgt); + void AddRuntimeDLL(cmGeneratorTarget const* tgt); // Output information. ItemVector Items; @@ -89,6 +94,7 @@ private: std::vector<std::string> FrameworkPaths; std::vector<std::string> RuntimeSearchPath; std::set<cmGeneratorTarget const*> SharedLibrariesLinked; + std::vector<cmGeneratorTarget const*> RuntimeDLLs; // Context information. cmGeneratorTarget const* const Target; diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index e40316e..da1a78e 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -14,6 +14,7 @@ #include <utility> #include <cm/iterator> +#include <cm/optional> #include <cm/string_view> #include <cm/vector> #include <cmext/algorithm> @@ -23,6 +24,7 @@ #include "cmsys/String.h" #include "cmAlgorithms.h" +#include "cmComputeLinkInformation.h" #include "cmGeneratorExpression.h" #include "cmGeneratorExpressionContext.h" #include "cmGeneratorExpressionDAGChecker.h" @@ -1687,6 +1689,54 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode } } targetObjectsNode; +static const struct TargetRuntimeDllsNode : public cmGeneratorExpressionNode +{ + TargetRuntimeDllsNode() {} // NOLINT(modernize-use-equals-default) + + std::string Evaluate( + const std::vector<std::string>& parameters, + cmGeneratorExpressionContext* context, + const GeneratorExpressionContent* content, + cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override + { + std::string tgtName = parameters.front(); + cmGeneratorTarget* gt = context->LG->FindGeneratorTargetToUse(tgtName); + if (!gt) { + std::ostringstream e; + e << "Objects of target \"" << tgtName + << "\" referenced but no such target exists."; + reportError(context, content->GetOriginalExpression(), e.str()); + return std::string(); + } + cmStateEnums::TargetType type = gt->GetType(); + if (type != cmStateEnums::EXECUTABLE && + type != cmStateEnums::SHARED_LIBRARY && + type != cmStateEnums::MODULE_LIBRARY) { + std::ostringstream e; + e << "Objects of target \"" << tgtName + << "\" referenced but is not one of the allowed target types " + << "(EXECUTABLE, SHARED, MODULE)."; + reportError(context, content->GetOriginalExpression(), e.str()); + return std::string(); + } + + if (auto* cli = gt->GetLinkInformation(context->Config)) { + std::vector<std::string> dllPaths; + auto const& dlls = cli->GetRuntimeDLLs(); + + for (auto const& dll : dlls) { + if (auto loc = dll->MaybeGetLocation(context->Config)) { + dllPaths.emplace_back(*loc); + } + } + + return cmJoin(dllPaths, ";"); + } + + return ""; + } +} targetRuntimeDllsNode; + static const struct CompileFeaturesNode : public cmGeneratorExpressionNode { CompileFeaturesNode() {} // NOLINT(modernize-use-equals-default) @@ -2603,6 +2653,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode( { "TARGET_EXISTS", &targetExistsNode }, { "TARGET_NAME_IF_EXISTS", &targetNameIfExistsNode }, { "TARGET_GENEX_EVAL", &targetGenexEvalNode }, + { "TARGET_RUNTIME_DLLS", &targetRuntimeDllsNode }, { "GENEX_EVAL", &genexEvalNode }, { "BUILD_INTERFACE", &buildInterfaceNode }, { "INSTALL_INTERFACE", &installInterfaceNode }, diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index d7e9952..d3c9959 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -1062,6 +1062,20 @@ const std::string& cmGeneratorTarget::GetLocation( return location; } +cm::optional<std::string> cmGeneratorTarget::MaybeGetLocation( + std::string const& config) const +{ + cm::optional<std::string> location; + if (cmGeneratorTarget::ImportInfo const* imp = this->GetImportInfo(config)) { + if (!imp->Location.empty()) { + location = imp->Location; + } + } else { + location = this->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact); + } + return location; +} + std::vector<cmCustomCommand> const& cmGeneratorTarget::GetPreBuildCommands() const { diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 8fe70ab..2935e0b 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -14,6 +14,8 @@ #include <utility> #include <vector> +#include <cm/optional> + #include "cmLinkItem.h" #include "cmListFileCache.h" #include "cmPolicies.h" @@ -50,6 +52,9 @@ public: bool CanCompileSources() const; const std::string& GetLocation(const std::string& config) const; + /** Get the full path to the target's main artifact, if known. */ + cm::optional<std::string> MaybeGetLocation(std::string const& config) const; + std::vector<cmCustomCommand> const& GetPreBuildCommands() const; std::vector<cmCustomCommand> const& GetPreLinkCommands() const; std::vector<cmCustomCommand> const& GetPostBuildCommands() const; |