diff --git a/Help/command/execute_process.rst b/Help/command/execute_process.rst index 4d5e38037a..a554aa11bb 100644 --- a/Help/command/execute_process.rst +++ b/Help/command/execute_process.rst @@ -24,7 +24,7 @@ Execute one or more child processes. [ENCODING ] [ECHO_OUTPUT_VARIABLE] [ECHO_ERROR_VARIABLE] - [COMMAND_ERROR_IS_FATAL ]) + [COMMAND_ERROR_IS_FATAL ]) Runs the given sequence of one or more commands. @@ -168,7 +168,7 @@ Options: `UTF-8 RFC `_ naming convention. -``COMMAND_ERROR_IS_FATAL `` +``COMMAND_ERROR_IS_FATAL `` .. versionadded:: 3.19 The option following ``COMMAND_ERROR_IS_FATAL`` determines the behavior when @@ -182,3 +182,18 @@ Options: If the last command in the list of commands fails, the ``execute_process()`` command halts with an error. Commands earlier in the list will not cause a fatal error. + + + ``NONE`` + .. versionadded:: 3.32 + + Regardless of any of the commands failing, the ``execute_process()`` + command will not halt with an error. + + .. versionadded:: 3.32 + + If not provided, the + :variable:`CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL` variable + is checked. If the variable is not set, the default is ``NONE``. + If ``RESULT_VARIABLE`` or ``RESULTS_VARIABLE`` is supplied, + :variable:`CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL` is ignored. diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 5e20196093..310af93de1 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -198,6 +198,7 @@ Variables that Change Behavior /variable/CMAKE_ERROR_DEPRECATED /variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION /variable/CMAKE_EXECUTE_PROCESS_COMMAND_ECHO + /variable/CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL /variable/CMAKE_EXPORT_BUILD_DATABASE /variable/CMAKE_EXPORT_COMPILE_COMMANDS /variable/CMAKE_EXPORT_PACKAGE_REGISTRY diff --git a/Help/release/dev/execute-process-error.rst b/Help/release/dev/execute-process-error.rst new file mode 100644 index 0000000000..73136b2321 --- /dev/null +++ b/Help/release/dev/execute-process-error.rst @@ -0,0 +1,6 @@ +execute-process-error +--------------------- + +* The :variable:`CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL` variable + was added to specify the :command:`execute_process` command's + default ``COMMAND_ERROR_IS_FATAL`` behavior. diff --git a/Help/variable/CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL.rst b/Help/variable/CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL.rst new file mode 100644 index 0000000000..0be51a9fdb --- /dev/null +++ b/Help/variable/CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL.rst @@ -0,0 +1,9 @@ +CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL +-------------------------------------------- + +.. versionadded:: 3.32 + +Specify a default for the :command:`execute_process` command's +``COMMAND_ERROR_IS_FATAL`` option. This variable is ignored when a +``RESULTS_VARIABLE`` or ``RESULT_VARIABLE`` keyword is supplied to +the command. diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx index e186a08d87..97ee05c30c 100644 --- a/Source/cmExecuteProcessCommand.cxx +++ b/Source/cmExecuteProcessCommand.cxx @@ -177,12 +177,25 @@ bool cmExecuteProcessCommand(std::vector const& args, } } - if (!arguments.CommandErrorIsFatal.empty()) { - if (arguments.CommandErrorIsFatal != "ANY"_s && - arguments.CommandErrorIsFatal != "LAST"_s) { - status.SetError("COMMAND_ERROR_IS_FATAL option can be ANY or LAST"); + std::string commandErrorIsFatal = arguments.CommandErrorIsFatal; + if (commandErrorIsFatal.empty() && arguments.ResultVariable.empty() && + arguments.ResultsVariable.empty()) { + commandErrorIsFatal = status.GetMakefile().GetSafeDefinition( + "CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL"); + } + + if (!commandErrorIsFatal.empty() && commandErrorIsFatal != "ANY"_s && + commandErrorIsFatal != "LAST"_s && commandErrorIsFatal != "NONE"_s) { + if (!arguments.CommandErrorIsFatal.empty()) { + status.SetError( + "COMMAND_ERROR_IS_FATAL option can be ANY, LAST or NONE"); return false; } + status.SetError(cmStrCat( + "Using CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL with invalid value " + "\"", + commandErrorIsFatal, "\". This variable can be ANY, LAST or NONE")); + return false; } // Create a process instance. cmUVProcessChainBuilder builder; @@ -479,7 +492,7 @@ bool cmExecuteProcessCommand(std::vector const& args, exception.second); }; - if (arguments.CommandErrorIsFatal == "ANY"_s) { + if (commandErrorIsFatal == "ANY"_s) { bool ret = true; if (timedOut) { status.SetError("Process terminated due to timeout"); @@ -510,7 +523,7 @@ bool cmExecuteProcessCommand(std::vector const& args, } } - if (arguments.CommandErrorIsFatal == "LAST"_s) { + if (commandErrorIsFatal == "LAST"_s) { bool ret = true; if (timedOut) { status.SetError("Process terminated due to timeout"); diff --git a/Tests/RunCMake/execute_process/AnyCommandErrorVar-result.txt b/Tests/RunCMake/execute_process/AnyCommandErrorVar-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/execute_process/AnyCommandErrorVar-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/execute_process/AnyCommandErrorVar-stderr.txt b/Tests/RunCMake/execute_process/AnyCommandErrorVar-stderr.txt new file mode 100644 index 0000000000..cc7aa12d95 --- /dev/null +++ b/Tests/RunCMake/execute_process/AnyCommandErrorVar-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at .*AnyCommandErrorVar.cmake:2 \(execute_process\): + execute_process failed command indexes: + + 2: "Child return code: 1" + 3: "Child return code: 1" diff --git a/Tests/RunCMake/execute_process/AnyCommandErrorVar.cmake b/Tests/RunCMake/execute_process/AnyCommandErrorVar.cmake new file mode 100644 index 0000000000..e3cb1ae8e3 --- /dev/null +++ b/Tests/RunCMake/execute_process/AnyCommandErrorVar.cmake @@ -0,0 +1,6 @@ +set(CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL ANY) +execute_process(COMMAND ${CMAKE_COMMAND} -E true + COMMAND ${CMAKE_COMMAND} -E false + COMMAND ${CMAKE_COMMAND} -E false + COMMAND ${CMAKE_COMMAND} -E true +) diff --git a/Tests/RunCMake/execute_process/AnyCommandErrorVarIgnore-result.txt b/Tests/RunCMake/execute_process/AnyCommandErrorVarIgnore-result.txt new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/Tests/RunCMake/execute_process/AnyCommandErrorVarIgnore-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/execute_process/AnyCommandErrorVarIgnore.cmake b/Tests/RunCMake/execute_process/AnyCommandErrorVarIgnore.cmake new file mode 100644 index 0000000000..b1c1b2f884 --- /dev/null +++ b/Tests/RunCMake/execute_process/AnyCommandErrorVarIgnore.cmake @@ -0,0 +1,7 @@ +set(CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL ANY) +execute_process(COMMAND ${CMAKE_COMMAND} -E true + COMMAND ${CMAKE_COMMAND} -E false + COMMAND ${CMAKE_COMMAND} -E false + COMMAND ${CMAKE_COMMAND} -E true + RESULTS_VARIABLE result +) diff --git a/Tests/RunCMake/execute_process/CommandError-stderr.txt b/Tests/RunCMake/execute_process/CommandError-stderr.txt index c28f3a3112..a5188e7b3c 100644 --- a/Tests/RunCMake/execute_process/CommandError-stderr.txt +++ b/Tests/RunCMake/execute_process/CommandError-stderr.txt @@ -1,2 +1,2 @@ CMake Error at .*CommandError.cmake:1 \(execute_process\): - execute_process COMMAND_ERROR_IS_FATAL option can be ANY or LAST + execute_process COMMAND_ERROR_IS_FATAL option can be ANY, LAST or NONE diff --git a/Tests/RunCMake/execute_process/CommandErrorVar-result.txt b/Tests/RunCMake/execute_process/CommandErrorVar-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/execute_process/CommandErrorVar-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/execute_process/CommandErrorVar-stderr.txt b/Tests/RunCMake/execute_process/CommandErrorVar-stderr.txt new file mode 100644 index 0000000000..557b93e801 --- /dev/null +++ b/Tests/RunCMake/execute_process/CommandErrorVar-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at [^ +]*CommandErrorVar.cmake:23 \(execute_process\): + execute_process Using CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL with + invalid value \"BAD_VALUE\". This variable can be ANY, LAST or NONE diff --git a/Tests/RunCMake/execute_process/CommandErrorVar.cmake b/Tests/RunCMake/execute_process/CommandErrorVar.cmake new file mode 100644 index 0000000000..4569c8afcf --- /dev/null +++ b/Tests/RunCMake/execute_process/CommandErrorVar.cmake @@ -0,0 +1,23 @@ +# Ignores var when RESULT_VARIABLE is used +set(CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL ANY) +execute_process(COMMAND ${CMAKE_COMMAND} -E false + RESULT_VARIABLE result +) + +# Ignores var when RESULTS_VARIABLE is used +execute_process(COMMAND ${CMAKE_COMMAND} -E false + RESULTS_VARIABLE results +) + +# Ignores var when argument supplied +execute_process(COMMAND ${CMAKE_COMMAND} -E false + COMMAND_ERROR_IS_FATAL NONE +) + +# Value of NONE has no effect +set(CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL NONE) +execute_process(COMMAND ${CMAKE_COMMAND} -E false) + +# Error on invalid value +set(CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL BAD_VALUE) +execute_process(COMMAND ${CMAKE_COMMAND} -E false) diff --git a/Tests/RunCMake/execute_process/LastCommandGoodVar.cmake b/Tests/RunCMake/execute_process/LastCommandGoodVar.cmake new file mode 100644 index 0000000000..ced2e177fe --- /dev/null +++ b/Tests/RunCMake/execute_process/LastCommandGoodVar.cmake @@ -0,0 +1,15 @@ +execute_process(COMMAND ${CMAKE_COMMAND} -E true + COMMAND ${CMAKE_COMMAND} -E false + COMMAND ${CMAKE_COMMAND} -E false + COMMAND ${CMAKE_COMMAND} -E true + RESULT_VARIABLE result + ) + +set(CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL LAST) +if(result EQUAL "0") + execute_process(COMMAND ${CMAKE_COMMAND} -E true + COMMAND ${CMAKE_COMMAND} -E false + COMMAND ${CMAKE_COMMAND} -E false + COMMAND ${CMAKE_COMMAND} -E true + ) +endif() diff --git a/Tests/RunCMake/execute_process/NoneCommandError.cmake b/Tests/RunCMake/execute_process/NoneCommandError.cmake new file mode 100644 index 0000000000..254732ab69 --- /dev/null +++ b/Tests/RunCMake/execute_process/NoneCommandError.cmake @@ -0,0 +1,5 @@ +set(CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL ANY) +execute_process(COMMAND ${CMAKE_COMMAND} -E true + COMMAND ${CMAKE_COMMAND} -E false + COMMAND_ERROR_IS_FATAL NONE +) diff --git a/Tests/RunCMake/execute_process/RunCMakeTest.cmake b/Tests/RunCMake/execute_process/RunCMakeTest.cmake index dad6322ee2..e9b18a54e4 100644 --- a/Tests/RunCMake/execute_process/RunCMakeTest.cmake +++ b/Tests/RunCMake/execute_process/RunCMakeTest.cmake @@ -32,12 +32,17 @@ run_cmake_command(EchoCommand3 ${CMAKE_COMMAND} run_cmake_command(EchoVariable ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/EchoVariable.cmake) run_cmake_command(CommandError ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/CommandError.cmake) +run_cmake_command(CommandErrorVar ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/CommandErrorVar.cmake) run_cmake_command(AnyCommandError ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/AnyCommandError.cmake) run_cmake_command(AnyCommandTimeout ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/AnyCommandTimeout.cmake) run_cmake_command(AnyCommandGood ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/AnyCommandGood.cmake) +run_cmake_command(AnyCommandErrorVar ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/AnyCommandErrorVar.cmake) +run_cmake_command(AnyCommandErrorVarIgnore ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/AnyCommandErrorVarIgnore.cmake) run_cmake_command(LastCommandError ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/LastCommandError.cmake) run_cmake_command(LastCommandTimeout ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/LastCommandTimeout.cmake) run_cmake_command(LastCommandGood ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/LastCommandGood.cmake) +run_cmake_command(LastCommandGoodVar ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/LastCommandGoodVar.cmake) +run_cmake_command(NoneCommandError ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/NoneCommandError.cmake) run_cmake_command(Stdin ${CMAKE_COMMAND} -DPRINT_STDIN_EXE=${PRINT_STDIN_EXE} -P ${RunCMake_SOURCE_DIR}/Stdin.cmake) run_cmake_command(StdinNoexist ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/StdinNoexist.cmake) run_cmake_command(StdoutNoexist ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/StdoutNoexist.cmake)