diff options
-rw-r--r-- | Help/command/execute_process.rst | 5 | ||||
-rw-r--r-- | Help/manual/cmake-variables.7.rst | 1 | ||||
-rw-r--r-- | Help/release/dev/add-execute_process-command-echo.rst | 6 | ||||
-rw-r--r-- | Help/variable/CMAKE_EXECUTE_PROCESS_COMMAND_ECHO.rst | 6 | ||||
-rw-r--r-- | Source/cmExecuteProcessCommand.cxx | 57 | ||||
-rw-r--r-- | Tests/RunCMake/execute_process/EchoCommand-result.txt | 1 | ||||
-rw-r--r-- | Tests/RunCMake/execute_process/EchoCommand-stderr.txt | 5 | ||||
-rw-r--r-- | Tests/RunCMake/execute_process/EchoCommand-stdout.txt | 12 | ||||
-rw-r--r-- | Tests/RunCMake/execute_process/EchoCommand.cmake | 41 | ||||
-rw-r--r-- | Tests/RunCMake/execute_process/EchoCommand2-result.txt | 1 | ||||
-rw-r--r-- | Tests/RunCMake/execute_process/EchoCommand2-stderr.txt | 5 | ||||
-rw-r--r-- | Tests/RunCMake/execute_process/EchoCommand2-stdout.txt | 12 | ||||
-rw-r--r-- | Tests/RunCMake/execute_process/EchoCommand3-result.txt | 1 | ||||
-rw-r--r-- | Tests/RunCMake/execute_process/EchoCommand3-stderr.txt | 2 | ||||
-rw-r--r-- | Tests/RunCMake/execute_process/RunCMakeTest.cmake | 8 |
15 files changed, 158 insertions, 5 deletions
diff --git a/Help/command/execute_process.rst b/Help/command/execute_process.rst index 2d71352..e6ad037 100644 --- a/Help/command/execute_process.rst +++ b/Help/command/execute_process.rst @@ -18,6 +18,7 @@ Execute one or more child processes. [ERROR_FILE <file>] [OUTPUT_QUIET] [ERROR_QUIET] + [COMMAND_ECHO <where>] [OUTPUT_STRIP_TRAILING_WHITESPACE] [ERROR_STRIP_TRAILING_WHITESPACE] [ENCODING <name>]) @@ -77,6 +78,10 @@ Options: ``OUTPUT_QUIET``, ``ERROR_QUIET`` The standard output or standard error results will be quietly ignored. +``COMMAND_ECHO <where>`` + The command being run will be echo'ed to ``<where>`` with ``<where>`` + being set to ``STDERR``|``STDOUT``|``NONE``. + ``ENCODING <name>`` On Windows, the encoding that is used to decode output from the process. Ignored on other platforms. diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 3e8c884..6d93ae9 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -159,6 +159,7 @@ Variables that Change Behavior /variable/CMAKE_ECLIPSE_VERSION /variable/CMAKE_ERROR_DEPRECATED /variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION + /variable/CMAKE_EXECUTE_PROCESS_COMMAND_ECHO /variable/CMAKE_EXPORT_COMPILE_COMMANDS /variable/CMAKE_EXPORT_PACKAGE_REGISTRY /variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY diff --git a/Help/release/dev/add-execute_process-command-echo.rst b/Help/release/dev/add-execute_process-command-echo.rst new file mode 100644 index 0000000..a44e40e --- /dev/null +++ b/Help/release/dev/add-execute_process-command-echo.rst @@ -0,0 +1,6 @@ +add-execute_process-command-echo +-------------------------------- + +* The :command:`execute_process` command gained a `COMMAND_ECHO` option + and supporting :variable:`CMAKE_EXECUTE_PROCESS_COMMAND_ECHO` variable + to enable echoing of the command-line string before execution. diff --git a/Help/variable/CMAKE_EXECUTE_PROCESS_COMMAND_ECHO.rst b/Help/variable/CMAKE_EXECUTE_PROCESS_COMMAND_ECHO.rst new file mode 100644 index 0000000..4a3121c --- /dev/null +++ b/Help/variable/CMAKE_EXECUTE_PROCESS_COMMAND_ECHO.rst @@ -0,0 +1,6 @@ +CMAKE_EXECUTE_PROCESS_COMMAND_ECHO +---------------------------------- + +If this variable is set to ``STDERR``|``STDOUT``|``NONE`` then commands in +:command:`execute_process` calls will be printed to either stderr or stdout +or not at all. diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx index ff6340f..0d9859e 100644 --- a/Source/cmExecuteProcessCommand.cxx +++ b/Source/cmExecuteProcessCommand.cxx @@ -6,11 +6,13 @@ #include "cmsys/Process.h" #include <algorithm> #include <ctype.h> /* isspace */ +#include <iostream> #include <stdio.h> #include "cmAlgorithms.h" #include "cmArgumentParser.h" #include "cmMakefile.h" +#include "cmMessageType.h" #include "cmProcessOutput.h" #include "cmSystemTools.h" @@ -47,6 +49,7 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, std::string OutputFile; std::string ErrorFile; std::string Timeout; + std::string CommandEcho; bool OutputQuiet = false; bool ErrorQuiet = false; bool OutputStripTrailingWhitespace = false; @@ -57,6 +60,7 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, static auto const parser = cmArgumentParser<Arguments>{} .Bind("COMMAND"_s, &Arguments::Commands) + .Bind("COMMAND_ECHO"_s, &Arguments::CommandEcho) .Bind("OUTPUT_VARIABLE"_s, &Arguments::OutputVariable) .Bind("ERROR_VARIABLE"_s, &Arguments::ErrorVariable) .Bind("RESULT_VARIABLE"_s, &Arguments::ResultVariable) @@ -117,9 +121,10 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, return false; } } - // Create a process instance. - cmsysProcess* cp = cmsysProcess_New(); + std::unique_ptr<cmsysProcess, void (*)(cmsysProcess*)> cp_ptr( + cmsysProcess_New(), cmsysProcess_Delete); + cmsysProcess* cp = cp_ptr.get(); // Set the command sequence. for (std::vector<std::string> const& cmd : arguments.Commands) { @@ -169,6 +174,51 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, cmsysProcess_SetTimeout(cp, timeout); } + bool echo_stdout = false; + bool echo_stderr = false; + bool echo_output_from_variable = true; + std::string echo_output = + this->Makefile->GetSafeDefinition("CMAKE_EXECUTE_PROCESS_COMMAND_ECHO"); + if (!arguments.CommandEcho.empty()) { + echo_output_from_variable = false; + echo_output = arguments.CommandEcho; + } + + if (!echo_output.empty()) { + if (echo_output == "STDERR") { + echo_stderr = true; + } else if (echo_output == "STDOUT") { + echo_stdout = true; + } else if (echo_output != "NONE") { + std::string error; + if (echo_output_from_variable) { + error = "CMAKE_EXECUTE_PROCESS_COMMAND_ECHO set to '"; + } else { + error = " called with '"; + } + error += echo_output; + error += "' expected STDERR|STDOUT|NONE"; + if (!echo_output_from_variable) { + error += " for COMMAND_ECHO."; + } + this->Makefile->IssueMessage(MessageType::FATAL_ERROR, error); + return true; + } + } + if (echo_stdout || echo_stderr) { + std::string command; + for (auto& cmd : arguments.Commands) { + command += "'"; + command += cmJoin(cmd, "' '"); + command += "'"; + command += "\n"; + } + if (echo_stdout) { + std::cout << command; + } else if (echo_stderr) { + std::cerr << command; + } + } // Start the process. cmsysProcess_Execute(cp); @@ -297,9 +347,6 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args, } } - // Delete the process instance. - cmsysProcess_Delete(cp); - return true; } diff --git a/Tests/RunCMake/execute_process/EchoCommand-result.txt b/Tests/RunCMake/execute_process/EchoCommand-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/execute_process/EchoCommand-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/execute_process/EchoCommand-stderr.txt b/Tests/RunCMake/execute_process/EchoCommand-stderr.txt new file mode 100644 index 0000000..f10ece8 --- /dev/null +++ b/Tests/RunCMake/execute_process/EchoCommand-stderr.txt @@ -0,0 +1,5 @@ +.*cmake.*-E' 'echo' '-- 2 COMMAND_ECHO STDERR' +.*cmake.*-E' 'echo' '-- 4 COMMAND_ECHO STDERR' +.*cmake.*-E' 'echo' '-- 8 COMMAND_ECHO STDOUT COMMAND_ECHO STDERR' +CMake Error at .*EchoCommand.cmake:.* \(execute_process\): + CMAKE_EXECUTE_PROCESS_COMMAND_ECHO set to 'BAD' expected STDERR|STDOUT|NONE$ diff --git a/Tests/RunCMake/execute_process/EchoCommand-stdout.txt b/Tests/RunCMake/execute_process/EchoCommand-stdout.txt new file mode 100644 index 0000000..0954b3b --- /dev/null +++ b/Tests/RunCMake/execute_process/EchoCommand-stdout.txt @@ -0,0 +1,12 @@ +.*cmake.*-E' 'echo' '-- 1 COMMAND_ECHO STDOUT' +-- 1 COMMAND_ECHO STDOUT +-- 2 COMMAND_ECHO STDERR +.*cmake.* '-E' 'echo' '-- 3 COMMAND_ECHO STDOUT' +-- 3 COMMAND_ECHO STDOUT +-- 4 COMMAND_ECHO STDERR +.*cmake.* '-E' 'echo' '-- 5 COMMAND_ECHO STDOUT' +-- 5 COMMAND_ECHO STDOUT +-- 6 COMMAND_ECHO NONE +.*cmake.* '-E' 'echo' '-- 7 COMMAND_ECHO STDERR COMMAND_ECHO STDOUT' +-- 7 COMMAND_ECHO STDERR COMMAND_ECHO STDOUT +-- 8 COMMAND_ECHO STDOUT COMMAND_ECHO STDERR$ diff --git a/Tests/RunCMake/execute_process/EchoCommand.cmake b/Tests/RunCMake/execute_process/EchoCommand.cmake new file mode 100644 index 0000000..9c7d13d --- /dev/null +++ b/Tests/RunCMake/execute_process/EchoCommand.cmake @@ -0,0 +1,41 @@ +if(CHECK_ERROR_OUTPUT_LOCATION) + execute_process(COMMAND ${CMAKE_COMMAND} -E echo + "-- 1 COMMAND_ECHO " COMMAND_ECHO ) +endif() +# test COMMAND_ECHO STDOUT +execute_process(COMMAND ${CMAKE_COMMAND} -E echo + "-- 1 COMMAND_ECHO STDOUT" COMMAND_ECHO STDOUT ) +# test COMMAND_ECHO STDERR +execute_process(COMMAND ${CMAKE_COMMAND} -E echo + "-- 2 COMMAND_ECHO STDERR" COMMAND_ECHO STDERR ) +# test CMAKE_EXECUTE_PROCESS_COMMAND_ECHO STDOUT +set(CMAKE_EXECUTE_PROCESS_COMMAND_ECHO STDOUT) +execute_process(COMMAND ${CMAKE_COMMAND} -E echo + "-- 3 COMMAND_ECHO STDOUT" ) +# test CMAKE_EXECUTE_PROCESS_COMMAND_ECHO STDERR +set(CMAKE_EXECUTE_PROCESS_COMMAND_ECHO STDERR) +execute_process(COMMAND ${CMAKE_COMMAND} -E echo + "-- 4 COMMAND_ECHO STDERR" ) +# make sure local will override global settings +execute_process(COMMAND ${CMAKE_COMMAND} -E echo + "-- 5 COMMAND_ECHO STDOUT" COMMAND_ECHO STDOUT ) +execute_process(COMMAND ${CMAKE_COMMAND} -E echo + "-- 6 COMMAND_ECHO NONE" COMMAND_ECHO NONE) +# test both and make sure override works +execute_process(COMMAND ${CMAKE_COMMAND} -E echo + "-- 7 COMMAND_ECHO STDERR COMMAND_ECHO STDOUT" COMMAND_ECHO STDERR + COMMAND_ECHO STDOUT) +execute_process(COMMAND ${CMAKE_COMMAND} -E echo + "-- 8 COMMAND_ECHO STDOUT COMMAND_ECHO STDERR" COMMAND_ECHO STDOUT + COMMAND_ECHO STDERR) + +# check for bad arguments to global and local +if(CHECK_GLOBAL) + # make sure a non STDERR or STDOUT value is an error + set(CMAKE_EXECUTE_PROCESS_COMMAND_ECHO BAD) + execute_process(COMMAND ${CMAKE_COMMAND} -E echo + "-- 9 - 1 CMAKE_EXECUTE_PROCESS_COMMAND_ECHO BAD" ) +else() + execute_process(COMMAND ${CMAKE_COMMAND} -E echo + "-- 9 - 2 COMMAND_ECHO BAD" COMMAND_ECHO BAD) +endif() diff --git a/Tests/RunCMake/execute_process/EchoCommand2-result.txt b/Tests/RunCMake/execute_process/EchoCommand2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/execute_process/EchoCommand2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/execute_process/EchoCommand2-stderr.txt b/Tests/RunCMake/execute_process/EchoCommand2-stderr.txt new file mode 100644 index 0000000..4ae01c4 --- /dev/null +++ b/Tests/RunCMake/execute_process/EchoCommand2-stderr.txt @@ -0,0 +1,5 @@ +.*cmake.*-E' 'echo' '-- 2 COMMAND_ECHO STDERR' +.*cmake.*-E' 'echo' '-- 4 COMMAND_ECHO STDERR' +.*cmake.*-E' 'echo' '-- 8 COMMAND_ECHO STDOUT COMMAND_ECHO STDERR' +CMake Error at .*EchoCommand.cmake:.* \(execute_process\): + called with 'BAD' expected STDERR|STDOUT|NONE for COMMAND_ECHO.$ diff --git a/Tests/RunCMake/execute_process/EchoCommand2-stdout.txt b/Tests/RunCMake/execute_process/EchoCommand2-stdout.txt new file mode 100644 index 0000000..0954b3b --- /dev/null +++ b/Tests/RunCMake/execute_process/EchoCommand2-stdout.txt @@ -0,0 +1,12 @@ +.*cmake.*-E' 'echo' '-- 1 COMMAND_ECHO STDOUT' +-- 1 COMMAND_ECHO STDOUT +-- 2 COMMAND_ECHO STDERR +.*cmake.* '-E' 'echo' '-- 3 COMMAND_ECHO STDOUT' +-- 3 COMMAND_ECHO STDOUT +-- 4 COMMAND_ECHO STDERR +.*cmake.* '-E' 'echo' '-- 5 COMMAND_ECHO STDOUT' +-- 5 COMMAND_ECHO STDOUT +-- 6 COMMAND_ECHO NONE +.*cmake.* '-E' 'echo' '-- 7 COMMAND_ECHO STDERR COMMAND_ECHO STDOUT' +-- 7 COMMAND_ECHO STDERR COMMAND_ECHO STDOUT +-- 8 COMMAND_ECHO STDOUT COMMAND_ECHO STDERR$ diff --git a/Tests/RunCMake/execute_process/EchoCommand3-result.txt b/Tests/RunCMake/execute_process/EchoCommand3-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/execute_process/EchoCommand3-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/execute_process/EchoCommand3-stderr.txt b/Tests/RunCMake/execute_process/EchoCommand3-stderr.txt new file mode 100644 index 0000000..e27f1e6 --- /dev/null +++ b/Tests/RunCMake/execute_process/EchoCommand3-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*EchoCommand.cmake:.*\(execute_process\): + execute_process called with no value for COMMAND_ECHO. diff --git a/Tests/RunCMake/execute_process/RunCMakeTest.cmake b/Tests/RunCMake/execute_process/RunCMakeTest.cmake index cb40b40..b203aab 100644 --- a/Tests/RunCMake/execute_process/RunCMakeTest.cmake +++ b/Tests/RunCMake/execute_process/RunCMakeTest.cmake @@ -16,3 +16,11 @@ endif() if(EXIT_CODE_EXE) run_cmake_command(ExitValues ${CMAKE_COMMAND} -DEXIT_CODE_EXE=${EXIT_CODE_EXE} -P ${RunCMake_SOURCE_DIR}/ExitValues.cmake) endif() + +run_cmake_command(EchoCommand ${CMAKE_COMMAND} -DCHECK_GLOBAL=TRUE + -P ${RunCMake_SOURCE_DIR}/EchoCommand.cmake) +run_cmake_command(EchoCommand2 ${CMAKE_COMMAND} -P + ${RunCMake_SOURCE_DIR}/EchoCommand.cmake) +run_cmake_command(EchoCommand3 ${CMAKE_COMMAND} + -DCHECK_ERROR_OUTPUT_LOCATION=TRUE -P + ${RunCMake_SOURCE_DIR}/EchoCommand.cmake) |