diff options
author | Kyle Edwards <kyle.edwards@kitware.com> | 2021-06-17 21:01:28 (GMT) |
---|---|---|
committer | Kyle Edwards <kyle.edwards@kitware.com> | 2021-10-27 19:17:23 (GMT) |
commit | 9b479124cc4be49a4b2c6e45e733b489f7a26432 (patch) | |
tree | c8ca0ce69ed5706d20cfc08a486507c58905233c /Source/cmInstallCommand.cxx | |
parent | d8af2d954f8619f0e8bc42252d310085dec94df4 (diff) | |
download | CMake-9b479124cc4be49a4b2c6e45e733b489f7a26432.zip CMake-9b479124cc4be49a4b2c6e45e733b489f7a26432.tar.gz CMake-9b479124cc4be49a4b2c6e45e733b489f7a26432.tar.bz2 |
install(TARGETS): Add FILE_SET mode
Diffstat (limited to 'Source/cmInstallCommand.cxx')
-rw-r--r-- | Source/cmInstallCommand.cxx | 119 |
1 files changed, 112 insertions, 7 deletions
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index eaf88f6..08c308d 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -6,11 +6,13 @@ #include <cassert> #include <cstddef> #include <iterator> +#include <map> #include <set> #include <sstream> #include <utility> #include <cm/memory> +#include <cm/string_view> #include <cmext/string_view> #include "cmsys/Glob.hxx" @@ -18,11 +20,13 @@ #include "cmArgumentParser.h" #include "cmExecutionStatus.h" #include "cmExportSet.h" +#include "cmFileSet.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmInstallCommandArguments.h" #include "cmInstallDirectoryGenerator.h" #include "cmInstallExportGenerator.h" +#include "cmInstallFileSetGenerator.h" #include "cmInstallFilesGenerator.h" #include "cmInstallGenerator.h" #include "cmInstallGetRuntimeDependenciesGenerator.h" @@ -89,6 +93,9 @@ public: bool MakeFilesFullPath(const char* modeName, const std::vector<std::string>& relFiles, std::vector<std::string>& absFiles); + bool MakeFilesFullPath(const char* modeName, const std::string& basePath, + const std::vector<std::string>& relFiles, + std::vector<std::string>& absFiles); bool CheckCMP0006(bool& failure) const; std::string GetDestination(const cmInstallCommandArguments* args, @@ -177,6 +184,19 @@ std::unique_ptr<cmInstallFilesGenerator> CreateInstallFilesGenerator( args.GetDestination()); } +std::unique_ptr<cmInstallFileSetGenerator> CreateInstallFileSetGenerator( + Helper& helper, cmTarget& target, cmFileSet* fileSet, + const std::string& destination, const cmInstallCommandArguments& args) +{ + cmInstallGenerator::MessageLevel message = + cmInstallGenerator::SelectMessageLevel(helper.Makefile); + return cm::make_unique<cmInstallFileSetGenerator>( + target.GetName(), fileSet, destination, args.GetPermissions(), + args.GetConfigurations(), args.GetComponent(), message, + args.GetExcludeFromAll(), args.GetOptional(), + helper.Makefile->GetBacktrace()); +} + void AddInstallRuntimeDependenciesGenerator( Helper& helper, cmInstallRuntimeDependencySet* runtimeDependencySet, const cmInstallCommandArguments& runtimeArgs, @@ -390,6 +410,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args, std::vector<std::string> PrivateHeader; std::vector<std::string> PublicHeader; std::vector<std::string> Resource; + std::vector<std::vector<std::string>> FileSets; }; static auto const argHelper = @@ -403,7 +424,8 @@ bool HandleTargetsMode(std::vector<std::string> const& args, .Bind("INCLUDES"_s, &ArgVectors::Includes) .Bind("PRIVATE_HEADER"_s, &ArgVectors::PrivateHeader) .Bind("PUBLIC_HEADER"_s, &ArgVectors::PublicHeader) - .Bind("RESOURCE"_s, &ArgVectors::Resource); + .Bind("RESOURCE"_s, &ArgVectors::Resource) + .Bind("FILE_SET"_s, &ArgVectors::FileSets); std::vector<std::string> genericArgVector; ArgVectors const argVectors = argHelper.Parse(args, &genericArgVector); @@ -442,6 +464,8 @@ bool HandleTargetsMode(std::vector<std::string> const& args, cmInstallCommandArguments publicHeaderArgs(helper.DefaultComponentName); cmInstallCommandArguments resourceArgs(helper.DefaultComponentName); cmInstallCommandIncludesArgument includesArgs; + std::vector<cmInstallCommandFileSetArguments> fileSetArgs( + argVectors.FileSets.size(), { helper.DefaultComponentName }); // now parse the args for specific parts of the target (e.g. LIBRARY, // RUNTIME, ARCHIVE etc. @@ -455,6 +479,15 @@ bool HandleTargetsMode(std::vector<std::string> const& args, publicHeaderArgs.Parse(argVectors.PublicHeader, &unknownArgs); resourceArgs.Parse(argVectors.Resource, &unknownArgs); includesArgs.Parse(&argVectors.Includes, &unknownArgs); + for (std::size_t i = 0; i < argVectors.FileSets.size(); i++) { + // We have to create a separate object for the parsing because + // cmArgumentParser<void>::Bind() binds to a specific address, but the + // objects in the vector can move around. So we parse in an object with a + // fixed address and then copy the data into the vector. + cmInstallCommandFileSetArguments fileSetArg(helper.DefaultComponentName); + fileSetArg.Parse(argVectors.FileSets[i], &unknownArgs); + fileSetArgs[i] = std::move(fileSetArg); + } if (!unknownArgs.empty()) { // Unknown argument. @@ -473,6 +506,9 @@ bool HandleTargetsMode(std::vector<std::string> const& args, privateHeaderArgs.SetGenericArguments(&genericArgs); publicHeaderArgs.SetGenericArguments(&genericArgs); resourceArgs.SetGenericArguments(&genericArgs); + for (auto& fileSetArg : fileSetArgs) { + fileSetArg.SetGenericArguments(&genericArgs); + } success = success && archiveArgs.Finalize(); success = success && libraryArgs.Finalize(); @@ -483,6 +519,9 @@ bool HandleTargetsMode(std::vector<std::string> const& args, success = success && privateHeaderArgs.Finalize(); success = success && publicHeaderArgs.Finalize(); success = success && resourceArgs.Finalize(); + for (auto& fileSetArg : fileSetArgs) { + success = success && fileSetArg.Finalize(); + } if (!success) { return false; @@ -493,7 +532,10 @@ bool HandleTargetsMode(std::vector<std::string> const& args, if (archiveArgs.GetNamelinkOnly() || runtimeArgs.GetNamelinkOnly() || objectArgs.GetNamelinkOnly() || frameworkArgs.GetNamelinkOnly() || bundleArgs.GetNamelinkOnly() || privateHeaderArgs.GetNamelinkOnly() || - publicHeaderArgs.GetNamelinkOnly() || resourceArgs.GetNamelinkOnly()) { + publicHeaderArgs.GetNamelinkOnly() || resourceArgs.GetNamelinkOnly() || + std::any_of(fileSetArgs.begin(), fileSetArgs.end(), + [](const cmInstallCommandFileSetArguments& fileSetArg) + -> bool { return fileSetArg.GetNamelinkOnly(); })) { status.SetError( "TARGETS given NAMELINK_ONLY option not in LIBRARY group. " "The NAMELINK_ONLY option may be specified only following LIBRARY."); @@ -502,7 +544,10 @@ bool HandleTargetsMode(std::vector<std::string> const& args, if (archiveArgs.GetNamelinkSkip() || runtimeArgs.GetNamelinkSkip() || objectArgs.GetNamelinkSkip() || frameworkArgs.GetNamelinkSkip() || bundleArgs.GetNamelinkSkip() || privateHeaderArgs.GetNamelinkSkip() || - publicHeaderArgs.GetNamelinkSkip() || resourceArgs.GetNamelinkSkip()) { + publicHeaderArgs.GetNamelinkSkip() || resourceArgs.GetNamelinkSkip() || + std::any_of(fileSetArgs.begin(), fileSetArgs.end(), + [](const cmInstallCommandFileSetArguments& fileSetArg) + -> bool { return fileSetArg.GetNamelinkSkip(); })) { status.SetError( "TARGETS given NAMELINK_SKIP option not in LIBRARY group. " "The NAMELINK_SKIP option may be specified only following LIBRARY."); @@ -515,7 +560,10 @@ bool HandleTargetsMode(std::vector<std::string> const& args, bundleArgs.HasNamelinkComponent() || privateHeaderArgs.HasNamelinkComponent() || publicHeaderArgs.HasNamelinkComponent() || - resourceArgs.HasNamelinkComponent()) { + resourceArgs.HasNamelinkComponent() || + std::any_of(fileSetArgs.begin(), fileSetArgs.end(), + [](const cmInstallCommandFileSetArguments& fileSetArg) + -> bool { return fileSetArg.HasNamelinkComponent(); })) { status.SetError( "TARGETS given NAMELINK_COMPONENT option not in LIBRARY group. " "The NAMELINK_COMPONENT option may be specified only following " @@ -531,12 +579,21 @@ bool HandleTargetsMode(std::vector<std::string> const& args, !libraryArgs.GetType().empty() || !runtimeArgs.GetType().empty() || !objectArgs.GetType().empty() || !frameworkArgs.GetType().empty() || !bundleArgs.GetType().empty() || !privateHeaderArgs.GetType().empty() || - !publicHeaderArgs.GetType().empty() || !resourceArgs.GetType().empty()) { + !publicHeaderArgs.GetType().empty() || !resourceArgs.GetType().empty() || + std::any_of(fileSetArgs.begin(), fileSetArgs.end(), + [](const cmInstallCommandFileSetArguments& fileSetArg) + -> bool { return !fileSetArg.GetType().empty(); })) { status.SetError( "TARGETS given TYPE option. The TYPE option may only be specified in " " install(FILES) and install(DIRECTORIES)."); return false; } + if (std::any_of(fileSetArgs.begin(), fileSetArgs.end(), + [](const cmInstallCommandFileSetArguments& fileSetArg) + -> bool { return fileSetArg.GetFileSet().empty(); })) { + status.SetError("TARGETS given FILE_SET option without file set name."); + return false; + } cmInstallRuntimeDependencySet* runtimeDependencySet = nullptr; if (withRuntimeDependencies) { @@ -647,6 +704,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args, bool installsPrivateHeader = false; bool installsPublicHeader = false; bool installsResource = false; + std::vector<bool> installsFileSet(fileSetArgs.size(), false); // Generate install script code to install the given targets. for (cmTarget* ti : targets) { @@ -662,6 +720,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args, std::unique_ptr<cmInstallFilesGenerator> privateHeaderGenerator; std::unique_ptr<cmInstallFilesGenerator> publicHeaderGenerator; std::unique_ptr<cmInstallFilesGenerator> resourceGenerator; + std::vector<std::unique_ptr<cmInstallFileSetGenerator>> fileSetGenerators; // Avoid selecting default destinations for PUBLIC_HEADER and // PRIVATE_HEADER if any artifacts are specified. @@ -991,6 +1050,35 @@ bool HandleTargetsMode(std::vector<std::string> const& args, } } + if (!namelinkOnly) { + for (std::size_t i = 0; i < fileSetArgs.size(); i++) { + auto* fileSet = target.GetFileSet(fileSetArgs[i].GetFileSet()); + auto interfaceFileSetEntries = cmExpandedList(target.GetSafeProperty( + cmTarget::GetInterfaceFileSetsPropertyName(fileSet->GetType()))); + if (fileSet && + std::find( + interfaceFileSetEntries.begin(), interfaceFileSetEntries.end(), + fileSetArgs[i].GetFileSet()) != interfaceFileSetEntries.end()) { + std::string destination; + if (fileSet->GetType() == "HEADERS"_s) { + destination = helper.GetIncludeDestination(&fileSetArgs[i]); + } else { + destination = fileSetArgs[i].GetDestination(); + if (destination.empty()) { + status.SetError( + cmStrCat("TARGETS given no FILE_SET DESTINATION for target \"", + target.GetName(), "\" file set \"", + fileSet->GetName(), "\".")); + return false; + } + } + fileSetGenerators.push_back(CreateInstallFileSetGenerator( + helper, target, fileSet, destination, fileSetArgs[i])); + installsFileSet[i] = true; + } + } + } + // Add this install rule to an export if one was specified. addTargetExport(); @@ -1016,6 +1104,9 @@ bool HandleTargetsMode(std::vector<std::string> const& args, helper.Makefile->AddInstallGenerator(std::move(privateHeaderGenerator)); helper.Makefile->AddInstallGenerator(std::move(publicHeaderGenerator)); helper.Makefile->AddInstallGenerator(std::move(resourceGenerator)); + for (auto& gen : fileSetGenerators) { + helper.Makefile->AddInstallGenerator(std::move(gen)); + } } if (withRuntimeDependencies && !runtimeDependencySet->Empty()) { @@ -1067,6 +1158,12 @@ bool HandleTargetsMode(std::vector<std::string> const& args, helper.Makefile->GetGlobalGenerator()->AddInstallComponent( resourceArgs.GetComponent()); } + for (std::size_t i = 0; i < fileSetArgs.size(); i++) { + if (installsFileSet[i]) { + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( + fileSetArgs[i].GetComponent()); + } + } return true; } @@ -2063,12 +2160,20 @@ bool Helper::MakeFilesFullPath(const char* modeName, const std::vector<std::string>& relFiles, std::vector<std::string>& absFiles) { + return this->MakeFilesFullPath( + modeName, this->Makefile->GetCurrentSourceDirectory(), relFiles, absFiles); +} + +bool Helper::MakeFilesFullPath(const char* modeName, + const std::string& basePath, + const std::vector<std::string>& relFiles, + std::vector<std::string>& absFiles) +{ for (std::string const& relFile : relFiles) { std::string file = relFile; std::string::size_type gpos = cmGeneratorExpression::Find(file); if (gpos != 0 && !cmSystemTools::FileIsFullPath(file)) { - file = - cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', relFile); + file = cmStrCat(basePath, '/', relFile); } // Make sure the file is not a directory. |