diff options
author | Kyle Edwards <kyle.edwards@kitware.com> | 2021-04-14 14:43:30 (GMT) |
---|---|---|
committer | Kyle Edwards <kyle.edwards@kitware.com> | 2021-06-04 12:52:02 (GMT) |
commit | ed3633d88cc5faa6fd7eb68fdd774d6d1f9cfdc9 (patch) | |
tree | b99345e45c9645c178601669ecd5d13c18b8ab1e /Source/cmInstallGetRuntimeDependenciesGenerator.cxx | |
parent | f2617cf8e6aca6ec0f8c7df6999c1f713c6d7474 (diff) | |
download | CMake-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.cxx | 206 |
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"; +} |