| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
- #include "cmInstallRuntimeDependencySetGenerator.h"
- #include <ostream>
- #include <string>
- #include <utility>
- #include <vector>
- #include "cmGeneratorExpression.h"
- #include "cmInstallGenerator.h"
- #include "cmInstallType.h"
- #include "cmListFileCache.h"
- #include "cmLocalGenerator.h"
- #include "cmMakefile.h"
- #include "cmMessageType.h"
- #include "cmOutputConverter.h"
- #include "cmScriptGenerator.h"
- #include "cmStringAlgorithms.h"
- #include "cmake.h"
- cmInstallRuntimeDependencySetGenerator::cmInstallRuntimeDependencySetGenerator(
- DependencyType type, cmInstallRuntimeDependencySet* dependencySet,
- std::vector<std::string> installRPaths, bool noInstallRPath,
- std::string installNameDir, bool noInstallName, const char* depsVar,
- const char* rpathPrefix, const char* tmpVarPrefix, std::string destination,
- std::vector<std::string> const& configurations, std::string component,
- std::string permissions, MessageLevel message, bool exclude_from_all,
- cmListFileBacktrace backtrace)
- : cmInstallGenerator(std::move(destination), configurations,
- std::move(component), message, exclude_from_all, false,
- std::move(backtrace))
- , Type(type)
- , DependencySet(dependencySet)
- , InstallRPaths(std::move(installRPaths))
- , NoInstallRPath(noInstallRPath)
- , InstallNameDir(std::move(installNameDir))
- , NoInstallName(noInstallName)
- , Permissions(std::move(permissions))
- , DepsVar(depsVar)
- , RPathPrefix(rpathPrefix)
- , TmpVarPrefix(tmpVarPrefix)
- {
- this->ActionsPerConfig = true;
- }
- bool cmInstallRuntimeDependencySetGenerator::Compute(cmLocalGenerator* lg)
- {
- this->LocalGenerator = lg;
- return true;
- }
- void cmInstallRuntimeDependencySetGenerator::GenerateScriptForConfig(
- std::ostream& os, const std::string& config, Indent indent)
- {
- if (!this->LocalGenerator->GetMakefile()
- ->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL")
- .empty() &&
- !this->NoInstallName) {
- std::string installNameDir = "@rpath/";
- if (!this->InstallNameDir.empty()) {
- installNameDir = this->InstallNameDir;
- cmGeneratorExpression::ReplaceInstallPrefix(installNameDir,
- "${CMAKE_INSTALL_PREFIX}");
- installNameDir = cmGeneratorExpression::Evaluate(
- installNameDir, this->LocalGenerator, config);
- if (installNameDir.empty()) {
- this->LocalGenerator->GetMakefile()->GetCMakeInstance()->IssueMessage(
- MessageType::FATAL_ERROR,
- "INSTALL_NAME_DIR argument must not evaluate to an "
- "empty string",
- this->Backtrace);
- return;
- }
- if (installNameDir.back() != '/') {
- installNameDir += '/';
- }
- }
- os << indent << "set(" << this->TmpVarPrefix << "_install_name_dir \""
- << installNameDir << "\")\n";
- }
- os << indent << "foreach(" << this->TmpVarPrefix << "_dep IN LISTS "
- << this->DepsVar << ")\n";
- if (!this->LocalGenerator->GetMakefile()
- ->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL")
- .empty()) {
- std::vector<std::string> evaluatedRPaths;
- for (auto const& rpath : this->InstallRPaths) {
- std::string result =
- cmGeneratorExpression::Evaluate(rpath, this->LocalGenerator, config);
- if (!result.empty()) {
- evaluatedRPaths.push_back(std::move(result));
- }
- }
- switch (this->Type) {
- case DependencyType::Library:
- this->GenerateAppleLibraryScript(os, config, evaluatedRPaths,
- indent.Next());
- break;
- case DependencyType::Framework:
- this->GenerateAppleFrameworkScript(os, config, evaluatedRPaths,
- indent.Next());
- break;
- }
- } else {
- std::string depVar = cmStrCat(this->TmpVarPrefix, "_dep");
- this->AddInstallRule(
- os, this->GetDestination(config), cmInstallType_SHARED_LIBRARY, {},
- false, this->Permissions.c_str(), nullptr, nullptr,
- " FOLLOW_SYMLINK_CHAIN", indent.Next(), depVar.c_str());
- if (this->LocalGenerator->GetMakefile()->GetSafeDefinition(
- "CMAKE_SYSTEM_NAME") == "Linux" &&
- !this->NoInstallRPath) {
- std::string evaluatedRPath;
- for (auto const& rpath : this->InstallRPaths) {
- std::string result =
- cmGeneratorExpression::Evaluate(rpath, this->LocalGenerator, config);
- if (!result.empty()) {
- if (evaluatedRPath.empty()) {
- evaluatedRPath = std::move(result);
- } else {
- evaluatedRPath += ':';
- evaluatedRPath += result;
- }
- }
- }
- os << indent.Next() << "get_filename_component(" << this->TmpVarPrefix
- << "_dep_name \"${" << this->TmpVarPrefix << "_dep}\" NAME)\n";
- if (evaluatedRPath.empty()) {
- os << indent.Next() << "file(RPATH_REMOVE FILE \""
- << GetDestDirPath(
- ConvertToAbsoluteDestination(this->GetDestination(config)))
- << "/${" << this->TmpVarPrefix << "_dep_name}\")\n";
- } else {
- os << indent.Next() << "file(RPATH_SET FILE \""
- << GetDestDirPath(
- ConvertToAbsoluteDestination(this->GetDestination(config)))
- << "/${" << this->TmpVarPrefix << "_dep_name}\" NEW_RPATH "
- << cmOutputConverter::EscapeForCMake(evaluatedRPath) << ")\n";
- }
- }
- }
- os << indent << "endforeach()\n";
- }
- void cmInstallRuntimeDependencySetGenerator::GenerateAppleLibraryScript(
- std::ostream& os, const std::string& config,
- const std::vector<std::string>& evaluatedRPaths, Indent indent)
- {
- os << indent << "if(NOT " << this->TmpVarPrefix
- << "_dep MATCHES \"\\\\.framework/\")\n";
- auto depName = cmStrCat(this->TmpVarPrefix, "_dep");
- this->AddInstallRule(
- os, this->GetDestination(config), cmInstallType_SHARED_LIBRARY, {}, false,
- this->Permissions.c_str(), nullptr, nullptr, " FOLLOW_SYMLINK_CHAIN",
- indent.Next(), depName.c_str());
- os << indent.Next() << "get_filename_component(" << this->TmpVarPrefix
- << "_dep_name \"${" << this->TmpVarPrefix << "_dep}\" NAME)\n";
- auto depNameVar = cmStrCat("${", this->TmpVarPrefix, "_dep_name}");
- this->GenerateInstallNameFixup(os, config, evaluatedRPaths,
- cmStrCat("${", this->TmpVarPrefix, "_dep}"),
- depNameVar, indent.Next());
- os << indent << "endif()\n";
- }
- void cmInstallRuntimeDependencySetGenerator::GenerateAppleFrameworkScript(
- std::ostream& os, const std::string& config,
- const std::vector<std::string>& evaluatedRPaths, Indent indent)
- {
- os << indent << "if(" << this->TmpVarPrefix
- << "_dep MATCHES \"^(.*/)?([^/]*\\\\.framework)/(.*)$\")\n"
- << indent.Next() << "set(" << this->TmpVarPrefix
- << "_dir \"${CMAKE_MATCH_1}\")\n"
- << indent.Next() << "set(" << this->TmpVarPrefix
- << "_name \"${CMAKE_MATCH_2}\")\n"
- << indent.Next() << "set(" << this->TmpVarPrefix
- << "_file \"${CMAKE_MATCH_3}\")\n"
- << indent.Next() << "set(" << this->TmpVarPrefix << "_path \"${"
- << this->TmpVarPrefix << "_dir}${" << this->TmpVarPrefix << "_name}\")\n";
- auto depName = cmStrCat(this->TmpVarPrefix, "_path");
- this->AddInstallRule(
- os, this->GetDestination(config), cmInstallType_DIRECTORY, {}, false,
- this->Permissions.c_str(), nullptr, nullptr, " USE_SOURCE_PERMISSIONS",
- indent.Next(), depName.c_str());
- auto depNameVar = cmStrCat("${", this->TmpVarPrefix, "_name}/${",
- this->TmpVarPrefix, "_file}");
- this->GenerateInstallNameFixup(os, config, evaluatedRPaths,
- cmStrCat("${", this->TmpVarPrefix, "_dep}"),
- depNameVar, indent.Next());
- os << indent << "endif()\n";
- }
- void cmInstallRuntimeDependencySetGenerator::GenerateInstallNameFixup(
- std::ostream& os, const std::string& config,
- const std::vector<std::string>& evaluatedRPaths, const std::string& filename,
- const std::string& depName, Indent indent)
- {
- if (!(this->NoInstallRPath && this->NoInstallName)) {
- auto indent2 = indent;
- if (evaluatedRPaths.empty() && this->NoInstallName) {
- indent2 = indent2.Next();
- os << indent << "if(" << this->RPathPrefix << "_" << filename << ")\n";
- }
- os << indent2 << "set(" << this->TmpVarPrefix << "_rpath_args)\n";
- if (!this->NoInstallRPath) {
- os << indent2 << "foreach(" << this->TmpVarPrefix << "_rpath IN LISTS "
- << this->RPathPrefix << '_' << filename << ")\n"
- << indent2.Next() << "list(APPEND " << this->TmpVarPrefix
- << "_rpath_args -delete_rpath \"${" << this->TmpVarPrefix
- << "_rpath}\")\n"
- << indent2 << "endforeach()\n";
- }
- os << indent2 << "execute_process(COMMAND \""
- << this->LocalGenerator->GetMakefile()->GetSafeDefinition(
- "CMAKE_INSTALL_NAME_TOOL")
- << "\" ${" << this->TmpVarPrefix << "_rpath_args}\n";
- if (!this->NoInstallRPath) {
- for (auto const& rpath : evaluatedRPaths) {
- os << indent2 << " -add_rpath "
- << cmOutputConverter::EscapeForCMake(rpath) << "\n";
- }
- }
- if (!this->NoInstallName) {
- os << indent2 << " -id \"${" << this->TmpVarPrefix
- << "_install_name_dir}" << depName << "\"\n";
- }
- os << indent2 << " \""
- << GetDestDirPath(
- ConvertToAbsoluteDestination(this->GetDestination(config)))
- << "/" << depName << "\")\n";
- if (evaluatedRPaths.empty() && this->NoInstallName) {
- os << indent << "endif()\n";
- }
- }
- }
- void cmInstallRuntimeDependencySetGenerator::GenerateStripFixup(
- std::ostream& os, const std::string& config, const std::string& depName,
- Indent indent)
- {
- std::string strip =
- this->LocalGenerator->GetMakefile()->GetSafeDefinition("CMAKE_STRIP");
- if (!strip.empty()) {
- os << indent << "if(CMAKE_INSTALL_DO_STRIP)\n"
- << indent.Next() << "execute_process(COMMAND \"" << strip << "\" ";
- if (this->LocalGenerator->GetMakefile()->GetSafeDefinition(
- "CMAKE_HOST_SYSTEM_NAME") == "Darwin") {
- os << "-x ";
- }
- os << "\""
- << GetDestDirPath(
- ConvertToAbsoluteDestination(this->GetDestination(config)))
- << "/" << depName << "\")\n"
- << indent << "endif()\n";
- }
- }
- std::string cmInstallRuntimeDependencySetGenerator::GetDestination(
- std::string const& config) const
- {
- return cmGeneratorExpression::Evaluate(this->Destination,
- this->LocalGenerator, config);
- }
|