summaryrefslogtreecommitdiffstats
path: root/Source/cmInstallGetRuntimeDependenciesGenerator.cxx
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2021-04-14 14:43:30 (GMT)
committerKyle Edwards <kyle.edwards@kitware.com>2021-06-04 12:52:02 (GMT)
commited3633d88cc5faa6fd7eb68fdd774d6d1f9cfdc9 (patch)
treeb99345e45c9645c178601669ecd5d13c18b8ab1e /Source/cmInstallGetRuntimeDependenciesGenerator.cxx
parentf2617cf8e6aca6ec0f8c7df6999c1f713c6d7474 (diff)
downloadCMake-ed3633d88cc5faa6fd7eb68fdd774d6d1f9cfdc9.zip
CMake-ed3633d88cc5faa6fd7eb68fdd774d6d1f9cfdc9.tar.gz
CMake-ed3633d88cc5faa6fd7eb68fdd774d6d1f9cfdc9.tar.bz2
install(TARGETS): Add RUNTIME_DEPENDENCIES option
Diffstat (limited to 'Source/cmInstallGetRuntimeDependenciesGenerator.cxx')
-rw-r--r--Source/cmInstallGetRuntimeDependenciesGenerator.cxx206
1 files changed, 206 insertions, 0 deletions
diff --git a/Source/cmInstallGetRuntimeDependenciesGenerator.cxx b/Source/cmInstallGetRuntimeDependenciesGenerator.cxx
new file mode 100644
index 0000000..4d585ce
--- /dev/null
+++ b/Source/cmInstallGetRuntimeDependenciesGenerator.cxx
@@ -0,0 +1,206 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmInstallGetRuntimeDependenciesGenerator.h"
+
+#include <memory>
+#include <ostream>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <cm/optional>
+#include <cm/string_view>
+#include <cmext/string_view>
+
+#include "cmGeneratorExpression.h"
+#include "cmInstallRuntimeDependencySet.h"
+#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
+#include "cmOutputConverter.h"
+#include "cmStringAlgorithms.h"
+
+namespace {
+template <typename T, typename F>
+void WriteMultiArgument(std::ostream& os, const cm::string_view& keyword,
+ const std::vector<T>& list,
+ cmScriptGeneratorIndent indent, F transform)
+{
+ bool first = true;
+ for (auto const& item : list) {
+ cm::optional<std::string> result = transform(item);
+ if (result) {
+ if (first) {
+ os << indent << " " << keyword << "\n";
+ first = false;
+ }
+ os << indent << " " << *result << "\n";
+ }
+ }
+}
+
+void WriteFilesArgument(
+ std::ostream& os, const cm::string_view& keyword,
+ const std::vector<std::unique_ptr<cmInstallRuntimeDependencySet::Item>>&
+ items,
+ const std::string& config, cmScriptGeneratorIndent indent)
+{
+ WriteMultiArgument(
+ os, keyword, items, indent,
+ [config](const std::unique_ptr<cmInstallRuntimeDependencySet::Item>& i)
+ -> std::string { return cmStrCat('"', i->GetItemPath(config), '"'); });
+}
+
+void WriteGenexEvaluatorArgument(std::ostream& os,
+ const cm::string_view& keyword,
+ const std::vector<std::string>& genexes,
+ const std::string& config,
+ cmLocalGenerator* lg,
+ cmScriptGeneratorIndent indent)
+{
+ WriteMultiArgument(
+ os, keyword, genexes, indent,
+ [config, lg](const std::string& genex) -> cm::optional<std::string> {
+ std::string result = cmGeneratorExpression::Evaluate(genex, lg, config);
+ if (result.empty()) {
+ return cm::nullopt;
+ }
+ return cmOutputConverter::EscapeForCMake(result);
+ });
+}
+}
+
+cmInstallGetRuntimeDependenciesGenerator::
+ cmInstallGetRuntimeDependenciesGenerator(
+ cmInstallRuntimeDependencySet* runtimeDependencySet,
+ std::vector<std::string> directories,
+ std::vector<std::string> preIncludeRegexes,
+ std::vector<std::string> preExcludeRegexes,
+ std::vector<std::string> postIncludeRegexes,
+ std::vector<std::string> postExcludeRegexes,
+ std::vector<std::string> postIncludeFiles,
+ std::vector<std::string> postExcludeFiles, std::string libraryComponent,
+ std::string frameworkComponent, bool noInstallRPath, const char* depsVar,
+ const char* rpathPrefix, std::vector<std::string> const& configurations,
+ MessageLevel message, bool exclude_from_all, cmListFileBacktrace backtrace)
+ : cmInstallGenerator("", configurations, "", message, exclude_from_all,
+ false, std::move(backtrace))
+ , RuntimeDependencySet(runtimeDependencySet)
+ , Directories(std::move(directories))
+ , PreIncludeRegexes(std::move(preIncludeRegexes))
+ , PreExcludeRegexes(std::move(preExcludeRegexes))
+ , PostIncludeRegexes(std::move(postIncludeRegexes))
+ , PostExcludeRegexes(std::move(postExcludeRegexes))
+ , PostIncludeFiles(std::move(postIncludeFiles))
+ , PostExcludeFiles(std::move(postExcludeFiles))
+ , LibraryComponent(std::move(libraryComponent))
+ , FrameworkComponent(std::move(frameworkComponent))
+ , NoInstallRPath(noInstallRPath)
+ , DepsVar(depsVar)
+ , RPathPrefix(rpathPrefix)
+{
+ this->ActionsPerConfig = true;
+}
+
+bool cmInstallGetRuntimeDependenciesGenerator::Compute(cmLocalGenerator* lg)
+{
+ this->LocalGenerator = lg;
+ return true;
+}
+
+void cmInstallGetRuntimeDependenciesGenerator::GenerateScript(std::ostream& os)
+{
+ // Track indentation.
+ Indent indent;
+
+ // Begin this block of installation.
+ os << indent << "if(";
+ if (this->FrameworkComponent.empty() ||
+ this->FrameworkComponent == this->LibraryComponent) {
+ os << this->CreateComponentTest(this->LibraryComponent,
+ this->ExcludeFromAll);
+ } else {
+ os << this->CreateComponentTest(this->LibraryComponent, true) << " OR "
+ << this->CreateComponentTest(this->FrameworkComponent,
+ this->ExcludeFromAll);
+ }
+ os << ")\n";
+
+ // Generate the script possibly with per-configuration code.
+ this->GenerateScriptConfigs(os, indent.Next());
+
+ // End this block of installation.
+ os << indent << "endif()\n\n";
+}
+
+void cmInstallGetRuntimeDependenciesGenerator::GenerateScriptForConfig(
+ std::ostream& os, const std::string& config, Indent indent)
+{
+ std::string installNameTool =
+ this->LocalGenerator->GetMakefile()->GetSafeDefinition(
+ "CMAKE_INSTALL_NAME_TOOL");
+
+ os << indent << "file(GET_RUNTIME_DEPENDENCIES\n"
+ << indent << " RESOLVED_DEPENDENCIES_VAR " << this->DepsVar << '\n';
+ WriteFilesArgument(os, "EXECUTABLES"_s,
+ this->RuntimeDependencySet->GetExecutables(), config,
+ indent);
+ WriteFilesArgument(os, "LIBRARIES"_s,
+ this->RuntimeDependencySet->GetLibraries(), config,
+ indent);
+ WriteFilesArgument(os, "MODULES"_s, this->RuntimeDependencySet->GetModules(),
+ config, indent);
+ if (this->RuntimeDependencySet->GetBundleExecutable()) {
+ os << indent << " BUNDLE_EXECUTABLE \""
+ << this->RuntimeDependencySet->GetBundleExecutable()->GetItemPath(
+ config)
+ << "\"\n";
+ }
+ WriteGenexEvaluatorArgument(os, "DIRECTORIES"_s, this->Directories, config,
+ this->LocalGenerator, indent);
+ WriteGenexEvaluatorArgument(os, "PRE_INCLUDE_REGEXES"_s,
+ this->PreIncludeRegexes, config,
+ this->LocalGenerator, indent);
+ WriteGenexEvaluatorArgument(os, "PRE_EXCLUDE_REGEXES"_s,
+ this->PreExcludeRegexes, config,
+ this->LocalGenerator, indent);
+ WriteGenexEvaluatorArgument(os, "POST_INCLUDE_REGEXES"_s,
+ this->PostIncludeRegexes, config,
+ this->LocalGenerator, indent);
+ WriteGenexEvaluatorArgument(os, "POST_EXCLUDE_REGEXES"_s,
+ this->PostExcludeRegexes, config,
+ this->LocalGenerator, indent);
+ WriteGenexEvaluatorArgument(os, "POST_INCLUDE_FILES"_s,
+ this->PostIncludeFiles, config,
+ this->LocalGenerator, indent);
+ WriteGenexEvaluatorArgument(os, "POST_EXCLUDE_FILES"_s,
+ this->PostExcludeFiles, config,
+ this->LocalGenerator, indent);
+
+ std::set<std::string> postExcludeFiles;
+ auto const addPostExclude =
+ [config, &postExcludeFiles, this](
+ const std::vector<std::unique_ptr<cmInstallRuntimeDependencySet::Item>>&
+ tgts) {
+ for (auto const& item : tgts) {
+ item->AddPostExcludeFiles(config, postExcludeFiles,
+ this->RuntimeDependencySet);
+ }
+ };
+ addPostExclude(this->RuntimeDependencySet->GetExecutables());
+ addPostExclude(this->RuntimeDependencySet->GetLibraries());
+ addPostExclude(this->RuntimeDependencySet->GetModules());
+ bool first = true;
+ for (auto const& file : postExcludeFiles) {
+ if (first) {
+ os << indent << " POST_EXCLUDE_FILES_STRICT\n";
+ first = false;
+ }
+ os << indent << " \"" << file << "\"\n";
+ }
+
+ if (!installNameTool.empty() && !this->NoInstallRPath) {
+ os << indent << " RPATH_PREFIX " << this->RPathPrefix << '\n';
+ }
+ os << indent << " )\n";
+}