Merge topic 'free-command-a'

9ba0bf60c6 cmA*Command: Turn into free functions

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !3660
diff --git a/Source/cmAddCompileDefinitionsCommand.cxx b/Source/cmAddCompileDefinitionsCommand.cxx
index 0474819..b00a4a7 100644
--- a/Source/cmAddCompileDefinitionsCommand.cxx
+++ b/Source/cmAddCompileDefinitionsCommand.cxx
@@ -2,19 +2,15 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmAddCompileDefinitionsCommand.h"
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 
-class cmExecutionStatus;
-
-bool cmAddCompileDefinitionsCommand::InitialPass(
-  std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmAddCompileDefinitionsCommand(std::vector<std::string> const& args,
+                                    cmExecutionStatus& status)
 {
-  if (args.empty()) {
-    return true;
-  }
-
+  cmMakefile& mf = status.GetMakefile();
   for (std::string const& i : args) {
-    this->Makefile->AddCompileDefinition(i);
+    mf.AddCompileDefinition(i);
   }
   return true;
 }
diff --git a/Source/cmAddCompileDefinitionsCommand.h b/Source/cmAddCompileDefinitionsCommand.h
index 5f90ed9..4bd621c 100644
--- a/Source/cmAddCompileDefinitionsCommand.h
+++ b/Source/cmAddCompileDefinitionsCommand.h
@@ -8,29 +8,9 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-class cmAddCompileDefinitionsCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmAddCompileDefinitionsCommand>();
-  }
-
-  /**
-   * 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;
-};
+bool cmAddCompileDefinitionsCommand(std::vector<std::string> const& args,
+                                    cmExecutionStatus& status);
 
 #endif
diff --git a/Source/cmAddCompileOptionsCommand.cxx b/Source/cmAddCompileOptionsCommand.cxx
index 412fb38..8ccb512 100644
--- a/Source/cmAddCompileOptionsCommand.cxx
+++ b/Source/cmAddCompileOptionsCommand.cxx
@@ -2,19 +2,15 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmAddCompileOptionsCommand.h"
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 
-class cmExecutionStatus;
-
-bool cmAddCompileOptionsCommand::InitialPass(
-  std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmAddCompileOptionsCommand(std::vector<std::string> const& args,
+                                cmExecutionStatus& status)
 {
-  if (args.empty()) {
-    return true;
-  }
-
+  cmMakefile& mf = status.GetMakefile();
   for (std::string const& i : args) {
-    this->Makefile->AddCompileOption(i);
+    mf.AddCompileOption(i);
   }
   return true;
 }
diff --git a/Source/cmAddCompileOptionsCommand.h b/Source/cmAddCompileOptionsCommand.h
index b34b7fc..b172412 100644
--- a/Source/cmAddCompileOptionsCommand.h
+++ b/Source/cmAddCompileOptionsCommand.h
@@ -8,29 +8,9 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-class cmAddCompileOptionsCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmAddCompileOptionsCommand>();
-  }
-
-  /**
-   * 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;
-};
+bool cmAddCompileOptionsCommand(std::vector<std::string> const& args,
+                                cmExecutionStatus& status);
 
 #endif
diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx
index 6eb38bd..e502a64 100644
--- a/Source/cmAddCustomCommandCommand.cxx
+++ b/Source/cmAddCustomCommandCommand.cxx
@@ -8,6 +8,7 @@
 
 #include "cmCustomCommand.h"
 #include "cmCustomCommandLines.h"
+#include "cmExecutionStatus.h"
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
@@ -16,21 +17,22 @@
 #include "cmSystemTools.h"
 #include "cmTarget.h"
 
-class cmExecutionStatus;
+static bool cmAddCustomCommandCommandCheckOutputs(
+  const std::vector<std::string>& outputs, cmExecutionStatus& status);
 
-// cmAddCustomCommandCommand
-bool cmAddCustomCommandCommand::InitialPass(
-  std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
+                               cmExecutionStatus& status)
 {
   /* Let's complain at the end of this function about the lack of a particular
      arg. For the moment, let's say that COMMAND, and either TARGET or SOURCE
      are required.
   */
   if (args.size() < 4) {
-    this->SetError("called with wrong number of arguments.");
+    status.SetError("called with wrong number of arguments.");
     return false;
   }
 
+  cmMakefile& mf = status.GetMakefile();
   std::string source, target, main_dependency, working, depfile, job_pool;
   std::string comment_buffer;
   const char* comment = nullptr;
@@ -167,9 +169,9 @@
         doing = doing_comment;
       } else if (copy == keyDEPFILE) {
         doing = doing_depfile;
-        if (this->Makefile->GetGlobalGenerator()->GetName() != "Ninja") {
-          this->SetError("Option DEPFILE not supported by " +
-                         this->Makefile->GetGlobalGenerator()->GetName());
+        if (mf.GetGlobalGenerator()->GetName() != "Ninja") {
+          status.SetError("Option DEPFILE not supported by " +
+                          mf.GetGlobalGenerator()->GetName());
           return false;
         }
       } else if (copy == keyJOB_POOL) {
@@ -192,7 +194,7 @@
             // and later references "${CMAKE_CURRENT_SOURCE_DIR}/out.txt".
             // This is fairly obscure so we can wait for someone to
             // complain.
-            filename = this->Makefile->GetCurrentBinaryDirectory();
+            filename = mf.GetCurrentBinaryDirectory();
             filename += "/";
           }
           filename += copy;
@@ -269,7 +271,7 @@
           comment = comment_buffer.c_str();
           break;
         default:
-          this->SetError("Wrong syntax. Unknown type of argument.");
+          status.SetError("Wrong syntax. Unknown type of argument.");
           return false;
       }
     }
