From d26e6cb1c2f352da12200727a887e940aac463a7 Mon Sep 17 00:00:00 2001 From: Regina Pfeifer Date: Thu, 18 Jul 2019 11:30:44 +0200 Subject: cmLoadCommandCommand: Code cleanup --- Source/cmLoadCommandCommand.cxx | 164 ++++++++++++++++++++++------------------ 1 file changed, 91 insertions(+), 73 deletions(-) diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx index 235dcd4..2697f44 100644 --- a/Source/cmLoadCommandCommand.cxx +++ b/Source/cmLoadCommandCommand.cxx @@ -25,21 +25,89 @@ class cmExecutionStatus; # include /* for malloc/free on QNX */ #endif -extern "C" void TrapsForSignalsCFunction(int sig); +namespace { + +const char* LastName = nullptr; + +extern "C" void TrapsForSignals(int sig) +{ + fprintf(stderr, "CMake loaded command %s crashed with signal: %d.\n", + LastName, sig); +} + +struct SignalHandlerGuard +{ + explicit SignalHandlerGuard(const char* name) + { + LastName = name != nullptr ? name : "????"; + + signal(SIGSEGV, TrapsForSignals); +#ifdef SIGBUS + signal(SIGBUS, TrapsForSignals); +#endif + signal(SIGILL, TrapsForSignals); + } + + ~SignalHandlerGuard() + { + signal(SIGSEGV, nullptr); +#ifdef SIGBUS + signal(SIGBUS, nullptr); +#endif + signal(SIGILL, nullptr); + } + + SignalHandlerGuard(SignalHandlerGuard const&) = delete; + SignalHandlerGuard& operator=(SignalHandlerGuard const&) = delete; +}; + +struct LoadedCommandImpl : cmLoadedCommandInfo +{ + explicit LoadedCommandImpl(CM_INIT_FUNCTION init) + : cmLoadedCommandInfo{ 0, 0, &cmStaticCAPI, 0, + nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr } + { + init(this); + } + + ~LoadedCommandImpl() + { + if (this->Destructor) { + SignalHandlerGuard guard(this->Name); + this->Destructor(this); + } + if (this->Error != nullptr) { + free(this->Error); + } + } + + LoadedCommandImpl(LoadedCommandImpl const&) = delete; + LoadedCommandImpl& operator=(LoadedCommandImpl const&) = delete; + + int DoInitialPass(cmMakefile* mf, int argc, char* argv[]) + { + SignalHandlerGuard guard(this->Name); + return this->InitialPass(this, mf, argc, argv); + } + + void DoFinalPass(cmMakefile* mf) + { + SignalHandlerGuard guard(this->Name); + this->FinalPass(this, mf); + } +}; // a class for loadabple commands class cmLoadedCommand : public cmCommand { public: - cmLoadedCommand() + cmLoadedCommand() = default; + explicit cmLoadedCommand(CM_INIT_FUNCTION init) + : Impl(std::make_shared(init)) { - memset(&this->info, 0, sizeof(this->info)); - this->info.CAPI = &cmStaticCAPI; } - //! clean up any memory allocated by the plugin - ~cmLoadedCommand() override; - /** * This is a virtual constructor for the command. */ @@ -47,8 +115,8 @@ public: { auto newC = cm::make_unique(); // we must copy when we clone - memcpy(&newC->info, &this->info, sizeof(info)); - return std::unique_ptr(std::move(newC)); + newC->Impl = this->Impl; + return std::unique_ptr(std::move(newC)); } /** @@ -67,57 +135,23 @@ public: void FinalPass() override; bool HasFinalPass() const override { - return this->info.FinalPass != nullptr; - } - - static const char* LastName; - static void TrapsForSignals(int sig) - { - fprintf(stderr, "CMake loaded command %s crashed with signal: %d.\n", - cmLoadedCommand::LastName, sig); - } - static void InstallSignalHandlers(const char* name, int remove = 0) - { - cmLoadedCommand::LastName = name; - if (!name) { - cmLoadedCommand::LastName = "????"; - } - - if (!remove) { - signal(SIGSEGV, TrapsForSignalsCFunction); -#ifdef SIGBUS - signal(SIGBUS, TrapsForSignalsCFunction); -#endif - signal(SIGILL, TrapsForSignalsCFunction); - } else { - signal(SIGSEGV, nullptr); -#ifdef SIGBUS - signal(SIGBUS, nullptr); -#endif - signal(SIGILL, nullptr); - } + return this->Impl->FinalPass != nullptr; } - cmLoadedCommandInfo info; +private: + std::shared_ptr Impl; }; -extern "C" void TrapsForSignalsCFunction(int sig) -{ - cmLoadedCommand::TrapsForSignals(sig); -} - -const char* cmLoadedCommand::LastName = nullptr; - bool cmLoadedCommand::InitialPass(std::vector const& args, cmExecutionStatus&) { - if (!info.InitialPass) { + if (!this->Impl->InitialPass) { return true; } // clear the error string - if (this->info.Error) { - free(this->info.Error); + if (this->Impl->Error) { + free(this->Impl->Error); } // create argc and argv and then invoke the command @@ -130,9 +164,7 @@ bool cmLoadedCommand::InitialPass(std::vector const& args, for (i = 0; i < argc; ++i) { argv[i] = strdup(args[i].c_str()); } - cmLoadedCommand::InstallSignalHandlers(info.Name); - int result = info.InitialPass(&info, this->Makefile, argc, argv); - cmLoadedCommand::InstallSignalHandlers(info.Name, 1); + int result = this->Impl->DoInitialPass(this->Makefile, argc, argv); cmFreeArguments(argc, argv); if (result) { @@ -140,32 +172,20 @@ bool cmLoadedCommand::InitialPass(std::vector const& args, } /* Initial Pass must have failed so set the error string */ - if (this->info.Error) { - this->SetError(this->info.Error); + if (this->Impl->Error) { + this->SetError(this->Impl->Error); } return false; } void cmLoadedCommand::FinalPass() { - if (this->info.FinalPass) { - cmLoadedCommand::InstallSignalHandlers(info.Name); - this->info.FinalPass(&this->info, this->Makefile); - cmLoadedCommand::InstallSignalHandlers(info.Name, 1); + if (this->Impl->FinalPass) { + this->Impl->DoFinalPass(this->Makefile); } } -cmLoadedCommand::~cmLoadedCommand() -{ - if (this->info.Destructor) { - cmLoadedCommand::InstallSignalHandlers(info.Name); - this->info.Destructor(&this->info); - cmLoadedCommand::InstallSignalHandlers(info.Name, 1); - } - if (this->info.Error) { - free(this->info.Error); - } -} +} // namespace // cmLoadCommandCommand bool cmLoadCommandCommand::InitialPass(std::vector const& args, @@ -240,10 +260,8 @@ bool cmLoadCommandCommand::InitialPass(std::vector const& args, // if the symbol is found call it to set the name on the // function blocker if (initFunction) { - // create a function blocker and set it up - auto f = cm::make_unique(); - (*initFunction)(&f->info); - this->Makefile->GetState()->AddScriptedCommand(args[0], std::move(f)); + this->Makefile->GetState()->AddScriptedCommand( + args[0], cm::make_unique(initFunction)); return true; } this->SetError("Attempt to load command failed. " -- cgit v0.12 From a74dad3bd3e5e4bbf09764a0b6bdedfe842442a7 Mon Sep 17 00:00:00 2001 From: Daniel Pfeifer Date: Wed, 28 Dec 2016 23:15:41 +0100 Subject: cmMakefile: decouple FinalAction from cmCommand --- Source/cmMakefile.cxx | 25 ++++++++++++++++++++++--- Source/cmMakefile.h | 13 ++++++++++--- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 501ea69..a350789 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -355,6 +355,20 @@ private: cmMakefile* Makefile; }; +class cmFinalPassAction +{ +public: + cmFinalPassAction(std::unique_ptr command) + : Command(std::move(command)) + { + } + + void operator()(cmMakefile&) { this->Command->FinalPass(); } + +private: + std::shared_ptr Command; +}; + bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff, cmExecutionStatus& status) { @@ -417,7 +431,7 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff, } } else if (pcmd->HasFinalPass()) { // use the command - this->FinalPassCommands.push_back(std::move(pcmd)); + this->AddFinalAction(cmFinalPassAction(std::move(pcmd))); } } } else { @@ -768,6 +782,11 @@ struct file_not_persistent }; } +void cmMakefile::AddFinalAction(FinalAction action) +{ + this->FinalActions.push_back(std::move(action)); +} + void cmMakefile::FinalPass() { // do all the variable expansions here @@ -775,8 +794,8 @@ void cmMakefile::FinalPass() // give all the commands a chance to do something // after the file has been parsed before generation - for (auto& command : this->FinalPassCommands) { - command->FinalPass(); + for (FinalAction& action : this->FinalActions) { + action(*this); } // go through all configured files and see which ones still exist. diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 1b4ead7..166a697 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -7,6 +7,7 @@ #include "cmsys/RegularExpression.hxx" #include +#include #include #include #include @@ -30,7 +31,6 @@ # include "cmSourceGroup.h" #endif -class cmCommand; class cmCompiledGeneratorExpression; class cmCustomCommandLines; class cmExecutionStatus; @@ -125,6 +125,13 @@ public: bool EnforceUniqueName(std::string const& name, std::string& msg, bool isCustom = false) const; + using FinalAction = std::function; + + /** + * Register an action that is executed during FinalPass + */ + void AddFinalAction(FinalAction action); + /** * Perform FinalPass, Library dependency analysis etc before output of the * makefile. @@ -132,7 +139,7 @@ public: void ConfigureFinalPass(); /** - * run the final pass on all commands. + * run all FinalActions. */ void FinalPass(); @@ -937,7 +944,7 @@ protected: size_t ObjectLibrariesSourceGroupIndex; #endif - std::vector> FinalPassCommands; + std::vector FinalActions; cmGlobalGenerator* GlobalGenerator; bool IsFunctionBlocked(const cmListFileFunction& lff, cmExecutionStatus& status); -- cgit v0.12 From 20169f0b8de5d0e5efea2d67a735332786173c23 Mon Sep 17 00:00:00 2001 From: Daniel Pfeifer Date: Wed, 28 Dec 2016 23:43:11 +0100 Subject: cmExportLibraryDependenciesCommand: Port away from FinalPass --- Source/cmExportLibraryDependenciesCommand.cxx | 57 +++++++++++---------------- Source/cmExportLibraryDependenciesCommand.h | 8 ---- 2 files changed, 24 insertions(+), 41 deletions(-) diff --git a/Source/cmExportLibraryDependenciesCommand.cxx b/Source/cmExportLibraryDependenciesCommand.cxx index 87ef2a9..8f2fff5 100644 --- a/Source/cmExportLibraryDependenciesCommand.cxx +++ b/Source/cmExportLibraryDependenciesCommand.cxx @@ -19,57 +19,31 @@ class cmExecutionStatus; -bool cmExportLibraryDependenciesCommand::InitialPass( - std::vector const& args, cmExecutionStatus&) -{ - if (args.empty()) { - this->SetError("called with incorrect number of arguments"); - return false; - } - - // store the arguments for the final pass - this->Filename = args[0]; - this->Append = false; - if (args.size() > 1) { - if (args[1] == "APPEND") { - this->Append = true; - } - } - return true; -} - -void cmExportLibraryDependenciesCommand::FinalPass() -{ - // export_library_dependencies() shouldn't modify anything - // ensure this by calling a const method - this->ConstFinalPass(); -} - -void cmExportLibraryDependenciesCommand::ConstFinalPass() const +static void FinalAction(cmMakefile& makefile, std::string const& filename, + bool append) { // Use copy-if-different if not appending. std::unique_ptr foutPtr; - if (this->Append) { + if (append) { const auto openmodeApp = std::ios::app; - foutPtr = - cm::make_unique(this->Filename.c_str(), openmodeApp); + foutPtr = cm::make_unique(filename.c_str(), openmodeApp); } else { std::unique_ptr ap( - new cmGeneratedFileStream(this->Filename, true)); + new cmGeneratedFileStream(filename, true)); ap->SetCopyIfDifferent(true); foutPtr = std::move(ap); } std::ostream& fout = *foutPtr; if (!fout) { - cmSystemTools::Error("Error Writing " + this->Filename); + cmSystemTools::Error("Error Writing " + filename); cmSystemTools::ReportLastSystemError(""); return; } // Collect dependency information about all library targets built in // the project. - cmake* cm = this->Makefile->GetCMakeInstance(); + cmake* cm = makefile.GetCMakeInstance(); cmGlobalGenerator* global = cm->GetGlobalGenerator(); const std::vector& locals = global->GetMakefiles(); std::map libDepsOld; @@ -166,3 +140,20 @@ void cmExportLibraryDependenciesCommand::ConstFinalPass() const } fout << "endif()\n"; } + +bool cmExportLibraryDependenciesCommand::InitialPass( + std::vector const& args, cmExecutionStatus&) +{ + if (args.empty()) { + this->SetError("called with incorrect number of arguments"); + return false; + } + + std::string const& filename = args[0]; + bool const append = args.size() > 1 && args[1] == "APPEND"; + this->Makefile->AddFinalAction([filename, append](cmMakefile& makefile) { + FinalAction(makefile, filename, append); + }); + + return true; +} diff --git a/Source/cmExportLibraryDependenciesCommand.h b/Source/cmExportLibraryDependenciesCommand.h index 5255d63..4817162 100644 --- a/Source/cmExportLibraryDependenciesCommand.h +++ b/Source/cmExportLibraryDependenciesCommand.h @@ -23,14 +23,6 @@ public: } bool InitialPass(std::vector const& args, cmExecutionStatus& status) override; - - void FinalPass() override; - bool HasFinalPass() const override { return true; } - -private: - std::string Filename; - bool Append = false; - void ConstFinalPass() const; }; #endif -- cgit v0.12 From 6a1a3763eea8f1bd2a6ca444c02af30d300cacc0 Mon Sep 17 00:00:00 2001 From: Daniel Pfeifer Date: Wed, 28 Dec 2016 23:58:29 +0100 Subject: cmFLTKWrapUICommand: Port away from FinalPass --- Source/cmFLTKWrapUICommand.cxx | 53 ++++++++++++++++++++++-------------------- Source/cmFLTKWrapUICommand.h | 22 ------------------ 2 files changed, 28 insertions(+), 47 deletions(-) diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx index 89629c7..70800b4 100644 --- a/Source/cmFLTKWrapUICommand.cxx +++ b/Source/cmFLTKWrapUICommand.cxx @@ -13,6 +13,23 @@ class cmExecutionStatus; class cmTarget; +static void FinalAction(cmMakefile& makefile, std::string const& name) +{ + // people should add the srcs to the target themselves, but the old command + // didn't support that, so check and see if they added the files in and if + // they didn;t then print a warning and add then anyhow + cmTarget* target = makefile.FindLocalNonAliasTarget(name); + if (!target) { + std::string msg = + "FLTK_WRAP_UI was called with a target that was never created: "; + msg += name; + msg += ". The problem was found while processing the source directory: "; + msg += makefile.GetCurrentSourceDirectory(); + msg += ". This FLTK_WRAP_UI call will be ignored."; + cmSystemTools::Message(msg, "Warning"); + } +} + // cmFLTKWrapUICommand bool cmFLTKWrapUICommand::InitialPass(std::vector const& args, cmExecutionStatus&) @@ -27,8 +44,8 @@ bool cmFLTKWrapUICommand::InitialPass(std::vector const& args, std::string const& fluid_exe = this->Makefile->GetRequiredDefinition("FLTK_FLUID_EXECUTABLE"); - // get parameter for the command - this->Target = args[0]; // Target that will use the generated files + // Target that will use the generated files + std::string const& target = args[0]; // get the list of GUI files from which .cxx and .h will be generated std::string outputDirectory = this->Makefile->GetCurrentBinaryDirectory(); @@ -41,6 +58,9 @@ bool cmFLTKWrapUICommand::InitialPass(std::vector const& args, this->Makefile->AddIncludeDirectories(outputDirectories); } + // List of produced files. + std::vector generatedSourcesClasses; + for (std::string const& arg : cmMakeRange(args).advance(1)) { cmSourceFile* curr = this->Makefile->GetSource(arg); // if we should use the source GUI @@ -84,40 +104,23 @@ bool cmFLTKWrapUICommand::InitialPass(std::vector const& args, cmSourceFile* sf = this->Makefile->GetSource(cxxres); sf->AddDepend(hname); sf->AddDepend(origname); - this->GeneratedSourcesClasses.push_back(sf); + generatedSourcesClasses.push_back(sf); } } // create the variable with the list of sources in it - size_t lastHeadersClass = this->GeneratedSourcesClasses.size(); + size_t lastHeadersClass = generatedSourcesClasses.size(); std::string sourceListValue; for (size_t classNum = 0; classNum < lastHeadersClass; classNum++) { if (classNum) { sourceListValue += ";"; } - sourceListValue += this->GeneratedSourcesClasses[classNum]->GetFullPath(); + sourceListValue += generatedSourcesClasses[classNum]->GetFullPath(); } - std::string varName = this->Target; - varName += "_FLTK_UI_SRCS"; + std::string const varName = target + "_FLTK_UI_SRCS"; this->Makefile->AddDefinition(varName, sourceListValue.c_str()); + this->Makefile->AddFinalAction( + [target](cmMakefile& makefile) { FinalAction(makefile, target); }); return true; } - -void cmFLTKWrapUICommand::FinalPass() -{ - // people should add the srcs to the target themselves, but the old command - // didn't support that, so check and see if they added the files in and if - // they didn;t then print a warning and add then anyhow - cmTarget* target = this->Makefile->FindLocalNonAliasTarget(this->Target); - if (!target) { - std::string msg = - "FLTK_WRAP_UI was called with a target that was never created: "; - msg += this->Target; - msg += ". The problem was found while processing the source directory: "; - msg += this->Makefile->GetCurrentSourceDirectory(); - msg += ". This FLTK_WRAP_UI call will be ignored."; - cmSystemTools::Message(msg, "Warning"); - return; - } -} diff --git a/Source/cmFLTKWrapUICommand.h b/Source/cmFLTKWrapUICommand.h index bff4f01..ea8d401 100644 --- a/Source/cmFLTKWrapUICommand.h +++ b/Source/cmFLTKWrapUICommand.h @@ -13,7 +13,6 @@ #include "cmCommand.h" class cmExecutionStatus; -class cmSourceFile; /** \class cmFLTKWrapUICommand * \brief Create .h and .cxx files rules for FLTK user interfaces files @@ -38,27 +37,6 @@ public: */ bool InitialPass(std::vector const& args, cmExecutionStatus& status) override; - - /** - * This is called at the end after all the information - * specified by the command is accumulated. Most commands do - * not implement this method. At this point, reading and - * writing to the cache can be done. - */ - void FinalPass() override; - bool HasFinalPass() const override { return true; } - -private: - /** - * List of produced files. - */ - std::vector GeneratedSourcesClasses; - - /** - * List of Fluid files that provide the source - * generating .cxx and .h files - */ - std::string Target; }; #endif -- cgit v0.12 From 7bc88b91655b3397054d26f519548f34068ad830 Mon Sep 17 00:00:00 2001 From: Daniel Pfeifer Date: Thu, 29 Dec 2016 00:44:44 +0100 Subject: cmInstallFilesCommand: Port away from FinalPass --- Source/cmInstallFilesCommand.cxx | 71 +++++++++++++++++++++------------------- Source/cmInstallFilesCommand.h | 19 ----------- 2 files changed, 38 insertions(+), 52 deletions(-) diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx index efbcb67..4522669 100644 --- a/Source/cmInstallFilesCommand.cxx +++ b/Source/cmInstallFilesCommand.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmInstallFilesCommand.h" -#include "cmAlgorithms.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmInstallFilesGenerator.h" @@ -13,7 +12,13 @@ class cmExecutionStatus; -// cmExecutableCommand +static std::string FindInstallSource(cmMakefile& makefile, const char* name); +static void CreateInstallGenerator(cmMakefile& makefile, + std::string const& dest, + std::vector const& files); +static void FinalAction(cmMakefile& makefile, std::string const& dest, + std::vector const& args); + bool cmInstallFilesCommand::InitialPass(std::vector const& args, cmExecutionStatus&) { @@ -25,18 +30,20 @@ bool cmInstallFilesCommand::InitialPass(std::vector const& args, // Enable the install target. this->Makefile->GetGlobalGenerator()->EnableInstallTarget(); - this->Destination = args[0]; + std::string const& dest = args[0]; if ((args.size() > 1) && (args[1] == "FILES")) { - this->IsFilesForm = true; + std::vector files; for (std::string const& arg : cmMakeRange(args).advance(2)) { // Find the source location for each file listed. - this->Files.push_back(this->FindInstallSource(arg.c_str())); + files.push_back(FindInstallSource(*this->Makefile, arg.c_str())); } - this->CreateInstallGenerator(); + CreateInstallGenerator(*this->Makefile, dest, files); } else { - this->IsFilesForm = false; - cmAppend(this->FinalArgs, args.begin() + 1, args.end()); + std::vector finalArgs(args.begin() + 1, args.end()); + this->Makefile->AddFinalAction([dest, finalArgs](cmMakefile& makefile) { + FinalAction(makefile, dest, finalArgs); + }); } this->Makefile->GetGlobalGenerator()->AddInstallComponent( @@ -45,23 +52,20 @@ bool cmInstallFilesCommand::InitialPass(std::vector const& args, return true; } -void cmInstallFilesCommand::FinalPass() +static void FinalAction(cmMakefile& makefile, std::string const& dest, + std::vector const& args) { - // No final pass for "FILES" form of arguments. - if (this->IsFilesForm) { - return; - } - std::string testf; - std::string const& ext = this->FinalArgs[0]; + std::string const& ext = args[0]; + std::vector installFiles; // two different options - if (this->FinalArgs.size() > 1) { + if (args.size() > 1) { // now put the files into the list - std::vector::iterator s = this->FinalArgs.begin(); + std::vector::const_iterator s = args.begin(); ++s; // for each argument, get the files - for (; s != this->FinalArgs.end(); ++s) { + for (; s != args.end(); ++s) { // replace any variables std::string const& temps = *s; if (!cmSystemTools::GetFilenamePath(temps).empty()) { @@ -72,30 +76,31 @@ void cmInstallFilesCommand::FinalPass() } // add to the result - this->Files.push_back(this->FindInstallSource(testf.c_str())); + installFiles.push_back(FindInstallSource(makefile, testf.c_str())); } } else // reg exp list { std::vector files; - std::string const& regex = this->FinalArgs[0]; - cmSystemTools::Glob(this->Makefile->GetCurrentSourceDirectory(), regex, - files); + std::string const& regex = args[0]; + cmSystemTools::Glob(makefile.GetCurrentSourceDirectory(), regex, files); std::vector::iterator s = files.begin(); // for each argument, get the files for (; s != files.end(); ++s) { - this->Files.push_back(this->FindInstallSource(s->c_str())); + installFiles.push_back(FindInstallSource(makefile, s->c_str())); } } - this->CreateInstallGenerator(); + CreateInstallGenerator(makefile, dest, installFiles); } -void cmInstallFilesCommand::CreateInstallGenerator() const +static void CreateInstallGenerator(cmMakefile& makefile, + std::string const& dest, + std::vector const& files) { // Construct the destination. This command always installs under // the prefix. We skip the leading slash given by the user. - std::string destination = this->Destination.substr(1); + std::string destination = dest.substr(1); cmSystemTools::ConvertToUnixSlashes(destination); if (destination.empty()) { destination = "."; @@ -106,12 +111,12 @@ void cmInstallFilesCommand::CreateInstallGenerator() const const char* no_rename = ""; bool no_exclude_from_all = false; std::string no_component = - this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"); + makefile.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"); std::vector no_configurations; cmInstallGenerator::MessageLevel message = - cmInstallGenerator::SelectMessageLevel(this->Makefile); - this->Makefile->AddInstallGenerator(new cmInstallFilesGenerator( - this->Files, destination.c_str(), false, no_permissions, no_configurations, + cmInstallGenerator::SelectMessageLevel(&makefile); + makefile.AddInstallGenerator(new cmInstallFilesGenerator( + files, destination.c_str(), false, no_permissions, no_configurations, no_component.c_str(), message, no_exclude_from_all, no_rename)); } @@ -121,7 +126,7 @@ void cmInstallFilesCommand::CreateInstallGenerator() const * present in the build tree. If a full path is given, it is just * returned. */ -std::string cmInstallFilesCommand::FindInstallSource(const char* name) const +static std::string FindInstallSource(cmMakefile& makefile, const char* name) { if (cmSystemTools::FileIsFullPath(name) || cmGeneratorExpression::Find(name) == 0) { @@ -130,10 +135,10 @@ std::string cmInstallFilesCommand::FindInstallSource(const char* name) const } // This is a relative path. - std::string tb = this->Makefile->GetCurrentBinaryDirectory(); + std::string tb = makefile.GetCurrentBinaryDirectory(); tb += "/"; tb += name; - std::string ts = this->Makefile->GetCurrentSourceDirectory(); + std::string ts = makefile.GetCurrentSourceDirectory(); ts += "/"; ts += name; diff --git a/Source/cmInstallFilesCommand.h b/Source/cmInstallFilesCommand.h index e068b0e..f9b84fd 100644 --- a/Source/cmInstallFilesCommand.h +++ b/Source/cmInstallFilesCommand.h @@ -37,25 +37,6 @@ public: */ bool InitialPass(std::vector const& args, cmExecutionStatus& status) override; - - /** - * This is called at the end after all the information - * specified by the command is accumulated. Most commands do - * not implement this method. At this point, reading and - * writing to the cache can be done. - */ - void FinalPass() override; - bool HasFinalPass() const override { return !this->IsFilesForm; } - -protected: - void CreateInstallGenerator() const; - std::string FindInstallSource(const char* name) const; - -private: - std::vector FinalArgs; - bool IsFilesForm = false; - std::string Destination; - std::vector Files; }; #endif -- cgit v0.12 From 316e40baec978980c9023532f4dade1e5ea0ad48 Mon Sep 17 00:00:00 2001 From: Daniel Pfeifer Date: Thu, 5 Jan 2017 23:27:14 +0100 Subject: cmInstallProgramsCommand: Port away from FinalPass --- Source/cmInstallProgramsCommand.cxx | 51 +++++++++++++++++++++---------------- Source/cmInstallProgramsCommand.h | 18 ------------- 2 files changed, 29 insertions(+), 40 deletions(-) diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx index a58f875..6ec02e7 100644 --- a/Source/cmInstallProgramsCommand.cxx +++ b/Source/cmInstallProgramsCommand.cxx @@ -2,7 +2,6 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmInstallProgramsCommand.h" -#include "cmAlgorithms.h" #include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmInstallFilesGenerator.h" @@ -12,6 +11,10 @@ class cmExecutionStatus; +static void FinalAction(cmMakefile& makefile, std::string const& dest, + std::vector const& args); +static std::string FindInstallSource(cmMakefile& makefile, const char* name); + // cmExecutableCommand bool cmInstallProgramsCommand::InitialPass( std::vector const& args, cmExecutionStatus&) @@ -24,51 +27,55 @@ bool cmInstallProgramsCommand::InitialPass( // Enable the install target. this->Makefile->GetGlobalGenerator()->EnableInstallTarget(); - this->Destination = args[0]; - - cmAppend(this->FinalArgs, args.begin() + 1, args.end()); - this->Makefile->GetGlobalGenerator()->AddInstallComponent( this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME")); + std::string const& dest = args[0]; + std::vector const finalArgs(args.begin() + 1, args.end()); + this->Makefile->AddFinalAction([dest, finalArgs](cmMakefile& makefile) { + FinalAction(makefile, dest, finalArgs); + }); return true; } -void cmInstallProgramsCommand::FinalPass() +static void FinalAction(cmMakefile& makefile, std::string const& dest, + std::vector const& args) { bool files_mode = false; - if (!this->FinalArgs.empty() && this->FinalArgs[0] == "FILES") { + if (!args.empty() && args[0] == "FILES") { files_mode = true; } + std::vector files; + // two different options - if (this->FinalArgs.size() > 1 || files_mode) { + if (args.size() > 1 || files_mode) { // for each argument, get the programs - std::vector::iterator s = this->FinalArgs.begin(); + std::vector::const_iterator s = args.begin(); if (files_mode) { // Skip the FILES argument in files mode. ++s; } - for (; s != this->FinalArgs.end(); ++s) { + for (; s != args.end(); ++s) { // add to the result - this->Files.push_back(this->FindInstallSource(s->c_str())); + files.push_back(FindInstallSource(makefile, s->c_str())); } } else // reg exp list { std::vector programs; - cmSystemTools::Glob(this->Makefile->GetCurrentSourceDirectory(), - this->FinalArgs[0], programs); + cmSystemTools::Glob(makefile.GetCurrentSourceDirectory(), args[0], + programs); std::vector::iterator s = programs.begin(); // for each argument, get the programs for (; s != programs.end(); ++s) { - this->Files.push_back(this->FindInstallSource(s->c_str())); + files.push_back(FindInstallSource(makefile, s->c_str())); } } // Construct the destination. This command always installs under // the prefix. We skip the leading slash given by the user. - std::string destination = this->Destination.substr(1); + std::string destination = dest.substr(1); cmSystemTools::ConvertToUnixSlashes(destination); if (destination.empty()) { destination = "."; @@ -79,12 +86,12 @@ void cmInstallProgramsCommand::FinalPass() const char* no_rename = ""; bool no_exclude_from_all = false; std::string no_component = - this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"); + makefile.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"); std::vector no_configurations; cmInstallGenerator::MessageLevel message = - cmInstallGenerator::SelectMessageLevel(this->Makefile); - this->Makefile->AddInstallGenerator(new cmInstallFilesGenerator( - this->Files, destination.c_str(), true, no_permissions, no_configurations, + cmInstallGenerator::SelectMessageLevel(&makefile); + makefile.AddInstallGenerator(new cmInstallFilesGenerator( + files, destination.c_str(), true, no_permissions, no_configurations, no_component.c_str(), message, no_exclude_from_all, no_rename)); } @@ -94,7 +101,7 @@ void cmInstallProgramsCommand::FinalPass() * present in the build tree. If a full path is given, it is just * returned. */ -std::string cmInstallProgramsCommand::FindInstallSource(const char* name) const +static std::string FindInstallSource(cmMakefile& makefile, const char* name) { if (cmSystemTools::FileIsFullPath(name) || cmGeneratorExpression::Find(name) == 0) { @@ -103,10 +110,10 @@ std::string cmInstallProgramsCommand::FindInstallSource(const char* name) const } // This is a relative path. - std::string tb = this->Makefile->GetCurrentBinaryDirectory(); + std::string tb = makefile.GetCurrentBinaryDirectory(); tb += "/"; tb += name; - std::string ts = this->Makefile->GetCurrentSourceDirectory(); + std::string ts = makefile.GetCurrentSourceDirectory(); ts += "/"; ts += name; diff --git a/Source/cmInstallProgramsCommand.h b/Source/cmInstallProgramsCommand.h index 3242365..ccd621d 100644 --- a/Source/cmInstallProgramsCommand.h +++ b/Source/cmInstallProgramsCommand.h @@ -37,24 +37,6 @@ public: */ bool InitialPass(std::vector const& args, cmExecutionStatus& status) override; - - /** - * This is called at the end after all the information - * specified by the command is accumulated. Most commands do - * not implement this method. At this point, reading and - * writing to the cache can be done. - */ - void FinalPass() override; - - bool HasFinalPass() const override { return true; } - -protected: - std::string FindInstallSource(const char* name) const; - -private: - std::vector FinalArgs; - std::string Destination; - std::vector Files; }; #endif -- cgit v0.12 From 360d4155920b851f114843e91234bb0ae33afef3 Mon Sep 17 00:00:00 2001 From: Daniel Pfeifer Date: Thu, 5 Jan 2017 23:41:01 +0100 Subject: cmLoadCommandCommand: Port away from FinalPass --- Source/cmLoadCommandCommand.cxx | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx index 2697f44..f5da2ee 100644 --- a/Source/cmLoadCommandCommand.cxx +++ b/Source/cmLoadCommandCommand.cxx @@ -126,18 +126,6 @@ public: bool InitialPass(std::vector const& args, cmExecutionStatus&) override; - /** - * This is called at the end after all the information - * specified by the command is accumulated. Most commands do - * not implement this method. At this point, reading and - * writing to the cache can be done. - */ - void FinalPass() override; - bool HasFinalPass() const override - { - return this->Impl->FinalPass != nullptr; - } - private: std::shared_ptr Impl; }; @@ -168,6 +156,11 @@ bool cmLoadedCommand::InitialPass(std::vector const& args, cmFreeArguments(argc, argv); if (result) { + if (this->Impl->FinalPass) { + auto impl = this->Impl; + this->Makefile->AddFinalAction( + [impl](cmMakefile& makefile) { impl->DoFinalPass(&makefile); }); + } return true; } @@ -178,13 +171,6 @@ bool cmLoadedCommand::InitialPass(std::vector const& args, return false; } -void cmLoadedCommand::FinalPass() -{ - if (this->Impl->FinalPass) { - this->Impl->DoFinalPass(this->Makefile); - } -} - } // namespace // cmLoadCommandCommand -- cgit v0.12 From fbee46e262044ac71170552adc4eb656ef0b030b Mon Sep 17 00:00:00 2001 From: Daniel Pfeifer Date: Fri, 6 Jan 2017 23:13:44 +0100 Subject: cmVariableWatchCommand: Port away from FinalPass --- Source/cmVariableWatchCommand.cxx | 41 +++++++++++++++++++++++++++++++-------- Source/cmVariableWatchCommand.h | 14 ------------- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx index 5fe55bd..afc0b76 100644 --- a/Source/cmVariableWatchCommand.cxx +++ b/Source/cmVariableWatchCommand.cxx @@ -3,6 +3,7 @@ #include "cmVariableWatchCommand.h" #include +#include #include "cmExecutionStatus.h" #include "cmListFileCache.h" @@ -84,15 +85,39 @@ static void deleteVariableWatchCallbackData(void* client_data) delete data; } -cmVariableWatchCommand::cmVariableWatchCommand() = default; - -cmVariableWatchCommand::~cmVariableWatchCommand() +/** This command does not really have a final pass but it needs to + stay alive since it owns variable watch callback information. */ +class FinalAction { - for (std::string const& wv : this->WatchedVariables) { - this->Makefile->GetCMakeInstance()->GetVariableWatch()->RemoveWatch( - wv, cmVariableWatchCommandVariableAccessed); +public: + FinalAction(cmMakefile* makefile, std::string variable) + : Action(std::make_shared(makefile, std::move(variable))) + { } -} + + void operator()(cmMakefile&) const {} + +private: + struct Impl + { + Impl(cmMakefile* makefile, std::string variable) + : Makefile(makefile) + , Variable(std::move(variable)) + { + } + + ~Impl() + { + this->Makefile->GetCMakeInstance()->GetVariableWatch()->RemoveWatch( + this->Variable, cmVariableWatchCommandVariableAccessed); + } + + cmMakefile* Makefile; + std::string Variable; + }; + + std::shared_ptr Action; +}; bool cmVariableWatchCommand::InitialPass(std::vector const& args, cmExecutionStatus&) @@ -118,7 +143,6 @@ bool cmVariableWatchCommand::InitialPass(std::vector const& args, data->InCallback = false; data->Command = command; - this->WatchedVariables.insert(variable); if (!this->Makefile->GetCMakeInstance()->GetVariableWatch()->AddWatch( variable, cmVariableWatchCommandVariableAccessed, data, deleteVariableWatchCallbackData)) { @@ -126,5 +150,6 @@ bool cmVariableWatchCommand::InitialPass(std::vector const& args, return false; } + this->Makefile->AddFinalAction(FinalAction(this->Makefile, variable)); return true; } diff --git a/Source/cmVariableWatchCommand.h b/Source/cmVariableWatchCommand.h index 0dbb0cb..221269f 100644 --- a/Source/cmVariableWatchCommand.h +++ b/Source/cmVariableWatchCommand.h @@ -5,7 +5,6 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include #include #include @@ -30,25 +29,12 @@ public: return cm::make_unique(); } - //! Default constructor - cmVariableWatchCommand(); - - //! Destructor. - ~cmVariableWatchCommand() override; - /** * This is called when the command is first encountered in * the CMakeLists.txt file. */ bool InitialPass(std::vector const& args, cmExecutionStatus& status) override; - - /** This command does not really have a final pass but it needs to - stay alive since it owns variable watch callback information. */ - bool HasFinalPass() const override { return true; } - -protected: - std::set WatchedVariables; }; #endif -- cgit v0.12 From 732dd344b974d880402b0cb047de328eca1df666 Mon Sep 17 00:00:00 2001 From: Daniel Pfeifer Date: Fri, 6 Jan 2017 23:16:18 +0100 Subject: cmCommand: remove FinalPass from interface --- Source/cmCommand.h | 13 ------------- Source/cmDisallowedCommand.h | 4 ---- Source/cmMakefile.cxx | 17 ----------------- 3 files changed, 34 deletions(-) diff --git a/Source/cmCommand.h b/Source/cmCommand.h index cdd2aba..b210f27 100644 --- a/Source/cmCommand.h +++ b/Source/cmCommand.h @@ -61,19 +61,6 @@ public: cmExecutionStatus&) = 0; /** - * This is called at the end after all the information - * specified by the command is accumulated. Most commands do - * not implement this method. At this point, reading and - * writing to the cache can be done. - */ - virtual void FinalPass() {} - - /** - * Does this command have a final pass? Query after InitialPass. - */ - virtual bool HasFinalPass() const { return false; } - - /** * This is a virtual constructor for the command. */ virtual std::unique_ptr Clone() = 0; diff --git a/Source/cmDisallowedCommand.h b/Source/cmDisallowedCommand.h index eed59ca..e07f255 100644 --- a/Source/cmDisallowedCommand.h +++ b/Source/cmDisallowedCommand.h @@ -38,10 +38,6 @@ public: bool InitialPass(std::vector const& args, cmExecutionStatus& status) override; - void FinalPass() override { this->Command->FinalPass(); } - - bool HasFinalPass() const override { return this->Command->HasFinalPass(); } - private: std::unique_ptr Command; cmPolicies::PolicyID Policy; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index a350789..d2b0ae6 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -355,20 +355,6 @@ private: cmMakefile* Makefile; }; -class cmFinalPassAction -{ -public: - cmFinalPassAction(std::unique_ptr command) - : Command(std::move(command)) - { - } - - void operator()(cmMakefile&) { this->Command->FinalPass(); } - -private: - std::shared_ptr Command; -}; - bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff, cmExecutionStatus& status) { @@ -429,9 +415,6 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff, if (this->GetCMakeInstance()->GetWorkingMode() != cmake::NORMAL_MODE) { cmSystemTools::SetFatalErrorOccured(); } - } else if (pcmd->HasFinalPass()) { - // use the command - this->AddFinalAction(cmFinalPassAction(std::move(pcmd))); } } } else { -- cgit v0.12