Browse Source

cmake_command: Add command to INVOKE other commands by name

Fixes: #18392
Cristian Adam 5 years ago
parent
commit
54e4f2ad45
29 changed files with 164 additions and 0 deletions
  1. 40 0
      Help/command/cmake_command.rst
  2. 4 0
      Help/command/function.rst
  3. 4 0
      Help/command/macro.rst
  4. 1 0
      Help/manual/cmake-commands.7.rst
  5. 6 0
      Help/release/dev/cmake_command-command.rst
  6. 2 0
      Source/CMakeLists.txt
  7. 47 0
      Source/cmCMakeCommand.cxx
  8. 20 0
      Source/cmCMakeCommand.h
  9. 2 0
      Source/cmCommands.cxx
  10. 2 0
      Tests/RunCMake/CMakeLists.txt
  11. 3 0
      Tests/RunCMake/cmake_command/CMakeLists.txt
  12. 8 0
      Tests/RunCMake/cmake_command/RunCMakeTest.cmake
  13. 1 0
      Tests/RunCMake/cmake_command/cmake_command_invoke_message-stderr.txt
  14. 1 0
      Tests/RunCMake/cmake_command/cmake_command_invoke_message.cmake
  15. 1 0
      Tests/RunCMake/cmake_command/cmake_command_invoke_message_fatal_error-result.txt
  16. 5 0
      Tests/RunCMake/cmake_command/cmake_command_invoke_message_fatal_error-stderr.txt
  17. 1 0
      Tests/RunCMake/cmake_command/cmake_command_invoke_message_fatal_error.cmake
  18. 1 0
      Tests/RunCMake/cmake_command/cmake_command_invoke_no_parameters-result.txt
  19. 2 0
      Tests/RunCMake/cmake_command/cmake_command_invoke_no_parameters-stderr.txt
  20. 1 0
      Tests/RunCMake/cmake_command/cmake_command_invoke_no_parameters.cmake
  21. 1 0
      Tests/RunCMake/cmake_command/cmake_command_invoke_unknown_function-result.txt
  22. 2 0
      Tests/RunCMake/cmake_command/cmake_command_invoke_unknown_function-stderr.txt
  23. 1 0
      Tests/RunCMake/cmake_command/cmake_command_invoke_unknown_function.cmake
  24. 1 0
      Tests/RunCMake/cmake_command/cmake_command_no_parameters-result.txt
  25. 2 0
      Tests/RunCMake/cmake_command/cmake_command_no_parameters-stderr.txt
  26. 1 0
      Tests/RunCMake/cmake_command/cmake_command_no_parameters.cmake
  27. 1 0
      Tests/RunCMake/cmake_command/cmake_command_unknown_meta_operation-result.txt
  28. 2 0
      Tests/RunCMake/cmake_command/cmake_command_unknown_meta_operation-stderr.txt
  29. 1 0
      Tests/RunCMake/cmake_command/cmake_command_unknown_meta_operation.cmake

+ 40 - 0
Help/command/cmake_command.rst

@@ -0,0 +1,40 @@
+cmake_command
+-------------
+
+Call meta-operations on CMake commands.
+
+Synopsis
+^^^^^^^^
+
+.. parsed-literal::
+
+  cmake_command(`INVOKE`_ <command> [<args>...])
+
+Introduction
+^^^^^^^^^^^^
+
+This command will call meta-operations on built-in CMake commands or
+those created via the :command:`macro` or :command:`function` commands.
+
+Invoking
+^^^^^^^^
+
+.. _INVOKE:
+
+.. code-block:: cmake
+
+  cmake_command(INVOKE <command> [<args>...])
+
+Invokes the named ``<command>`` with the given arguments (if any).
+For example, the code:
+
+.. code-block:: cmake
+
+  set(message_command "message")
+  cmake_command(INVOKE ${message_command} STATUS "Hello World!")
+
+is equivalent to
+
+.. code-block:: cmake
+
+  message(STATUS "Hello World!")

+ 4 - 0
Help/command/function.rst

@@ -44,11 +44,15 @@ can be invoked through any of
   foo()
   Foo()
   FOO()
+  cmake_command(INVOKE foo)
 
 and so on. However, it is strongly recommended to stay with the
 case chosen in the function definition. Typically functions use
 all-lowercase names.
 
+The :command:`cmake_command(INVOKE ...)` command can also be used to invoke the
+function.
+
 Arguments
 ^^^^^^^^^
 

+ 4 - 0
Help/command/macro.rst

