diff options
Diffstat (limited to 'Source/cmInstallCommand.cxx')
-rw-r--r-- | Source/cmInstallCommand.cxx | 186 |
1 files changed, 185 insertions, 1 deletions
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index c9bb467..c36778d 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -2,8 +2,10 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmInstallCommand.h" +#include <algorithm> #include <cassert> #include <cstddef> +#include <iterator> #include <set> #include <sstream> #include <utility> @@ -23,7 +25,10 @@ #include "cmInstallExportGenerator.h" #include "cmInstallFilesGenerator.h" #include "cmInstallGenerator.h" +#include "cmInstallGetRuntimeDependenciesGenerator.h" #include "cmInstallImportedRuntimeArtifactsGenerator.h" +#include "cmInstallRuntimeDependencySet.h" +#include "cmInstallRuntimeDependencySetGenerator.h" #include "cmInstallScriptGenerator.h" #include "cmInstallTargetGenerator.h" #include "cmListFileCache.h" @@ -31,6 +36,7 @@ #include "cmMessageType.h" #include "cmPolicies.h" #include "cmProperty.h" +#include "cmRuntimeDependencyArchive.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSubcommandTable.h" @@ -40,6 +46,29 @@ namespace { +struct RuntimeDependenciesArgs +{ + 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; +}; + +auto const RuntimeDependenciesArgHelper = + cmArgumentParser<RuntimeDependenciesArgs>{} + .Bind("DIRECTORIES"_s, &RuntimeDependenciesArgs::Directories) + .Bind("PRE_INCLUDE_REGEXES"_s, &RuntimeDependenciesArgs::PreIncludeRegexes) + .Bind("PRE_EXCLUDE_REGEXES"_s, &RuntimeDependenciesArgs::PreExcludeRegexes) + .Bind("POST_INCLUDE_REGEXES"_s, + &RuntimeDependenciesArgs::PostIncludeRegexes) + .Bind("POST_EXCLUDE_REGEXES"_s, + &RuntimeDependenciesArgs::PostExcludeRegexes) + .Bind("POST_INCLUDE_FILES"_s, &RuntimeDependenciesArgs::PostIncludeFiles) + .Bind("POST_EXCLUDE_FILES"_s, &RuntimeDependenciesArgs::PostExcludeFiles); + class Helper { public: @@ -147,12 +176,106 @@ std::unique_ptr<cmInstallFilesGenerator> CreateInstallFilesGenerator( args.GetDestination()); } +void AddInstallRuntimeDependenciesGenerator( + Helper& helper, cmInstallRuntimeDependencySet* runtimeDependencySet, + const cmInstallCommandArguments& runtimeArgs, + const cmInstallCommandArguments& libraryArgs, + const cmInstallCommandArguments& frameworkArgs, + RuntimeDependenciesArgs runtimeDependenciesArgs, bool& installsRuntime, + bool& installsLibrary, bool& installsFramework) +{ + bool dllPlatform = + !helper.Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX").empty(); + bool apple = + helper.Makefile->GetSafeDefinition("CMAKE_HOST_SYSTEM_NAME") == "Darwin"; + auto const& runtimeDependenciesArgsRef = + dllPlatform ? runtimeArgs : libraryArgs; + std::vector<std::string> configurations = + runtimeDependenciesArgsRef.GetConfigurations(); + if (apple) { + std::copy(frameworkArgs.GetConfigurations().begin(), + frameworkArgs.GetConfigurations().end(), + std::back_inserter(configurations)); + } + + // Create file(GET_RUNTIME_DEPENDENCIES) generator. + auto getRuntimeDependenciesGenerator = + cm::make_unique<cmInstallGetRuntimeDependenciesGenerator>( + runtimeDependencySet, std::move(runtimeDependenciesArgs.Directories), + std::move(runtimeDependenciesArgs.PreIncludeRegexes), + std::move(runtimeDependenciesArgs.PreExcludeRegexes), + std::move(runtimeDependenciesArgs.PostIncludeRegexes), + std::move(runtimeDependenciesArgs.PostExcludeRegexes), + std::move(runtimeDependenciesArgs.PostIncludeFiles), + std::move(runtimeDependenciesArgs.PostExcludeFiles), + runtimeDependenciesArgsRef.GetComponent(), + apple ? frameworkArgs.GetComponent() : "", true, "_CMAKE_DEPS", + "_CMAKE_RPATH", configurations, + cmInstallGenerator::SelectMessageLevel(helper.Makefile), + runtimeDependenciesArgsRef.GetExcludeFromAll() && + (apple ? frameworkArgs.GetExcludeFromAll() : true), + helper.Makefile->GetBacktrace()); + helper.Makefile->AddInstallGenerator( + std::move(getRuntimeDependenciesGenerator)); + + // Create the library dependencies generator. + auto libraryRuntimeDependenciesGenerator = + cm::make_unique<cmInstallRuntimeDependencySetGenerator>( + cmInstallRuntimeDependencySetGenerator::DependencyType::Library, + runtimeDependencySet, std::vector<std::string>{}, true, std::string{}, + true, "_CMAKE_DEPS", "_CMAKE_RPATH", "_CMAKE_TMP", + dllPlatform ? helper.GetRuntimeDestination(&runtimeArgs) + : helper.GetLibraryDestination(&libraryArgs), + runtimeDependenciesArgsRef.GetConfigurations(), + runtimeDependenciesArgsRef.GetComponent(), + runtimeDependenciesArgsRef.GetPermissions(), + cmInstallGenerator::SelectMessageLevel(helper.Makefile), + runtimeDependenciesArgsRef.GetExcludeFromAll(), + helper.Makefile->GetBacktrace()); + helper.Makefile->AddInstallGenerator( + std::move(libraryRuntimeDependenciesGenerator)); + if (dllPlatform) { + installsRuntime = true; + } else { + installsLibrary = true; + } + + if (apple) { + // Create the framework dependencies generator. + auto frameworkRuntimeDependenciesGenerator = + cm::make_unique<cmInstallRuntimeDependencySetGenerator>( + cmInstallRuntimeDependencySetGenerator::DependencyType::Framework, + runtimeDependencySet, std::vector<std::string>{}, true, std::string{}, + true, "_CMAKE_DEPS", "_CMAKE_RPATH", "_CMAKE_TMP", + frameworkArgs.GetDestination(), frameworkArgs.GetConfigurations(), + frameworkArgs.GetComponent(), frameworkArgs.GetPermissions(), + cmInstallGenerator::SelectMessageLevel(helper.Makefile), + frameworkArgs.GetExcludeFromAll(), helper.Makefile->GetBacktrace()); + helper.Makefile->AddInstallGenerator( + std::move(frameworkRuntimeDependenciesGenerator)); + installsFramework = true; + } +} + std::set<std::string> const allowedTypes{ "BIN", "SBIN", "LIB", "INCLUDE", "SYSCONF", "SHAREDSTATE", "LOCALSTATE", "RUNSTATE", "DATA", "INFO", "LOCALE", "MAN", "DOC", }; +template <typename T> +bool AddBundleExecutable(Helper& helper, + cmInstallRuntimeDependencySet* runtimeDependencySet, + T&& bundleExecutable) +{ + if (!runtimeDependencySet->AddBundleExecutable(bundleExecutable)) { + helper.SetError( + "A runtime dependency set may only have one bundle executable."); + return false; + } + return true; +} + bool HandleScriptMode(std::vector<std::string> const& args, cmExecutionStatus& status) { @@ -289,13 +412,23 @@ bool HandleTargetsMode(std::vector<std::string> const& args, // These generic args also contain the targets and the export stuff std::vector<std::string> targetList; std::string exports; + std::vector<std::string> runtimeDependenciesArgVector; std::vector<std::string> unknownArgs; + std::vector<std::string> parsedArgs; cmInstallCommandArguments genericArgs(helper.DefaultComponentName); genericArgs.Bind("TARGETS"_s, targetList); genericArgs.Bind("EXPORT"_s, exports); - genericArgs.Parse(genericArgVector, &unknownArgs); + genericArgs.Bind("RUNTIME_DEPENDENCIES"_s, runtimeDependenciesArgVector); + genericArgs.Parse(genericArgVector, &unknownArgs, nullptr, &parsedArgs); bool success = genericArgs.Finalize(); + bool withRuntimeDependencies = + std::find(parsedArgs.begin(), parsedArgs.end(), "RUNTIME_DEPENDENCIES") != + parsedArgs.end(); + RuntimeDependenciesArgs runtimeDependenciesArgs = + RuntimeDependenciesArgHelper.Parse(runtimeDependenciesArgVector, + &unknownArgs); + cmInstallCommandArguments archiveArgs(helper.DefaultComponentName); cmInstallCommandArguments libraryArgs(helper.DefaultComponentName); cmInstallCommandArguments runtimeArgs(helper.DefaultComponentName); @@ -402,6 +535,32 @@ bool HandleTargetsMode(std::vector<std::string> const& args, return false; } + cmInstallRuntimeDependencySet* runtimeDependencySet = nullptr; + if (withRuntimeDependencies) { + auto system = helper.Makefile->GetSafeDefinition("CMAKE_HOST_SYSTEM_NAME"); + if (!cmRuntimeDependencyArchive::PlatformSupportsRuntimeDependencies( + system)) { + status.SetError( + cmStrCat("TARGETS RUNTIME_DEPENDENCIES is not supported on system \"", + system, '"')); + return false; + } + if (helper.Makefile->IsOn("CMAKE_CROSSCOMPILING")) { + status.SetError("TARGETS RUNTIME_DEPENDENCIES is not supported " + "when cross-compiling."); + return false; + } + if (helper.Makefile->GetSafeDefinition("CMAKE_HOST_SYSTEM_NAME") == + "Darwin" && + frameworkArgs.GetDestination().empty()) { + status.SetError( + "TARGETS RUNTIME_DEPENDENCIES given no FRAMEWORK DESTINATION"); + return false; + } + runtimeDependencySet = helper.Makefile->GetGlobalGenerator() + ->CreateAnonymousRuntimeDependencySet(); + } + // Select the mode for installing symlinks to versioned shared libraries. cmInstallTargetGenerator::NamelinkModeType namelinkMode = cmInstallTargetGenerator::NamelinkModeNone; @@ -546,6 +705,9 @@ bool HandleTargetsMode(std::vector<std::string> const& args, target, runtimeArgs, false, helper.Makefile->GetBacktrace(), helper.GetRuntimeDestination(nullptr)); } + if (runtimeDependencySet && runtimeGenerator) { + runtimeDependencySet->AddLibrary(runtimeGenerator.get()); + } } else { // This is a non-DLL platform. // If it is marked with FRAMEWORK property use the FRAMEWORK set of @@ -591,6 +753,9 @@ bool HandleTargetsMode(std::vector<std::string> const& args, namelinkOnly = (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly); } + if (runtimeDependencySet && libraryGenerator) { + runtimeDependencySet->AddLibrary(libraryGenerator.get()); + } } } break; case cmStateEnums::STATIC_LIBRARY: { @@ -633,6 +798,9 @@ bool HandleTargetsMode(std::vector<std::string> const& args, libraryGenerator->SetNamelinkMode(namelinkMode); namelinkOnly = (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly); + if (runtimeDependencySet) { + runtimeDependencySet->AddModule(libraryGenerator.get()); + } } else { status.SetError( cmStrCat("TARGETS given no LIBRARY DESTINATION for module " @@ -685,6 +853,12 @@ bool HandleTargetsMode(std::vector<std::string> const& args, target.GetName(), "\".")); return false; } + if (runtimeDependencySet) { + if (!AddBundleExecutable(helper, runtimeDependencySet, + bundleGenerator.get())) { + return false; + } + } } else { // Executables use the RUNTIME properties. if (!runtimeArgs.GetDestination().empty()) { @@ -693,6 +867,9 @@ bool HandleTargetsMode(std::vector<std::string> const& args, runtimeGenerator = CreateInstallTargetGenerator( target, runtimeArgs, false, helper.Makefile->GetBacktrace(), helper.GetRuntimeDestination(&runtimeArgs)); + if (runtimeDependencySet) { + runtimeDependencySet->AddExecutable(runtimeGenerator.get()); + } } // On DLL platforms an executable may also have an import @@ -821,6 +998,13 @@ bool HandleTargetsMode(std::vector<std::string> const& args, helper.Makefile->AddInstallGenerator(std::move(resourceGenerator)); } + if (withRuntimeDependencies && !runtimeDependencySet->Empty()) { + AddInstallRuntimeDependenciesGenerator( + helper, runtimeDependencySet, runtimeArgs, libraryArgs, frameworkArgs, + std::move(runtimeDependenciesArgs), installsRuntime, installsLibrary, + installsFramework); + } + // Tell the global generator about any installation component names // specified if (installsArchive) { |