@@ -284,31 +286,31 @@
   // At this point we could complain about the lack of arguments.  For
   // the moment, let's say that COMMAND, TARGET are always required.
   if (output.empty() && target.empty()) {
-    this->SetError("Wrong syntax. A TARGET or OUTPUT must be specified.");
+    status.SetError("Wrong syntax. A TARGET or OUTPUT must be specified.");
     return false;
   }
 
   if (source.empty() && !target.empty() && !output.empty()) {
-    this->SetError(
+    status.SetError(
       "Wrong syntax. A TARGET and OUTPUT can not both be specified.");
     return false;
   }
   if (append && output.empty()) {
-    this->SetError("given APPEND option with no OUTPUT.");
+    status.SetError("given APPEND option with no OUTPUT.");
     return false;
   }
 
   // Make sure the output names and locations are safe.
-  if (!this->CheckOutputs(output) || !this->CheckOutputs(outputs) ||
-      !this->CheckOutputs(byproducts)) {
+  if (!cmAddCustomCommandCommandCheckOutputs(output, status) ||
+      !cmAddCustomCommandCommandCheckOutputs(outputs, status) ||
+      !cmAddCustomCommandCommandCheckOutputs(byproducts, status)) {
     return false;
   }
 
   // Check for an append request.
   if (append) {
     // Lookup an existing command.
-    if (cmSourceFile* sf =
-          this->Makefile->GetSourceFileWithOutput(output[0])) {
+    if (cmSourceFile* sf = mf.GetSourceFileWithOutput(output[0])) {
       if (cmCustomCommand* cc = sf->GetCustomCommand()) {
         cc->AppendCommands(commandLines);
         cc->AppendDepends(depends);
@@ -321,12 +323,12 @@
     std::ostringstream e;
     e << "given APPEND option with output\n\"" << output[0]
       << "\"\nwhich is not already a custom command output.";
-    this->SetError(e.str());
+    status.SetError(e.str());
     return false;
   }
 
   if (uses_terminal && !job_pool.empty()) {
-    this->SetError("JOB_POOL is shadowed by USES_TERMINAL.");
+    status.SetError("JOB_POOL is shadowed by USES_TERMINAL.");
     return false;
   }
 
@@ -335,22 +337,21 @@
   if (source.empty() && output.empty()) {
     // Source is empty, use the target.
     std::vector<std::string> no_depends;
-    this->Makefile->AddCustomCommandToTarget(
-      target, byproducts, no_depends, commandLines, cctype, comment,
-      working.c_str(), escapeOldStyle, uses_terminal, depfile, job_pool,
-      command_expand_lists);
+    mf.AddCustomCommandToTarget(target, byproducts, no_depends, commandLines,
+                                cctype, comment, working.c_str(),
+                                escapeOldStyle, uses_terminal, depfile,
+                                job_pool, command_expand_lists);
   } else if (target.empty()) {
     // Target is empty, use the output.
-    this->Makefile->AddCustomCommandToOutput(
-      output, byproducts, depends, main_dependency, commandLines, comment,
-      working.c_str(), false, escapeOldStyle, uses_terminal,
-      command_expand_lists, depfile, job_pool);
+    mf.AddCustomCommandToOutput(output, byproducts, depends, main_dependency,
+                                commandLines, comment, working.c_str(), false,
+                                escapeOldStyle, uses_terminal,
+                                command_expand_lists, depfile, job_pool);
 
     // Add implicit dependency scanning requests if any were given.
     if (!implicit_depends.empty()) {
       bool okay = false;
-      if (cmSourceFile* sf =
-            this->Makefile->GetSourceFileWithOutput(output[0])) {
+      if (cmSourceFile* sf = mf.GetSourceFileWithOutput(output[0])) {
         if (cmCustomCommand* cc = sf->GetCustomCommand()) {
           okay = true;
           cc->SetImplicitDepends(implicit_depends);
@@ -360,21 +361,21 @@
         std::ostringstream e;
         e << "could not locate source file with a custom command producing \""
           << output[0] << "\" even though this command tried to create it!";
-        this->SetError(e.str());
+        status.SetError(e.str());
         return false;
       }
     }
   } else if (!byproducts.empty()) {
-    this->SetError("BYPRODUCTS may not be specified with SOURCE signatures");
+    status.SetError("BYPRODUCTS may not be specified with SOURCE signatures");
     return false;
   } else if (uses_terminal) {
-    this->SetError("USES_TERMINAL may not be used with SOURCE signatures");
+    status.SetError("USES_TERMINAL may not be used with SOURCE signatures");
     return false;
   } else {
     bool issueMessage = true;
     std::ostringstream e;
     MessageType messageType = MessageType::AUTHOR_WARNING;
-    switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0050)) {
+    switch (mf.GetPolicyStatus(cmPolicies::CMP0050)) {
       case cmPolicies::WARN:
         e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0050) << "\n";
         break;
@@ -391,30 +392,31 @@
     if (issueMessage) {
       e << "The SOURCE signatures of add_custom_command are no longer "
            "supported.";
-      this->Makefile->IssueMessage(messageType, e.str());
+      mf.IssueMessage(messageType, e.str());
       if (messageType == MessageType::FATAL_ERROR) {
         return false;
       }
     }
 
     // Use the old-style mode for backward compatibility.
-    this->Makefile->AddCustomCommandOldStyle(target, outputs, depends, source,
-                                             commandLines, comment);
+    mf.AddCustomCommandOldStyle(target, outputs, depends, source, commandLines,
+                                comment);
   }
 
   return true;
 }
 
-bool cmAddCustomCommandCommand::CheckOutputs(
-  const std::vector<std::string>& outputs)
+bool cmAddCustomCommandCommandCheckOutputs(
+  const std::vector<std::string>& outputs, cmExecutionStatus& status)
 {
+  cmMakefile& mf = status.GetMakefile();
   for (std::string const& o : outputs) {
     // Make sure the file will not be generated into the source
     // directory during an out of source build.
-    if (!this->Makefile->CanIWriteThisFile(o)) {
+    if (!mf.CanIWriteThisFile(o)) {
       std::string e = "attempted to have a file \"" + o +
         "\" in a source directory as an output of custom command.";
-      this->SetError(e);
+      status.SetError(e);
       cmSystemTools::SetFatalErrorOccured();
       return false;
     }
@@ -425,7 +427,7 @@
       std::ostringstream msg;
       msg << "called with OUTPUT containing a \"" << o[pos]
           << "\".  This character is not allowed.";
-      this->SetError(msg.str());
+      status.SetError(msg.str());
       return false;
     }
   }
diff --git a/Source/cmAddCustomCommandCommand.h b/Source/cmAddCustomCommandCommand.h
index 931aeab..4f8c58f 100644
--- a/Source/cmAddCustomCommandCommand.h
+++ b/Source/cmAddCustomCommandCommand.h
@@ -8,38 +8,9 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmAddCustomCommandCommand
- * \brief cmAddCustomCommandCommand defines a new command (rule) that can
- *  be executed within the build process
- *
- */
-
-class cmAddCustomCommandCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmAddCustomCommandCommand>();
-  }
-
-  /**
-   * 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:
-  bool CheckOutputs(const std::vector<std::string>& outputs);
-};
+bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
+                               cmExecutionStatus& status);
 
 #endif
diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx
index 0ecd5f5..f812ab5 100644
--- a/Source/cmAddCustomTargetCommand.cxx
+++ b/Source/cmAddCustomTargetCommand.cxx
@@ -6,6 +6,7 @@
 #include <utility>
 
 #include "cmCustomCommandLines.h"
+#include "cmExecutionStatus.h"
 #include "cmGeneratorExpression.h"
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
@@ -14,17 +15,15 @@
 #include "cmSystemTools.h"
 #include "cmTarget.h"
 
-class cmExecutionStatus;
-
-// cmAddCustomTargetCommand
-bool cmAddCustomTargetCommand::InitialPass(
-  std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmAddCustomTargetCommand(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();
   std::string const& targetName = args[0];
 
   // Check the target name.
@@ -33,7 +32,7 @@
     e << "called with invalid target name \"" << targetName
       << "\".  Target names may not contain a slash.  "
       << "Use ADD_CUSTOM_COMMAND to generate files.";
-    this->SetError(e.str());
+    status.SetError(e.str());
     return false;
   }
 
@@ -122,7 +121,7 @@
         case doing_byproducts: {
           std::string filename;
           if (!cmSystemTools::FileIsFullPath(copy)) {
-            filename = this->Makefile->GetCurrentBinaryDirectory();
+            filename = mf.GetCurrentBinaryDirectory();
             filename += "/";
           }
           filename += copy;
@@ -145,7 +144,7 @@
           job_pool = copy;
           break;
         default:
-          this->SetError("Wrong syntax. Unknown type of argument.");
+          status.SetError("Wrong syntax. Unknown type of argument.");
           return false;
       }
     }
@@ -156,7 +155,7 @@
     std::ostringstream msg;
     msg << "called with target name containing a \"" << targetName[pos]
         << "\".  This character is not allowed.";
-    this->SetError(msg.str());
+    status.SetError(msg.str());
     return false;
   }
 
@@ -168,8 +167,7 @@
   if (nameOk) {
     nameOk = targetName.find(':') == std::string::npos;
   }
-  if (!nameOk &&
-      !this->Makefile->CheckCMP0037(targetName, cmStateEnums::UTILITY)) {
+  if (!nameOk && !mf.CheckCMP0037(targetName, cmStateEnums::UTILITY)) {
     return false;
   }
 
@@ -182,39 +180,37 @@
   // Enforce name uniqueness.
   {
     std::string msg;
-    if (!this->Makefile->EnforceUniqueName(targetName, msg, true)) {
-      this->SetError(msg);
+    if (!mf.EnforceUniqueName(targetName, msg, true)) {
+      status.SetError(msg);
       return false;
     }
   }
 
   if (commandLines.empty() && !byproducts.empty()) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "BYPRODUCTS may not be specified without any COMMAND");
+    mf.IssueMessage(MessageType::FATAL_ERROR,
+                    "BYPRODUCTS may not be specified without any COMMAND");
     return true;
   }
   if (commandLines.empty() && uses_terminal) {
-    this->Makefile->IssueMessage(
-      MessageType::FATAL_ERROR,
-      "USES_TERMINAL may not be specified without any COMMAND");
+    mf.IssueMessage(MessageType::FATAL_ERROR,
+                    "USES_TERMINAL may not be specified without any COMMAND");
     return true;
   }
   if (commandLines.empty() && command_expand_lists) {
-    this->Makefile->IssueMessage(
+    mf.IssueMessage(
       MessageType::FATAL_ERROR,
       "COMMAND_EXPAND_LISTS may not be specified without any COMMAND");
     return true;
   }
 
   if (uses_terminal && !job_pool.empty()) {
-    this->SetError("JOB_POOL is shadowed by USES_TERMINAL.");
+    status.SetError("JOB_POOL is shadowed by USES_TERMINAL.");
     return false;
   }
 
   // Add the utility target to the makefile.
   bool escapeOldStyle = !verbatim;
-  cmTarget* target = this->Makefile->AddUtilityCommand(
+  cmTarget* target = mf.AddUtilityCommand(
     targetName, cmMakefile::TargetOrigin::Project, excludeFromAll,
     working_directory.c_str(), byproducts, depends, commandLines,
     escapeOldStyle, comment, uses_terminal, command_expand_lists, job_pool);
diff --git a/Source/cmAddCustomTargetCommand.h b/Source/cmAddCustomTargetCommand.h
index db577bc..e23ef9f 100644
--- a/Source/cmAddCustomTargetCommand.h
+++ b/Source/cmAddCustomTargetCommand.h
@@ -8,36 +8,9 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmAddCustomTargetCommand
- * \brief Command that adds a target to the build system.
- *
- * cmAddCustomTargetCommand adds an extra target to the build system.
- * This is useful when you would like to add special
- * targets like "install,", "clean," and so on.
- */
-class cmAddCustomTargetCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmAddCustomTargetCommand>();
-  }
-
-  /**
-   * 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;
-};
+bool cmAddCustomTargetCommand(std::vector<std::string> const& args,
+                              cmExecutionStatus& status);
 
 #endif
diff --git a/Source/cmAddDefinitionsCommand.cxx b/Source/cmAddDefinitionsCommand.cxx
index 62e57a3..0b10aee 100644
--- a/Source/cmAddDefinitionsCommand.cxx
+++ b/Source/cmAddDefinitionsCommand.cxx
@@ -2,21 +2,15 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmAddDefinitionsCommand.h"
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 
-class cmExecutionStatus;
-
-// cmAddDefinitionsCommand
-bool cmAddDefinitionsCommand::InitialPass(std::vector<std::string> const& args,
-                                          cmExecutionStatus&)
+bool cmAddDefinitionsCommand(std::vector<std::string> const& args,
+                             cmExecutionStatus& status)
 {
-  // it is OK to have no arguments
-  if (args.empty()) {
-    return true;
-  }
-
+  cmMakefile& mf = status.GetMakefile();
   for (std::string const& i : args) {
-    this->Makefile->AddDefineFlag(i);
+    mf.AddDefineFlag(i);
   }
   return true;
 }
diff --git a/Source/cmAddDefinitionsCommand.h b/Source/cmAddDefinitionsCommand.h
index 0e32c83..a67f095 100644
--- a/Source/cmAddDefinitionsCommand.h
+++ b/Source/cmAddDefinitionsCommand.h
@@ -8,35 +8,9 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmAddDefinitionsCommand
- * \brief Specify a list of compiler defines
- *
- * cmAddDefinitionsCommand specifies a list of compiler defines. These defines
- * will be added to the compile command.
- */
-class cmAddDefinitionsCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmAddDefinitionsCommand>();
-  }
-
-  /**
-   * 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;
-};
+bool cmAddDefinitionsCommand(std::vector<std::string> const& args,
+                             cmExecutionStatus& status);
 
 #endif
diff --git a/Source/cmAddDependenciesCommand.cxx b/Source/cmAddDependenciesCommand.cxx
index 4956a47..0ddbda8 100644
--- a/Source/cmAddDependenciesCommand.cxx
+++ b/Source/cmAddDependenciesCommand.cxx
@@ -4,34 +4,33 @@
 
 #include <sstream>
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmRange.h"
 #include "cmTarget.h"
 
-class cmExecutionStatus;
-
-// cmDependenciesCommand
-bool cmAddDependenciesCommand::InitialPass(
-  std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmAddDependenciesCommand(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;
   }
 
+  cmMakefile& mf = status.GetMakefile();
   std::string const& target_name = args[0];
-  if (this->Makefile->IsAlias(target_name)) {
+  if (mf.IsAlias(target_name)) {
     std::ostringstream e;
     e << "Cannot add target-level dependencies to alias target \""
       << target_name << "\".\n";
-    this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+    mf.IssueMessage(MessageType::FATAL_ERROR, e.str());
   }
-  if (cmTarget* target = this->Makefile->FindTargetToUse(target_name)) {
+  if (cmTarget* target = mf.FindTargetToUse(target_name)) {
 
     // skip over target_name
     for (std::string const& arg : cmMakeRange(args).advance(1)) {
-      target->AddUtility(arg, this->Makefile);
+      target->AddUtility(arg, &mf);
     }
   } else {
     std::ostringstream e;
@@ -41,7 +40,7 @@
       << "by the add_executable, add_library, or add_custom_target commands.  "
       << "If you want to add file-level dependencies see the DEPENDS option "
       << "of the add_custom_target and add_custom_command commands.";
-    this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+    mf.IssueMessage(MessageType::FATAL_ERROR, e.str());
   }
 
   return true;
diff --git a/Source/cmAddDependenciesCommand.h b/Source/cmAddDependenciesCommand.h
index ce912d3..0c60e3a 100644
--- a/Source/cmAddDependenciesCommand.h
+++ b/Source/cmAddDependenciesCommand.h
@@ -8,34 +8,9 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmAddDependenciesCommand
- * \brief Add a dependency to a target
- *
- * cmAddDependenciesCommand adds a dependency to a target
- */
-class cmAddDependenciesCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmAddDependenciesCommand>();
-  }
-
-  /**
-   * 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;
-};
+bool cmAddDependenciesCommand(std::vector<std::string> const& args,
+                              cmExecutionStatus& status);
 
 #endif
diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx
index 5685fdf..59d6be3 100644
--- a/Source/cmAddExecutableCommand.cxx
+++ b/Source/cmAddExecutableCommand.cxx
@@ -4,22 +4,22 @@
 
 #include <sstream>
 
+#include "cmExecutionStatus.h"
 #include "cmGeneratorExpression.h"
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
 #include "cmStateTypes.h"
 #include "cmTarget.h"
 
-class cmExecutionStatus;
-
-// cmExecutableCommand
-bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args,
-                                         cmExecutionStatus&)
+bool cmAddExecutableCommand(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();
   std::vector<std::string>::const_iterator s = args.begin();
 
   std::string const& exename = *s;
@@ -61,59 +61,58 @@
   if (nameOk && !importTarget && !isAlias) {
     nameOk = exename.find(':') == std::string::npos;
   }
-  if (!nameOk &&
-      !this->Makefile->CheckCMP0037(exename, cmStateEnums::EXECUTABLE)) {
+  if (!nameOk && !mf.CheckCMP0037(exename, cmStateEnums::EXECUTABLE)) {
     return false;
   }
 
   // Special modifiers are not allowed with IMPORTED signature.
   if (importTarget && (use_win32 || use_macbundle || excludeFromAll)) {
     if (use_win32) {
-      this->SetError("may not be given WIN32 for an IMPORTED target.");
+      status.SetError("may not be given WIN32 for an IMPORTED target.");
     } else if (use_macbundle) {
-      this->SetError("may not be given MACOSX_BUNDLE for an IMPORTED target.");
+      status.SetError(
+        "may not be given MACOSX_BUNDLE for an IMPORTED target.");
     } else // if(excludeFromAll)
     {
-      this->SetError(
+      status.SetError(
         "may not be given EXCLUDE_FROM_ALL for an IMPORTED target.");
     }
     return false;
   }
   if (isAlias) {
     if (!cmGeneratorExpression::IsValidTargetName(exename)) {
-      this->SetError("Invalid name for ALIAS: " + exename);
+      status.SetError("Invalid name for ALIAS: " + exename);
       return false;
     }
     if (excludeFromAll) {
-      this->SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense.");
+      status.SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense.");
       return false;
     }
     if (importTarget || importGlobal) {
-      this->SetError("IMPORTED with ALIAS is not allowed.");
+      status.SetError("IMPORTED with ALIAS is not allowed.");
       return false;
     }
     if (args.size() != 3) {
       std::ostringstream e;
       e << "ALIAS requires exactly one target argument.";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
 
     std::string const& aliasedName = *s;
-    if (this->Makefile->IsAlias(aliasedName)) {
+    if (mf.IsAlias(aliasedName)) {
       std::ostringstream e;
       e << "cannot create ALIAS target \"" << exename << "\" because target \""
         << aliasedName << "\" is itself an ALIAS.";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
-    cmTarget* aliasedTarget =
-      this->Makefile->FindTargetToUse(aliasedName, true);
+    cmTarget* aliasedTarget = mf.FindTargetToUse(aliasedName, true);
     if (!aliasedTarget) {
       std::ostringstream e;
       e << "cannot create ALIAS target \"" << exename << "\" because target \""
         << aliasedName << "\" does not already exist.";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
     cmStateEnums::TargetType type = aliasedTarget->GetType();
@@ -121,7 +120,7 @@
       std::ostringstream e;
       e << "cannot create ALIAS target \"" << exename << "\" because target \""
         << aliasedName << "\" is not an executable.";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
     if (aliasedTarget->IsImported() &&
@@ -129,42 +128,40 @@
       std::ostringstream e;
       e << "cannot create ALIAS target \"" << exename << "\" because target \""
         << aliasedName << "\" is imported but not globally visible.";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
-    this->Makefile->AddAlias(exename, aliasedName);
+    mf.AddAlias(exename, aliasedName);
     return true;
   }
 
   // Handle imported target creation.
   if (importTarget) {
     // Make sure the target does not already exist.
-    if (this->Makefile->FindTargetToUse(exename)) {
+    if (mf.FindTargetToUse(exename)) {
       std::ostringstream e;
       e << "cannot create imported target \"" << exename
         << "\" because another target with the same name already exists.";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
 
     // Create the imported target.
-    this->Makefile->AddImportedTarget(exename, cmStateEnums::EXECUTABLE,
-                                      importGlobal);
+    mf.AddImportedTarget(exename, cmStateEnums::EXECUTABLE, importGlobal);
     return true;
   }
 
   // Enforce name uniqueness.
   {
     std::string msg;
-    if (!this->Makefile->EnforceUniqueName(exename, msg)) {
-      this->SetError(msg);
+    if (!mf.EnforceUniqueName(exename, msg)) {
+      status.SetError(msg);
       return false;
     }
   }
 
   std::vector<std::string> srclists(s, args.end());
-  cmTarget* tgt =
-    this->Makefile->AddExecutable(exename, srclists, excludeFromAll);
+  cmTarget* tgt = mf.AddExecutable(exename, srclists, excludeFromAll);
   if (use_win32) {
     tgt->SetProperty("WIN32_EXECUTABLE", "ON");
   }
diff --git a/Source/cmAddExecutableCommand.h b/Source/cmAddExecutableCommand.h
index ec57c3f..f7bc273 100644
--- a/Source/cmAddExecutableCommand.h
+++ b/Source/cmAddExecutableCommand.h
@@ -8,35 +8,9 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmExecutablesCommand
- * \brief Defines a list of executables to build.
- *
- * cmExecutablesCommand defines a list of executable (i.e., test)
- * programs to create.
- */
-class cmAddExecutableCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmAddExecutableCommand>();
-  }
-
-  /**
-   * 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;
-};
+bool cmAddExecutableCommand(std::vector<std::string> const& args,
+                            cmExecutionStatus& status);
 
 #endif
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index ad12e89..626b7c9 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -5,6 +5,7 @@
 #include <sstream>
 
 #include "cmAlgorithms.h"
+#include "cmExecutionStatus.h"
 #include "cmGeneratorExpression.h"
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
@@ -14,21 +15,19 @@
 #include "cmSystemTools.h"
 #include "cmTarget.h"
 
-class cmExecutionStatus;
-
-// cmLibraryCommand
-bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
-                                      cmExecutionStatus&)
+bool cmAddLibraryCommand(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();
   // Library type defaults to value of BUILD_SHARED_LIBS, if it exists,
   // otherwise it defaults to static library.
   cmStateEnums::TargetType type = cmStateEnums::SHARED_LIBRARY;
-  if (cmSystemTools::IsOff(
-        this->Makefile->GetDefinition("BUILD_SHARED_LIBS"))) {
+  if (cmSystemTools::IsOff(mf.GetDefinition("BUILD_SHARED_LIBS"))) {
     type = cmStateEnums::STATIC_LIBRARY;
   }
   bool excludeFromAll = false;
@@ -52,7 +51,7 @@
       if (type == cmStateEnums::INTERFACE_LIBRARY) {
         std::ostringstream e;
         e << "INTERFACE library specified with conflicting STATIC type.";
-        this->SetError(e.str());
+        status.SetError(e.str());
         return false;
       }
       ++s;
@@ -62,7 +61,7 @@
       if (type == cmStateEnums::INTERFACE_LIBRARY) {
         std::ostringstream e;
         e << "INTERFACE library specified with conflicting SHARED type.";
-        this->SetError(e.str());
+        status.SetError(e.str());
         return false;
       }
       ++s;
@@ -72,7 +71,7 @@
       if (type == cmStateEnums::INTERFACE_LIBRARY) {
         std::ostringstream e;
         e << "INTERFACE library specified with conflicting MODULE type.";
-        this->SetError(e.str());
+        status.SetError(e.str());
         return false;
       }
       ++s;
@@ -82,7 +81,7 @@
       if (type == cmStateEnums::INTERFACE_LIBRARY) {
         std::ostringstream e;
         e << "INTERFACE library specified with conflicting OBJECT type.";
-        this->SetError(e.str());
+        status.SetError(e.str());
         return false;
       }
       ++s;
@@ -92,7 +91,7 @@
       if (type == cmStateEnums::INTERFACE_LIBRARY) {
         std::ostringstream e;
         e << "INTERFACE library specified with conflicting UNKNOWN type.";
-        this->SetError(e.str());
+        status.SetError(e.str());
         return false;
       }
       ++s;
@@ -102,7 +101,7 @@
       if (type == cmStateEnums::INTERFACE_LIBRARY) {
         std::ostringstream e;
         e << "INTERFACE library specified with conflicting ALIAS type.";
-        this->SetError(e.str());
+        status.SetError(e.str());
         return false;
       }
       ++s;
@@ -111,19 +110,19 @@
       if (haveSpecifiedType) {
         std::ostringstream e;
         e << "INTERFACE library specified with conflicting/multiple types.";
-        this->SetError(e.str());
+        status.SetError(e.str());
         return false;
       }
       if (isAlias) {
         std::ostringstream e;
         e << "INTERFACE library specified with conflicting ALIAS type.";
-        this->SetError(e.str());
+        status.SetError(e.str());
         return false;
       }
       if (excludeFromAll) {
         std::ostringstream e;
         e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL.";
-        this->SetError(e.str());
+        status.SetError(e.str());
         return false;
       }
       ++s;
@@ -133,7 +132,7 @@
       if (type == cmStateEnums::INTERFACE_LIBRARY) {
         std::ostringstream e;
         e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL.";
-        this->SetError(e.str());
+        status.SetError(e.str());
         return false;
       }
       ++s;
@@ -147,7 +146,7 @@
     } else if (type == cmStateEnums::INTERFACE_LIBRARY && *s == "GLOBAL") {
       std::ostringstream e;
       e << "GLOBAL option may only be used with IMPORTED libraries.";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     } else {
       break;
@@ -158,13 +157,13 @@
     if (s != args.end()) {
       std::ostringstream e;
       e << "INTERFACE library requires no source arguments.";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
     if (importGlobal && !importTarget) {
       std::ostringstream e;
       e << "INTERFACE library specified as GLOBAL, but not as IMPORTED.";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
   }
@@ -175,47 +174,46 @@
   if (nameOk && !importTarget && !isAlias) {
     nameOk = libName.find(':') == std::string::npos;
   }
-  if (!nameOk && !this->Makefile->CheckCMP0037(libName, type)) {
+  if (!nameOk && !mf.CheckCMP0037(libName, type)) {
     return false;
   }
 
   if (isAlias) {
     if (!cmGeneratorExpression::IsValidTargetName(libName)) {
-      this->SetError("Invalid name for ALIAS: " + libName);
+      status.SetError("Invalid name for ALIAS: " + libName);
       return false;
     }
     if (excludeFromAll) {
-      this->SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense.");
+      status.SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense.");
       return false;
     }
     if (importTarget || importGlobal) {
-      this->SetError("IMPORTED with ALIAS is not allowed.");
+      status.SetError("IMPORTED with ALIAS is not allowed.");
       return false;
     }
     if (args.size() != 3) {
       std::ostringstream e;
       e << "ALIAS requires exactly one target argument.";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
 
     std::string const& aliasedName = *s;
-    if (this->Makefile->IsAlias(aliasedName)) {
+    if (mf.IsAlias(aliasedName)) {
       std::ostringstream e;
       e << "cannot create ALIAS target \"" << libName << "\" because target \""
         << aliasedName << "\" is itself an ALIAS.";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
-    cmTarget* aliasedTarget =
-      this->Makefile->FindTargetToUse(aliasedName, true);
+    cmTarget* aliasedTarget = mf.FindTargetToUse(aliasedName, true);
     if (!aliasedTarget) {
       std::ostringstream e;
       e << "cannot create ALIAS target \"" << libName << "\" because target \""
         << aliasedName
         << "\" does not already "
            "exist.";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
     cmStateEnums::TargetType aliasedType = aliasedTarget->GetType();
@@ -229,7 +227,7 @@
       std::ostringstream e;
       e << "cannot create ALIAS target \"" << libName << "\" because target \""
         << aliasedName << "\" is not a library.";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
     if (aliasedTarget->IsImported() &&
@@ -237,15 +235,15 @@
       std::ostringstream e;
       e << "cannot create ALIAS target \"" << libName << "\" because target \""
         << aliasedName << "\" is imported but not globally visible.";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
-    this->Makefile->AddAlias(libName, aliasedName);
+    mf.AddAlias(libName, aliasedName);
     return true;
   }
 
   if (importTarget && excludeFromAll) {
-    this->SetError("excludeFromAll with IMPORTED target makes no sense.");
+    status.SetError("excludeFromAll with IMPORTED target makes no sense.");
     return false;
   }
 
@@ -255,14 +253,13 @@
     yet its linker language. */
   if ((type == cmStateEnums::SHARED_LIBRARY ||
        type == cmStateEnums::MODULE_LIBRARY) &&
-      !this->Makefile->GetState()->GetGlobalPropertyAsBool(
-        "TARGET_SUPPORTS_SHARED_LIBS")) {
+      !mf.GetState()->GetGlobalPropertyAsBool("TARGET_SUPPORTS_SHARED_LIBS")) {
     std::ostringstream w;
     w << "ADD_LIBRARY called with "
       << (type == cmStateEnums::SHARED_LIBRARY ? "SHARED" : "MODULE")
       << " option but the target platform does not support dynamic linking. "
          "Building a STATIC library instead. This may lead to problems.";
-    this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
+    mf.IssueMessage(MessageType::AUTHOR_WARNING, w.str());
     type = cmStateEnums::STATIC_LIBRARY;
   }
 
@@ -270,14 +267,13 @@
   if (importTarget) {
     // The IMPORTED signature requires a type to be specified explicitly.
     if (!haveSpecifiedType) {
-      this->SetError("called with IMPORTED argument but no library type.");
+      status.SetError("called with IMPORTED argument but no library type.");
       return false;
     }
     if (type == cmStateEnums::OBJECT_LIBRARY) {
       std::string reason;
-      if (!this->Makefile->GetGlobalGenerator()->HasKnownObjectFileLocation(
-            &reason)) {
-        this->Makefile->IssueMessage(
+      if (!mf.GetGlobalGenerator()->HasKnownObjectFileLocation(&reason)) {
+        mf.IssueMessage(
           MessageType::FATAL_ERROR,
           "The OBJECT library type may not be used for IMPORTED libraries" +
             reason + ".");
@@ -288,28 +284,28 @@
       if (!cmGeneratorExpression::IsValidTargetName(libName)) {
         std::ostringstream e;
         e << "Invalid name for IMPORTED INTERFACE library target: " << libName;
-        this->SetError(e.str());
+        status.SetError(e.str());
         return false;
       }
     }
 
     // Make sure the target does not already exist.
-    if (this->Makefile->FindTargetToUse(libName)) {
+    if (mf.FindTargetToUse(libName)) {
       std::ostringstream e;
       e << "cannot create imported target \"" << libName
         << "\" because another target with the same name already exists.";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
 
     // Create the imported target.
-    this->Makefile->AddImportedTarget(libName, type, importGlobal);
+    mf.AddImportedTarget(libName, type, importGlobal);
     return true;
   }
 
   // A non-imported target may not have UNKNOWN type.
   if (type == cmStateEnums::UNKNOWN_LIBRARY) {
-    this->Makefile->IssueMessage(
+    mf.IssueMessage(
       MessageType::FATAL_ERROR,
       "The UNKNOWN library type may be used only for IMPORTED libraries.");
     return true;
@@ -318,8 +314,8 @@
   // Enforce name uniqueness.
   {
     std::string msg;
-    if (!this->Makefile->EnforceUniqueName(libName, msg)) {
-      this->SetError(msg);
+    if (!mf.EnforceUniqueName(libName, msg)) {
+      status.SetError(msg);
       return false;
     }
   }
@@ -331,17 +327,17 @@
         libName.find("::") != std::string::npos) {
       std::ostringstream e;
       e << "Invalid name for INTERFACE library target: " << libName;
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
 
-    this->Makefile->AddLibrary(libName, type, srclists, excludeFromAll);
+    mf.AddLibrary(libName, type, srclists, excludeFromAll);
     return true;
   }
 
   cmAppend(srclists, s, args.end());
 
-  this->Makefile->AddLibrary(libName, type, srclists, excludeFromAll);
+  mf.AddLibrary(libName, type, srclists, excludeFromAll);
 
   return true;
 }
diff --git a/Source/cmAddLibraryCommand.h b/Source/cmAddLibraryCommand.h
index 56dab41..609449c 100644
--- a/Source/cmAddLibraryCommand.h
+++ b/Source/cmAddLibraryCommand.h
@@ -8,35 +8,9 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmLibrarysCommand
- * \brief Defines a list of executables to build.
- *
- * cmLibrarysCommand defines a list of executable (i.e., test)
- * programs to create.
- */
-class cmAddLibraryCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmAddLibraryCommand>();
-  }
-
-  /**
-   * 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;
-};
+bool cmAddLibraryCommand(std::vector<std::string> const& args,
+                         cmExecutionStatus& status);
 
 #endif
diff --git a/Source/cmAddLinkOptionsCommand.cxx b/Source/cmAddLinkOptionsCommand.cxx
index 10ebd12..7ed31bd 100644
--- a/Source/cmAddLinkOptionsCommand.cxx
+++ b/Source/cmAddLinkOptionsCommand.cxx
@@ -2,19 +2,15 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmAddLinkOptionsCommand.h"
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 
-class cmExecutionStatus;
-
-bool cmAddLinkOptionsCommand::InitialPass(std::vector<std::string> const& args,
-                                          cmExecutionStatus&)
+bool cmAddLinkOptionsCommand(std::vector<std::string> const& args,
+                             cmExecutionStatus& status)
 {
-  if (args.empty()) {
-    return true;
-  }
-
+  cmMakefile& mf = status.GetMakefile();
   for (std::string const& i : args) {
-    this->Makefile->AddLinkOption(i);
+    mf.AddLinkOption(i);
   }
   return true;
 }
diff --git a/Source/cmAddLinkOptionsCommand.h b/Source/cmAddLinkOptionsCommand.h
index 8e46be6..466fc32 100644
--- a/Source/cmAddLinkOptionsCommand.h
+++ b/Source/cmAddLinkOptionsCommand.h
@@ -8,29 +8,9 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-class cmAddLinkOptionsCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmAddLinkOptionsCommand>();
-  }
-
-  /**
-   * 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;
-};
+bool cmAddLinkOptionsCommand(std::vector<std::string> const& args,
+                             cmExecutionStatus& status);
 
 #endif
diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx
index 7947188..50c682f 100644
--- a/Source/cmAddSubDirectoryCommand.cxx
+++ b/Source/cmAddSubDirectoryCommand.cxx
@@ -5,21 +5,20 @@
 #include <sstream>
 #include <string.h>
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmRange.h"
 #include "cmSystemTools.h"
 
-class cmExecutionStatus;
-
-// cmAddSubDirectoryCommand
-bool cmAddSubDirectoryCommand::InitialPass(
-  std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmAddSubDirectoryCommand(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();
   // store the binpath
   std::string const& srcArg = args.front();
   std::string binArg;
@@ -35,7 +34,7 @@
     if (binArg.empty()) {
       binArg = arg;
     } else {
-      this->SetError("called with incorrect number of arguments");
+      status.SetError("called with incorrect number of arguments");
       return false;
     }
   }
@@ -46,7 +45,7 @@
   if (cmSystemTools::FileIsFullPath(srcArg)) {
     srcPath = srcArg;
   } else {
-    srcPath = this->Makefile->GetCurrentSourceDirectory();
+    srcPath = mf.GetCurrentSourceDirectory();
     srcPath += "/";
     srcPath += srcArg;
   }
@@ -54,7 +53,7 @@
     std::string error = "given source \"";
     error += srcArg;
     error += "\" which is not an existing directory.";
-    this->SetError(error);
+    status.SetError(error);
     return false;
   }
   srcPath = cmSystemTools::CollapseFullPath(srcPath);
@@ -65,22 +64,22 @@
     // No binary directory was specified.  If the source directory is
     // not a subdirectory of the current directory then it is an
     // error.
-    if (!cmSystemTools::IsSubDirectory(
-          srcPath, this->Makefile->GetCurrentSourceDirectory())) {
+    if (!cmSystemTools::IsSubDirectory(srcPath,
+                                       mf.GetCurrentSourceDirectory())) {
       std::ostringstream e;
       e << "not given a binary directory but the given source directory "
         << "\"" << srcPath << "\" is not a subdirectory of \""
-        << this->Makefile->GetCurrentSourceDirectory() << "\".  "
+        << mf.GetCurrentSourceDirectory() << "\".  "
         << "When specifying an out-of-tree source a binary directory "
         << "must be explicitly specified.";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
 
     // Remove the CurrentDirectory from the srcPath and replace it
     // with the CurrentOutputDirectory.
-    const std::string& src = this->Makefile->GetCurrentSourceDirectory();
-    const std::string& bin = this->Makefile->GetCurrentBinaryDirectory();
+    const std::string& src = mf.GetCurrentSourceDirectory();
+    const std::string& bin = mf.GetCurrentBinaryDirectory();
     size_t srcLen = src.length();
     size_t binLen = bin.length();
     if (srcLen > 0 && src.back() == '/') {
@@ -96,7 +95,7 @@
     if (cmSystemTools::FileIsFullPath(binArg)) {
       binPath = binArg;
     } else {
-      binPath = this->Makefile->GetCurrentBinaryDirectory();
+      binPath = mf.GetCurrentBinaryDirectory();
       binPath += "/";
       binPath += binArg;
     }
@@ -104,7 +103,7 @@
   binPath = cmSystemTools::CollapseFullPath(binPath);
 
   // Add the subdirectory using the computed full paths.
-  this->Makefile->AddSubDirectory(srcPath, binPath, excludeFromAll, true);
+  mf.AddSubDirectory(srcPath, binPath, excludeFromAll, true);
 
   return true;
 }
diff --git a/Source/cmAddSubDirectoryCommand.h b/Source/cmAddSubDirectoryCommand.h
index 664334e..87da840 100644
--- a/Source/cmAddSubDirectoryCommand.h
+++ b/Source/cmAddSubDirectoryCommand.h
@@ -8,36 +8,9 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmAddSubDirectoryCommand
- * \brief Specify a subdirectory to build
- *
- * cmAddSubDirectoryCommand specifies a subdirectory to process
- * by CMake. CMake will descend
- * into the specified source directory and process any CMakeLists.txt found.
- */
-class cmAddSubDirectoryCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmAddSubDirectoryCommand>();
-  }
-
-  /**
-   * 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;
-};
+bool cmAddSubDirectoryCommand(std::vector<std::string> const& args,
+                              cmExecutionStatus& status);
 
 #endif
diff --git a/Source/cmAddTestCommand.cxx b/Source/cmAddTestCommand.cxx
index b0c462b..7904bf5 100644
--- a/Source/cmAddTestCommand.cxx
+++ b/Source/cmAddTestCommand.cxx
@@ -4,34 +4,36 @@
 
 #include <sstream>
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmTest.h"
 #include "cmTestGenerator.h"
 
-class cmExecutionStatus;
+static bool cmAddTestCommandHandleNameMode(
+  std::vector<std::string> const& args, cmExecutionStatus& status);
 
-// cmExecutableCommand
-bool cmAddTestCommand::InitialPass(std::vector<std::string> const& args,
-                                   cmExecutionStatus&)
+bool cmAddTestCommand(std::vector<std::string> const& args,
+                      cmExecutionStatus& status)
 {
   if (!args.empty() && args[0] == "NAME") {
-    return this->HandleNameMode(args);
+    return cmAddTestCommandHandleNameMode(args, status);
   }
 
   // First argument is the name of the test Second argument is the name of
   // the executable to run (a target or external program) Remaining arguments
   // are the arguments to pass to the executable
   if (args.size() < 2) {
-    this->SetError("called with incorrect number of arguments");
+    status.SetError("called with incorrect number of arguments");
     return false;
   }
 
+  cmMakefile& mf = status.GetMakefile();
   // Collect the command with arguments.
   std::vector<std::string> command(args.begin() + 1, args.end());
 
   // Create the test but add a generator only the first time it is
   // seen.  This preserves behavior from before test generators.
-  cmTest* test = this->Makefile->GetTest(args[0]);
+  cmTest* test = mf.GetTest(args[0]);
   if (test) {
     // If the test was already added by a new-style signature do not
     // allow it to be duplicated.
@@ -39,20 +41,21 @@
       std::ostringstream e;
       e << " given test name \"" << args[0]
         << "\" which already exists in this directory.";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
   } else {
-    test = this->Makefile->CreateTest(args[0]);
+    test = mf.CreateTest(args[0]);
     test->SetOldStyle(true);
-    this->Makefile->AddTestGenerator(new cmTestGenerator(test));
+    mf.AddTestGenerator(new cmTestGenerator(test));
   }
   test->SetCommand(command);
 
   return true;
 }
 
-bool cmAddTestCommand::HandleNameMode(std::vector<std::string> const& args)
+bool cmAddTestCommandHandleNameMode(std::vector<std::string> const& args,
+                                    cmExecutionStatus& status)
 {
   std::string name;
   std::vector<std::string> configurations;
@@ -73,25 +76,25 @@
   for (unsigned int i = 1; i < args.size(); ++i) {
     if (args[i] == "COMMAND") {
       if (!command.empty()) {
-        this->SetError(" may be given at most one COMMAND.");
+        status.SetError(" may be given at most one COMMAND.");
         return false;
       }
       doing = DoingCommand;
     } else if (args[i] == "CONFIGURATIONS") {
       if (!configurations.empty()) {
-        this->SetError(" may be given at most one set of CONFIGURATIONS.");
+        status.SetError(" may be given at most one set of CONFIGURATIONS.");
         return false;
       }
       doing = DoingConfigs;
     } else if (args[i] == "WORKING_DIRECTORY") {
       if (!working_directory.empty()) {
-        this->SetError(" may be given at most one WORKING_DIRECTORY.");
+        status.SetError(" may be given at most one WORKING_DIRECTORY.");
         return false;
       }
       doing = DoingWorkingDirectory;
     } else if (args[i] == "COMMAND_EXPAND_LISTS") {
       if (command_expand_lists) {
-        this->SetError(" may be given at most one COMMAND_EXPAND_LISTS.");
+        status.SetError(" may be given at most one COMMAND_EXPAND_LISTS.");
         return false;
       }
       command_expand_lists = true;
@@ -109,41 +112,43 @@
     } else {
       std::ostringstream e;
       e << " given unknown argument:\n  " << args[i] << "\n";
-      this->SetError(e.str());
+      status.SetError(e.str());
       return false;
     }
   }
 
   // Require a test name.
   if (name.empty()) {
-    this->SetError(" must be given non-empty NAME.");
+    status.SetError(" must be given non-empty NAME.");
     return false;
   }
 
   // Require a command.
   if (command.empty()) {
-    this->SetError(" must be given non-empty COMMAND.");
+    status.SetError(" must be given non-empty COMMAND.");
     return false;
   }
 
+  cmMakefile& mf = status.GetMakefile();
+
   // Require a unique test name within the directory.
-  if (this->Makefile->GetTest(name)) {
+  if (mf.GetTest(name)) {
     std::ostringstream e;
     e << " given test NAME \"" << name
       << "\" which already exists in this directory.";
-    this->SetError(e.str());
+    status.SetError(e.str());
     return false;
   }
 
   // Add the test.
-  cmTest* test = this->Makefile->CreateTest(name);
+  cmTest* test = mf.CreateTest(name);
   test->SetOldStyle(false);
   test->SetCommand(command);
   if (!working_directory.empty()) {
     test->SetProperty("WORKING_DIRECTORY", working_directory.c_str());
   }
   test->SetCommandExpandLists(command_expand_lists);
-  this->Makefile->AddTestGenerator(new cmTestGenerator(test, configurations));
+  mf.AddTestGenerator(new cmTestGenerator(test, configurations));
 
   return true;
 }
diff --git a/Source/cmAddTestCommand.h b/Source/cmAddTestCommand.h
index 3d37d2b..5877547 100644
--- a/Source/cmAddTestCommand.h
+++ b/Source/cmAddTestCommand.h
@@ -8,37 +8,9 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmAddTestCommand
- * \brief Add a test to the lists of tests to run.
- *
- * cmAddTestCommand adds a test to the list of tests to run .
- */
-class cmAddTestCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmAddTestCommand>();
-  }
-
-  /**
-   * 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 HandleNameMode(std::vector<std::string> const& args);
-};
+bool cmAddTestCommand(std::vector<std::string> const& args,
+                      cmExecutionStatus& status);
 
 #endif
diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx
index 45c6411..83199b4 100644
--- a/Source/cmAuxSourceDirectoryCommand.cxx
+++ b/Source/cmAuxSourceDirectoryCommand.cxx
@@ -7,28 +7,27 @@
 #include <stddef.h>
 #include <utility>
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmSourceFile.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmake.h"
 
-class cmExecutionStatus;
-
-// cmAuxSourceDirectoryCommand
-bool cmAuxSourceDirectoryCommand::InitialPass(
-  std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmAuxSourceDirectoryCommand(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;
   }
 
+  cmMakefile& mf = status.GetMakefile();
   std::string sourceListValue;
   std::string const& templateDirectory = args[0];
   std::string tdir;
   if (!cmSystemTools::FileIsFullPath(templateDirectory)) {
-    tdir = this->Makefile->GetCurrentSourceDirectory();
+    tdir = mf.GetCurrentSourceDirectory();
     tdir += "/";
     tdir += templateDirectory;
   } else {
@@ -36,7 +35,7 @@
   }
 
   // was the list already populated
-  const char* def = this->Makefile->GetDefinition(args[1]);
+  const char* def = mf.GetDefinition(args[1]);
   if (def) {
     sourceListValue = def;
   }
@@ -55,14 +54,14 @@
         std::string ext = file.substr(dotpos + 1);
         std::string base = file.substr(0, dotpos);
         // Process only source files
-        auto cm = this->Makefile->GetCMakeInstance();
+        auto cm = mf.GetCMakeInstance();
         if (!base.empty() && cm->IsSourceExtension(ext)) {
           std::string fullname = templateDirectory;
           fullname += "/";
           fullname += file;
           // add the file as a class file so
           // depends can be done
-          cmSourceFile* sf = this->Makefile->GetOrCreateSource(fullname);
+          cmSourceFile* sf = mf.GetOrCreateSource(fullname);
           sf->SetProperty("ABSTRACT", "0");
           files.push_back(std::move(fullname));
         }
@@ -74,6 +73,6 @@
     sourceListValue += ";";
   }
   sourceListValue += cmJoin(files, ";");
-  this->Makefile->AddDefinition(args[1], sourceListValue);
+  mf.AddDefinition(args[1], sourceListValue);
   return true;
 }
diff --git a/Source/cmAuxSourceDirectoryCommand.h b/Source/cmAuxSourceDirectoryCommand.h
index 973a464..ae26092 100644
--- a/Source/cmAuxSourceDirectoryCommand.h
+++ b/Source/cmAuxSourceDirectoryCommand.h
@@ -8,38 +8,9 @@
 #include <string>
 #include <vector>
 
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmAuxSourceDirectoryCommand
- * \brief Specify auxiliary source code directories.
- *
- * cmAuxSourceDirectoryCommand specifies source code directories
- * that must be built as part of this build process. This directories
- * are not recursively processed like the SUBDIR command (cmSubdirCommand).
- * A side effect of this command is to create a subdirectory in the build
- * directory structure.
- */
-class cmAuxSourceDirectoryCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  std::unique_ptr<cmCommand> Clone() override
-  {
-    return cm::make_unique<cmAuxSourceDirectoryCommand>();
-  }
-
-  /**
-   * 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;
-};
+bool cmAuxSourceDirectoryCommand(std::vector<std::string> const& args,
+                                 cmExecutionStatus& status);
 
 #endif
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 8c62c30..8565e1c 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -233,21 +233,14 @@
 
 void GetProjectCommands(cmState* state)
 {
-  state->AddBuiltinCommand("add_custom_command",
-                           cm::make_unique<cmAddCustomCommandCommand>());
-  state->AddBuiltinCommand("add_custom_target",
-                           cm::make_unique<cmAddCustomTargetCommand>());
-  state->AddBuiltinCommand("add_definitions",
-                           cm::make_unique<cmAddDefinitionsCommand>());
-  state->AddBuiltinCommand("add_dependencies",
-                           cm::make_unique<cmAddDependenciesCommand>());
-  state->AddBuiltinCommand("add_executable",
-                           cm::make_unique<cmAddExecutableCommand>());
-  state->AddBuiltinCommand("add_library",
-                           cm::make_unique<cmAddLibraryCommand>());
-  state->AddBuiltinCommand("add_subdirectory",
-                           cm::make_unique<cmAddSubDirectoryCommand>());
-  state->AddBuiltinCommand("add_test", cm::make_unique<cmAddTestCommand>());
+  state->AddBuiltinCommand("add_custom_command", cmAddCustomCommandCommand);
+  state->AddBuiltinCommand("add_custom_target", cmAddCustomTargetCommand);
+  state->AddBuiltinCommand("add_definitions", cmAddDefinitionsCommand);
+  state->AddBuiltinCommand("add_dependencies", cmAddDependenciesCommand);
+  state->AddBuiltinCommand("add_executable", cmAddExecutableCommand);
+  state->AddBuiltinCommand("add_library", cmAddLibraryCommand);
+  state->AddBuiltinCommand("add_subdirectory", cmAddSubDirectoryCommand);
+  state->AddBuiltinCommand("add_test", cmAddTestCommand);
   state->AddBuiltinCommand("build_command", cm::make_unique<cmBuildCommand>());
   state->AddBuiltinCommand("create_test_sourcelist",
                            cm::make_unique<cmCreateTestSourceList>());
@@ -303,11 +296,10 @@
 
 #if !defined(CMAKE_BOOTSTRAP)
   state->AddBuiltinCommand("add_compile_definitions",
-                           cm::make_unique<cmAddCompileDefinitionsCommand>());
-  state->AddBuiltinCommand("add_compile_options",
-                           cm::make_unique<cmAddCompileOptionsCommand>());
+                           cmAddCompileDefinitionsCommand);
+  state->AddBuiltinCommand("add_compile_options", cmAddCompileOptionsCommand);
   state->AddBuiltinCommand("aux_source_directory",
-                           cm::make_unique<cmAuxSourceDirectoryCommand>());
+                           cmAuxSourceDirectoryCommand);
   state->AddBuiltinCommand("export", cm::make_unique<cmExportCommand>());
   state->AddBuiltinCommand("fltk_wrap_ui",
                            cm::make_unique<cmFLTKWrapUICommand>());
@@ -316,8 +308,7 @@
     cm::make_unique<cmIncludeExternalMSProjectCommand>());
   state->AddBuiltinCommand("install_programs",
                            cm::make_unique<cmInstallProgramsCommand>());
-  state->AddBuiltinCommand("add_link_options",
-                           cm::make_unique<cmAddLinkOptionsCommand>());
+  state->AddBuiltinCommand("add_link_options", cmAddLinkOptionsCommand);
   state->AddBuiltinCommand("link_libraries",
                            cm::make_unique<cmLinkLibrariesCommand>());
   state->AddBuiltinCommand("target_link_options",