@@ -42,11 +42,15 @@ can be invoked through any of
   foo()
   Foo()
   FOO()
+  cmake_command(INVOKE foo)
 
 and so on. However, it is strongly recommended to stay with the
 case chosen in the macro definition.  Typically macros use
 all-lowercase names.
 
+The :command:`cmake_command(INVOKE ...)` command can also be used to invoke the
+macro.
+
 Arguments
 ^^^^^^^^^
 

+ 1 - 0
Help/manual/cmake-commands.7.rst

@@ -16,6 +16,7 @@ These commands are always available.
    :maxdepth: 1
 
    /command/break
+   /command/cmake_command
    /command/cmake_host_system_information
    /command/cmake_minimum_required
    /command/cmake_parse_arguments

+ 6 - 0
Help/release/dev/cmake_command-command.rst

@@ -0,0 +1,6 @@
+cmake_command
+-------------
+
+* The :command:`cmake_command()` command was added for meta-operations on
+  scripted or built-in commands, starting with a mode to ``INVOKE`` other
+  commands.

+ 2 - 0
Source/CMakeLists.txt

@@ -484,6 +484,8 @@ set(SRCS
   cmBuildCommand.h
   cmBuildNameCommand.cxx
   cmBuildNameCommand.h
+  cmCMakeCommand.cxx
+  cmCMakeCommand.h
   cmCMakeHostSystemInformationCommand.cxx
   cmCMakeHostSystemInformationCommand.h
   cmCMakeMinimumRequired.cxx

+ 47 - 0
Source/cmCMakeCommand.cxx

@@ -0,0 +1,47 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#include "cmCMakeCommand.h"
+
+#include <cstddef>
+
+#include "cmExecutionStatus.h"
+#include "cmListFileCache.h"
+#include "cmMakefile.h"
+
+bool cmCMakeCommand(std::vector<std::string> const& args,
+                    cmExecutionStatus& status)
+{
+  if (args.empty()) {
+    status.SetError("called with incorrect number of arguments");
+    return false;
+  }
+
+  cmMakefile& makefile = status.GetMakefile();
+  cmListFileContext context = makefile.GetExecutionContext();
+
+  if (args[0] == "INVOKE") {
+    if (args.size() == 1) {
+      status.SetError("called with incorrect number of arguments");
+      return false;
+    }
+
+    // First argument is the name of the function to call
+    cmListFileFunction func;
+    func.Name = args[1];
+    func.Line = context.Line;
+
+    // The rest of the arguments are passed to the function call above
+    func.Arguments.resize(args.size() - 1);
+    for (size_t i = 2; i < args.size(); ++i) {
+      cmListFileArgument lfarg;
+      lfarg.Line = context.Line;
+      lfarg.Value = args[i];
+      func.Arguments.emplace_back(lfarg);
+    }
+
+    return makefile.ExecuteCommand(func, status);
+  }
+
+  status.SetError("called with unknown meta-operation");
+  return false;
+}

+ 20 - 0
Source/cmCMakeCommand.h

@@ -0,0 +1,20 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cmCMakeCommand_h
+#define cmCMakeCommand_h
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <string>
+#include <vector>
+
+class cmExecutionStatus;
+
+/**
+ * \brief Calls a scripted or build-in command
+ *
+ */
+bool cmCMakeCommand(std::vector<std::string> const& args,
+                    cmExecutionStatus& status);
+
+#endif

+ 2 - 0
Source/cmCommands.cxx

@@ -91,6 +91,7 @@
 #  include "cmAddLinkOptionsCommand.h"
 #  include "cmAuxSourceDirectoryCommand.h"
 #  include "cmBuildNameCommand.h"
+#  include "cmCMakeCommand.h"
 #  include "cmCMakeHostSystemInformationCommand.h"
 #  include "cmExportCommand.h"
 #  include "cmExportLibraryDependenciesCommand.h"
@@ -196,6 +197,7 @@ void GetScriptingCommands(cmState* state)
     "match the opening WHILE command.");
 
 #if !defined(CMAKE_BOOTSTRAP)
+  state->AddBuiltinCommand("cmake_command", cmCMakeCommand);
   state->AddBuiltinCommand("cmake_host_system_information",
                            cmCMakeHostSystemInformationCommand);
   state->AddBuiltinCommand("load_cache", cmLoadCacheCommand);

+ 2 - 0
Tests/RunCMake/CMakeLists.txt

