mirror of
https://github.com/Kitware/CMake.git
synced 2025-12-31 19:00:54 -06:00
execute_process: Add option to echo command lines
Add COMMAND_ECHO option to the execute_process command. This will allow execute_process to show the command it will run. Also add a cmake variable CMAKE_EXECUTE_PROCESS_COMMAND_ECHO. Both the option and the variable can be set to one of the following: STDERR|STDOUT|NONE. The command will be printed to stderr or stdout or not at all. Fixes: #18933
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -158,6 +158,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
|
||||
|
||||
6
Help/release/dev/add-execute_process-command-echo.rst
Normal file
6
Help/release/dev/add-execute_process-command-echo.rst
Normal file
@@ -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.
|
||||
6
Help/variable/CMAKE_EXECUTE_PROCESS_COMMAND_ECHO.rst
Normal file
6
Help/variable/CMAKE_EXECUTE_PROCESS_COMMAND_ECHO.rst
Normal file
@@ -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.
|
||||
@@ -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,7 +121,6 @@ bool cmExecuteProcessCommand::InitialPass(std::vector<std::string> const& args,
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a process instance.
|
||||
std::unique_ptr<cmsysProcess, void (*)(cmsysProcess*)> cp_ptr(
|
||||
cmsysProcess_New(), cmsysProcess_Delete);
|
||||
@@ -171,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);
|
||||
|
||||
|
||||
1
Tests/RunCMake/execute_process/EchoCommand-result.txt
Normal file
1
Tests/RunCMake/execute_process/EchoCommand-result.txt
Normal file
@@ -0,0 +1 @@
|
||||
1
|
||||
5
Tests/RunCMake/execute_process/EchoCommand-stderr.txt
Normal file
5
Tests/RunCMake/execute_process/EchoCommand-stderr.txt
Normal file
@@ -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$
|
||||
12
Tests/RunCMake/execute_process/EchoCommand-stdout.txt
Normal file
12
Tests/RunCMake/execute_process/EchoCommand-stdout.txt
Normal file
@@ -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$
|
||||
41
Tests/RunCMake/execute_process/EchoCommand.cmake
Normal file
41
Tests/RunCMake/execute_process/EchoCommand.cmake
Normal file
@@ -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()
|
||||
1
Tests/RunCMake/execute_process/EchoCommand2-result.txt
Normal file
1
Tests/RunCMake/execute_process/EchoCommand2-result.txt
Normal file
@@ -0,0 +1 @@
|
||||
1
|
||||
5
Tests/RunCMake/execute_process/EchoCommand2-stderr.txt
Normal file
5
Tests/RunCMake/execute_process/EchoCommand2-stderr.txt
Normal file
@@ -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.$
|
||||
12
Tests/RunCMake/execute_process/EchoCommand2-stdout.txt
Normal file
12
Tests/RunCMake/execute_process/EchoCommand2-stdout.txt
Normal file
@@ -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$
|
||||
1
Tests/RunCMake/execute_process/EchoCommand3-result.txt
Normal file
1
Tests/RunCMake/execute_process/EchoCommand3-result.txt
Normal file
@@ -0,0 +1 @@
|
||||
1
|
||||
2
Tests/RunCMake/execute_process/EchoCommand3-stderr.txt
Normal file
2
Tests/RunCMake/execute_process/EchoCommand3-stderr.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
CMake Error at .*EchoCommand.cmake:.*\(execute_process\):
|
||||
execute_process called with no value for COMMAND_ECHO.
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user