| /* 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 "cmListFileCache.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"; | 
 | } |