1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
3 #include "cmInstallGetRuntimeDependenciesGenerator.h"
12 #include <cm/optional>
13 #include <cm/string_view>
14 #include <cmext/string_view>
16 #include "cmGeneratorExpression.h"
17 #include "cmInstallRuntimeDependencySet.h"
18 #include "cmListFileCache.h"
19 #include "cmLocalGenerator.h"
20 #include "cmMakefile.h"
21 #include "cmOutputConverter.h"
22 #include "cmStringAlgorithms.h"
25 template <typename T, typename F>
26 void WriteMultiArgument(std::ostream& os, const cm::string_view& keyword,
27 const std::vector<T>& list,
28 cmScriptGeneratorIndent indent, F transform)
31 for (auto const& item : list) {
32 cm::optional<std::string> result = transform(item);
35 os << indent << " " << keyword << "\n";
38 os << indent << " " << *result << "\n";
43 void WriteFilesArgument(
44 std::ostream& os, const cm::string_view& keyword,
45 const std::vector<std::unique_ptr<cmInstallRuntimeDependencySet::Item>>&
47 const std::string& config, cmScriptGeneratorIndent indent)
50 os, keyword, items, indent,
51 [config](const std::unique_ptr<cmInstallRuntimeDependencySet::Item>& i)
52 -> std::string { return cmStrCat('"', i->GetItemPath(config), '"'); });
55 void WriteGenexEvaluatorArgument(std::ostream& os,
56 const cm::string_view& keyword,
57 const std::vector<std::string>& genexes,
58 const std::string& config,
60 cmScriptGeneratorIndent indent)
63 os, keyword, genexes, indent,
64 [config, lg](const std::string& genex) -> cm::optional<std::string> {
65 std::string result = cmGeneratorExpression::Evaluate(genex, lg, config);
69 return cmOutputConverter::EscapeForCMake(result);
74 cmInstallGetRuntimeDependenciesGenerator::
75 cmInstallGetRuntimeDependenciesGenerator(
76 cmInstallRuntimeDependencySet* runtimeDependencySet,
77 std::vector<std::string> directories,
78 std::vector<std::string> preIncludeRegexes,
79 std::vector<std::string> preExcludeRegexes,
80 std::vector<std::string> postIncludeRegexes,
81 std::vector<std::string> postExcludeRegexes,
82 std::vector<std::string> postIncludeFiles,
83 std::vector<std::string> postExcludeFiles, std::string libraryComponent,
84 std::string frameworkComponent, bool noInstallRPath, const char* depsVar,
85 const char* rpathPrefix, std::vector<std::string> const& configurations,
86 MessageLevel message, bool exclude_from_all, cmListFileBacktrace backtrace)
87 : cmInstallGenerator("", configurations, "", message, exclude_from_all,
88 false, std::move(backtrace))
89 , RuntimeDependencySet(runtimeDependencySet)
90 , Directories(std::move(directories))
91 , PreIncludeRegexes(std::move(preIncludeRegexes))
92 , PreExcludeRegexes(std::move(preExcludeRegexes))
93 , PostIncludeRegexes(std::move(postIncludeRegexes))
94 , PostExcludeRegexes(std::move(postExcludeRegexes))
95 , PostIncludeFiles(std::move(postIncludeFiles))
96 , PostExcludeFiles(std::move(postExcludeFiles))
97 , LibraryComponent(std::move(libraryComponent))
98 , FrameworkComponent(std::move(frameworkComponent))
99 , NoInstallRPath(noInstallRPath)
101 , RPathPrefix(rpathPrefix)
103 this->ActionsPerConfig = true;
106 bool cmInstallGetRuntimeDependenciesGenerator::Compute(cmLocalGenerator* lg)
108 this->LocalGenerator = lg;
112 void cmInstallGetRuntimeDependenciesGenerator::GenerateScript(std::ostream& os)
114 // Track indentation.
117 // Begin this block of installation.
118 os << indent << "if(";
119 if (this->FrameworkComponent.empty() ||
120 this->FrameworkComponent == this->LibraryComponent) {
121 os << this->CreateComponentTest(this->LibraryComponent,
122 this->ExcludeFromAll);
124 os << this->CreateComponentTest(this->LibraryComponent, true) << " OR "
125 << this->CreateComponentTest(this->FrameworkComponent,
126 this->ExcludeFromAll);
130 // Generate the script possibly with per-configuration code.
131 this->GenerateScriptConfigs(os, indent.Next());
133 // End this block of installation.
134 os << indent << "endif()\n\n";
137 void cmInstallGetRuntimeDependenciesGenerator::GenerateScriptForConfig(
138 std::ostream& os, const std::string& config, Indent indent)
140 std::string installNameTool =
141 this->LocalGenerator->GetMakefile()->GetSafeDefinition(
142 "CMAKE_INSTALL_NAME_TOOL");
144 os << indent << "file(GET_RUNTIME_DEPENDENCIES\n"
145 << indent << " RESOLVED_DEPENDENCIES_VAR " << this->DepsVar << '\n';
146 WriteFilesArgument(os, "EXECUTABLES"_s,
147 this->RuntimeDependencySet->GetExecutables(), config,
149 WriteFilesArgument(os, "LIBRARIES"_s,
150 this->RuntimeDependencySet->GetLibraries(), config,
152 WriteFilesArgument(os, "MODULES"_s, this->RuntimeDependencySet->GetModules(),
154 if (this->RuntimeDependencySet->GetBundleExecutable()) {
155 os << indent << " BUNDLE_EXECUTABLE \""
156 << this->RuntimeDependencySet->GetBundleExecutable()->GetItemPath(
160 WriteGenexEvaluatorArgument(os, "DIRECTORIES"_s, this->Directories, config,
161 this->LocalGenerator, indent);
162 WriteGenexEvaluatorArgument(os, "PRE_INCLUDE_REGEXES"_s,
163 this->PreIncludeRegexes, config,
164 this->LocalGenerator, indent);
165 WriteGenexEvaluatorArgument(os, "PRE_EXCLUDE_REGEXES"_s,
166 this->PreExcludeRegexes, config,
167 this->LocalGenerator, indent);
168 WriteGenexEvaluatorArgument(os, "POST_INCLUDE_REGEXES"_s,
169 this->PostIncludeRegexes, config,
170 this->LocalGenerator, indent);
171 WriteGenexEvaluatorArgument(os, "POST_EXCLUDE_REGEXES"_s,
172 this->PostExcludeRegexes, config,
173 this->LocalGenerator, indent);
174 WriteGenexEvaluatorArgument(os, "POST_INCLUDE_FILES"_s,
175 this->PostIncludeFiles, config,
176 this->LocalGenerator, indent);
177 WriteGenexEvaluatorArgument(os, "POST_EXCLUDE_FILES"_s,
178 this->PostExcludeFiles, config,
179 this->LocalGenerator, indent);
181 std::set<std::string> postExcludeFiles;
182 auto const addPostExclude =
183 [config, &postExcludeFiles, this](
184 const std::vector<std::unique_ptr<cmInstallRuntimeDependencySet::Item>>&
186 for (auto const& item : tgts) {
187 item->AddPostExcludeFiles(config, postExcludeFiles,
188 this->RuntimeDependencySet);
191 addPostExclude(this->RuntimeDependencySet->GetExecutables());
192 addPostExclude(this->RuntimeDependencySet->GetLibraries());
193 addPostExclude(this->RuntimeDependencySet->GetModules());
195 for (auto const& file : postExcludeFiles) {
197 os << indent << " POST_EXCLUDE_FILES_STRICT\n";
200 os << indent << " \"" << file << "\"\n";
203 if (!installNameTool.empty() && !this->NoInstallRPath) {
204 os << indent << " RPATH_PREFIX " << this->RPathPrefix << '\n';
206 os << indent << " )\n";