diff options
author | Brad King <brad.king@kitware.com> | 2019-09-24 14:27:06 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2019-09-24 14:27:17 (GMT) |
commit | c4afe766f70e42f6d293f9626093049443f8962b (patch) | |
tree | 469f03275ec6de8c09497efc0be8b0bf627579d2 /Source | |
parent | a3492c094a4288ede26225e4a06d5d8175936ed1 (diff) | |
parent | 920f0dd83ad473d291e5ceb519ed7155ca92168a (diff) | |
download | CMake-c4afe766f70e42f6d293f9626093049443f8962b.zip CMake-c4afe766f70e42f6d293f9626093049443f8962b.tar.gz CMake-c4afe766f70e42f6d293f9626093049443f8962b.tar.bz2 |
Merge topic 'free-free-set-them-free'
920f0dd83a cmInstallCommand: Port away from cmCommand
1dd31297ca cmTargetLinkLibrariesCommand: Port away from cmCommand
d5c63f073f cmSourceGroupCommand: Port away from cmCommand
42e413bcbb cmSetTargetPropertiesCommand: Port away from cmCommand
77aa75b8dc cmProjectCommand: Port away from cmCommand
9c521088df cmLoadCacheCommand: Port away from cmCommand
fcfec154ac cmLinkDirectoriesCommand: Port away from cmCommand
d038beec21 cmIncludeDirectoryCommand: Port away from cmCommand
...
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !3829
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmCommands.cxx | 22 | ||||
-rw-r--r-- | Source/cmExportCommand.cxx | 103 | ||||
-rw-r--r-- | Source/cmExportCommand.h | 33 | ||||
-rw-r--r-- | Source/cmIncludeDirectoryCommand.cxx | 44 | ||||
-rw-r--r-- | Source/cmIncludeDirectoryCommand.h | 35 | ||||
-rw-r--r-- | Source/cmInstallCommand.cxx | 594 | ||||
-rw-r--r-- | Source/cmInstallCommand.h | 66 | ||||
-rw-r--r-- | Source/cmLinkDirectoriesCommand.cxx | 30 | ||||
-rw-r--r-- | Source/cmLinkDirectoriesCommand.h | 36 | ||||
-rw-r--r-- | Source/cmLoadCacheCommand.cxx | 52 | ||||
-rw-r--r-- | Source/cmLoadCacheCommand.h | 37 | ||||
-rw-r--r-- | Source/cmProjectCommand.cxx | 196 | ||||
-rw-r--r-- | Source/cmProjectCommand.h | 36 | ||||
-rw-r--r-- | Source/cmSetTargetPropertiesCommand.cxx | 44 | ||||
-rw-r--r-- | Source/cmSetTargetPropertiesCommand.h | 29 | ||||
-rw-r--r-- | Source/cmSourceGroupCommand.cxx | 80 | ||||
-rw-r--r-- | Source/cmSourceGroupCommand.h | 51 | ||||
-rw-r--r-- | Source/cmTargetLinkLibrariesCommand.cxx | 261 | ||||
-rw-r--r-- | Source/cmTargetLinkLibrariesCommand.h | 56 |
19 files changed, 763 insertions, 1042 deletions
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx index 262590b..88d17f1 100644 --- a/Source/cmCommands.cxx +++ b/Source/cmCommands.cxx @@ -231,20 +231,18 @@ void GetProjectCommands(cmState* state) cmGetSourceFilePropertyCommand); state->AddBuiltinCommand("get_target_property", cmGetTargetPropertyCommand); state->AddBuiltinCommand("get_test_property", cmGetTestPropertyCommand); - state->AddBuiltinCommand("include_directories", - cm::make_unique<cmIncludeDirectoryCommand>()); + state->AddBuiltinCommand("include_directories", cmIncludeDirectoryCommand); state->AddBuiltinCommand("include_regular_expression", cmIncludeRegularExpressionCommand); - state->AddBuiltinCommand("install", cm::make_unique<cmInstallCommand>()); + state->AddBuiltinCommand("install", cmInstallCommand); state->AddBuiltinCommand("install_files", cmInstallFilesCommand); state->AddBuiltinCommand("install_targets", cmInstallTargetsCommand); - state->AddBuiltinCommand("link_directories", - cm::make_unique<cmLinkDirectoriesCommand>()); - state->AddBuiltinCommand("project", cm::make_unique<cmProjectCommand>()); + state->AddBuiltinCommand("link_directories", cmLinkDirectoriesCommand); + state->AddBuiltinCommand("project", cmProjectCommand); state->AddBuiltinCommand("set_source_files_properties", cmSetSourceFilesPropertiesCommand); state->AddBuiltinCommand("set_target_properties", - cm::make_unique<cmSetTargetPropertiesCommand>()); + cmSetTargetPropertiesCommand); state->AddBuiltinCommand("set_tests_properties", cmSetTestsPropertiesCommand); state->AddBuiltinCommand("subdirs", cmSubdirCommand); @@ -259,7 +257,7 @@ void GetProjectCommands(cmState* state) "target_include_directories", cm::make_unique<cmTargetIncludeDirectoriesCommand>()); state->AddBuiltinCommand("target_link_libraries", - cm::make_unique<cmTargetLinkLibrariesCommand>()); + cmTargetLinkLibrariesCommand); state->AddBuiltinCommand("target_sources", cm::make_unique<cmTargetSourcesCommand>()); state->AddBuiltinCommand("try_compile", @@ -275,7 +273,7 @@ void GetProjectCommands(cmState* state) state->AddBuiltinCommand("add_compile_options", cmAddCompileOptionsCommand); state->AddBuiltinCommand("aux_source_directory", cmAuxSourceDirectoryCommand); - state->AddBuiltinCommand("export", cm::make_unique<cmExportCommand>()); + state->AddBuiltinCommand("export", cmExportCommand); state->AddBuiltinCommand("fltk_wrap_ui", cmFLTKWrapUICommand); state->AddBuiltinCommand("include_external_msproject", cmIncludeExternalMSProjectCommand); @@ -286,13 +284,11 @@ void GetProjectCommands(cmState* state) cm::make_unique<cmTargetLinkOptionsCommand>()); state->AddBuiltinCommand("target_link_directories", cm::make_unique<cmTargetLinkDirectoriesCommand>()); - state->AddBuiltinCommand("load_cache", - cm::make_unique<cmLoadCacheCommand>()); + state->AddBuiltinCommand("load_cache", cmLoadCacheCommand); state->AddBuiltinCommand("qt_wrap_cpp", cmQTWrapCPPCommand); state->AddBuiltinCommand("qt_wrap_ui", cmQTWrapUICommand); state->AddBuiltinCommand("remove_definitions", cmRemoveDefinitionsCommand); - state->AddBuiltinCommand("source_group", - cm::make_unique<cmSourceGroupCommand>()); + state->AddBuiltinCommand("source_group", cmSourceGroupCommand); state->AddDisallowedCommand( "export_library_dependencies", cmExportLibraryDependenciesCommand, diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx index 2713856..79af6e9 100644 --- a/Source/cmExportCommand.cxx +++ b/Source/cmExportCommand.cxx @@ -11,6 +11,7 @@ #include "cmAlgorithms.h" #include "cmArgumentParser.h" +#include "cmExecutionStatus.h" #include "cmExportBuildAndroidMKGenerator.h" #include "cmExportBuildFileGenerator.h" #include "cmExportSet.h" @@ -23,23 +24,31 @@ #include "cmSystemTools.h" #include "cmTarget.h" -class cmExecutionStatus; - #if defined(__HAIKU__) # include <FindDirectory.h> # include <StorageDefs.h> #endif -bool cmExportCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +#if defined(_WIN32) && !defined(__CYGWIN__) +# include <windows.h> +#endif + +static bool HandlePackage(std::vector<std::string> const& args, + cmExecutionStatus& status); + +static void StorePackageRegistry(cmMakefile& mf, std::string const& package, + const char* content, const char* hash); + +bool cmExportCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 2) { - this->SetError("called with too few arguments"); + status.SetError("called with too few arguments"); return false; } if (args[0] == "PACKAGE") { - return this->HandlePackage(args); + return HandlePackage(args, status); } struct Arguments @@ -72,7 +81,7 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args, parser.Parse(args, &unknownArgs, &keywordsMissingValue); if (!unknownArgs.empty()) { - this->SetError("Unknown argument: \"" + unknownArgs.front() + "\"."); + status.SetError("Unknown argument: \"" + unknownArgs.front() + "\"."); return false; } @@ -84,7 +93,7 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args, } if (arguments.Filename.empty() && fname.empty()) { if (args[0] != "EXPORT") { - this->SetError("FILE <filename> option missing."); + status.SetError("FILE <filename> option missing."); return false; } fname = arguments.ExportSetName + ".cmake"; @@ -95,30 +104,32 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args, std::ostringstream e; e << "FILE option given filename \"" << arguments.Filename << "\" which does not have an extension of \".cmake\".\n"; - this->SetError(e.str()); + status.SetError(e.str()); return false; } fname = arguments.Filename; } + cmMakefile& mf = status.GetMakefile(); + // Get the file to write. if (cmSystemTools::FileIsFullPath(fname)) { - if (!this->Makefile->CanIWriteThisFile(fname)) { + if (!mf.CanIWriteThisFile(fname)) { std::ostringstream e; e << "FILE option given filename \"" << fname << "\" which is in the source tree.\n"; - this->SetError(e.str()); + status.SetError(e.str()); return false; } } else { // Interpret relative paths with respect to the current build dir. - std::string dir = this->Makefile->GetCurrentBinaryDirectory(); + std::string const& dir = mf.GetCurrentBinaryDirectory(); fname = dir + "/" + fname; } std::vector<std::string> targets; - cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator(); + cmGlobalGenerator* gg = mf.GetGlobalGenerator(); cmExportSet* exportSet = nullptr; if (args[0] == "EXPORT") { @@ -127,32 +138,32 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args, if (it == setMap.end()) { std::ostringstream e; e << "Export set \"" << arguments.ExportSetName << "\" not found."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } exportSet = &it->second; } else if (!arguments.Targets.empty() || cmContains(keywordsMissingValue, "TARGETS")) { for (std::string const& currentTarget : arguments.Targets) { - if (this->Makefile->IsAlias(currentTarget)) { + if (mf.IsAlias(currentTarget)) { std::ostringstream e; e << "given ALIAS target \"" << currentTarget << "\" which may not be exported."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } if (cmTarget* target = gg->FindTarget(currentTarget)) { if (target->GetType() == cmStateEnums::UTILITY) { - this->SetError("given custom target \"" + currentTarget + - "\" which may not be exported."); + status.SetError("given custom target \"" + currentTarget + + "\" which may not be exported."); return false; } } else { std::ostringstream e; e << "given target \"" << currentTarget << "\" which is not built by this project."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } targets.push_back(currentTarget); @@ -165,7 +176,7 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args, } } } else { - this->SetError("EXPORT or TARGETS specifier missing."); + status.SetError("EXPORT or TARGETS specifier missing."); return false; } @@ -184,12 +195,12 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args, } else { ebfg->SetTargets(targets); } - this->Makefile->AddExportBuildFileGenerator(ebfg); + mf.AddExportBuildFileGenerator(ebfg); ebfg->SetExportOld(arguments.ExportOld); // Compute the set of configurations exported. std::vector<std::string> configurationTypes; - this->Makefile->GetConfigurations(configurationTypes); + mf.GetConfigurations(configurationTypes); if (configurationTypes.empty()) { configurationTypes.emplace_back(); } @@ -205,7 +216,8 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args, return true; } -bool cmExportCommand::HandlePackage(std::vector<std::string> const& args) +static bool HandlePackage(std::vector<std::string> const& args, + cmExecutionStatus& status) { // Parse PACKAGE mode arguments. enum Doing @@ -222,14 +234,14 @@ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args) } else { std::ostringstream e; e << "PACKAGE given unknown argument: " << args[i]; - this->SetError(e.str()); + status.SetError(e.str()); return false; } } // Verify the package name. if (package.empty()) { - this->SetError("PACKAGE must be given a package name."); + status.SetError("PACKAGE must be given a package name."); return false; } const char* packageExpr = "^[A-Za-z0-9_.-]+$"; @@ -238,16 +250,18 @@ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args) std::ostringstream e; e << "PACKAGE given invalid package name \"" << package << "\". " << "Package names must match \"" << packageExpr << "\"."; - this->SetError(e.str()); + status.SetError(e.str()); return false; } + cmMakefile& mf = status.GetMakefile(); + // CMP0090 decides both the default and what variable changes it. - switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0090)) { + switch (mf.GetPolicyStatus(cmPolicies::CMP0090)) { case cmPolicies::WARN: case cmPolicies::OLD: // Default is to export, but can be disabled. - if (this->Makefile->IsOn("CMAKE_EXPORT_NO_PACKAGE_REGISTRY")) { + if (mf.IsOn("CMAKE_EXPORT_NO_PACKAGE_REGISTRY")) { return true; } break; @@ -255,7 +269,7 @@ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args) case cmPolicies::REQUIRED_ALWAYS: case cmPolicies::NEW: // Default is to not export, but can be enabled. - if (!this->Makefile->IsOn("CMAKE_EXPORT_PACKAGE_REGISTRY")) { + if (!mf.IsOn("CMAKE_EXPORT_PACKAGE_REGISTRY")) { return true; } break; @@ -264,22 +278,17 @@ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args) // We store the current build directory in the registry as a value // named by a hash of its own content. This is deterministic and is // unique with high probability. - const std::string& outDir = this->Makefile->GetCurrentBinaryDirectory(); + const std::string& outDir = mf.GetCurrentBinaryDirectory(); std::string hash = cmSystemTools::ComputeStringMD5(outDir); -#if defined(_WIN32) && !defined(__CYGWIN__) - this->StorePackageRegistryWin(package, outDir.c_str(), hash.c_str()); -#else - this->StorePackageRegistryDir(package, outDir.c_str(), hash.c_str()); -#endif + StorePackageRegistry(mf, package, outDir.c_str(), hash.c_str()); return true; } #if defined(_WIN32) && !defined(__CYGWIN__) -# include <windows.h> -void cmExportCommand::ReportRegistryError(std::string const& msg, - std::string const& key, long err) +static void ReportRegistryError(cmMakefile& mf, std::string const& msg, + std::string const& key, long err) { std::ostringstream e; e << msg << "\n" @@ -291,12 +300,11 @@ void cmExportCommand::ReportRegistryError(std::string const& msg, e << "Windows reported:\n" << " " << cmsys::Encoding::ToNarrow(winmsg); } - this->Makefile->IssueMessage(MessageType::WARNING, e.str()); + mf.IssueMessage(MessageType::WARNING, e.str()); } -void cmExportCommand::StorePackageRegistryWin(std::string const& package, - const char* content, - const char* hash) +static void StorePackageRegistry(cmMakefile& mf, std::string const& package, + const char* content, const char* hash) { std::string key = cmStrCat("Software\\Kitware\\CMake\\Packages\\", package); HKEY hKey; @@ -304,7 +312,7 @@ void cmExportCommand::StorePackageRegistryWin(std::string const& package, RegCreateKeyExW(HKEY_CURRENT_USER, cmsys::Encoding::ToWide(key).c_str(), 0, 0, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, 0, &hKey, 0); if (err != ERROR_SUCCESS) { - this->ReportRegistryError("Cannot create/open registry key", key, err); + ReportRegistryError(mf, "Cannot create/open registry key", key, err); return; } @@ -317,14 +325,13 @@ void cmExportCommand::StorePackageRegistryWin(std::string const& package, if (err != ERROR_SUCCESS) { std::ostringstream msg; msg << "Cannot set registry value \"" << hash << "\" under key"; - this->ReportRegistryError(msg.str(), key, err); + ReportRegistryError(mf, msg.str(), key, err); return; } } #else -void cmExportCommand::StorePackageRegistryDir(std::string const& package, - const char* content, - const char* hash) +static void StorePackageRegistry(cmMakefile& mf, std::string const& package, + const char* content, const char* hash) { # if defined(__HAIKU__) char dir[B_PATH_NAME_LENGTH]; @@ -356,7 +363,7 @@ void cmExportCommand::StorePackageRegistryDir(std::string const& package, << " " << fname << "\n" << cmSystemTools::GetLastSystemError() << "\n"; /* clang-format on */ - this->Makefile->IssueMessage(MessageType::WARNING, e.str()); + mf.IssueMessage(MessageType::WARNING, e.str()); } } } diff --git a/Source/cmExportCommand.h b/Source/cmExportCommand.h index 819a3c3..9655628 100644 --- a/Source/cmExportCommand.h +++ b/Source/cmExportCommand.h @@ -8,38 +8,9 @@ #include <string> #include <vector> -#include <cm/memory> - -#include "cmCommand.h" - class cmExecutionStatus; -class cmExportCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmExportCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - bool HandlePackage(std::vector<std::string> const& args); - void StorePackageRegistryWin(std::string const& package, const char* content, - const char* hash); - void StorePackageRegistryDir(std::string const& package, const char* content, - const char* hash); - void ReportRegistryError(std::string const& msg, std::string const& key, - long err); -}; +bool cmExportCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmIncludeDirectoryCommand.cxx b/Source/cmIncludeDirectoryCommand.cxx index a4d0a0d..170aea1 100644 --- a/Source/cmIncludeDirectoryCommand.cxx +++ b/Source/cmIncludeDirectoryCommand.cxx @@ -7,24 +7,28 @@ #include <utility> #include "cmAlgorithms.h" +#include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" #include "cmMakefile.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; +static void GetIncludes(cmMakefile& mf, const std::string& arg, + std::vector<std::string>& incs); +static void NormalizeInclude(cmMakefile& mf, std::string& inc); -// cmIncludeDirectoryCommand -bool cmIncludeDirectoryCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmIncludeDirectoryCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { return true; } + cmMakefile& mf = status.GetMakefile(); + auto i = args.begin(); - bool before = this->Makefile->IsOn("CMAKE_INCLUDE_DIRECTORIES_BEFORE"); + bool before = mf.IsOn("CMAKE_INCLUDE_DIRECTORIES_BEFORE"); bool system = false; if ((*i) == "BEFORE") { @@ -45,13 +49,13 @@ bool cmIncludeDirectoryCommand::InitialPass( continue; } if (i->empty()) { - this->SetError("given empty-string as include directory."); + status.SetError("given empty-string as include directory."); return false; } std::vector<std::string> includes; - this->GetIncludes(*i, includes); + GetIncludes(mf, *i, includes); if (before) { cmAppend(beforeIncludes, includes); @@ -64,9 +68,9 @@ bool cmIncludeDirectoryCommand::InitialPass( } std::reverse(beforeIncludes.begin(), beforeIncludes.end()); - this->Makefile->AddIncludeDirectories(afterIncludes); - this->Makefile->AddIncludeDirectories(beforeIncludes, before); - this->Makefile->AddSystemIncludeDirectories(systemIncludes); + mf.AddIncludeDirectories(afterIncludes); + mf.AddIncludeDirectories(beforeIncludes, before); + mf.AddSystemIncludeDirectories(systemIncludes); return true; } @@ -83,8 +87,8 @@ bool cmIncludeDirectoryCommand::InitialPass( // output from a program and passing it into a command the cleanup doesn't // always happen // -void cmIncludeDirectoryCommand::GetIncludes(const std::string& arg, - std::vector<std::string>& incs) +static void GetIncludes(cmMakefile& mf, const std::string& arg, + std::vector<std::string>& incs) { // break apart any line feed arguments std::string::size_type pos = 0; @@ -92,7 +96,7 @@ void cmIncludeDirectoryCommand::GetIncludes(const std::string& arg, while ((pos = arg.find('\n', lastPos)) != std::string::npos) { if (pos) { std::string inc = arg.substr(lastPos, pos); - this->NormalizeInclude(inc); + NormalizeInclude(mf, inc); if (!inc.empty()) { incs.push_back(std::move(inc)); } @@ -100,13 +104,13 @@ void cmIncludeDirectoryCommand::GetIncludes(const std::string& arg, lastPos = pos + 1; } std::string inc = arg.substr(lastPos); - this->NormalizeInclude(inc); + NormalizeInclude(mf, inc); if (!inc.empty()) { incs.push_back(std::move(inc)); } } -void cmIncludeDirectoryCommand::NormalizeInclude(std::string& inc) +static void NormalizeInclude(cmMakefile& mf, std::string& inc) { std::string::size_type b = inc.find_first_not_of(" \r"); std::string::size_type e = inc.find_last_not_of(" \r"); @@ -119,13 +123,9 @@ void cmIncludeDirectoryCommand::NormalizeInclude(std::string& inc) if (!cmIsOff(inc)) { cmSystemTools::ConvertToUnixSlashes(inc); - - if (!cmSystemTools::FileIsFullPath(inc)) { - if (!cmGeneratorExpression::StartsWithGeneratorExpression(inc)) { - std::string tmp = - cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', inc); - inc = tmp; - } + if (!cmSystemTools::FileIsFullPath(inc) && + !cmGeneratorExpression::StartsWithGeneratorExpression(inc)) { + inc = cmStrCat(mf.GetCurrentSourceDirectory(), '/', inc); } } } diff --git a/Source/cmIncludeDirectoryCommand.h b/Source/cmIncludeDirectoryCommand.h index bcaae9d..66caff7 100644 --- a/Source/cmIncludeDirectoryCommand.h +++ b/Source/cmIncludeDirectoryCommand.h @@ -8,40 +8,9 @@ #include <string> #include <vector> -#include <cm/memory> - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmIncludeDirectoryCommand - * \brief Add include directories to the build. - * - * cmIncludeDirectoryCommand is used to specify directory locations - * to search for included files. - */ -class cmIncludeDirectoryCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmIncludeDirectoryCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -protected: - // used internally - void GetIncludes(const std::string& arg, std::vector<std::string>& incs); - void NormalizeInclude(std::string& inc); -}; +bool cmIncludeDirectoryCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index f7050d4..27d0dfb 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -4,12 +4,14 @@ #include "cm_static_string_view.hxx" #include "cmsys/Glob.hxx" +#include <cm/memory> #include <cstddef> #include <set> #include <sstream> #include <utility> #include "cmArgumentParser.h" +#include "cmExecutionStatus.h" #include "cmExportSet.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" @@ -26,13 +28,61 @@ #include "cmPolicies.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" +#include "cmSubcommandTable.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetExport.h" -class cmExecutionStatus; +namespace { -static cmInstallTargetGenerator* CreateInstallTargetGenerator( +class Helper +{ +public: + Helper(cmExecutionStatus& status) + : Status(status) + , Makefile(&status.GetMakefile()) + { + this->DefaultComponentName = this->Makefile->GetSafeDefinition( + "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"); + if (this->DefaultComponentName.empty()) { + this->DefaultComponentName = "Unspecified"; + } + } + + void SetError(std::string const& err) { this->Status.SetError(err); } + + bool MakeFilesFullPath(const char* modeName, + const std::vector<std::string>& relFiles, + std::vector<std::string>& absFiles); + bool CheckCMP0006(bool& failure); + + std::string GetDestination(const cmInstallCommandArguments* args, + const std::string& varName, + const std::string& guess); + std::string GetRuntimeDestination(const cmInstallCommandArguments* args); + std::string GetSbinDestination(const cmInstallCommandArguments* args); + std::string GetArchiveDestination(const cmInstallCommandArguments* args); + std::string GetLibraryDestination(const cmInstallCommandArguments* args); + std::string GetIncludeDestination(const cmInstallCommandArguments* args); + std::string GetSysconfDestination(const cmInstallCommandArguments* args); + std::string GetSharedStateDestination(const cmInstallCommandArguments* args); + std::string GetLocalStateDestination(const cmInstallCommandArguments* args); + std::string GetRunStateDestination(const cmInstallCommandArguments* args); + std::string GetDataRootDestination(const cmInstallCommandArguments* args); + std::string GetDataDestination(const cmInstallCommandArguments* args); + std::string GetInfoDestination(const cmInstallCommandArguments* args); + std::string GetLocaleDestination(const cmInstallCommandArguments* args); + std::string GetManDestination(const cmInstallCommandArguments* args); + std::string GetDocDestination(const cmInstallCommandArguments* args); + std::string GetDestinationForType(const cmInstallCommandArguments* args, + const std::string& type); + + cmExecutionStatus& Status; + cmMakefile* Makefile; + std::string DefaultComponentName; +}; + +cmInstallTargetGenerator* CreateInstallTargetGenerator( cmTarget& target, const cmInstallCommandArguments& args, bool impLib, cmListFileBacktrace const& backtrace, const std::string& destination, bool forceOpt = false, bool namelink = false) @@ -51,7 +101,7 @@ static cmInstallTargetGenerator* CreateInstallTargetGenerator( return g; } -static cmInstallTargetGenerator* CreateInstallTargetGenerator( +cmInstallTargetGenerator* CreateInstallTargetGenerator( cmTarget& target, const cmInstallCommandArguments& args, bool impLib, cmListFileBacktrace const& backtrace, bool forceOpt = false, bool namelink = false) @@ -61,7 +111,7 @@ static cmInstallTargetGenerator* CreateInstallTargetGenerator( namelink); } -static cmInstallFilesGenerator* CreateInstallFilesGenerator( +cmInstallFilesGenerator* CreateInstallFilesGenerator( cmMakefile* mf, const std::vector<std::string>& absFiles, const cmInstallCommandArguments& args, bool programs, const std::string& destination) @@ -74,7 +124,7 @@ static cmInstallFilesGenerator* CreateInstallFilesGenerator( args.GetExcludeFromAll(), args.GetRename().c_str(), args.GetOptional()); } -static cmInstallFilesGenerator* CreateInstallFilesGenerator( +cmInstallFilesGenerator* CreateInstallFilesGenerator( cmMakefile* mf, const std::vector<std::string>& absFiles, const cmInstallCommandArguments& args, bool programs) { @@ -82,68 +132,18 @@ static cmInstallFilesGenerator* CreateInstallFilesGenerator( args.GetDestination()); } -static const std::set<std::string> allowedTypes{ +std::set<std::string> const allowedTypes{ "BIN", "SBIN", "LIB", "INCLUDE", "SYSCONF", "SHAREDSTATE", "LOCALSTATE", "RUNSTATE", "DATA", "INFO", "LOCALE", "MAN", "DOC", }; -// cmInstallCommand -bool cmInstallCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool HandleScriptMode(std::vector<std::string> const& args, + cmExecutionStatus& status) { - // Allow calling with no arguments so that arguments may be built up - // using a variable that may be left empty. - if (args.empty()) { - return true; - } - - // Enable the install target. - this->Makefile->GetGlobalGenerator()->EnableInstallTarget(); - - this->DefaultComponentName = - this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"); - if (this->DefaultComponentName.empty()) { - this->DefaultComponentName = "Unspecified"; - } - - std::string const& mode = args[0]; - - // Switch among the command modes. - if (mode == "SCRIPT") { - return this->HandleScriptMode(args); - } - if (mode == "CODE") { - return this->HandleScriptMode(args); - } - if (mode == "TARGETS") { - return this->HandleTargetsMode(args); - } - if (mode == "FILES") { - return this->HandleFilesMode(args); - } - if (mode == "PROGRAMS") { - return this->HandleFilesMode(args); - } - if (mode == "DIRECTORY") { - return this->HandleDirectoryMode(args); - } - if (mode == "EXPORT") { - return this->HandleExportMode(args); - } - if (mode == "EXPORT_ANDROID_MK") { - return this->HandleExportAndroidMKMode(args); - } - - // Unknown mode. - std::string e = cmStrCat("called with unknown mode ", args[0]); - this->SetError(e); - return false; -} + Helper helper(status); -bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args) -{ - std::string component = this->DefaultComponentName; + std::string component = helper.DefaultComponentName; int componentCount = 0; bool doing_script = false; bool doing_code = false; @@ -163,9 +163,9 @@ bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args) } if (componentCount > 1) { - this->SetError("given more than one COMPONENT for the SCRIPT or CODE " - "signature of the INSTALL command. " - "Use multiple INSTALL commands with one COMPONENT each."); + status.SetError("given more than one COMPONENT for the SCRIPT or CODE " + "signature of the INSTALL command. " + "Use multiple INSTALL commands with one COMPONENT each."); return false; } @@ -187,40 +187,43 @@ bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args) std::string script = arg; if (!cmSystemTools::FileIsFullPath(script)) { script = - cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', arg); + cmStrCat(helper.Makefile->GetCurrentSourceDirectory(), '/', arg); } if (cmSystemTools::FileIsDirectory(script)) { - this->SetError("given a directory as value of SCRIPT argument."); + status.SetError("given a directory as value of SCRIPT argument."); return false; } - this->Makefile->AddInstallGenerator(new cmInstallScriptGenerator( + helper.Makefile->AddInstallGenerator(new cmInstallScriptGenerator( script.c_str(), false, component.c_str(), exclude_from_all)); } else if (doing_code) { doing_code = false; std::string const& code = arg; - this->Makefile->AddInstallGenerator(new cmInstallScriptGenerator( + helper.Makefile->AddInstallGenerator(new cmInstallScriptGenerator( code.c_str(), true, component.c_str(), exclude_from_all)); } } if (doing_script) { - this->SetError("given no value for SCRIPT argument."); + status.SetError("given no value for SCRIPT argument."); return false; } if (doing_code) { - this->SetError("given no value for CODE argument."); + status.SetError("given no value for CODE argument."); return false; } // Tell the global generator about any installation component names // specified. - this->Makefile->GetGlobalGenerator()->AddInstallComponent(component); + helper.Makefile->GetGlobalGenerator()->AddInstallComponent(component); return true; } -bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) +bool HandleTargetsMode(std::vector<std::string> const& args, + cmExecutionStatus& status) { + Helper helper(status); + // This is the TARGETS mode. std::vector<cmTarget*> targets; @@ -260,21 +263,21 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) std::vector<std::string> targetList; std::string exports; std::vector<std::string> unknownArgs; - cmInstallCommandArguments genericArgs(this->DefaultComponentName); + cmInstallCommandArguments genericArgs(helper.DefaultComponentName); genericArgs.Bind("TARGETS"_s, targetList); genericArgs.Bind("EXPORT"_s, exports); genericArgs.Parse(genericArgVector, &unknownArgs); bool success = genericArgs.Finalize(); - cmInstallCommandArguments archiveArgs(this->DefaultComponentName); - cmInstallCommandArguments libraryArgs(this->DefaultComponentName); - cmInstallCommandArguments runtimeArgs(this->DefaultComponentName); - cmInstallCommandArguments objectArgs(this->DefaultComponentName); - cmInstallCommandArguments frameworkArgs(this->DefaultComponentName); - cmInstallCommandArguments bundleArgs(this->DefaultComponentName); - cmInstallCommandArguments privateHeaderArgs(this->DefaultComponentName); - cmInstallCommandArguments publicHeaderArgs(this->DefaultComponentName); - cmInstallCommandArguments resourceArgs(this->DefaultComponentName); + cmInstallCommandArguments archiveArgs(helper.DefaultComponentName); + cmInstallCommandArguments libraryArgs(helper.DefaultComponentName); + cmInstallCommandArguments runtimeArgs(helper.DefaultComponentName); + cmInstallCommandArguments objectArgs(helper.DefaultComponentName); + cmInstallCommandArguments frameworkArgs(helper.DefaultComponentName); + cmInstallCommandArguments bundleArgs(helper.DefaultComponentName); + cmInstallCommandArguments privateHeaderArgs(helper.DefaultComponentName); + cmInstallCommandArguments publicHeaderArgs(helper.DefaultComponentName); + cmInstallCommandArguments resourceArgs(helper.DefaultComponentName); cmInstallCommandIncludesArgument includesArgs; // now parse the args for specific parts of the target (e.g. LIBRARY, @@ -292,7 +295,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) if (!unknownArgs.empty()) { // Unknown argument. - this->SetError( + status.SetError( cmStrCat("TARGETS given unknown argument \"", unknownArgs[0], "\".")); return false; } @@ -328,7 +331,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) objectArgs.GetNamelinkOnly() || frameworkArgs.GetNamelinkOnly() || bundleArgs.GetNamelinkOnly() || privateHeaderArgs.GetNamelinkOnly() || publicHeaderArgs.GetNamelinkOnly() || resourceArgs.GetNamelinkOnly()) { - this->SetError( + status.SetError( "TARGETS given NAMELINK_ONLY option not in LIBRARY group. " "The NAMELINK_ONLY option may be specified only following LIBRARY."); return false; @@ -337,7 +340,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) objectArgs.GetNamelinkSkip() || frameworkArgs.GetNamelinkSkip() || bundleArgs.GetNamelinkSkip() || privateHeaderArgs.GetNamelinkSkip() || publicHeaderArgs.GetNamelinkSkip() || resourceArgs.GetNamelinkSkip()) { - this->SetError( + status.SetError( "TARGETS given NAMELINK_SKIP option not in LIBRARY group. " "The NAMELINK_SKIP option may be specified only following LIBRARY."); return false; @@ -350,15 +353,15 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) privateHeaderArgs.HasNamelinkComponent() || publicHeaderArgs.HasNamelinkComponent() || resourceArgs.HasNamelinkComponent()) { - this->SetError( + status.SetError( "TARGETS given NAMELINK_COMPONENT option not in LIBRARY group. " "The NAMELINK_COMPONENT option may be specified only following " "LIBRARY."); return false; } if (libraryArgs.GetNamelinkOnly() && libraryArgs.GetNamelinkSkip()) { - this->SetError("TARGETS given NAMELINK_ONLY and NAMELINK_SKIP. " - "At most one of these two options may be specified."); + status.SetError("TARGETS given NAMELINK_ONLY and NAMELINK_SKIP. " + "At most one of these two options may be specified."); return false; } if (!genericArgs.GetType().empty() || !archiveArgs.GetType().empty() || @@ -366,7 +369,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) !objectArgs.GetType().empty() || !frameworkArgs.GetType().empty() || !bundleArgs.GetType().empty() || !privateHeaderArgs.GetType().empty() || !publicHeaderArgs.GetType().empty() || !resourceArgs.GetType().empty()) { - this->SetError( + status.SetError( "TARGETS given TYPE option. The TYPE option may only be specified in " " install(FILES) and install(DIRECTORIES)."); return false; @@ -388,17 +391,17 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) for (std::string const& tgt : targetList) { - if (this->Makefile->IsAlias(tgt)) { - this->SetError( + if (helper.Makefile->IsAlias(tgt)) { + status.SetError( cmStrCat("TARGETS given target \"", tgt, "\" which is an alias.")); return false; } // Lookup this target in the current directory. - cmTarget* target = this->Makefile->FindLocalNonAliasTarget(tgt); + cmTarget* target = helper.Makefile->FindLocalNonAliasTarget(tgt); if (!target) { // If no local target has been found, find it in the global scope. cmTarget* const global_target = - this->Makefile->GetGlobalGenerator()->FindTarget(tgt, true); + helper.Makefile->GetGlobalGenerator()->FindTarget(tgt, true); if (global_target && !global_target->IsImported()) { target = global_target; } @@ -411,7 +414,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) target->GetType() != cmStateEnums::MODULE_LIBRARY && target->GetType() != cmStateEnums::OBJECT_LIBRARY && target->GetType() != cmStateEnums::INTERFACE_LIBRARY) { - this->SetError( + status.SetError( cmStrCat("TARGETS given target \"", tgt, "\" which is not an executable, library, or module.")); return false; @@ -420,7 +423,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) targets.push_back(target); } else { // Did not find the target. - this->SetError( + status.SetError( cmStrCat("TARGETS given target \"", tgt, "\" which does not exist.")); return false; } @@ -472,20 +475,20 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) if (!archiveArgs.GetDestination().empty()) { // The import library uses the ARCHIVE properties. archiveGenerator = CreateInstallTargetGenerator( - target, archiveArgs, true, this->Makefile->GetBacktrace()); + target, archiveArgs, true, helper.Makefile->GetBacktrace()); } if (!runtimeArgs.GetDestination().empty()) { // The DLL uses the RUNTIME properties. runtimeGenerator = CreateInstallTargetGenerator( - target, runtimeArgs, false, this->Makefile->GetBacktrace()); + target, runtimeArgs, false, helper.Makefile->GetBacktrace()); } if ((archiveGenerator == nullptr) && (runtimeGenerator == nullptr)) { archiveGenerator = CreateInstallTargetGenerator( - target, archiveArgs, true, this->Makefile->GetBacktrace(), - this->GetArchiveDestination(nullptr)); + target, archiveArgs, true, helper.Makefile->GetBacktrace(), + helper.GetArchiveDestination(nullptr)); runtimeGenerator = CreateInstallTargetGenerator( - target, runtimeArgs, false, this->Makefile->GetBacktrace(), - this->GetRuntimeDestination(nullptr)); + target, runtimeArgs, false, helper.Makefile->GetBacktrace(), + helper.GetRuntimeDestination(nullptr)); } } else { // This is a non-DLL platform. @@ -500,9 +503,9 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) // Use the FRAMEWORK properties. if (!frameworkArgs.GetDestination().empty()) { frameworkGenerator = CreateInstallTargetGenerator( - target, frameworkArgs, false, this->Makefile->GetBacktrace()); + target, frameworkArgs, false, helper.Makefile->GetBacktrace()); } else { - this->SetError( + status.SetError( cmStrCat("TARGETS given no FRAMEWORK DESTINATION for shared " "library FRAMEWORK target \"", target.GetName(), "\".")); @@ -512,15 +515,15 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) // The shared library uses the LIBRARY properties. if (namelinkMode != cmInstallTargetGenerator::NamelinkModeOnly) { libraryGenerator = CreateInstallTargetGenerator( - target, libraryArgs, false, this->Makefile->GetBacktrace(), - this->GetLibraryDestination(&libraryArgs)); + target, libraryArgs, false, helper.Makefile->GetBacktrace(), + helper.GetLibraryDestination(&libraryArgs)); libraryGenerator->SetNamelinkMode( cmInstallTargetGenerator::NamelinkModeSkip); } if (namelinkMode != cmInstallTargetGenerator::NamelinkModeSkip) { namelinkGenerator = CreateInstallTargetGenerator( - target, libraryArgs, false, this->Makefile->GetBacktrace(), - this->GetLibraryDestination(&libraryArgs), false, true); + target, libraryArgs, false, helper.Makefile->GetBacktrace(), + helper.GetLibraryDestination(&libraryArgs), false, true); namelinkGenerator->SetNamelinkMode( cmInstallTargetGenerator::NamelinkModeOnly); } @@ -541,32 +544,31 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) // Use the FRAMEWORK properties. if (!frameworkArgs.GetDestination().empty()) { frameworkGenerator = CreateInstallTargetGenerator( - target, frameworkArgs, false, this->Makefile->GetBacktrace()); + target, frameworkArgs, false, helper.Makefile->GetBacktrace()); } else { - this->SetError( + status.SetError( cmStrCat("TARGETS given no FRAMEWORK DESTINATION for static " "library FRAMEWORK target \"", target.GetName(), "\".")); - return false; } } else { // Static libraries use ARCHIVE properties. archiveGenerator = CreateInstallTargetGenerator( - target, archiveArgs, false, this->Makefile->GetBacktrace(), - this->GetArchiveDestination(&archiveArgs)); + target, archiveArgs, false, helper.Makefile->GetBacktrace(), + helper.GetArchiveDestination(&archiveArgs)); } } break; case cmStateEnums::MODULE_LIBRARY: { // Modules use LIBRARY properties. if (!libraryArgs.GetDestination().empty()) { libraryGenerator = CreateInstallTargetGenerator( - target, libraryArgs, false, this->Makefile->GetBacktrace()); + target, libraryArgs, false, helper.Makefile->GetBacktrace()); libraryGenerator->SetNamelinkMode(namelinkMode); namelinkOnly = (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly); } else { - this->SetError( + status.SetError( cmStrCat("TARGETS given no LIBRARY DESTINATION for module " "target \"", target.GetName(), "\".")); @@ -578,16 +580,16 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) if (!objectArgs.GetDestination().empty()) { // Verify that we know where the objects are to install them. std::string reason; - if (!this->Makefile->GetGlobalGenerator() + if (!helper.Makefile->GetGlobalGenerator() ->HasKnownObjectFileLocation(&reason)) { - this->SetError( + status.SetError( cmStrCat("TARGETS given OBJECT library \"", target.GetName(), "\" whose objects may not be installed", reason, ".")); return false; } objectGenerator = CreateInstallTargetGenerator( - target, objectArgs, false, this->Makefile->GetBacktrace()); + target, objectArgs, false, helper.Makefile->GetBacktrace()); } else { // Installing an OBJECT library without a destination transforms // it to an INTERFACE library. It installs no files but can be @@ -599,29 +601,29 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) // Application bundles use the BUNDLE properties. if (!bundleArgs.GetDestination().empty()) { bundleGenerator = CreateInstallTargetGenerator( - target, bundleArgs, false, this->Makefile->GetBacktrace()); + target, bundleArgs, false, helper.Makefile->GetBacktrace()); } else if (!runtimeArgs.GetDestination().empty()) { bool failure = false; - if (this->CheckCMP0006(failure)) { + if (helper.CheckCMP0006(failure)) { // For CMake 2.4 compatibility fallback to the RUNTIME // properties. bundleGenerator = CreateInstallTargetGenerator( - target, runtimeArgs, false, this->Makefile->GetBacktrace()); + target, runtimeArgs, false, helper.Makefile->GetBacktrace()); } else if (failure) { return false; } } if (!bundleGenerator) { - this->SetError(cmStrCat("TARGETS given no BUNDLE DESTINATION for " - "MACOSX_BUNDLE executable target \"", - target.GetName(), "\".")); + status.SetError(cmStrCat("TARGETS given no BUNDLE DESTINATION for " + "MACOSX_BUNDLE executable target \"", + target.GetName(), "\".")); return false; } } else { // Executables use the RUNTIME properties. runtimeGenerator = CreateInstallTargetGenerator( - target, runtimeArgs, false, this->Makefile->GetBacktrace(), - this->GetRuntimeDestination(&runtimeArgs)); + target, runtimeArgs, false, helper.Makefile->GetBacktrace(), + helper.GetRuntimeDestination(&runtimeArgs)); } // On DLL platforms an executable may also have an import @@ -632,7 +634,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) target.IsExecutableWithExports()) { // The import library uses the ARCHIVE properties. archiveGenerator = CreateInstallTargetGenerator( - target, archiveArgs, true, this->Makefile->GetBacktrace(), true); + target, archiveArgs, true, helper.Makefile->GetBacktrace(), true); } } break; case cmStateEnums::INTERFACE_LIBRARY: @@ -662,42 +664,42 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) if ((files) && (*files)) { std::vector<std::string> relFiles = cmExpandedList(files); std::vector<std::string> absFiles; - if (!this->MakeFilesFullPath("PRIVATE_HEADER", relFiles, absFiles)) { + if (!helper.MakeFilesFullPath("PRIVATE_HEADER", relFiles, absFiles)) { return false; } // Create the files install generator. privateHeaderGenerator = CreateInstallFilesGenerator( - this->Makefile, absFiles, privateHeaderArgs, false, - this->GetIncludeDestination(&privateHeaderArgs)); + helper.Makefile, absFiles, privateHeaderArgs, false, + helper.GetIncludeDestination(&privateHeaderArgs)); } files = target.GetProperty("PUBLIC_HEADER"); if ((files) && (*files)) { std::vector<std::string> relFiles = cmExpandedList(files); std::vector<std::string> absFiles; - if (!this->MakeFilesFullPath("PUBLIC_HEADER", relFiles, absFiles)) { + if (!helper.MakeFilesFullPath("PUBLIC_HEADER", relFiles, absFiles)) { return false; } // Create the files install generator. publicHeaderGenerator = CreateInstallFilesGenerator( - this->Makefile, absFiles, publicHeaderArgs, false, - this->GetIncludeDestination(&publicHeaderArgs)); + helper.Makefile, absFiles, publicHeaderArgs, false, + helper.GetIncludeDestination(&publicHeaderArgs)); } files = target.GetProperty("RESOURCE"); if ((files) && (*files)) { std::vector<std::string> relFiles = cmExpandedList(files); std::vector<std::string> absFiles; - if (!this->MakeFilesFullPath("RESOURCE", relFiles, absFiles)) { + if (!helper.MakeFilesFullPath("RESOURCE", relFiles, absFiles)) { return false; } // Create the files install generator. if (!resourceArgs.GetDestination().empty()) { resourceGenerator = CreateInstallFilesGenerator( - this->Makefile, absFiles, resourceArgs, false); + helper.Makefile, absFiles, resourceArgs, false); } else { cmSystemTools::Message( cmStrCat("INSTALL TARGETS - target ", target.GetName(), @@ -721,16 +723,16 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) installsPublicHeader || publicHeaderGenerator != nullptr; installsResource = installsResource || resourceGenerator; - this->Makefile->AddInstallGenerator(archiveGenerator); - this->Makefile->AddInstallGenerator(libraryGenerator); - this->Makefile->AddInstallGenerator(namelinkGenerator); - this->Makefile->AddInstallGenerator(runtimeGenerator); - this->Makefile->AddInstallGenerator(objectGenerator); - this->Makefile->AddInstallGenerator(frameworkGenerator); - this->Makefile->AddInstallGenerator(bundleGenerator); - this->Makefile->AddInstallGenerator(privateHeaderGenerator); - this->Makefile->AddInstallGenerator(publicHeaderGenerator); - this->Makefile->AddInstallGenerator(resourceGenerator); + helper.Makefile->AddInstallGenerator(archiveGenerator); + helper.Makefile->AddInstallGenerator(libraryGenerator); + helper.Makefile->AddInstallGenerator(namelinkGenerator); + helper.Makefile->AddInstallGenerator(runtimeGenerator); + helper.Makefile->AddInstallGenerator(objectGenerator); + helper.Makefile->AddInstallGenerator(frameworkGenerator); + helper.Makefile->AddInstallGenerator(bundleGenerator); + helper.Makefile->AddInstallGenerator(privateHeaderGenerator); + helper.Makefile->AddInstallGenerator(publicHeaderGenerator); + helper.Makefile->AddInstallGenerator(resourceGenerator); // Add this install rule to an export if one was specified and // this is not a namelink-only rule. @@ -747,7 +749,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) te->InterfaceIncludeDirectories = cmJoin(includesArgs.GetIncludeDirs(), ";"); - this->Makefile->GetGlobalGenerator() + helper.Makefile->GetGlobalGenerator() ->GetExportSets()[exports] .AddTargetExport(std::move(te)); } @@ -756,54 +758,57 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) // Tell the global generator about any installation component names // specified if (installsArchive) { - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( archiveArgs.GetComponent()); } if (installsLibrary) { - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( libraryArgs.GetComponent()); } if (installsNamelink) { - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( libraryArgs.GetNamelinkComponent()); } if (installsRuntime) { - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( runtimeArgs.GetComponent()); } if (installsObject) { - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( objectArgs.GetComponent()); } if (installsFramework) { - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( frameworkArgs.GetComponent()); } if (installsBundle) { - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( bundleArgs.GetComponent()); } if (installsPrivateHeader) { - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( privateHeaderArgs.GetComponent()); } if (installsPublicHeader) { - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( publicHeaderArgs.GetComponent()); } if (installsResource) { - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( resourceArgs.GetComponent()); } return true; } -bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args) +bool HandleFilesMode(std::vector<std::string> const& args, + cmExecutionStatus& status) { + Helper helper(status); + // This is the FILES mode. bool programs = (args[0] == "PROGRAMS"); - cmInstallCommandArguments ica(this->DefaultComponentName); + cmInstallCommandArguments ica(helper.DefaultComponentName); std::vector<std::string> files; ica.Bind(programs ? "PROGRAMS"_s : "FILES"_s, files); std::vector<std::string> unknownArgs; @@ -811,14 +816,14 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args) if (!unknownArgs.empty()) { // Unknown argument. - this->SetError( + status.SetError( cmStrCat(args[0], " given unknown argument \"", unknownArgs[0], "\".")); return false; } std::string type = ica.GetType(); if (!type.empty() && allowedTypes.count(type) == 0) { - this->SetError( + status.SetError( cmStrCat(args[0], " given non-type \"", type, "\" with TYPE argument.")); return false; } @@ -832,27 +837,27 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args) if (!ica.GetRename().empty() && filesVector.size() > 1) { // The rename option works only with one file. - this->SetError( + status.SetError( cmStrCat(args[0], " given RENAME option with more than one file.")); return false; } std::vector<std::string> absFiles; - if (!this->MakeFilesFullPath(args[0].c_str(), filesVector, absFiles)) { + if (!helper.MakeFilesFullPath(args[0].c_str(), filesVector, absFiles)) { return false; } - cmPolicies::PolicyStatus status = - this->Makefile->GetPolicyStatus(cmPolicies::CMP0062); + cmPolicies::PolicyStatus policyStatus = + helper.Makefile->GetPolicyStatus(cmPolicies::CMP0062); - cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator(); + cmGlobalGenerator* gg = helper.Makefile->GetGlobalGenerator(); for (std::string const& file : filesVector) { if (gg->IsExportedTargetsFile(file)) { const char* modal = nullptr; std::ostringstream e; MessageType messageType = MessageType::AUTHOR_WARNING; - switch (status) { + switch (policyStatus) { case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0062) << "\n"; modal = "should"; @@ -872,7 +877,7 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args) << " not be installed with the " "install() command. Use the install(EXPORT) mechanism " "instead. See the cmake-packages(7) manual for more.\n"; - this->Makefile->IssueMessage(messageType, e.str()); + helper.Makefile->IssueMessage(messageType, e.str()); if (messageType == MessageType::FATAL_ERROR) { return false; } @@ -885,34 +890,36 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args) } if (!type.empty() && !ica.GetDestination().empty()) { - this->SetError(cmStrCat(args[0], - " given both TYPE and DESTINATION arguments. " - "You may only specify one.")); + status.SetError(cmStrCat(args[0], + " given both TYPE and DESTINATION arguments. " + "You may only specify one.")); return false; } - std::string destination = this->GetDestinationForType(&ica, type); + std::string destination = helper.GetDestinationForType(&ica, type); if (destination.empty()) { // A destination is required. - this->SetError(cmStrCat(args[0], " given no DESTINATION!")); + status.SetError(cmStrCat(args[0], " given no DESTINATION!")); return false; } // Create the files install generator. - this->Makefile->AddInstallGenerator(CreateInstallFilesGenerator( - this->Makefile, absFiles, ica, programs, destination)); + helper.Makefile->AddInstallGenerator(CreateInstallFilesGenerator( + helper.Makefile, absFiles, ica, programs, destination)); // Tell the global generator about any installation component names // specified. - this->Makefile->GetGlobalGenerator()->AddInstallComponent( + helper.Makefile->GetGlobalGenerator()->AddInstallComponent( ica.GetComponent()); return true; } -bool cmInstallCommand::HandleDirectoryMode( - std::vector<std::string> const& args) +bool HandleDirectoryMode(std::vector<std::string> const& args, + cmExecutionStatus& status) { + Helper helper(status); + enum Doing { DoingNone, @@ -937,14 +944,14 @@ bool cmInstallCommand::HandleDirectoryMode( std::string permissions_file; std::string permissions_dir; std::vector<std::string> configurations; - std::string component = this->DefaultComponentName; + std::string component = helper.DefaultComponentName; std::string literal_args; std::string type; for (unsigned int i = 1; i < args.size(); ++i) { if (args[i] == "DESTINATION") { if (in_match_mode) { - this->SetError(cmStrCat(args[0], " does not allow \"", args[i], - "\" after PATTERN or REGEX.")); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } @@ -952,8 +959,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingDestination; } else if (args[i] == "TYPE") { if (in_match_mode) { - this->SetError(cmStrCat(args[0], " does not allow \"", args[i], - "\" after PATTERN or REGEX.")); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } @@ -961,8 +968,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingType; } else if (args[i] == "OPTIONAL") { if (in_match_mode) { - this->SetError(cmStrCat(args[0], " does not allow \"", args[i], - "\" after PATTERN or REGEX.")); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } @@ -971,8 +978,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingNone; } else if (args[i] == "MESSAGE_NEVER") { if (in_match_mode) { - this->SetError(cmStrCat(args[0], " does not allow \"", args[i], - "\" after PATTERN or REGEX.")); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } @@ -990,16 +997,16 @@ bool cmInstallCommand::HandleDirectoryMode( } else if (args[i] == "EXCLUDE") { // Add this property to the current match rule. if (!in_match_mode || doing == DoingPattern || doing == DoingRegex) { - this->SetError(cmStrCat(args[0], " does not allow \"", args[i], - "\" before a PATTERN or REGEX is given.")); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" before a PATTERN or REGEX is given.")); return false; } literal_args += " EXCLUDE"; doing = DoingNone; } else if (args[i] == "PERMISSIONS") { if (!in_match_mode) { - this->SetError(cmStrCat(args[0], " does not allow \"", args[i], - "\" before a PATTERN or REGEX is given.")); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" before a PATTERN or REGEX is given.")); return false; } @@ -1008,8 +1015,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingPermsMatch; } else if (args[i] == "FILE_PERMISSIONS") { if (in_match_mode) { - this->SetError(cmStrCat(args[0], " does not allow \"", args[i], - "\" after PATTERN or REGEX.")); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } @@ -1017,8 +1024,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingPermsFile; } else if (args[i] == "DIRECTORY_PERMISSIONS") { if (in_match_mode) { - this->SetError(cmStrCat(args[0], " does not allow \"", args[i], - "\" after PATTERN or REGEX.")); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } @@ -1026,8 +1033,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingPermsDir; } else if (args[i] == "USE_SOURCE_PERMISSIONS") { if (in_match_mode) { - this->SetError(cmStrCat(args[0], " does not allow \"", args[i], - "\" after PATTERN or REGEX.")); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } @@ -1036,8 +1043,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingNone; } else if (args[i] == "FILES_MATCHING") { if (in_match_mode) { - this->SetError(cmStrCat(args[0], " does not allow \"", args[i], - "\" after PATTERN or REGEX.")); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } @@ -1046,8 +1053,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingNone; } else if (args[i] == "CONFIGURATIONS") { if (in_match_mode) { - this->SetError(cmStrCat(args[0], " does not allow \"", args[i], - "\" after PATTERN or REGEX.")); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } @@ -1055,8 +1062,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingConfigurations; } else if (args[i] == "COMPONENT") { if (in_match_mode) { - this->SetError(cmStrCat(args[0], " does not allow \"", args[i], - "\" after PATTERN or REGEX.")); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } @@ -1064,8 +1071,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingComponent; } else if (args[i] == "EXCLUDE_FROM_ALL") { if (in_match_mode) { - this->SetError(cmStrCat(args[0], " does not allow \"", args[i], - "\" after PATTERN or REGEX.")); + status.SetError(cmStrCat(args[0], " does not allow \"", args[i], + "\" after PATTERN or REGEX.")); return false; } exclude_from_all = true; @@ -1076,14 +1083,14 @@ bool cmInstallCommand::HandleDirectoryMode( std::string::size_type gpos = cmGeneratorExpression::Find(dir); if (gpos != 0 && !cmSystemTools::FileIsFullPath(dir)) { dir = - cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', args[i]); + cmStrCat(helper.Makefile->GetCurrentSourceDirectory(), '/', args[i]); } // Make sure the name is a directory. if (cmSystemTools::FileExists(dir) && !cmSystemTools::FileIsDirectory(dir)) { - this->SetError(cmStrCat(args[0], " given non-directory \"", args[i], - "\" to install.")); + status.SetError(cmStrCat(args[0], " given non-directory \"", args[i], + "\" to install.")); return false; } @@ -1096,8 +1103,8 @@ bool cmInstallCommand::HandleDirectoryMode( doing = DoingNone; } else if (doing == DoingType) { if (allowedTypes.count(args[i]) == 0) { - this->SetError(cmStrCat(args[0], " given non-type \"", args[i], - "\" with TYPE argument.")); + status.SetError(cmStrCat(args[0], " given non-type \"", args[i], + "\" with TYPE argument.")); return false; } @@ -1133,15 +1140,15 @@ bool cmInstallCommand::HandleDirectoryMode( // Check the requested permission. if (!cmInstallCommandArguments::CheckPermissions(args[i], permissions_file)) { - this->SetError(cmStrCat(args[0], " given invalid file permission \"", - args[i], "\".")); + status.SetError(cmStrCat(args[0], " given invalid file permission \"", + args[i], "\".")); return false; } } else if (doing == DoingPermsDir) { // Check the requested permission. if (!cmInstallCommandArguments::CheckPermissions(args[i], permissions_dir)) { - this->SetError(cmStrCat( + status.SetError(cmStrCat( args[0], " given invalid directory permission \"", args[i], "\".")); return false; } @@ -1149,13 +1156,13 @@ bool cmInstallCommand::HandleDirectoryMode( // Check the requested permission. if (!cmInstallCommandArguments::CheckPermissions(args[i], literal_args)) { - this->SetError( + status.SetError( cmStrCat(args[0], " given invalid permission \"", args[i], "\".")); return false; } } else { // Unknown argument. - this->SetError( + status.SetError( cmStrCat(args[0], " given unknown argument \"", args[i], "\".")); return false; } @@ -1174,40 +1181,42 @@ bool cmInstallCommand::HandleDirectoryMode( if (!destination) { if (type.empty()) { // A destination is required. - this->SetError(cmStrCat(args[0], " given no DESTINATION!")); + status.SetError(cmStrCat(args[0], " given no DESTINATION!")); return false; } - destinationStr = this->GetDestinationForType(nullptr, type); + destinationStr = helper.GetDestinationForType(nullptr, type); destination = destinationStr.c_str(); } else if (!type.empty()) { - this->SetError(cmStrCat(args[0], - " given both TYPE and DESTINATION " - "arguments. You may only specify one.")); + status.SetError(cmStrCat(args[0], + " given both TYPE and DESTINATION " + "arguments. You may only specify one.")); return false; } cmInstallGenerator::MessageLevel message = - cmInstallGenerator::SelectMessageLevel(this->Makefile, message_never); + cmInstallGenerator::SelectMessageLevel(helper.Makefile, message_never); // Create the directory install generator. - this->Makefile->AddInstallGenerator(new cmInstallDirectoryGenerator( + helper.Makefile->AddInstallGenerator(new cmInstallDirectoryGenerator( dirs, destination, permissions_file.c_str(), permissions_dir.c_str(), configurations, component.c_str(), message, exclude_from_all, literal_args.c_str(), optional)); // Tell the global generator about any installation component names // specified. - this->Makefile->GetGlobalGenerator()->AddInstallComponent(component); + helper.Makefile->GetGlobalGenerator()->AddInstallComponent(component); return true; } -bool cmInstallCommand::HandleExportAndroidMKMode( - std::vector<std::string> const& args) +bool HandleExportAndroidMKMode(std::vector<std::string> const& args, + cmExecutionStatus& status) { #ifndef CMAKE_BOOTSTRAP + Helper helper(status); + // This is the EXPORT mode. - cmInstallCommandArguments ica(this->DefaultComponentName); + cmInstallCommandArguments ica(helper.DefaultComponentName); std::string exp; std::string name_space; @@ -1224,7 +1233,7 @@ bool cmInstallCommand::HandleExportAndroidMKMode( if (!unknownArgs.empty()) { // Unknown argument. - this->SetError( + status.SetError( cmStrCat(args[0], " given unknown argument \"", unknownArgs[0], "\".")); return false; } @@ -1236,30 +1245,30 @@ bool cmInstallCommand::HandleExportAndroidMKMode( // Make sure there is a destination. if (ica.GetDestination().empty()) { // A destination is required. - this->SetError(cmStrCat(args[0], " given no DESTINATION!")); + status.SetError(cmStrCat(args[0], " given no DESTINATION!")); return false; } // Check the file name. std::string fname = filename; if (fname.find_first_of(":/\\") != std::string::npos) { - this->SetError(cmStrCat(args[0], " given invalid export file name \"", - fname, - "\". The FILE argument may not contain a path. " - "Specify the path in the DESTINATION argument.")); + status.SetError(cmStrCat(args[0], " given invalid export file name \"", + fname, + "\". The FILE argument may not contain a path. " + "Specify the path in the DESTINATION argument.")); return false; } // Check the file extension. if (!fname.empty() && cmSystemTools::GetFilenameLastExtension(fname) != ".mk") { - this->SetError(cmStrCat( + status.SetError(cmStrCat( args[0], " given invalid export file name \"", fname, R"(". The FILE argument must specify a name ending in ".mk".)")); return false; } if (fname.find_first_of(":/\\") != std::string::npos) { - this->SetError( + status.SetError( cmStrCat(args[0], " given export name \"", exp, "\". " "This name cannot be safely converted to a file name. " @@ -1273,10 +1282,10 @@ bool cmInstallCommand::HandleExportAndroidMKMode( } cmExportSet& exportSet = - this->Makefile->GetGlobalGenerator()->GetExportSets()[exp]; + helper.Makefile->GetGlobalGenerator()->GetExportSets()[exp]; cmInstallGenerator::MessageLevel message = - cmInstallGenerator::SelectMessageLevel(this->Makefile); + cmInstallGenerator::SelectMessageLevel(helper.Makefile); // Create the export install generator. cmInstallExportGenerator* exportGenerator = new cmInstallExportGenerator( @@ -1284,20 +1293,23 @@ bool cmInstallCommand::HandleExportAndroidMKMode( ica.GetConfigurations(), ica.GetComponent().c_str(), message, ica.GetExcludeFromAll(), fname.c_str(), name_space.c_str(), exportOld, true); - this->Makefile->AddInstallGenerator(exportGenerator); + helper.Makefile->AddInstallGenerator(exportGenerator); return true; #else static_cast<void>(args); - this->SetError("EXPORT_ANDROID_MK not supported in bootstrap cmake"); + status.SetError("EXPORT_ANDROID_MK not supported in bootstrap cmake"); return false; #endif } -bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args) +bool HandleExportMode(std::vector<std::string> const& args, + cmExecutionStatus& status) { + Helper helper(status); + // This is the EXPORT mode. - cmInstallCommandArguments ica(this->DefaultComponentName); + cmInstallCommandArguments ica(helper.DefaultComponentName); std::string exp; std::string name_space; @@ -1314,7 +1326,7 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args) if (!unknownArgs.empty()) { // Unknown argument. - this->SetError( + status.SetError( cmStrCat(args[0], " given unknown argument \"", unknownArgs[0], "\".")); return false; } @@ -1326,25 +1338,25 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args) // Make sure there is a destination. if (ica.GetDestination().empty()) { // A destination is required. - this->SetError(cmStrCat(args[0], " given no DESTINATION!")); + status.SetError(cmStrCat(args[0], " given no DESTINATION!")); return false; } // Check the file name. std::string fname = filename; if (fname.find_first_of(":/\\") != std::string::npos) { - this->SetError(cmStrCat(args[0], " given invalid export file name \"", - fname, - "\". " - "The FILE argument may not contain a path. " - "Specify the path in the DESTINATION argument.")); + status.SetError(cmStrCat(args[0], " given invalid export file name \"", + fname, + "\". " + "The FILE argument may not contain a path. " + "Specify the path in the DESTINATION argument.")); return false; } // Check the file extension. if (!fname.empty() && cmSystemTools::GetFilenameLastExtension(fname) != ".cmake") { - this->SetError( + status.SetError( cmStrCat(args[0], " given invalid export file name \"", fname, "\". " "The FILE argument must specify a name ending in \".cmake\".")); @@ -1356,7 +1368,7 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args) fname = cmStrCat(exp, ".cmake"); if (fname.find_first_of(":/\\") != std::string::npos) { - this->SetError(cmStrCat( + status.SetError(cmStrCat( args[0], " given export name \"", exp, "\". " "This name cannot be safely converted to a file name. " @@ -1367,17 +1379,17 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args) } cmExportSet& exportSet = - this->Makefile->GetGlobalGenerator()->GetExportSets()[exp]; + helper.Makefile->GetGlobalGenerator()->GetExportSets()[exp]; if (exportOld) { for (auto const& te : exportSet.GetTargetExports()) { cmTarget* tgt = - this->Makefile->GetGlobalGenerator()->FindTarget(te->TargetName); + helper.Makefile->GetGlobalGenerator()->FindTarget(te->TargetName); const bool newCMP0022Behavior = (tgt && tgt->GetPolicyStatusCMP0022() != cmPolicies::WARN && tgt->GetPolicyStatusCMP0022() != cmPolicies::OLD); if (!newCMP0022Behavior) { - this->SetError(cmStrCat( + status.SetError(cmStrCat( "INSTALL(EXPORT) given keyword \"" "EXPORT_LINK_INTERFACE_LIBRARIES\", but target \"", te->TargetName, "\" does not have policy CMP0022 set to NEW.")); @@ -1387,7 +1399,7 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args) } cmInstallGenerator::MessageLevel message = - cmInstallGenerator::SelectMessageLevel(this->Makefile); + cmInstallGenerator::SelectMessageLevel(helper.Makefile); // Create the export install generator. cmInstallExportGenerator* exportGenerator = new cmInstallExportGenerator( @@ -1395,14 +1407,14 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args) ica.GetConfigurations(), ica.GetComponent().c_str(), message, ica.GetExcludeFromAll(), fname.c_str(), name_space.c_str(), exportOld, false); - this->Makefile->AddInstallGenerator(exportGenerator); + helper.Makefile->AddInstallGenerator(exportGenerator); return true; } -bool cmInstallCommand::MakeFilesFullPath( - const char* modeName, const std::vector<std::string>& relFiles, - std::vector<std::string>& absFiles) +bool Helper::MakeFilesFullPath(const char* modeName, + const std::vector<std::string>& relFiles, + std::vector<std::string>& absFiles) { for (std::string const& relFile : relFiles) { std::string file = relFile; @@ -1424,7 +1436,7 @@ bool cmInstallCommand::MakeFilesFullPath( return true; } -bool cmInstallCommand::CheckCMP0006(bool& failure) +bool Helper::CheckCMP0006(bool& failure) { switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0006)) { case cmPolicies::WARN: @@ -1449,9 +1461,9 @@ bool cmInstallCommand::CheckCMP0006(bool& failure) return false; } -std::string cmInstallCommand::GetDestination( - const cmInstallCommandArguments* args, const std::string& varName, - const std::string& guess) +std::string Helper::GetDestination(const cmInstallCommandArguments* args, + const std::string& varName, + const std::string& guess) { if (args && !args->GetDestination().empty()) { return args->GetDestination(); @@ -1463,55 +1475,54 @@ std::string cmInstallCommand::GetDestination( return guess; } -std::string cmInstallCommand::GetRuntimeDestination( +std::string Helper::GetRuntimeDestination( const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_BINDIR", "bin"); } -std::string cmInstallCommand::GetSbinDestination( - const cmInstallCommandArguments* args) +std::string Helper::GetSbinDestination(const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_SBINDIR", "sbin"); } -std::string cmInstallCommand::GetArchiveDestination( +std::string Helper::GetArchiveDestination( const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_LIBDIR", "lib"); } -std::string cmInstallCommand::GetLibraryDestination( +std::string Helper::GetLibraryDestination( const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_LIBDIR", "lib"); } -std::string cmInstallCommand::GetIncludeDestination( +std::string Helper::GetIncludeDestination( const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_INCLUDEDIR", "include"); } -std::string cmInstallCommand::GetSysconfDestination( +std::string Helper::GetSysconfDestination( const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_SYSCONFDIR", "etc"); } -std::string cmInstallCommand::GetSharedStateDestination( +std::string Helper::GetSharedStateDestination( const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_SHAREDSTATEDIR", "com"); } -std::string cmInstallCommand::GetLocalStateDestination( +std::string Helper::GetLocalStateDestination( const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_LOCALSTATEDIR", "var"); } -std::string cmInstallCommand::GetRunStateDestination( +std::string Helper::GetRunStateDestination( const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_RUNSTATEDIR", @@ -1519,49 +1530,44 @@ std::string cmInstallCommand::GetRunStateDestination( "/run"); } -std::string cmInstallCommand::GetDataRootDestination( +std::string Helper::GetDataRootDestination( const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_DATAROOTDIR", "share"); } -std::string cmInstallCommand::GetDataDestination( - const cmInstallCommandArguments* args) +std::string Helper::GetDataDestination(const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_DATADIR", this->GetDataRootDestination(nullptr)); } -std::string cmInstallCommand::GetInfoDestination( - const cmInstallCommandArguments* args) +std::string Helper::GetInfoDestination(const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_INFODIR", this->GetDataRootDestination(nullptr) + "/info"); } -std::string cmInstallCommand::GetLocaleDestination( - const cmInstallCommandArguments* args) +std::string Helper::GetLocaleDestination(const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_LOCALEDIR", this->GetDataRootDestination(nullptr) + "/locale"); } -std::string cmInstallCommand::GetManDestination( - const cmInstallCommandArguments* args) +std::string Helper::GetManDestination(const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_MANDIR", this->GetDataRootDestination(nullptr) + "/man"); } -std::string cmInstallCommand::GetDocDestination( - const cmInstallCommandArguments* args) +std::string Helper::GetDocDestination(const cmInstallCommandArguments* args) { return this->GetDestination(args, "CMAKE_INSTALL_DOCDIR", this->GetDataRootDestination(nullptr) + "/doc"); } -std::string cmInstallCommand::GetDestinationForType( +std::string Helper::GetDestinationForType( const cmInstallCommandArguments* args, const std::string& type) { if (args && !args->GetDestination().empty()) { @@ -1608,3 +1614,31 @@ std::string cmInstallCommand::GetDestinationForType( } return ""; } + +} // namespace + +bool cmInstallCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + // Allow calling with no arguments so that arguments may be built up + // using a variable that may be left empty. + if (args.empty()) { + return true; + } + + // Enable the install target. + status.GetMakefile().GetGlobalGenerator()->EnableInstallTarget(); + + static cmSubcommandTable const subcommand{ + { "SCRIPT"_s, HandleScriptMode }, + { "CODE"_s, HandleScriptMode }, + { "TARGETS"_s, HandleTargetsMode }, + { "FILES"_s, HandleFilesMode }, + { "PROGRAMS"_s, HandleFilesMode }, + { "DIRECTORY"_s, HandleDirectoryMode }, + { "EXPORT"_s, HandleExportMode }, + { "EXPORT_ANDROID_MK"_s, HandleExportAndroidMKMode }, + }; + + return subcommand(args[0], args, status); +} diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h index 9ffb842..32f00ce 100644 --- a/Source/cmInstallCommand.h +++ b/Source/cmInstallCommand.h @@ -8,71 +8,9 @@ #include <string> #include <vector> -#include <cm/memory> - -#include "cmCommand.h" - class cmExecutionStatus; -class cmInstallCommandArguments; - -/** \class cmInstallCommand - * \brief Specifies where to install some files - * - * cmInstallCommand is a general-purpose interface command for - * specifying install rules. - */ -class cmInstallCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmInstallCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - bool HandleScriptMode(std::vector<std::string> const& args); - bool HandleTargetsMode(std::vector<std::string> const& args); - bool HandleFilesMode(std::vector<std::string> const& args); - bool HandleDirectoryMode(std::vector<std::string> const& args); - bool HandleExportMode(std::vector<std::string> const& args); - bool HandleExportAndroidMKMode(std::vector<std::string> const& args); - bool MakeFilesFullPath(const char* modeName, - const std::vector<std::string>& relFiles, - std::vector<std::string>& absFiles); - bool CheckCMP0006(bool& failure); - - std::string GetDestination(const cmInstallCommandArguments* args, - const std::string& varName, - const std::string& guess); - std::string GetRuntimeDestination(const cmInstallCommandArguments* args); - std::string GetSbinDestination(const cmInstallCommandArguments* args); - std::string GetArchiveDestination(const cmInstallCommandArguments* args); - std::string GetLibraryDestination(const cmInstallCommandArguments* args); - std::string GetIncludeDestination(const cmInstallCommandArguments* args); - std::string GetSysconfDestination(const cmInstallCommandArguments* args); - std::string GetSharedStateDestination(const cmInstallCommandArguments* args); - std::string GetLocalStateDestination(const cmInstallCommandArguments* args); - std::string GetRunStateDestination(const cmInstallCommandArguments* args); - std::string GetDataRootDestination(const cmInstallCommandArguments* args); - std::string GetDataDestination(const cmInstallCommandArguments* args); - std::string GetInfoDestination(const cmInstallCommandArguments* args); - std::string GetLocaleDestination(const cmInstallCommandArguments* args); - std::string GetManDestination(const cmInstallCommandArguments* args); - std::string GetDocDestination(const cmInstallCommandArguments* args); - std::string GetDestinationForType(const cmInstallCommandArguments* args, - const std::string& type); - std::string DefaultComponentName; -}; +bool cmInstallCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmLinkDirectoriesCommand.cxx b/Source/cmLinkDirectoriesCommand.cxx index 57b69c8..2914046 100644 --- a/Source/cmLinkDirectoriesCommand.cxx +++ b/Source/cmLinkDirectoriesCommand.cxx @@ -4,6 +4,7 @@ #include <sstream> +#include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" #include "cmMakefile.h" #include "cmMessageType.h" @@ -11,17 +12,18 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; +static void AddLinkDir(cmMakefile& mf, std::string const& dir, + std::vector<std::string>& directories); -// cmLinkDirectoriesCommand -bool cmLinkDirectoriesCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmLinkDirectoriesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { return true; } - bool before = this->Makefile->IsOn("CMAKE_LINK_DIRECTORIES_BEFORE"); + cmMakefile& mf = status.GetMakefile(); + bool before = mf.IsOn("CMAKE_LINK_DIRECTORIES_BEFORE"); auto i = args.cbegin(); if ((*i) == "BEFORE") { @@ -34,16 +36,16 @@ bool cmLinkDirectoriesCommand::InitialPass( std::vector<std::string> directories; for (; i != args.cend(); ++i) { - this->AddLinkDir(*i, directories); + AddLinkDir(mf, *i, directories); } - this->Makefile->AddLinkDirectory(cmJoin(directories, ";"), before); + mf.AddLinkDirectory(cmJoin(directories, ";"), before); return true; } -void cmLinkDirectoriesCommand::AddLinkDir( - std::string const& dir, std::vector<std::string>& directories) +static void AddLinkDir(cmMakefile& mf, std::string const& dir, + std::vector<std::string>& directories) { std::string unixPath = dir; cmSystemTools::ConvertToUnixSlashes(unixPath); @@ -56,10 +58,10 @@ void cmLinkDirectoriesCommand::AddLinkDir( << " " << unixPath << "\n" << "as a link directory.\n"; /* clang-format on */ - switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0015)) { + switch (mf.GetPolicyStatus(cmPolicies::CMP0015)) { case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0015); - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, e.str()); + mf.IssueMessage(MessageType::AUTHOR_WARNING, e.str()); break; case cmPolicies::OLD: // OLD behavior does not convert @@ -67,7 +69,7 @@ void cmLinkDirectoriesCommand::AddLinkDir( case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0015); - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + mf.IssueMessage(MessageType::FATAL_ERROR, e.str()); CM_FALLTHROUGH; case cmPolicies::NEW: // NEW behavior converts @@ -75,9 +77,7 @@ void cmLinkDirectoriesCommand::AddLinkDir( break; } if (convertToAbsolute) { - std::string tmp = - cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', unixPath); - unixPath = tmp; + unixPath = cmStrCat(mf.GetCurrentSourceDirectory(), '/', unixPath); } } directories.push_back(unixPath); diff --git a/Source/cmLinkDirectoriesCommand.h b/Source/cmLinkDirectoriesCommand.h index 489d90f..a7caa5c 100644 --- a/Source/cmLinkDirectoriesCommand.h +++ b/Source/cmLinkDirectoriesCommand.h @@ -8,41 +8,9 @@ #include <string> #include <vector> -#include <cm/memory> - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmLinkDirectoriesCommand - * \brief Define a list of directories containing files to link. - * - * cmLinkDirectoriesCommand is used to specify a list - * of directories containing files to link into executable(s). - * Note that the command supports the use of CMake built-in variables - * such as CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR. - */ -class cmLinkDirectoriesCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmLinkDirectoriesCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - void AddLinkDir(std::string const& dir, - std::vector<std::string>& directories); -}; +bool cmLinkDirectoriesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx index 3fd7343..cca1633 100644 --- a/Source/cmLoadCacheCommand.cxx +++ b/Source/cmLoadCacheCommand.cxx @@ -3,24 +3,30 @@ #include "cmLoadCacheCommand.h" #include "cmsys/FStream.hxx" +#include <set> +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmStateTypes.h" #include "cmSystemTools.h" #include "cmake.h" -class cmExecutionStatus; +static bool ReadWithPrefix(std::vector<std::string> const& args, + cmExecutionStatus& status); -// cmLoadCacheCommand -bool cmLoadCacheCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +static void CheckLine(cmMakefile& mf, std::string const& prefix, + std::set<std::string> const& variablesToRead, + const char* line); + +bool cmLoadCacheCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { - this->SetError("called with wrong number of arguments."); + status.SetError("called with wrong number of arguments."); } if (args.size() >= 2 && args[1] == "READ_WITH_PREFIX") { - return this->ReadWithPrefix(args); + return ReadWithPrefix(args, status); } // Cache entries to be excluded from the import list. @@ -59,24 +65,26 @@ bool cmLoadCacheCommand::InitialPass(std::vector<std::string> const& args, } } + cmMakefile& mf = status.GetMakefile(); + // Loop over each build directory listed in the arguments. Each // directory has a cache file. for (std::string const& arg : args) { if ((arg == "EXCLUDE") || (arg == "INCLUDE_INTERNALS")) { break; } - this->Makefile->GetCMakeInstance()->LoadCache(arg, false, excludes, - includes); + mf.GetCMakeInstance()->LoadCache(arg, false, excludes, includes); } return true; } -bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args) +static bool ReadWithPrefix(std::vector<std::string> const& args, + cmExecutionStatus& status) { // Make sure we have a prefix. if (args.size() < 3) { - this->SetError("READ_WITH_PREFIX form must specify a prefix."); + status.SetError("READ_WITH_PREFIX form must specify a prefix."); return false; } @@ -84,17 +92,19 @@ bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args) std::string cacheFile = args[0] + "/CMakeCache.txt"; if (!cmSystemTools::FileExists(cacheFile)) { std::string e = "Cannot load cache file from " + cacheFile; - this->SetError(e); + status.SetError(e); return false; } // Prepare the table of variables to read. - this->Prefix = args[2]; - this->VariablesToRead.insert(args.begin() + 3, args.end()); + std::string const prefix = args[2]; + std::set<std::string> const variablesToRead(args.begin() + 3, args.end()); // Read the cache file. cmsys::ifstream fin(cacheFile.c_str()); + cmMakefile& mf = status.GetMakefile(); + // This is a big hack read loop to overcome a buggy ifstream // implementation on HP-UX. This should work on all platforms even // for small buffer sizes. @@ -123,7 +133,7 @@ bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args) } if (i != end) { // Completed a line. - this->CheckLine(line.c_str()); + CheckLine(mf, prefix, variablesToRead, line.c_str()); line.clear(); // Skip the newline character. @@ -134,13 +144,15 @@ bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args) } if (!line.empty()) { // Partial last line. - this->CheckLine(line.c_str()); + CheckLine(mf, prefix, variablesToRead, line.c_str()); } return true; } -void cmLoadCacheCommand::CheckLine(const char* line) +static void CheckLine(cmMakefile& mf, std::string const& prefix, + std::set<std::string> const& variablesToRead, + const char* line) { // Check one line of the cache file. std::string var; @@ -148,14 +160,14 @@ void cmLoadCacheCommand::CheckLine(const char* line) cmStateEnums::CacheEntryType type = cmStateEnums::UNINITIALIZED; if (cmake::ParseCacheEntry(line, var, value, type)) { // Found a real entry. See if this one was requested. - if (this->VariablesToRead.find(var) != this->VariablesToRead.end()) { + if (variablesToRead.find(var) != variablesToRead.end()) { // This was requested. Set this variable locally with the given // prefix. - var = this->Prefix + var; + var = prefix + var; if (!value.empty()) { - this->Makefile->AddDefinition(var, value); + mf.AddDefinition(var, value); } else { - this->Makefile->RemoveDefinition(var); + mf.RemoveDefinition(var); } } } diff --git a/Source/cmLoadCacheCommand.h b/Source/cmLoadCacheCommand.h index 37f0372..7cee663 100644 --- a/Source/cmLoadCacheCommand.h +++ b/Source/cmLoadCacheCommand.h @@ -5,45 +5,12 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <set> #include <string> #include <vector> -#include <cm/memory> - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmLoadCacheCommand - * \brief load a cache file - * - * cmLoadCacheCommand loads the non internal values of a cache file - */ -class cmLoadCacheCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmLoadCacheCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -protected: - std::set<std::string> VariablesToRead; - std::string Prefix; - - bool ReadWithPrefix(std::vector<std::string> const& args); - void CheckLine(const char* line); -}; +bool cmLoadCacheCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx index 5fa6a21..373e767 100644 --- a/Source/cmProjectCommand.cxx +++ b/Source/cmProjectCommand.cxx @@ -10,6 +10,7 @@ #include <limits> #include <utility> +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" @@ -17,40 +18,39 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -class cmExecutionStatus; +static bool IncludeByVariable(cmExecutionStatus& status, + const std::string& variable); +static void TopLevelCMakeVarCondSet(cmMakefile& mf, std::string const& name, + std::string const& value); -// cmProjectCommand -bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +bool cmProjectCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { - this->SetError("PROJECT called with incorrect number of arguments"); + status.SetError("PROJECT called with incorrect number of arguments"); return false; } - if (!this->IncludeByVariable("CMAKE_PROJECT_INCLUDE_BEFORE")) { + cmMakefile& mf = status.GetMakefile(); + if (!IncludeByVariable(status, "CMAKE_PROJECT_INCLUDE_BEFORE")) { return false; } std::string const& projectName = args[0]; - this->Makefile->SetProjectName(projectName); + mf.SetProjectName(projectName); - this->Makefile->AddCacheDefinition( - projectName + "_BINARY_DIR", - this->Makefile->GetCurrentBinaryDirectory().c_str(), - "Value Computed by CMake", cmStateEnums::STATIC); - this->Makefile->AddCacheDefinition( - projectName + "_SOURCE_DIR", - this->Makefile->GetCurrentSourceDirectory().c_str(), - "Value Computed by CMake", cmStateEnums::STATIC); + mf.AddCacheDefinition(projectName + "_BINARY_DIR", + mf.GetCurrentBinaryDirectory().c_str(), + "Value Computed by CMake", cmStateEnums::STATIC); + mf.AddCacheDefinition(projectName + "_SOURCE_DIR", + mf.GetCurrentSourceDirectory().c_str(), + "Value Computed by CMake", cmStateEnums::STATIC); - this->Makefile->AddDefinition("PROJECT_BINARY_DIR", - this->Makefile->GetCurrentBinaryDirectory()); - this->Makefile->AddDefinition("PROJECT_SOURCE_DIR", - this->Makefile->GetCurrentSourceDirectory()); + mf.AddDefinition("PROJECT_BINARY_DIR", mf.GetCurrentBinaryDirectory()); + mf.AddDefinition("PROJECT_SOURCE_DIR", mf.GetCurrentSourceDirectory()); - this->Makefile->AddDefinition("PROJECT_NAME", projectName); + mf.AddDefinition("PROJECT_NAME", projectName); // Set the CMAKE_PROJECT_NAME variable to be the highest-level // project name in the tree. If there are two project commands @@ -58,12 +58,10 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, // CMakeLists.txt file, then go with the last one, so that // CMAKE_PROJECT_NAME will match PROJECT_NAME, and cmake --build // will work. - if (!this->Makefile->GetDefinition("CMAKE_PROJECT_NAME") || - (this->Makefile->IsRootMakefile())) { - this->Makefile->AddDefinition("CMAKE_PROJECT_NAME", projectName); - this->Makefile->AddCacheDefinition( - "CMAKE_PROJECT_NAME", projectName.c_str(), "Value Computed by CMake", - cmStateEnums::STATIC); + if (!mf.GetDefinition("CMAKE_PROJECT_NAME") || mf.IsRootMakefile()) { + mf.AddDefinition("CMAKE_PROJECT_NAME", projectName); + mf.AddCacheDefinition("CMAKE_PROJECT_NAME", projectName.c_str(), + "Value Computed by CMake", cmStateEnums::STATIC); } bool haveVersion = false; @@ -90,9 +88,8 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, for (size_t i = 1; i < args.size(); ++i) { if (args[i] == "LANGUAGES") { if (haveLanguages) { - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - "LANGUAGES may be specified at most once."); + mf.IssueMessage(MessageType::FATAL_ERROR, + "LANGUAGES may be specified at most once."); cmSystemTools::SetFatalErrorOccured(); return true; } @@ -106,12 +103,12 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, "the following parameters must be specified after LANGUAGES " "keyword: ", cmJoin(languages, ", "), '.'); - this->Makefile->IssueMessage(MessageType::WARNING, msg); + mf.IssueMessage(MessageType::WARNING, msg); } } else if (args[i] == "VERSION") { if (haveVersion) { - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, - "VERSION may be specified at most once."); + mf.IssueMessage(MessageType::FATAL_ERROR, + "VERSION may be specified at most once."); cmSystemTools::SetFatalErrorOccured(); return true; } @@ -120,8 +117,8 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, missedValueReporter(); } doing = DoingVersion; - missedValueReporter = [this, &resetReporter]() { - this->Makefile->IssueMessage( + missedValueReporter = [&mf, &resetReporter]() { + mf.IssueMessage( MessageType::WARNING, "VERSION keyword not followed by a value or was followed by a " "value that expanded to nothing."); @@ -129,9 +126,8 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, }; } else if (args[i] == "DESCRIPTION") { if (haveDescription) { - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - "DESCRIPTION may be specified at most once."); + mf.IssueMessage(MessageType::FATAL_ERROR, + "DESCRIPTION may be specified at most once."); cmSystemTools::SetFatalErrorOccured(); return true; } @@ -140,8 +136,8 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, missedValueReporter(); } doing = DoingDescription; - missedValueReporter = [this, &resetReporter]() { - this->Makefile->IssueMessage( + missedValueReporter = [&mf, &resetReporter]() { + mf.IssueMessage( MessageType::WARNING, "DESCRIPTION keyword not followed by a value or was followed " "by a value that expanded to nothing."); @@ -149,16 +145,15 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, }; } else if (args[i] == "HOMEPAGE_URL") { if (haveHomepage) { - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - "HOMEPAGE_URL may be specified at most once."); + mf.IssueMessage(MessageType::FATAL_ERROR, + "HOMEPAGE_URL may be specified at most once."); cmSystemTools::SetFatalErrorOccured(); return true; } haveHomepage = true; doing = DoingHomepage; - missedValueReporter = [this, &resetReporter]() { - this->Makefile->IssueMessage( + missedValueReporter = [&mf, &resetReporter]() { + mf.IssueMessage( MessageType::WARNING, "HOMEPAGE_URL keyword not followed by a value or was followed " "by a value that expanded to nothing."); @@ -190,10 +185,9 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, if ((haveVersion || haveDescription || haveHomepage) && !haveLanguages && !languages.empty()) { - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - "project with VERSION, DESCRIPTION or HOMEPAGE_URL must " - "use LANGUAGES before language names."); + mf.IssueMessage(MessageType::FATAL_ERROR, + "project with VERSION, DESCRIPTION or HOMEPAGE_URL must " + "use LANGUAGES before language names."); cmSystemTools::SetFatalErrorOccured(); return true; } @@ -202,13 +196,12 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, } cmPolicies::PolicyStatus const cmp0048 = - this->Makefile->GetPolicyStatus(cmPolicies::CMP0048); + mf.GetPolicyStatus(cmPolicies::CMP0048); if (haveVersion) { // Set project VERSION variables to given values if (cmp0048 == cmPolicies::OLD || cmp0048 == cmPolicies::WARN) { - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - "VERSION not allowed unless CMP0048 is set to NEW"); + mf.IssueMessage(MessageType::FATAL_ERROR, + "VERSION not allowed unless CMP0048 is set to NEW"); cmSystemTools::SetFatalErrorOccured(); return true; } @@ -217,13 +210,13 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, R"(^([0-9]+(\.[0-9]+(\.[0-9]+(\.[0-9]+)?)?)?)?$)"); if (!vx.find(version)) { std::string e = R"(VERSION ")" + version + R"(" format invalid.)"; - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e); + mf.IssueMessage(MessageType::FATAL_ERROR, e); cmSystemTools::SetFatalErrorOccured(); return true; } cmPolicies::PolicyStatus const cmp0096 = - this->Makefile->GetPolicyStatus(cmPolicies::CMP0096); + mf.GetPolicyStatus(cmPolicies::CMP0096); constexpr std::size_t MAX_VERSION_COMPONENTS = 4u; std::string version_string; @@ -257,34 +250,30 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, std::string vv; vv = projectName + "_VERSION"; - this->Makefile->AddDefinition("PROJECT_VERSION", version_string); - this->Makefile->AddDefinition(vv, version_string); + mf.AddDefinition("PROJECT_VERSION", version_string); + mf.AddDefinition(vv, version_string); vv = projectName + "_VERSION_MAJOR"; - this->Makefile->AddDefinition("PROJECT_VERSION_MAJOR", - version_components[0]); - this->Makefile->AddDefinition(vv, version_components[0]); + mf.AddDefinition("PROJECT_VERSION_MAJOR", version_components[0]); + mf.AddDefinition(vv, version_components[0]); vv = projectName + "_VERSION_MINOR"; - this->Makefile->AddDefinition("PROJECT_VERSION_MINOR", - version_components[1]); - this->Makefile->AddDefinition(vv, version_components[1]); + mf.AddDefinition("PROJECT_VERSION_MINOR", version_components[1]); + mf.AddDefinition(vv, version_components[1]); vv = projectName + "_VERSION_PATCH"; - this->Makefile->AddDefinition("PROJECT_VERSION_PATCH", - version_components[2]); - this->Makefile->AddDefinition(vv, version_components[2]); + mf.AddDefinition("PROJECT_VERSION_PATCH", version_components[2]); + mf.AddDefinition(vv, version_components[2]); vv = projectName + "_VERSION_TWEAK"; - this->Makefile->AddDefinition("PROJECT_VERSION_TWEAK", - version_components[3]); - this->Makefile->AddDefinition(vv, version_components[3]); + mf.AddDefinition("PROJECT_VERSION_TWEAK", version_components[3]); + mf.AddDefinition(vv, version_components[3]); // Also, try set top level variables - TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION", version_string.c_str()); - TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MAJOR", - version_components[0].c_str()); - TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MINOR", - version_components[1].c_str()); - TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_PATCH", - version_components[2].c_str()); - TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_TWEAK", - version_components[3].c_str()); + TopLevelCMakeVarCondSet(mf, "CMAKE_PROJECT_VERSION", version_string); + TopLevelCMakeVarCondSet(mf, "CMAKE_PROJECT_VERSION_MAJOR", + version_components[0]); + TopLevelCMakeVarCondSet(mf, "CMAKE_PROJECT_VERSION_MINOR", + version_components[1]); + TopLevelCMakeVarCondSet(mf, "CMAKE_PROJECT_VERSION_PATCH", + version_components[2]); + TopLevelCMakeVarCondSet(mf, "CMAKE_PROJECT_VERSION_TWEAK", + version_components[3]); } else if (cmp0048 != cmPolicies::OLD) { // Set project VERSION variables to empty std::vector<std::string> vv = { "PROJECT_VERSION", @@ -297,7 +286,7 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, projectName + "_VERSION_MINOR", projectName + "_VERSION_PATCH", projectName + "_VERSION_TWEAK" }; - if (this->Makefile->IsRootMakefile()) { + if (mf.IsRootMakefile()) { vv.emplace_back("CMAKE_PROJECT_VERSION"); vv.emplace_back("CMAKE_PROJECT_VERSION_MAJOR"); vv.emplace_back("CMAKE_PROJECT_VERSION_MINOR"); @@ -306,7 +295,7 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, } std::string vw; for (std::string const& i : vv) { - const char* const v = this->Makefile->GetDefinition(i); + const char* const v = mf.GetDefinition(i); if (v && *v) { if (cmp0048 == cmPolicies::WARN) { if (!injectedProjectCommand) { @@ -314,51 +303,54 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, vw += i; } } else { - this->Makefile->AddDefinition(i, ""); + mf.AddDefinition(i, ""); } } } if (!vw.empty()) { - this->Makefile->IssueMessage( + mf.IssueMessage( MessageType::AUTHOR_WARNING, cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0048), "\nThe following variable(s) would be set to empty:", vw)); } } - this->Makefile->AddDefinition("PROJECT_DESCRIPTION", description); - this->Makefile->AddDefinition(projectName + "_DESCRIPTION", description); - TopLevelCMakeVarCondSet("CMAKE_PROJECT_DESCRIPTION", description.c_str()); + mf.AddDefinition("PROJECT_DESCRIPTION", description); + mf.AddDefinition(projectName + "_DESCRIPTION", description); + TopLevelCMakeVarCondSet(mf, "CMAKE_PROJECT_DESCRIPTION", description); - this->Makefile->AddDefinition("PROJECT_HOMEPAGE_URL", homepage); - this->Makefile->AddDefinition(projectName + "_HOMEPAGE_URL", homepage); - TopLevelCMakeVarCondSet("CMAKE_PROJECT_HOMEPAGE_URL", homepage.c_str()); + mf.AddDefinition("PROJECT_HOMEPAGE_URL", homepage); + mf.AddDefinition(projectName + "_HOMEPAGE_URL", homepage); + TopLevelCMakeVarCondSet(mf, "CMAKE_PROJECT_HOMEPAGE_URL", homepage); if (languages.empty()) { // if no language is specified do c and c++ languages = { "C", "CXX" }; } - this->Makefile->EnableLanguage(languages, false); + mf.EnableLanguage(languages, false); - if (!this->IncludeByVariable("CMAKE_PROJECT_INCLUDE")) { + if (!IncludeByVariable(status, "CMAKE_PROJECT_INCLUDE")) { return false; } - if (!this->IncludeByVariable("CMAKE_PROJECT_" + projectName + "_INCLUDE")) { + if (!IncludeByVariable(status, + "CMAKE_PROJECT_" + projectName + "_INCLUDE")) { return false; } return true; } -bool cmProjectCommand::IncludeByVariable(const std::string& variable) +static bool IncludeByVariable(cmExecutionStatus& status, + const std::string& variable) { - const char* const include = this->Makefile->GetDefinition(variable); + cmMakefile& mf = status.GetMakefile(); + const char* const include = mf.GetDefinition(variable); if (!include) { return true; } - const bool readit = this->Makefile->ReadDependentFile(include); + const bool readit = mf.ReadDependentFile(include); if (readit) { return true; } @@ -367,24 +359,20 @@ bool cmProjectCommand::IncludeByVariable(const std::string& variable) return true; } - std::string m = cmStrCat("could not find file:\n" - " ", - include); - this->SetError(m); + status.SetError(cmStrCat("could not find file:\n ", include)); return false; } -void cmProjectCommand::TopLevelCMakeVarCondSet(const char* const name, - const char* const value) +static void TopLevelCMakeVarCondSet(cmMakefile& mf, std::string const& name, + std::string const& value) { // Set the CMAKE_PROJECT_XXX variable to be the highest-level // project name in the tree. If there are two project commands // in the same CMakeLists.txt file, and it is the top level // CMakeLists.txt file, then go with the last one. - if (!this->Makefile->GetDefinition(name) || - (this->Makefile->IsRootMakefile())) { - this->Makefile->AddDefinition(name, value); - this->Makefile->AddCacheDefinition(name, value, "Value Computed by CMake", - cmStateEnums::STATIC); + if (!mf.GetDefinition(name) || mf.IsRootMakefile()) { + mf.AddDefinition(name, value); + mf.AddCacheDefinition(name, value.c_str(), "Value Computed by CMake", + cmStateEnums::STATIC); } } diff --git a/Source/cmProjectCommand.h b/Source/cmProjectCommand.h index ffbd330..c06b459 100644 --- a/Source/cmProjectCommand.h +++ b/Source/cmProjectCommand.h @@ -8,41 +8,9 @@ #include <string> #include <vector> -#include <cm/memory> - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmProjectCommand - * \brief Specify the name for this build project. - * - * cmProjectCommand is used to specify a name for this build project. - * It is defined once per set of CMakeList.txt files (including - * all subdirectories). Currently it just sets the name of the workspace - * file for Microsoft Visual C++ - */ -class cmProjectCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmProjectCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - bool IncludeByVariable(const std::string& variable); - void TopLevelCMakeVarCondSet(const char* name, const char* value); -}; +bool cmProjectCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmSetTargetPropertiesCommand.cxx b/Source/cmSetTargetPropertiesCommand.cxx index b4360e4..8d917db 100644 --- a/Source/cmSetTargetPropertiesCommand.cxx +++ b/Source/cmSetTargetPropertiesCommand.cxx @@ -5,31 +5,32 @@ #include <iterator> #include "cmAlgorithms.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmStringAlgorithms.h" #include "cmTarget.h" -class cmExecutionStatus; +static bool SetOneTarget(const std::string& tname, + std::vector<std::string>& propertyPairs, + cmMakefile* mf); -// cmSetTargetPropertiesCommand -bool cmSetTargetPropertiesCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +bool cmSetTargetPropertiesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.size() < 2) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } // first collect up the list of files std::vector<std::string> propertyPairs; int numFiles = 0; - std::vector<std::string>::const_iterator j; - for (j = args.begin(); j != args.end(); ++j) { + for (auto j = args.begin(); j != args.end(); ++j) { if (*j == "PROPERTIES") { // now loop through the rest of the arguments, new style ++j; if (std::distance(j, args.end()) % 2 != 0) { - this->SetError("called with incorrect number of arguments."); + status.SetError("called with incorrect number of arguments."); return false; } cmAppend(propertyPairs, j, args.end()); @@ -38,33 +39,32 @@ bool cmSetTargetPropertiesCommand::InitialPass( numFiles++; } if (propertyPairs.empty()) { - this->SetError("called with illegal arguments, maybe missing " - "a PROPERTIES specifier?"); + status.SetError("called with illegal arguments, maybe missing " + "a PROPERTIES specifier?"); return false; } + cmMakefile& mf = status.GetMakefile(); + // now loop over all the targets - int i; - for (i = 0; i < numFiles; ++i) { - if (this->Makefile->IsAlias(args[i])) { - this->SetError("can not be used on an ALIAS target."); + for (int i = 0; i < numFiles; ++i) { + if (mf.IsAlias(args[i])) { + status.SetError("can not be used on an ALIAS target."); return false; } - bool ret = cmSetTargetPropertiesCommand::SetOneTarget( - args[i], propertyPairs, this->Makefile); + bool ret = SetOneTarget(args[i], propertyPairs, &mf); if (!ret) { - std::string message = - cmStrCat("Can not find target to add properties to: ", args[i]); - this->SetError(message); + status.SetError( + cmStrCat("Can not find target to add properties to: ", args[i])); return false; } } return true; } -bool cmSetTargetPropertiesCommand::SetOneTarget( - const std::string& tname, std::vector<std::string>& propertyPairs, - cmMakefile* mf) +static bool SetOneTarget(const std::string& tname, + std::vector<std::string>& propertyPairs, + cmMakefile* mf) { if (cmTarget* target = mf->FindTargetToUse(tname)) { // now loop through all the props and set them diff --git a/Source/cmSetTargetPropertiesCommand.h b/Source/cmSetTargetPropertiesCommand.h index e77b752..9d40c74 100644 --- a/Source/cmSetTargetPropertiesCommand.h +++ b/Source/cmSetTargetPropertiesCommand.h @@ -8,34 +8,9 @@ #include <string> #include <vector> -#include <cm/memory> - -#include "cmCommand.h" - class cmExecutionStatus; -class cmMakefile; - -class cmSetTargetPropertiesCommand : public cmCommand -{ -public: - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmSetTargetPropertiesCommand>(); - } - - /** - * This is called when the command is first encountered in - * the input file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - /** - * Used by this command and cmSetPropertiesCommand - */ - static bool SetOneTarget(const std::string& tname, - std::vector<std::string>& propertyPairs, - cmMakefile* mf); -}; +bool cmSetTargetPropertiesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx index 3be7fec..3a13e57 100644 --- a/Source/cmSourceGroupCommand.cxx +++ b/Source/cmSourceGroupCommand.cxx @@ -3,16 +3,22 @@ #include "cmSourceGroupCommand.h" #include <cstddef> +#include <map> #include <set> #include <utility> #include "cmAlgorithms.h" +#include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmSourceGroup.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" namespace { + +using ParsedArguments = std::map<std::string, std::vector<std::string>>; +using ExpectedOptions = std::vector<std::string>; + const std::string kTreeOptionName = "TREE"; const std::string kPrefixOptionName = "PREFIX"; const std::string kFilesOptionName = "FILES"; @@ -117,13 +123,8 @@ bool addFilesToItsSourceGroups(const std::string& root, return true; } -} -class cmExecutionStatus; - -// cmSourceGroupCommand -cmSourceGroupCommand::ExpectedOptions -cmSourceGroupCommand::getExpectedOptions() const +ExpectedOptions getExpectedOptions() { ExpectedOptions options; @@ -135,15 +136,14 @@ cmSourceGroupCommand::getExpectedOptions() const return options; } -bool cmSourceGroupCommand::isExpectedOption( - const std::string& argument, const ExpectedOptions& expectedOptions) +bool isExpectedOption(const std::string& argument, + const ExpectedOptions& expectedOptions) { return cmContains(expectedOptions, argument); } -void cmSourceGroupCommand::parseArguments( - const std::vector<std::string>& args, - cmSourceGroupCommand::ParsedArguments& parsedArguments) +void parseArguments(const std::vector<std::string>& args, + ParsedArguments& parsedArguments) { const ExpectedOptions expectedOptions = getExpectedOptions(); size_t i = 0; @@ -172,21 +172,35 @@ void cmSourceGroupCommand::parseArguments( } } -bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args, - cmExecutionStatus&) +} // namespace + +static bool checkArgumentsPreconditions(const ParsedArguments& parsedArguments, + std::string& errorMsg); + +static bool processTree(cmMakefile& mf, ParsedArguments& parsedArguments, + std::string& errorMsg); + +static bool checkSingleParameterArgumentPreconditions( + const std::string& argument, const ParsedArguments& parsedArguments, + std::string& errorMsg); + +bool cmSourceGroupCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { if (args.empty()) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } + cmMakefile& mf = status.GetMakefile(); + // If only two arguments are given, the pre-1.8 version of the // command is being invoked. if (args.size() == 2 && args[1] != "FILES") { - cmSourceGroup* sg = this->Makefile->GetOrCreateSourceGroup(args[0]); + cmSourceGroup* sg = mf.GetOrCreateSourceGroup(args[0]); if (!sg) { - this->SetError("Could not create or find source group"); + status.SetError("Could not create or find source group"); return false; } @@ -204,21 +218,21 @@ bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args, } if (parsedArguments.find(kTreeOptionName) != parsedArguments.end()) { - if (!processTree(parsedArguments, errorMsg)) { - this->SetError(errorMsg); + if (!processTree(mf, parsedArguments, errorMsg)) { + status.SetError(errorMsg); return false; } } else { if (parsedArguments.find(kSourceGroupOptionName) == parsedArguments.end()) { - this->SetError("Missing source group name."); + status.SetError("Missing source group name."); return false; } - cmSourceGroup* sg = this->Makefile->GetOrCreateSourceGroup(args[0]); + cmSourceGroup* sg = mf.GetOrCreateSourceGroup(args[0]); if (!sg) { - this->SetError("Could not create or find source group"); + status.SetError("Could not create or find source group"); return false; } @@ -234,8 +248,7 @@ bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args, for (auto const& filesArg : filesArguments) { std::string src = filesArg; if (!cmSystemTools::FileIsFullPath(src)) { - src = - cmStrCat(this->Makefile->GetCurrentSourceDirectory(), '/', filesArg); + src = cmStrCat(mf.GetCurrentSourceDirectory(), '/', filesArg); } src = cmSystemTools::CollapseFullPath(src); sg->AddGroupFile(src); @@ -245,8 +258,8 @@ bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args, return true; } -bool cmSourceGroupCommand::checkArgumentsPreconditions( - const ParsedArguments& parsedArguments, std::string& errorMsg) const +static bool checkArgumentsPreconditions(const ParsedArguments& parsedArguments, + std::string& errorMsg) { return checkSingleParameterArgumentPreconditions( kPrefixOptionName, parsedArguments, errorMsg) && @@ -256,8 +269,8 @@ bool cmSourceGroupCommand::checkArgumentsPreconditions( parsedArguments, errorMsg); } -bool cmSourceGroupCommand::processTree(ParsedArguments& parsedArguments, - std::string& errorMsg) +static bool processTree(cmMakefile& mf, ParsedArguments& parsedArguments, + std::string& errorMsg) { const std::string root = cmSystemTools::CollapseFullPath(parsedArguments[kTreeOptionName].front()); @@ -265,9 +278,8 @@ bool cmSourceGroupCommand::processTree(ParsedArguments& parsedArguments, ? "" : parsedArguments[kPrefixOptionName].front(); - const std::vector<std::string> filesVector = - prepareFilesPathsForTree(parsedArguments[kFilesOptionName], - this->Makefile->GetCurrentSourceDirectory()); + const std::vector<std::string> filesVector = prepareFilesPathsForTree( + parsedArguments[kFilesOptionName], mf.GetCurrentSourceDirectory()); if (!rootIsPrefix(root, filesVector, errorMsg)) { return false; @@ -276,13 +288,13 @@ bool cmSourceGroupCommand::processTree(ParsedArguments& parsedArguments, std::set<std::string> sourceGroupPaths = getSourceGroupFilesPaths(root, filesVector); - return addFilesToItsSourceGroups(root, sourceGroupPaths, prefix, - *(this->Makefile), errorMsg); + return addFilesToItsSourceGroups(root, sourceGroupPaths, prefix, mf, + errorMsg); } -bool cmSourceGroupCommand::checkSingleParameterArgumentPreconditions( +static bool checkSingleParameterArgumentPreconditions( const std::string& argument, const ParsedArguments& parsedArguments, - std::string& errorMsg) const + std::string& errorMsg) { auto foundArgument = parsedArguments.find(argument); if (foundArgument != parsedArguments.end()) { diff --git a/Source/cmSourceGroupCommand.h b/Source/cmSourceGroupCommand.h index 6273d92..ad39701 100644 --- a/Source/cmSourceGroupCommand.h +++ b/Source/cmSourceGroupCommand.h @@ -5,59 +5,12 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include <map> #include <string> #include <vector> -#include <cm/memory> - -#include "cmCommand.h" - class cmExecutionStatus; -/** \class cmSourceGroupCommand - * \brief Adds a cmSourceGroup to the cmMakefile. - * - * cmSourceGroupCommand is used to define cmSourceGroups which split up - * source files in to named, organized groups in the generated makefiles. - */ -class cmSourceGroupCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmSourceGroupCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - using ParsedArguments = std::map<std::string, std::vector<std::string>>; - using ExpectedOptions = std::vector<std::string>; - - ExpectedOptions getExpectedOptions() const; - - bool isExpectedOption(const std::string& argument, - const ExpectedOptions& expectedOptions); - - void parseArguments(const std::vector<std::string>& args, - cmSourceGroupCommand::ParsedArguments& parsedArguments); - - bool processTree(ParsedArguments& parsedArguments, std::string& errorMsg); - - bool checkArgumentsPreconditions(const ParsedArguments& parsedArguments, - std::string& errorMsg) const; - bool checkSingleParameterArgumentPreconditions( - const std::string& argument, const ParsedArguments& parsedArguments, - std::string& errorMsg) const; -}; +bool cmSourceGroupCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index b432599..0d2383a 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -5,6 +5,7 @@ #include <cstring> #include <sstream> +#include "cmExecutionStatus.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" @@ -15,44 +16,64 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" +#include "cmTargetLinkLibraryType.h" #include "cmake.h" -class cmExecutionStatus; +namespace { -const char* cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[3] = { - "general", "debug", "optimized" +enum ProcessingState +{ + ProcessingLinkLibraries, + ProcessingPlainLinkInterface, + ProcessingKeywordLinkInterface, + ProcessingPlainPublicInterface, + ProcessingKeywordPublicInterface, + ProcessingPlainPrivateInterface, + ProcessingKeywordPrivateInterface }; -// cmTargetLinkLibrariesCommand -bool cmTargetLinkLibrariesCommand::InitialPass( - std::vector<std::string> const& args, cmExecutionStatus&) +const char* LinkLibraryTypeNames[3] = { "general", "debug", "optimized" }; + +} // namespace + +static void LinkLibraryTypeSpecifierWarning(cmMakefile& mf, int left, + int right); + +static bool HandleLibrary(cmMakefile& mf, cmTarget* target, + ProcessingState currentProcessingState, + const std::string& lib, cmTargetLinkLibraryType llt); + +bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status) { // Must have at least one argument. if (args.empty()) { - this->SetError("called with incorrect number of arguments"); + status.SetError("called with incorrect number of arguments"); return false; } + + cmMakefile& mf = status.GetMakefile(); + // Alias targets cannot be on the LHS of this command. - if (this->Makefile->IsAlias(args[0])) { - this->SetError("can not be used on an ALIAS target."); + if (mf.IsAlias(args[0])) { + status.SetError("can not be used on an ALIAS target."); return false; } // Lookup the target for which libraries are specified. - this->Target = - this->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget( - args[0]); - if (!this->Target) { + cmTarget* target = + mf.GetCMakeInstance()->GetGlobalGenerator()->FindTarget(args[0]); + if (!target) { const std::vector<cmTarget*>& importedTargets = - this->Makefile->GetOwnedImportedTargets(); + mf.GetOwnedImportedTargets(); for (cmTarget* importedTarget : importedTargets) { if (importedTarget->GetName() == args[0]) { - this->Target = importedTarget; + target = importedTarget; break; } } } - if (!this->Target) { + if (!target) { MessageType t = MessageType::FATAL_ERROR; // fail by default std::ostringstream e; e << "Cannot specify link libraries for target \"" << args[0] << "\" " @@ -60,7 +81,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass( // The bad target is the only argument. Check how policy CMP0016 is set, // and accept, warn or fail respectively: if (args.size() < 2) { - switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0016)) { + switch (mf.GetPolicyStatus(cmPolicies::CMP0016)) { case cmPolicies::WARN: t = MessageType::AUTHOR_WARNING; // Print the warning. @@ -84,10 +105,10 @@ bool cmTargetLinkLibrariesCommand::InitialPass( // Now actually print the message. switch (t) { case MessageType::AUTHOR_WARNING: - this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, e.str()); + mf.IssueMessage(MessageType::AUTHOR_WARNING, e.str()); break; case MessageType::FATAL_ERROR: - this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + mf.IssueMessage(MessageType::FATAL_ERROR, e.str()); cmSystemTools::SetFatalErrorOccured(); break; default: @@ -97,11 +118,11 @@ bool cmTargetLinkLibrariesCommand::InitialPass( } // Having a UTILITY library on the LHS is a bug. - if (this->Target->GetType() == cmStateEnums::UTILITY) { + if (target->GetType() == cmStateEnums::UTILITY) { std::ostringstream e; const char* modal = nullptr; MessageType messageType = MessageType::AUTHOR_WARNING; - switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0039)) { + switch (mf.GetPolicyStatus(cmPolicies::CMP0039)) { case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0039) << "\n"; modal = "should"; @@ -114,9 +135,9 @@ bool cmTargetLinkLibrariesCommand::InitialPass( messageType = MessageType::FATAL_ERROR; } if (modal) { - e << "Utility target \"" << this->Target->GetName() << "\" " << modal + e << "Utility target \"" << target->GetName() << "\" " << modal << " not be used as the target of a target_link_libraries call."; - this->Makefile->IssueMessage(messageType, e.str()); + mf.IssueMessage(messageType, e.str()); if (messageType == MessageType::FATAL_ERROR) { return false; } @@ -134,15 +155,15 @@ bool cmTargetLinkLibrariesCommand::InitialPass( // Start with primary linking and switch to link interface // specification if the keyword is encountered as the first argument. - this->CurrentProcessingState = ProcessingLinkLibraries; + ProcessingState currentProcessingState = ProcessingLinkLibraries; // Add libraries, note that there is an optional prefix // of debug and optimized that can be used. for (unsigned int i = 1; i < args.size(); ++i) { if (args[i] == "LINK_INTERFACE_LIBRARIES") { - this->CurrentProcessingState = ProcessingPlainLinkInterface; + currentProcessingState = ProcessingPlainLinkInterface; if (i != 1) { - this->Makefile->IssueMessage( + mf.IssueMessage( MessageType::FATAL_ERROR, "The LINK_INTERFACE_LIBRARIES option must appear as the second " "argument, just after the target name."); @@ -150,84 +171,83 @@ bool cmTargetLinkLibrariesCommand::InitialPass( } } else if (args[i] == "INTERFACE") { if (i != 1 && - this->CurrentProcessingState != ProcessingKeywordPrivateInterface && - this->CurrentProcessingState != ProcessingKeywordPublicInterface && - this->CurrentProcessingState != ProcessingKeywordLinkInterface) { - this->Makefile->IssueMessage( + currentProcessingState != ProcessingKeywordPrivateInterface && + currentProcessingState != ProcessingKeywordPublicInterface && + currentProcessingState != ProcessingKeywordLinkInterface) { + mf.IssueMessage( MessageType::FATAL_ERROR, "The INTERFACE, PUBLIC or PRIVATE option must appear as the second " "argument, just after the target name."); return true; } - this->CurrentProcessingState = ProcessingKeywordLinkInterface; + currentProcessingState = ProcessingKeywordLinkInterface; } else if (args[i] == "LINK_PUBLIC") { if (i != 1 && - this->CurrentProcessingState != ProcessingPlainPrivateInterface && - this->CurrentProcessingState != ProcessingPlainPublicInterface) { - this->Makefile->IssueMessage( + currentProcessingState != ProcessingPlainPrivateInterface && + currentProcessingState != ProcessingPlainPublicInterface) { + mf.IssueMessage( MessageType::FATAL_ERROR, "The LINK_PUBLIC or LINK_PRIVATE option must appear as the second " "argument, just after the target name."); return true; } - this->CurrentProcessingState = ProcessingPlainPublicInterface; + currentProcessingState = ProcessingPlainPublicInterface; } else if (args[i] == "PUBLIC") { if (i != 1 && - this->CurrentProcessingState != ProcessingKeywordPrivateInterface && - this->CurrentProcessingState != ProcessingKeywordPublicInterface && - this->CurrentProcessingState != ProcessingKeywordLinkInterface) { - this->Makefile->IssueMessage( + currentProcessingState != ProcessingKeywordPrivateInterface && + currentProcessingState != ProcessingKeywordPublicInterface && + currentProcessingState != ProcessingKeywordLinkInterface) { + mf.IssueMessage( MessageType::FATAL_ERROR, "The INTERFACE, PUBLIC or PRIVATE option must appear as the second " "argument, just after the target name."); return true; } - this->CurrentProcessingState = ProcessingKeywordPublicInterface; + currentProcessingState = ProcessingKeywordPublicInterface; } else if (args[i] == "LINK_PRIVATE") { - if (i != 1 && - this->CurrentProcessingState != ProcessingPlainPublicInterface && - this->CurrentProcessingState != ProcessingPlainPrivateInterface) { - this->Makefile->IssueMessage( + if (i != 1 && currentProcessingState != ProcessingPlainPublicInterface && + currentProcessingState != ProcessingPlainPrivateInterface) { + mf.IssueMessage( MessageType::FATAL_ERROR, "The LINK_PUBLIC or LINK_PRIVATE option must appear as the second " "argument, just after the target name."); return true; } - this->CurrentProcessingState = ProcessingPlainPrivateInterface; + currentProcessingState = ProcessingPlainPrivateInterface; } else if (args[i] == "PRIVATE") { if (i != 1 && - this->CurrentProcessingState != ProcessingKeywordPrivateInterface && - this->CurrentProcessingState != ProcessingKeywordPublicInterface && - this->CurrentProcessingState != ProcessingKeywordLinkInterface) { - this->Makefile->IssueMessage( + currentProcessingState != ProcessingKeywordPrivateInterface && + currentProcessingState != ProcessingKeywordPublicInterface && + currentProcessingState != ProcessingKeywordLinkInterface) { + mf.IssueMessage( MessageType::FATAL_ERROR, "The INTERFACE, PUBLIC or PRIVATE option must appear as the second " "argument, just after the target name."); return true; } - this->CurrentProcessingState = ProcessingKeywordPrivateInterface; + currentProcessingState = ProcessingKeywordPrivateInterface; } else if (args[i] == "debug") { if (haveLLT) { - this->LinkLibraryTypeSpecifierWarning(llt, DEBUG_LibraryType); + LinkLibraryTypeSpecifierWarning(mf, llt, DEBUG_LibraryType); } llt = DEBUG_LibraryType; haveLLT = true; } else if (args[i] == "optimized") { if (haveLLT) { - this->LinkLibraryTypeSpecifierWarning(llt, OPTIMIZED_LibraryType); + LinkLibraryTypeSpecifierWarning(mf, llt, OPTIMIZED_LibraryType); } llt = OPTIMIZED_LibraryType; haveLLT = true; } else if (args[i] == "general") { if (haveLLT) { - this->LinkLibraryTypeSpecifierWarning(llt, GENERAL_LibraryType); + LinkLibraryTypeSpecifierWarning(mf, llt, GENERAL_LibraryType); } llt = GENERAL_LibraryType; haveLLT = true; } else if (haveLLT) { // The link type was specified by the previous argument. haveLLT = false; - if (!this->HandleLibrary(args[i], llt)) { + if (!HandleLibrary(mf, target, currentProcessingState, args[i], llt)) { return false; } } else { @@ -239,7 +259,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass( // with old versions of CMake and new) llt = GENERAL_LibraryType; std::string linkType = cmStrCat(args[0], "_LINK_TYPE"); - const char* linkTypeString = this->Makefile->GetDefinition(linkType); + const char* linkTypeString = mf.GetDefinition(linkType); if (linkTypeString) { if (strcmp(linkTypeString, "debug") == 0) { llt = DEBUG_LibraryType; @@ -248,7 +268,7 @@ bool cmTargetLinkLibrariesCommand::InitialPass( llt = OPTIMIZED_LibraryType; } } - if (!this->HandleLibrary(args[i], llt)) { + if (!HandleLibrary(mf, target, currentProcessingState, args[i], llt)) { return false; } } @@ -256,16 +276,14 @@ bool cmTargetLinkLibrariesCommand::InitialPass( // Make sure the last argument was not a library type specifier. if (haveLLT) { - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - cmStrCat("The \"", - cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[llt], - "\" argument must be followed by a library.")); + mf.IssueMessage(MessageType::FATAL_ERROR, + cmStrCat("The \"", LinkLibraryTypeNames[llt], + "\" argument must be followed by a library.")); cmSystemTools::SetFatalErrorOccured(); } const cmPolicies::PolicyStatus policy22Status = - this->Target->GetPolicyStatusCMP0022(); + target->GetPolicyStatusCMP0022(); // If any of the LINK_ options were given, make sure the // LINK_INTERFACE_LIBRARIES target property exists. @@ -274,41 +292,40 @@ bool cmTargetLinkLibrariesCommand::InitialPass( // result in an empty link interface. if ((policy22Status == cmPolicies::OLD || policy22Status == cmPolicies::WARN) && - this->CurrentProcessingState != ProcessingLinkLibraries && - !this->Target->GetProperty("LINK_INTERFACE_LIBRARIES")) { - this->Target->SetProperty("LINK_INTERFACE_LIBRARIES", ""); + currentProcessingState != ProcessingLinkLibraries && + !target->GetProperty("LINK_INTERFACE_LIBRARIES")) { + target->SetProperty("LINK_INTERFACE_LIBRARIES", ""); } return true; } -void cmTargetLinkLibrariesCommand::LinkLibraryTypeSpecifierWarning(int left, - int right) +static void LinkLibraryTypeSpecifierWarning(cmMakefile& mf, int left, + int right) { - this->Makefile->IssueMessage( + mf.IssueMessage( MessageType::AUTHOR_WARNING, cmStrCat( - "Link library type specifier \"", - cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[left], - "\" is followed by specifier \"", - cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[right], + "Link library type specifier \"", LinkLibraryTypeNames[left], + "\" is followed by specifier \"", LinkLibraryTypeNames[right], "\" instead of a library name. The first specifier will be ignored.")); } -bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, - cmTargetLinkLibraryType llt) +static bool HandleLibrary(cmMakefile& mf, cmTarget* target, + ProcessingState currentProcessingState, + const std::string& lib, cmTargetLinkLibraryType llt) { - if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY && - this->CurrentProcessingState != ProcessingKeywordLinkInterface) { - this->Makefile->IssueMessage( + if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY && + currentProcessingState != ProcessingKeywordLinkInterface) { + mf.IssueMessage( MessageType::FATAL_ERROR, "INTERFACE library can only be used with the INTERFACE keyword of " "target_link_libraries"); return false; } - if (this->Target->IsImported() && - this->CurrentProcessingState != ProcessingKeywordLinkInterface) { - this->Makefile->IssueMessage( + if (target->IsImported() && + currentProcessingState != ProcessingKeywordLinkInterface) { + mf.IssueMessage( MessageType::FATAL_ERROR, "IMPORTED library can only be used with the INTERFACE keyword of " "target_link_libraries"); @@ -316,19 +333,18 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, } cmTarget::TLLSignature sig = - (this->CurrentProcessingState == ProcessingPlainPrivateInterface || - this->CurrentProcessingState == ProcessingPlainPublicInterface || - this->CurrentProcessingState == ProcessingKeywordPrivateInterface || - this->CurrentProcessingState == ProcessingKeywordPublicInterface || - this->CurrentProcessingState == ProcessingKeywordLinkInterface) + (currentProcessingState == ProcessingPlainPrivateInterface || + currentProcessingState == ProcessingPlainPublicInterface || + currentProcessingState == ProcessingKeywordPrivateInterface || + currentProcessingState == ProcessingKeywordPublicInterface || + currentProcessingState == ProcessingKeywordLinkInterface) ? cmTarget::KeywordTLLSignature : cmTarget::PlainTLLSignature; - if (!this->Target->PushTLLCommandTrace( - sig, this->Makefile->GetExecutionContext())) { + if (!target->PushTLLCommandTrace(sig, mf.GetExecutionContext())) { std::ostringstream e; const char* modal = nullptr; MessageType messageType = MessageType::AUTHOR_WARNING; - switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0023)) { + switch (mf.GetPolicyStatus(cmPolicies::CMP0023)) { case cmPolicies::WARN: e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0023) << "\n"; modal = "should"; @@ -349,14 +365,14 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, e << "The " << existingSig << " signature for target_link_libraries has " "already been used with the target \"" - << this->Target->GetName() + << target->GetName() << "\". All uses of target_link_libraries with a target " << modal << " be either all-keyword or all-plain.\n"; - this->Target->GetTllSignatureTraces(e, - sig == cmTarget::KeywordTLLSignature - ? cmTarget::PlainTLLSignature - : cmTarget::KeywordTLLSignature); - this->Makefile->IssueMessage(messageType, e.str()); + target->GetTllSignatureTraces(e, + sig == cmTarget::KeywordTLLSignature + ? cmTarget::PlainTLLSignature + : cmTarget::KeywordTLLSignature); + mf.IssueMessage(messageType, e.str()); if (messageType == MessageType::FATAL_ERROR) { return false; } @@ -366,9 +382,9 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, bool warnRemoteInterface = false; bool rejectRemoteLinking = false; bool encodeRemoteReference = false; - if (this->Makefile != this->Target->GetMakefile()) { + if (&mf != target->GetMakefile()) { // The LHS target was created in another directory. - switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0079)) { + switch (mf.GetPolicyStatus(cmPolicies::CMP0079)) { case cmPolicies::WARN: warnRemoteInterface = true; CM_FALLTHROUGH; @@ -389,7 +405,7 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, // same directory as the target was created. Add a suffix to // the name to tell ResolveLinkItem to look up the name in the // caller's directory. - cmDirectoryId const dirId = this->Makefile->GetDirectoryId(); + cmDirectoryId const dirId = mf.GetDirectoryId(); libRef = lib + CMAKE_DIRECTORY_ID_SEP + dirId.String; } else { // This is an absolute path or a library name added by a caller @@ -401,21 +417,21 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, // Handle normal case where the command was called with another keyword than // INTERFACE / LINK_INTERFACE_LIBRARIES or none at all. (The "LINK_LIBRARIES" // property of the target on the LHS shall be populated.) - if (this->CurrentProcessingState != ProcessingKeywordLinkInterface && - this->CurrentProcessingState != ProcessingPlainLinkInterface) { + if (currentProcessingState != ProcessingKeywordLinkInterface && + currentProcessingState != ProcessingPlainLinkInterface) { if (rejectRemoteLinking) { - this->Makefile->IssueMessage( + mf.IssueMessage( MessageType::FATAL_ERROR, cmStrCat("Attempt to add link library \"", lib, "\" to target \"", - this->Target->GetName(), + target->GetName(), "\" which is not built in this " "directory.\nThis is allowed only when policy CMP0079 " "is set to NEW.")); return false; } - cmTarget* tgt = this->Makefile->GetGlobalGenerator()->FindTarget(lib); + cmTarget* tgt = mf.GetGlobalGenerator()->FindTarget(lib); if (tgt && (tgt->GetType() != cmStateEnums::STATIC_LIBRARY) && (tgt->GetType() != cmStateEnums::SHARED_LIBRARY) && @@ -423,7 +439,7 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, (tgt->GetType() != cmStateEnums::OBJECT_LIBRARY) && (tgt->GetType() != cmStateEnums::INTERFACE_LIBRARY) && !tgt->IsExecutableWithExports()) { - this->Makefile->IssueMessage( + mf.IssueMessage( MessageType::FATAL_ERROR, cmStrCat( "Target \"", lib, "\" of type ", @@ -433,15 +449,15 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, "executables with the ENABLE_EXPORTS property set.")); } - this->Target->AddLinkLibrary(*this->Makefile, lib, libRef, llt); + target->AddLinkLibrary(mf, lib, libRef, llt); } if (warnRemoteInterface) { - this->Makefile->IssueMessage( + mf.IssueMessage( MessageType::AUTHOR_WARNING, cmStrCat( cmPolicies::GetPolicyWarning(cmPolicies::CMP0079), "\nTarget\n ", - this->Target->GetName(), + target->GetName(), "\nis not created in this " "directory. For compatibility with older versions of CMake, link " "library\n ", @@ -454,18 +470,17 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, // LINK_PRIVATE and stop its processing. (The "INTERFACE_LINK_LIBRARIES" // property of the target on the LHS shall only be populated if it is a // STATIC library.) - if (this->CurrentProcessingState == ProcessingKeywordPrivateInterface || - this->CurrentProcessingState == ProcessingPlainPrivateInterface) { - if (this->Target->GetType() == cmStateEnums::STATIC_LIBRARY || - this->Target->GetType() == cmStateEnums::OBJECT_LIBRARY) { + if (currentProcessingState == ProcessingKeywordPrivateInterface || + currentProcessingState == ProcessingPlainPrivateInterface) { + if (target->GetType() == cmStateEnums::STATIC_LIBRARY || + target->GetType() == cmStateEnums::OBJECT_LIBRARY) { std::string configLib = - this->Target->GetDebugGeneratorExpressions(libRef, llt); + target->GetDebugGeneratorExpressions(libRef, llt); if (cmGeneratorExpression::IsValidTargetName(lib) || cmGeneratorExpression::Find(lib) != std::string::npos) { configLib = "$<LINK_ONLY:" + configLib + ">"; } - this->Target->AppendProperty("INTERFACE_LINK_LIBRARIES", - configLib.c_str()); + target->AppendProperty("INTERFACE_LINK_LIBRARIES", configLib.c_str()); } return true; } @@ -473,23 +488,23 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, // Handle general case where the command was called with another keyword than // PRIVATE / LINK_PRIVATE or none at all. (The "INTERFACE_LINK_LIBRARIES" // property of the target on the LHS shall be populated.) - this->Target->AppendProperty( + target->AppendProperty( "INTERFACE_LINK_LIBRARIES", - this->Target->GetDebugGeneratorExpressions(libRef, llt).c_str()); + target->GetDebugGeneratorExpressions(libRef, llt).c_str()); // Stop processing if called without any keyword. - if (this->CurrentProcessingState == ProcessingLinkLibraries) { + if (currentProcessingState == ProcessingLinkLibraries) { return true; } // Stop processing if policy CMP0022 is set to NEW. const cmPolicies::PolicyStatus policy22Status = - this->Target->GetPolicyStatusCMP0022(); + target->GetPolicyStatusCMP0022(); if (policy22Status != cmPolicies::OLD && policy22Status != cmPolicies::WARN) { return true; } // Stop processing if called with an INTERFACE library on the LHS. - if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) { + if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) { return true; } @@ -499,7 +514,7 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, { // Get the list of configurations considered to be DEBUG. std::vector<std::string> debugConfigs = - this->Makefile->GetCMakeInstance()->GetDebugConfigs(); + mf.GetCMakeInstance()->GetDebugConfigs(); std::string prop; // Include this library in the link interface for the target. @@ -507,19 +522,19 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, // Put in the DEBUG configuration interfaces. for (std::string const& dc : debugConfigs) { prop = cmStrCat("LINK_INTERFACE_LIBRARIES_", dc); - this->Target->AppendProperty(prop, libRef.c_str()); + target->AppendProperty(prop, libRef.c_str()); } } if (llt == OPTIMIZED_LibraryType || llt == GENERAL_LibraryType) { // Put in the non-DEBUG configuration interfaces. - this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", libRef.c_str()); + target->AppendProperty("LINK_INTERFACE_LIBRARIES", libRef.c_str()); // Make sure the DEBUG configuration interfaces exist so that the // general one will not be used as a fall-back. for (std::string const& dc : debugConfigs) { prop = cmStrCat("LINK_INTERFACE_LIBRARIES_", dc); - if (!this->Target->GetProperty(prop)) { - this->Target->SetProperty(prop, ""); + if (!target->GetProperty(prop)) { + target->SetProperty(prop, ""); } } } diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h index caf2cf4..4b2deab 100644 --- a/Source/cmTargetLinkLibrariesCommand.h +++ b/Source/cmTargetLinkLibrariesCommand.h @@ -8,61 +8,9 @@ #include <string> #include <vector> -#include <cm/memory> - -#include "cmCommand.h" -#include "cmTargetLinkLibraryType.h" - class cmExecutionStatus; -class cmTarget; - -/** \class cmTargetLinkLibrariesCommand - * \brief Specify a list of libraries to link into executables. - * - * cmTargetLinkLibrariesCommand is used to specify a list of libraries to link - * into executable(s) or shared objects. The names of the libraries - * should be those defined by the LIBRARY(library) command(s). - * - * Additionally, it allows to propagate usage-requirements (including link - * libraries) from one target into another. - */ -class cmTargetLinkLibrariesCommand : public cmCommand -{ -public: - /** - * This is a virtual constructor for the command. - */ - std::unique_ptr<cmCommand> Clone() override - { - return cm::make_unique<cmTargetLinkLibrariesCommand>(); - } - - /** - * This is called when the command is first encountered in - * the CMakeLists.txt file. - */ - bool InitialPass(std::vector<std::string> const& args, - cmExecutionStatus& status) override; - -private: - void LinkLibraryTypeSpecifierWarning(int left, int right); - static const char* LinkLibraryTypeNames[3]; - - cmTarget* Target = nullptr; - enum ProcessingState - { - ProcessingLinkLibraries, - ProcessingPlainLinkInterface, - ProcessingKeywordLinkInterface, - ProcessingPlainPublicInterface, - ProcessingKeywordPublicInterface, - ProcessingPlainPrivateInterface, - ProcessingKeywordPrivateInterface - }; - - ProcessingState CurrentProcessingState = ProcessingLinkLibraries; - bool HandleLibrary(const std::string& lib, cmTargetLinkLibraryType llt); -}; +bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args, + cmExecutionStatus& status); #endif |