From 19d86e26e392a80163d90cbc1accaf45412968f8 Mon Sep 17 00:00:00 2001 From: Wouter Klouwen Date: Fri, 16 Nov 2018 16:06:54 +0000 Subject: ExternalProject: add LOG_OUTPUT_ON_FAILURE option This option only has an effect if at least one of the other LOG_ options is enabled. If an error occurs for a step which has logging to file enabled, that step's output will be printed to the console. For cases where a large amount of output is recorded, just the end of that output may be printed to the console. --- Auxiliary/vim/syntax/cmake.vim | 1 + Modules/ExternalProject.cmake | 51 ++++++++++++++++++++-- .../LogOutputOnFailure-build-result.txt | 1 + .../LogOutputOnFailure-build-stderr.txt | 1 + .../LogOutputOnFailure-build-stdout.txt | 8 ++++ .../ExternalProject/LogOutputOnFailure.cmake | 20 +++++++++ .../LogOutputOnFailureMerged-build-result.txt | 1 + .../LogOutputOnFailureMerged-build-stderr.txt | 1 + .../LogOutputOnFailureMerged-build-stdout.txt | 7 +++ .../ExternalProject/LogOutputOnFailureMerged.cmake | 21 +++++++++ Tests/RunCMake/ExternalProject/RunCMakeTest.cmake | 7 +++ 11 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-result.txt create mode 100644 Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-stderr.txt create mode 100644 Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-stdout.txt create mode 100644 Tests/RunCMake/ExternalProject/LogOutputOnFailure.cmake create mode 100644 Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-result.txt create mode 100644 Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-stderr.txt create mode 100644 Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-stdout.txt create mode 100644 Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged.cmake diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim index d4d0edf..b67ef06 100644 --- a/Auxiliary/vim/syntax/cmake.vim +++ b/Auxiliary/vim/syntax/cmake.vim @@ -877,6 +877,7 @@ syn keyword cmakeKWExternalProject contained \ LOG_DOWNLOAD \ LOG_INSTALL \ LOG_MERGED_STDOUTERR + \ LOG_OUTPUT_ON_FAILURE \ LOG_PATCH \ LOG_TEST \ LOG_UPDATE diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index 93cd74a..e763bab 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -550,6 +550,14 @@ External Project Definition ``LOG_MERGED_STDOUTERR `` When enabled, the output the step is not split by stdout and stderr. + ``LOG_OUTPUT_ON_FAILURE `` + This option only has an effect if at least one of the other ``LOG_`` + options is enabled. If an error occurs for a step which has logging to + file enabled, that step's output will be printed to the console if + ``LOG_OUTPUT_ON_FAILURE`` is set to true. For cases where a large amount + of output is recorded, just the end of that output may be printed to the + console. + **Terminal Access Options:** Steps can be given direct access to the terminal in some cases. Giving a step access to the terminal may allow it to receive terminal input if @@ -1953,6 +1961,7 @@ endif() set(script ${stamp_dir}/${name}-${step}-$.cmake) set(logbase ${log_dir}/${name}-${step}) get_property(log_merged TARGET ${name} PROPERTY _EP_LOG_MERGED_STDOUTERR) + get_property(log_output_on_failure TARGET ${name} PROPERTY _EP_LOG_OUTPUT_ON_FAILURE) if (log_merged) set(stdout_log "${logbase}.log") set(stderr_log "${logbase}.log") @@ -1961,21 +1970,55 @@ endif() set(stderr_log "${logbase}-err.log") endif() set(code " +cmake_minimum_required(VERSION 3.13) ${code_cygpath_make} set(command \"${command}\") +set(log_merged \"${log_merged}\") +set(log_output_on_failure \"${log_output_on_failure}\") +set(stdout_log \"${stdout_log}\") +set(stderr_log \"${stderr_log}\") execute_process( COMMAND \${command} RESULT_VARIABLE result - OUTPUT_FILE \"${stdout_log}\" - ERROR_FILE \"${stderr_log}\" + OUTPUT_FILE \"\${stdout_log}\" + ERROR_FILE \"\${stderr_log}\" ) +macro(read_up_to_max_size log_file output_var) + file(SIZE \${log_file} determined_size) + set(max_size 10240) + if (determined_size GREATER max_size) + math(EXPR seek_position \"\${determined_size} - \${max_size}\") + file(READ \${log_file} \${output_var} OFFSET \${seek_position}) + set(\${output_var} \"...skipping to end...\\n\${\${output_var}}\") + else() + file(READ \${log_file} \${output_var}) + endif() +endmacro() if(result) set(msg \"Command failed: \${result}\\n\") foreach(arg IN LISTS command) set(msg \"\${msg} '\${arg}'\") endforeach() - set(msg \"\${msg}\\nSee also\\n ${stderr_log}\") - message(FATAL_ERROR \"\${msg}\") + if (\${log_merged}) + set(msg \"\${msg}\\nSee also\\n \${stderr_log}\") + else() + set(msg \"\${msg}\\nSee also\\n ${logbase}-*.log\") + endif() + if (\${log_output_on_failure}) + message(SEND_ERROR \"\${msg}\") + if (\${log_merged}) + read_up_to_max_size(\"\${stderr_log}\" error_log_contents) + message(STATUS \"Log output is:\\n\${error_log_contents}\") + else() + read_up_to_max_size(\"\${stdout_log}\" out_log_contents) + read_up_to_max_size(\"\${stderr_log}\" err_log_contents) + message(STATUS \"stdout output is:\\n\${out_log_contents}\") + message(STATUS \"stderr output is:\\n\${err_log_contents}\") + endif() + message(FATAL_ERROR \"Stopping after outputting logs.\") + else() + message(FATAL_ERROR \"\${msg}\") + endif() else() set(msg \"${name} ${step} command succeeded. See also ${logbase}-*.log\") message(STATUS \"\${msg}\") diff --git a/Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-result.txt b/Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-result.txt new file mode 100644 index 0000000..c20fd86 --- /dev/null +++ b/Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-result.txt @@ -0,0 +1 @@ +^[^0] diff --git a/Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-stderr.txt b/Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-stderr.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-stderr.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-stdout.txt b/Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-stdout.txt new file mode 100644 index 0000000..87e5384 --- /dev/null +++ b/Tests/RunCMake/ExternalProject/LogOutputOnFailure-build-stdout.txt @@ -0,0 +1,8 @@ +( )?-- stdout output is: +( )?This is some dummy output with some long lines to ensure formatting is preserved +( )? Including lines with leading spaces +( )? +( )?And also blank lines[ + ]+ +( )?-- stderr output is: +( )?cmake -E env: no command given diff --git a/Tests/RunCMake/ExternalProject/LogOutputOnFailure.cmake b/Tests/RunCMake/ExternalProject/LogOutputOnFailure.cmake new file mode 100644 index 0000000..863bbef --- /dev/null +++ b/Tests/RunCMake/ExternalProject/LogOutputOnFailure.cmake @@ -0,0 +1,20 @@ +include(ExternalProject) + +set(dummyOutput [[ +This is some dummy output with some long lines to ensure formatting is preserved + Including lines with leading spaces + +And also blank lines +]]) + +ExternalProject_Add(FailsWithOutput + SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR} + CONFIGURE_COMMAND "" + BUILD_COMMAND ${CMAKE_COMMAND} -E echo ${dummyOutput} + COMMAND ${CMAKE_COMMAND} -E env # missing command, forces fail + TEST_COMMAND "" + INSTALL_COMMAND "" + LOG_BUILD YES + LOG_OUTPUT_ON_FAILURE YES + USES_TERMINAL_BUILD YES +) diff --git a/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-result.txt b/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-result.txt new file mode 100644 index 0000000..c20fd86 --- /dev/null +++ b/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-result.txt @@ -0,0 +1 @@ +^[^0] diff --git a/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-stderr.txt b/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-stderr.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-stderr.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-stdout.txt b/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-stdout.txt new file mode 100644 index 0000000..11c7317 --- /dev/null +++ b/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged-build-stdout.txt @@ -0,0 +1,7 @@ +( )?-- Log output is: +( )?This is some dummy output with some long lines to ensure formatting is preserved +( )? Including lines with leading spaces +( )? +( )?And also blank lines[ + ]+ +( )?cmake -E env: no command given diff --git a/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged.cmake b/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged.cmake new file mode 100644 index 0000000..116448b --- /dev/null +++ b/Tests/RunCMake/ExternalProject/LogOutputOnFailureMerged.cmake @@ -0,0 +1,21 @@ +include(ExternalProject) + +set(dummyOutput [[ +This is some dummy output with some long lines to ensure formatting is preserved + Including lines with leading spaces + +And also blank lines +]]) + +ExternalProject_Add(FailsWithOutput + SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR} + CONFIGURE_COMMAND "" + BUILD_COMMAND ${CMAKE_COMMAND} -E echo ${dummyOutput} + COMMAND ${CMAKE_COMMAND} -E env # missing command, forces fail + TEST_COMMAND "" + INSTALL_COMMAND "" + LOG_BUILD YES + LOG_OUTPUT_ON_FAILURE YES + LOG_MERGED_STDOUTERR YES + USES_TERMINAL_BUILD YES +) diff --git a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake index bf11381..caaf0d2 100644 --- a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake +++ b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake @@ -29,6 +29,13 @@ endfunction() __ep_test_with_build(MultiCommand) +# Output is not predictable enough to be able to verify it reliably +# when using the various different Visual Studio generators +if(NOT RunCMake_GENERATOR MATCHES "Visual Studio") + __ep_test_with_build(LogOutputOnFailure) + __ep_test_with_build(LogOutputOnFailureMerged) +endif() + # We can't test the substitution when using the old MSYS due to # make/sh mangling the paths (substitution is performed correctly, # but the mangling means we can't reliably test the output). -- cgit v0.12