execute_process: Add ECHO_(OUTPUT|ERROR)_VARIABLE options

Fixes: #20378
This commit is contained in:
Cristian Adam 2020-02-21 15:20:45 +01:00
parent 25ca8e5ce5
commit 6ec274b002
8 changed files with 63 additions and 8 deletions

View File

@ -21,7 +21,9 @@ Execute one or more child processes.
[COMMAND_ECHO <where>]
[OUTPUT_STRIP_TRAILING_WHITESPACE]
[ERROR_STRIP_TRAILING_WHITESPACE]
[ENCODING <name>])
[ENCODING <name>]
[ECHO_OUTPUT_VARIABLE]
[ECHO_ERROR_VARIABLE])
Runs the given sequence of one or more commands.
@ -105,6 +107,15 @@ Options:
for this encoding. In CMake 3.11.0, ``UTF-8`` was added for consistency with
the `UTF-8 RFC <https://www.ietf.org/rfc/rfc3629>`_ naming convention.
``ECHO_OUTPUT_VARIABLE``, ``ECHO_ERROR_VARIABLE``
The standard output or standard error will not be exclusively redirected to
the configured variables.
The output will be duplicated, it will be sent into the configured variables
and also on standard output or standard error.
This is analogous to the ``tee`` Unix command.
If more than one ``OUTPUT_*`` or ``ERROR_*`` option is given for the
same pipe the precedence is not specified.
If no ``OUTPUT_*`` or ``ERROR_*`` options are given the output will

View File

@ -0,0 +1,5 @@
execute_process
---------------
* The :command:`execute_process` command gained the ``ECHO_OUTPUT_VARIABLE``
and ``ECHO_ERROR_VARIABLE`` options.

View File

@ -61,6 +61,8 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
bool ErrorQuiet = false;
bool OutputStripTrailingWhitespace = false;
bool ErrorStripTrailingWhitespace = false;
bool EchoOutputVariable = false;
bool EchoErrorVariable = false;
std::string Encoding;
};
@ -83,7 +85,9 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
&Arguments::OutputStripTrailingWhitespace)
.Bind("ERROR_STRIP_TRAILING_WHITESPACE"_s,
&Arguments::ErrorStripTrailingWhitespace)
.Bind("ENCODING"_s, &Arguments::Encoding);
.Bind("ENCODING"_s, &Arguments::Encoding)
.Bind("ECHO_OUTPUT_VARIABLE"_s, &Arguments::EchoOutputVariable)
.Bind("ECHO_ERROR_VARIABLE"_s, &Arguments::EchoErrorVariable);
std::vector<std::string> unparsedArguments;
std::vector<std::string> keywordsMissingValue;
@ -241,28 +245,32 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
while ((p = cmsysProcess_WaitForData(cp, &data, &length, nullptr))) {
// Put the output in the right place.
if (p == cmsysProcess_Pipe_STDOUT && !arguments.OutputQuiet) {
if (arguments.OutputVariable.empty()) {
if (arguments.OutputVariable.empty() || arguments.EchoOutputVariable) {
processOutput.DecodeText(data, length, strdata, 1);
cmSystemTools::Stdout(strdata);
} else {
}
if (!arguments.OutputVariable.empty()) {
cmExecuteProcessCommandAppend(tempOutput, data, length);
}
} else if (p == cmsysProcess_Pipe_STDERR && !arguments.ErrorQuiet) {
if (arguments.ErrorVariable.empty()) {
if (arguments.ErrorVariable.empty() || arguments.EchoErrorVariable) {
processOutput.DecodeText(data, length, strdata, 2);
cmSystemTools::Stderr(strdata);
} else {
}
if (!arguments.ErrorVariable.empty()) {
cmExecuteProcessCommandAppend(tempError, data, length);
}
}
}
if (!arguments.OutputQuiet && arguments.OutputVariable.empty()) {
if (!arguments.OutputQuiet &&
(arguments.OutputVariable.empty() || arguments.EchoOutputVariable)) {
processOutput.DecodeText(std::string(), strdata, 1);
if (!strdata.empty()) {
cmSystemTools::Stdout(strdata);
}
}
if (!arguments.ErrorQuiet && arguments.ErrorVariable.empty()) {
if (!arguments.ErrorQuiet &&
(arguments.ErrorVariable.empty() || arguments.EchoErrorVariable)) {
processOutput.DecodeText(std::string(), strdata, 2);
if (!strdata.empty()) {
cmSystemTools::Stderr(strdata);

View File

@ -0,0 +1,3 @@
CMake Error at [^
]*EchoVariableOutput.cmake:2 \(message\):
Text to stderr

View File

@ -0,0 +1 @@
-- Text to stdout

View File

@ -0,0 +1,23 @@
execute_process(
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/EchoVariableOutput.cmake
OUTPUT_VARIABLE stdout
ERROR_QUIET
ECHO_OUTPUT_VARIABLE
)
file(READ ${CMAKE_CURRENT_LIST_DIR}/EchoVariable-stdout.txt expected_stdout)
if (NOT stdout MATCHES "${expected_stdout}")
message(FATAL_ERROR "stdout differs from the expected stdout")
endif()
execute_process(
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/EchoVariableOutput.cmake
ERROR_VARIABLE stderr
OUTPUT_QUIET
ECHO_ERROR_VARIABLE
)
file(READ ${CMAKE_CURRENT_LIST_DIR}/EchoVariable-stderr.txt expected_stderr)
if (NOT stderr MATCHES "${expected_stderr}")
message(FATAL_ERROR "stderr differs from the expected stderr")
endif()

View File

@ -0,0 +1,2 @@
message(STATUS "Text to stdout")
message(FATAL_ERROR "Text to stderr")

View File

@ -24,3 +24,5 @@ run_cmake_command(EchoCommand2 ${CMAKE_COMMAND} -P
run_cmake_command(EchoCommand3 ${CMAKE_COMMAND}
-DCHECK_ERROR_OUTPUT_LOCATION=TRUE -P
${RunCMake_SOURCE_DIR}/EchoCommand.cmake)
run_cmake_command(EchoVariable ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/EchoVariable.cmake)