diff options
author | Kyle Edwards <kyle.edwards@kitware.com> | 2021-05-26 17:30:32 (GMT) |
---|---|---|
committer | Kyle Edwards <kyle.edwards@kitware.com> | 2021-05-31 13:02:45 (GMT) |
commit | df7040a2718a0de2b074a6e55c5ce960d85d8d6f (patch) | |
tree | 09d73aac24b53ef435735307fb125c9fad68e68c /Source/cmInstallCommand.cxx | |
parent | 60e752ced8e9b604591082ee3b21d545fafa8ad8 (diff) | |
download | CMake-df7040a2718a0de2b074a6e55c5ce960d85d8d6f.zip CMake-df7040a2718a0de2b074a6e55c5ce960d85d8d6f.tar.gz CMake-df7040a2718a0de2b074a6e55c5ce960d85d8d6f.tar.bz2 |
install(): Add IMPORTED_RUNTIME_ARTIFACTS mode
Diffstat (limited to 'Source/cmInstallCommand.cxx')
-rw-r--r-- | Source/cmInstallCommand.cxx | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index e973764..c9bb467 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmInstallCommand.h" +#include <cassert> #include <cstddef> #include <set> #include <sstream> @@ -22,6 +23,7 @@ #include "cmInstallExportGenerator.h" #include "cmInstallFilesGenerator.h" #include "cmInstallGenerator.h" +#include "cmInstallImportedRuntimeArtifactsGenerator.h" #include "cmInstallScriptGenerator.h" #include "cmInstallTargetGenerator.h" #include "cmListFileCache.h" @@ -865,6 +867,227 @@ bool HandleTargetsMode(std::vector<std::string> const& args, return true; } +bool HandleImportedRuntimeArtifactsMode(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + Helper helper(status); + + // This is the IMPORTED_RUNTIME_ARTIFACTS mode. + std::vector<cmTarget*> targets; + + struct ArgVectors + { + std::vector<std::string> Library; + std::vector<std::string> Runtime; + std::vector<std::string> Framework; + std::vector<std::string> Bundle; + }; + + static auto const argHelper = cmArgumentParser<ArgVectors>{} + .Bind("LIBRARY"_s, &ArgVectors::Library) + .Bind("RUNTIME"_s, &ArgVectors::Runtime) + .Bind("FRAMEWORK"_s, &ArgVectors::Framework) + .Bind("BUNDLE"_s, &ArgVectors::Bundle); + + std::vector<std::string> genericArgVector; + ArgVectors const argVectors = argHelper.Parse(args, &genericArgVector); + + // now parse the generic args (i.e. the ones not specialized on LIBRARY, + // RUNTIME etc. (see above) + std::vector<std::string> targetList; + std::vector<std::string> unknownArgs; + cmInstallCommandArguments genericArgs(helper.DefaultComponentName); + genericArgs.Bind("IMPORTED_RUNTIME_ARTIFACTS"_s, targetList); + genericArgs.Parse(genericArgVector, &unknownArgs); + bool success = genericArgs.Finalize(); + + cmInstallCommandArguments libraryArgs(helper.DefaultComponentName); + cmInstallCommandArguments runtimeArgs(helper.DefaultComponentName); + cmInstallCommandArguments frameworkArgs(helper.DefaultComponentName); + cmInstallCommandArguments bundleArgs(helper.DefaultComponentName); + + // now parse the args for specific parts of the target (e.g. LIBRARY, + // RUNTIME etc. + libraryArgs.Parse(argVectors.Library, &unknownArgs); + runtimeArgs.Parse(argVectors.Runtime, &unknownArgs); + frameworkArgs.Parse(argVectors.Framework, &unknownArgs); + bundleArgs.Parse(argVectors.Bundle, &unknownArgs); + + if (!unknownArgs.empty()) { + // Unknown argument. + status.SetError( + cmStrCat("IMPORTED_RUNTIME_ARTIFACTS given unknown argument \"", + unknownArgs[0], "\".")); + return false; + } + + // apply generic args + libraryArgs.SetGenericArguments(&genericArgs); + runtimeArgs.SetGenericArguments(&genericArgs); + frameworkArgs.SetGenericArguments(&genericArgs); + bundleArgs.SetGenericArguments(&genericArgs); + + success = success && libraryArgs.Finalize(); + success = success && runtimeArgs.Finalize(); + success = success && frameworkArgs.Finalize(); + success = success && bundleArgs.Finalize(); + + if (!success) { + return false; + } + + // Check if there is something to do. + if (targetList.empty()) { + return true; + } + + for (std::string const& tgt : targetList) { + if (helper.Makefile->IsAlias(tgt)) { + status.SetError(cmStrCat("IMPORTED_RUNTIME_ARTIFACTS given target \"", + tgt, "\" which is an alias.")); + return false; + } + // Lookup this target in the current directory. + cmTarget* target = helper.Makefile->FindTargetToUse(tgt); + if (!target || !target->IsImported()) { + // If no local target has been found, find it in the global scope. + cmTarget* const global_target = + helper.Makefile->GetGlobalGenerator()->FindTarget(tgt, true); + if (global_target && global_target->IsImported()) { + target = global_target; + } + } + if (target) { + // Found the target. Check its type. + if (target->GetType() != cmStateEnums::EXECUTABLE && + target->GetType() != cmStateEnums::SHARED_LIBRARY && + target->GetType() != cmStateEnums::MODULE_LIBRARY) { + status.SetError( + cmStrCat("IMPORTED_RUNTIME_ARTIFACTS given target \"", tgt, + "\" which is not an executable, library, or module.")); + return false; + } + // Store the target in the list to be installed. + targets.push_back(target); + } else { + // Did not find the target. + status.SetError(cmStrCat("IMPORTED_RUNTIME_ARTIFACTS given target \"", + tgt, "\" which does not exist.")); + return false; + } + } + + // Keep track of whether we will be performing an installation of + // any files of the given type. + bool installsLibrary = false; + bool installsRuntime = false; + bool installsFramework = false; + bool installsBundle = false; + + auto const createInstallGenerator = + [helper](cmTarget& target, const cmInstallCommandArguments& typeArgs, + const std::string& destination) + -> std::unique_ptr<cmInstallImportedRuntimeArtifactsGenerator> { + return cm::make_unique<cmInstallImportedRuntimeArtifactsGenerator>( + target.GetName(), destination, typeArgs.GetPermissions(), + typeArgs.GetConfigurations(), typeArgs.GetComponent(), + cmInstallGenerator::SelectMessageLevel(helper.Makefile), + typeArgs.GetExcludeFromAll(), typeArgs.GetOptional(), + helper.Makefile->GetBacktrace()); + }; + + // Generate install script code to install the given targets. + for (cmTarget* ti : targets) { + // Handle each target type. + cmTarget& target = *ti; + std::unique_ptr<cmInstallImportedRuntimeArtifactsGenerator> + libraryGenerator; + std::unique_ptr<cmInstallImportedRuntimeArtifactsGenerator> + runtimeGenerator; + std::unique_ptr<cmInstallImportedRuntimeArtifactsGenerator> + frameworkGenerator; + std::unique_ptr<cmInstallImportedRuntimeArtifactsGenerator> + bundleGenerator; + + switch (target.GetType()) { + case cmStateEnums::SHARED_LIBRARY: + if (target.IsDLLPlatform()) { + runtimeGenerator = createInstallGenerator( + target, runtimeArgs, helper.GetRuntimeDestination(&runtimeArgs)); + } else if (target.IsFrameworkOnApple()) { + if (frameworkArgs.GetDestination().empty()) { + status.SetError(cmStrCat("IMPORTED_RUNTIME_ARTIFACTS given no " + "FRAMEWORK DESTINATION for shared " + "library FRAMEWORK target \"", + target.GetName(), "\".")); + return false; + } + frameworkGenerator = createInstallGenerator( + target, frameworkArgs, frameworkArgs.GetDestination()); + } else { + libraryGenerator = createInstallGenerator( + target, libraryArgs, helper.GetLibraryDestination(&libraryArgs)); + } + break; + case cmStateEnums::MODULE_LIBRARY: + libraryGenerator = createInstallGenerator( + target, libraryArgs, helper.GetLibraryDestination(&libraryArgs)); + break; + case cmStateEnums::EXECUTABLE: + if (target.IsAppBundleOnApple()) { + if (bundleArgs.GetDestination().empty()) { + status.SetError( + cmStrCat("IMPORTED_RUNTIME_ARTIFACTS given no BUNDLE " + "DESTINATION for MACOSX_BUNDLE executable target \"", + target.GetName(), "\".")); + return false; + } + bundleGenerator = createInstallGenerator( + target, bundleArgs, bundleArgs.GetDestination()); + } else { + runtimeGenerator = createInstallGenerator( + target, runtimeArgs, helper.GetRuntimeDestination(&runtimeArgs)); + } + break; + default: + assert(false && "This should never happen"); + break; + } + + // Keep track of whether we're installing anything in each category + installsLibrary = installsLibrary || libraryGenerator; + installsRuntime = installsRuntime || runtimeGenerator; + installsFramework = installsFramework || frameworkGenerator; + installsBundle = installsBundle || bundleGenerator; + + helper.Makefile->AddInstallGenerator(std::move(libraryGenerator)); + helper.Makefile->AddInstallGenerator(std::move(runtimeGenerator)); + helper.Makefile->AddInstallGenerator(std::move(frameworkGenerator)); + helper.Makefile->AddInstallGenerator(std::move(bundleGenerator)); + } + + // Tell the global generator about any installation component names + // specified + if (installsLibrary) { + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( + libraryArgs.GetComponent()); + } + if (installsRuntime) { + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( + runtimeArgs.GetComponent()); + } + if (installsFramework) { + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( + frameworkArgs.GetComponent()); + } + if (installsBundle) { + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( + bundleArgs.GetComponent()); + } + + return true; +} + bool HandleFilesMode(std::vector<std::string> const& args, cmExecutionStatus& status) { @@ -1705,6 +1928,7 @@ bool cmInstallCommand(std::vector<std::string> const& args, { "SCRIPT"_s, HandleScriptMode }, { "CODE"_s, HandleScriptMode }, { "TARGETS"_s, HandleTargetsMode }, + { "IMPORTED_RUNTIME_ARTIFACTS"_s, HandleImportedRuntimeArtifactsMode }, { "FILES"_s, HandleFilesMode }, { "PROGRAMS"_s, HandleFilesMode }, { "DIRECTORY"_s, HandleDirectoryMode }, |