summaryrefslogtreecommitdiffstats
path: root/Source/cmInstallCommand.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmInstallCommand.cxx')
-rw-r--r--Source/cmInstallCommand.cxx186
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) {