From 012c9863096612971f3b8d227a5b372be3281ca4 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 21 Jun 2010 13:00:41 -0400 Subject: ExternalProject: Add LOG_* options to hide step output Optionally hide the output of each external project build step by wrapping its command in a launcher script. Make output available in log files instead. This simplifies the output of external project builds. --- Modules/ExternalProject.cmake | 137 +++++++++++++++++++++++++++++++++++ Tests/ExternalProject/CMakeLists.txt | 6 ++ 2 files changed, 143 insertions(+) diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index d0845e6..9b35a95 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -43,6 +43,13 @@ # [TEST_BEFORE_INSTALL 1] # Add test step executed before install step # [TEST_AFTER_INSTALL 1] # Add test step executed after install step # [TEST_COMMAND cmd...] # Command to drive test +# #--Output logging------------- +# [LOG_DOWNLOAD 1] # Wrap download in script to log output +# [LOG_UPDATE 1] # Wrap update in script to log output +# [LOG_CONFIGURE 1] # Wrap configure in script to log output +# [LOG_BUILD 1] # Wrap build in script to log output +# [LOG_TEST 1] # Wrap test in script to log output +# [LOG_INSTALL 1] # Wrap install in script to log output # ) # The *_DIR options specify directories for the project, with default # directories computed as follows. @@ -86,6 +93,7 @@ # [DEPENDS files...] # Files on which this step depends # [ALWAYS 1] # No stamp file, step always runs # [WORKING_DIRECTORY dir] # Working directory for command +# [LOG 1] # Wrap step in script to log output # ) # The command line, comment, and working directory of every standard # and custom step is processed to replace tokens @@ -606,6 +614,81 @@ function(_ep_get_build_command name step cmd_var) set(${cmd_var} "${cmd}" PARENT_SCOPE) endfunction(_ep_get_build_command) +function(_ep_write_log_script name step cmd_var) + ExternalProject_Get_Property(${name} stamp_dir) + set(command "${${cmd_var}}") + + set(make "") + if("${command}" MATCHES "^\\$\\(MAKE\\)") + # GNU make recognizes the string "$(MAKE)" as recursive make, so + # ensure that it appears directly in the makefile. + string(REGEX REPLACE "^\\$\\(MAKE\\)" "\${make}" command "${command}") + set(make "-Dmake=$(MAKE)") + endif() + + set(config "") + if("${CMAKE_CFG_INTDIR}" MATCHES "^\\$") + string(REPLACE "${CMAKE_CFG_INTDIR}" "\${config}" command "${command}") + set(config "-Dconfig=${CMAKE_CFG_INTDIR}") + endif() + + # Wrap multiple 'COMMAND' lines up into a second-level wrapper + # script so all output can be sent to one log file. + if("${command}" MATCHES ";COMMAND;") + set(code_execute_process " +execute_process(COMMAND \${command} RESULT_VARIABLE result) +if(result) + set(msg \"Command failed (\${result}):\\n\") + foreach(arg IN LISTS command) + set(msg \"\${msg} '\${arg}'\") + endforeach(arg) + message(FATAL_ERROR \"\${msg}\") +endif() +") + set(code "") + set(cmd "") + set(sep "") + foreach(arg IN LISTS command) + if("x${arg}" STREQUAL "xCOMMAND") + set(code "${code}set(command \"${cmd}\")${code_execute_process}") + set(cmd "") + set(sep "") + else() + set(cmd "${cmd}${sep}${arg}") + set(sep ";") + endif() + endforeach() + set(code "${code}set(command \"${cmd}\")${code_execute_process}") + file(WRITE ${stamp_dir}/${name}-${step}-impl.cmake "${code}") + set(command ${CMAKE_COMMAND} "-Dmake=\${make}" "-Dconfig=\${config}" -P ${stamp_dir}/${name}-${step}-impl.cmake) + endif() + + # Wrap the command in a script to log output to files. + set(script ${stamp_dir}/${name}-${step}.cmake) + set(logbase ${stamp_dir}/${name}-${step}) + file(WRITE ${script} " +set(command \"${command}\") +execute_process( + COMMAND \${command} + RESULT_VARIABLE result + OUTPUT_FILE \"${logbase}-out.log\" + ERROR_FILE \"${logbase}-err.log\" + ) +if(result) + set(msg \"Command failed: \${result}\\n\") + foreach(arg IN LISTS command) + set(msg \"\${msg} '\${arg}'\") + endforeach(arg) + set(msg \"\${msg}\\nSee also\\n ${logbase}-*.log\\n\") + message(FATAL_ERROR \"\${msg}\") +else() + set(msg \"${name} ${step} command succeeded. See also ${logbase}-*.log\\n\") + message(STATUS \"\${msg}\") +endif() +") + set(command ${CMAKE_COMMAND} ${make} ${config} -P ${script}) + set(${cmd_var} "${command}" PARENT_SCOPE) +endfunction(_ep_write_log_script) # This module used to use "/${CMAKE_CFG_INTDIR}" directly and produced # makefiles with "/./" in paths for custom command dependencies. Which @@ -695,6 +778,12 @@ function(ExternalProject_Add_Step name step) set(touch ${CMAKE_COMMAND} -E touch ${stamp_dir}${cfgdir}/${name}-${step}) endif() + # Wrap with log script? + get_property(log TARGET ${name} PROPERTY _EP_${step}_LOG) + if(log) + _ep_write_log_script(${name} ${step} command) + endif() + add_custom_command( OUTPUT ${stamp_dir}${cfgdir}/${name}-${step} COMMENT ${comment} @@ -906,12 +995,20 @@ function(_ep_add_download_command name) endif() endif() + get_property(log TARGET ${name} PROPERTY _EP_LOG_DOWNLOAD) + if(log) + set(log LOG 1) + else() + set(log "") + endif() + ExternalProject_Add_Step(${name} download COMMENT ${comment} COMMAND ${cmd} WORKING_DIRECTORY ${work_dir} DEPENDS ${depends} DEPENDEES mkdir + ${log} ) endfunction(_ep_add_download_command) @@ -969,12 +1066,20 @@ function(_ep_add_update_command name) set(always 1) endif() + get_property(log TARGET ${name} PROPERTY _EP_LOG_UPDATE) + if(log) + set(log LOG 1) + else() + set(log "") + endif() + ExternalProject_Add_Step(${name} update COMMENT ${comment} COMMAND ${cmd} ALWAYS ${always} WORKING_DIRECTORY ${work_dir} DEPENDEES download + ${log} ) endfunction(_ep_add_update_command) @@ -1045,11 +1150,19 @@ function(_ep_add_configure_command name) configure_file(${tmp_dir}/${name}-cfgcmd.txt.in ${tmp_dir}/${name}-cfgcmd.txt) list(APPEND file_deps ${tmp_dir}/${name}-cfgcmd.txt) + get_property(log TARGET ${name} PROPERTY _EP_LOG_CONFIGURE) + if(log) + set(log LOG 1) + else() + set(log "") + endif() + ExternalProject_Add_Step(${name} configure COMMAND ${cmd} WORKING_DIRECTORY ${binary_dir} DEPENDEES update patch DEPENDS ${file_deps} + ${log} ) endfunction(_ep_add_configure_command) @@ -1064,10 +1177,18 @@ function(_ep_add_build_command name) _ep_get_build_command(${name} BUILD cmd) endif() + get_property(log TARGET ${name} PROPERTY _EP_LOG_BUILD) + if(log) + set(log LOG 1) + else() + set(log "") + endif() + ExternalProject_Add_Step(${name} build COMMAND ${cmd} WORKING_DIRECTORY ${binary_dir} DEPENDEES configure + ${log} ) endfunction(_ep_add_build_command) @@ -1082,10 +1203,18 @@ function(_ep_add_install_command name) _ep_get_build_command(${name} INSTALL cmd) endif() + get_property(log TARGET ${name} PROPERTY _EP_LOG_INSTALL) + if(log) + set(log LOG 1) + else() + set(log "") + endif() + ExternalProject_Add_Step(${name} install COMMAND ${cmd} WORKING_DIRECTORY ${binary_dir} DEPENDEES build + ${log} ) endfunction(_ep_add_install_command) @@ -1113,10 +1242,18 @@ function(_ep_add_test_command name) set(dep_args DEPENDEES install) endif() + get_property(log TARGET ${name} PROPERTY _EP_LOG_TEST) + if(log) + set(log LOG 1) + else() + set(log "") + endif() + ExternalProject_Add_Step(${name} test COMMAND ${cmd} WORKING_DIRECTORY ${binary_dir} ${dep_args} + ${log} ) endif() endfunction(_ep_add_test_command) diff --git a/Tests/ExternalProject/CMakeLists.txt b/Tests/ExternalProject/CMakeLists.txt index 99da9c4..26c6deb 100644 --- a/Tests/ExternalProject/CMakeLists.txt +++ b/Tests/ExternalProject/CMakeLists.txt @@ -79,6 +79,7 @@ if(can_build_tutorial_step5) URL "${CMAKE_CURRENT_SOURCE_DIR}/../Tutorial/Step5" CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= -G ${CMAKE_GENERATOR} TEST_BEFORE_INSTALL 1 + LOG_INSTALL 1 ) ExternalProject_Get_Property(${proj} install_dir) set(TutorialStep5_install_dir ${install_dir}) @@ -88,6 +89,7 @@ if(can_build_tutorial_step5) URL "${CMAKE_CURRENT_SOURCE_DIR}/../Tutorial/Step5" CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= -G ${CMAKE_GENERATOR} TEST_AFTER_INSTALL 1 + LOG_TEST 1 ) endif() @@ -104,6 +106,7 @@ ExternalProject_Add(${proj} CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= -DTEST_LIST:STRING=A::B::C INSTALL_COMMAND "" + LOG_CONFIGURE 1 ) set(proj TutorialStep1-LocalNoDirTAR) @@ -132,6 +135,7 @@ ExternalProject_Add(${proj} URL_MD5 38c648e817339c356f6be00eeed79bd0 CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= -G ${CMAKE_GENERATOR} INSTALL_COMMAND "" + LOG_BUILD 1 ) set(proj TutorialStep1-LocalNoDirTGZ) @@ -356,6 +360,7 @@ if(do_svn_tests) CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= INSTALL_COMMAND "" DEPENDS "SetupLocalSVNRepository" + LOG_DOWNLOAD 1 ) endif() @@ -430,6 +435,7 @@ if(do_git_tests) CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= INSTALL_COMMAND "" DEPENDS "SetupLocalGITRepository" + LOG_UPDATE 1 ) endif() -- cgit v0.12