@@ -651,3 +651,5 @@ add_RunCMake_test("CTestCommandExpandLists")
 
 add_RunCMake_test(PrecompileHeaders)
 add_RunCMake_test("UnityBuild")
+
+add_RunCMake_test(cmake_command)

+ 3 - 0
Tests/RunCMake/cmake_command/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.16)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)

+ 8 - 0
Tests/RunCMake/cmake_command/RunCMakeTest.cmake

@@ -0,0 +1,8 @@
+include(RunCMake)
+
+run_cmake(cmake_command_no_parameters)
+run_cmake(cmake_command_unknown_meta_operation)
+run_cmake(cmake_command_invoke_message)
+run_cmake(cmake_command_invoke_message_fatal_error)
+run_cmake(cmake_command_invoke_no_parameters)
+run_cmake(cmake_command_invoke_unknown_function)

+ 1 - 0
Tests/RunCMake/cmake_command/cmake_command_invoke_message-stderr.txt

@@ -0,0 +1 @@
+WORKS!

+ 1 - 0
Tests/RunCMake/cmake_command/cmake_command_invoke_message.cmake

@@ -0,0 +1 @@
+cmake_command(INVOKE message WORKS!)

+ 1 - 0
Tests/RunCMake/cmake_command/cmake_command_invoke_message_fatal_error-result.txt

@@ -0,0 +1 @@
+1

+ 5 - 0
Tests/RunCMake/cmake_command/cmake_command_invoke_message_fatal_error-stderr.txt

@@ -0,0 +1,5 @@
+CMake Error at cmake_command_invoke_message_fatal_error.cmake:1 \(message\):
+  error!
+Call Stack \(most recent call first\):
+  cmake_command_invoke_message_fatal_error.cmake:1 \(cmake_command\)
+  CMakeLists.txt:3 \(include\)

+ 1 - 0
Tests/RunCMake/cmake_command/cmake_command_invoke_message_fatal_error.cmake

@@ -0,0 +1 @@
+cmake_command(INVOKE message FATAL_ERROR error!)

+ 1 - 0
Tests/RunCMake/cmake_command/cmake_command_invoke_no_parameters-result.txt

@@ -0,0 +1 @@
+1

+ 2 - 0
Tests/RunCMake/cmake_command/cmake_command_invoke_no_parameters-stderr.txt

@@ -0,0 +1,2 @@
+CMake Error at cmake_command_invoke_no_parameters.cmake:1 \(cmake_command\):
+  cmake_command called with incorrect number of arguments

+ 1 - 0
Tests/RunCMake/cmake_command/cmake_command_invoke_no_parameters.cmake

@@ -0,0 +1 @@
+cmake_command(INVOKE)

+ 1 - 0
Tests/RunCMake/cmake_command/cmake_command_invoke_unknown_function-result.txt

@@ -0,0 +1 @@
+1

+ 2 - 0
Tests/RunCMake/cmake_command/cmake_command_invoke_unknown_function-stderr.txt

@@ -0,0 +1,2 @@
+CMake Error at cmake_command_invoke_unknown_function.cmake:1 \(unknown\):
+  Unknown CMake command "unknown".

+ 1 - 0
Tests/RunCMake/cmake_command/cmake_command_invoke_unknown_function.cmake

@@ -0,0 +1 @@
+cmake_command(INVOKE unknown)

+ 1 - 0
Tests/RunCMake/cmake_command/cmake_command_no_parameters-result.txt

@@ -0,0 +1 @@
+1

+ 2 - 0
Tests/RunCMake/cmake_command/cmake_command_no_parameters-stderr.txt

@@ -0,0 +1,2 @@
+CMake Error at cmake_command_no_parameters.cmake:1 \(cmake_command\):
+  cmake_command called with incorrect number of arguments

+ 1 - 0
Tests/RunCMake/cmake_command/cmake_command_no_parameters.cmake

@@ -0,0 +1 @@
+cmake_command(INVOKE)

+ 1 - 0
Tests/RunCMake/cmake_command/cmake_command_unknown_meta_operation-result.txt

@@ -0,0 +1 @@
+1

+ 2 - 0
Tests/RunCMake/cmake_command/cmake_command_unknown_meta_operation-stderr.txt

@@ -0,0 +1,2 @@
+CMake Error at cmake_command_unknown_meta_operation.cmake:1 \(cmake_command\):
+  cmake_command called with unknown meta-operation

+ 1 - 0
Tests/RunCMake/cmake_command/cmake_command_unknown_meta_operation.cmake

@@ -0,0 +1 @@
+cmake_command(UNKNOWN)