diff --git a/CMake/MITKDashboardScript.NEWTEMPLATE.cmake b/CMake/MITKDashboardScript.NEWTEMPLATE.cmake index 371be72dee..f94d5201b4 100644 --- a/CMake/MITKDashboardScript.NEWTEMPLATE.cmake +++ b/CMake/MITKDashboardScript.NEWTEMPLATE.cmake @@ -1,497 +1,512 @@ #[===========================================================================[ Configuration ]===========================================================================] set(CTEST_CMAKE_GENERATOR # "Visual Studio 15 2017" "Visual Studio 16 2019" # "Unix Makefiles" # "Ninja" ) set(CTEST_CMAKE_GENERATOR_PLATFORM # Win32 x64 ) set(CTEST_BUILD_CONFIGURATION # Debug Release # MinSizeRel # RelWithDebInfo ) set(CTEST_DASHBOARD_MODEL # Continuous Experimental # Nightly ) set(MITK_BUILD_CONFIGURATION # All WorkbenchRelease ) set(MITK_REPOSITORY https://phabricator.mitk.org/source/mitk.git) set(MITK_TAG master) # Git branch name, tag, or commit hash set(MITK_EXTENSIONS "MITK-ProjectTemplate|https://phabricator.mitk.org/source/mitk-projecttemplate.git|master" # "MITK-Diffusion|https://phabricator.mitk.org/source/mitk-diffusion.git|master" ) set(CTEST_BUILD_NAME "") # Automatically set but can be overridden here set(GIT_SHALLOW_CLONE ON) # TODO: Explain implications and when to switch off #[===========================================================================[ Helper functions ]===========================================================================] #[[ Call vswhere tool to query properties of the installed Visual Studio versions. Use OUTPUT_VARIABLE to specify the variable that is used to store the output of vswhere. All other arguments are passed to vswhere. The OUTPUT_VARIABLE is not touched if vswhere was not found or returned an error. ]] function(vswhere) cmake_parse_arguments(VSWHERE "" OUTPUT_VARIABLE "" ${ARGN}) if(NOT VSWHERE_OUTPUT_VARIABLE) return() endif() set(program_files_x86 "ProgramFiles(x86)") set(vswhere_executable "$ENV{${program_files_x86}}\\Microsoft Visual Studio\\Installer\\vswhere.exe") if(EXISTS ${vswhere_executable}) execute_process(COMMAND ${vswhere_executable} ${VSWHERE_UNPARSED_ARGUMENTS} RESULT_VARIABLE exit_code OUTPUT_VARIABLE output OUTPUT_STRIP_TRAILING_WHITESPACE) if(exit_code EQUAL 0 AND output) set(${VSWHERE_OUTPUT_VARIABLE} ${output} PARENT_SCOPE) endif() endif() endfunction() #[[ Extract the product line and major version from CTEST_CMAKE_GENERATOR if it starts with "Visual Studio xx yyyy", where xx is the major version and yyyy the product line. Use PRODUCT_LINE and MAJOR_VERSION to specify the variables that are used to store the results. ]] function(parse_visual_studio_generator) cmake_parse_arguments(VS "" "PRODUCT_LINE;MAJOR_VERSION" "" ${ARGN}) if(CTEST_CMAKE_GENERATOR MATCHES "^Visual Studio ([0-9]+) ([0-9]+)") if(VS_MAJOR_VERSION) set(${VS_MAJOR_VERSION} ${CMAKE_MATCH_1} PARENT_SCOPE) endif() if(VS_PRODUCT_LINE) set(${VS_PRODUCT_LINE} ${CMAKE_MATCH_2} PARENT_SCOPE) endif() endif() endfunction() function(get_os) cmake_parse_arguments(OS "" "NAME;VERSION" "" ${ARGN}) if(APPLE) if(OS_NAME) set(${OS_NAME} macOS PARENT_SCOPE) endif() if(OS_VERSION) execute_process(COMMAND sw_vers -productVersion RESULT_VARIABLE exit_code OUTPUT_VARIABLE version OUTPUT_STRIP_TRAILING_WHITESPACE) if(exit_code EQUAL 0 AND version) set(${OS_VERSION} ${version} PARENT_SCOPE) endif() endif() elseif(UNIX AND EXISTS /etc/os-release) # Linux with systemd file(READ /etc/os-release os_release) if(OS_NAME AND os_release MATCHES "NAME=\\\"?([^\\\"\\n]+)") set(${OS_NAME} ${CMAKE_MATCH_1} PARENT_SCOPE) endif() if(OS_VERSION AND os_release MATCHES "VERSION_ID=\\\"?([^\\\"\\n]+)") set(${OS_VERSION} ${CMAKE_MATCH_1} PARENT_SCOPE) endif() elseif(WIN32) if(OS_NAME) set(${OS_NAME} Windows PARENT_SCOPE) endif() if(OS_VERSION) execute_process(COMMAND wmic os get Version -value RESULT_VARIABLE exit_code OUTPUT_VARIABLE version OUTPUT_STRIP_TRAILING_WHITESPACE) if(exit_code EQUAL 0 AND version) if(version MATCHES "Version=([0-9]+)\\.([0-9]+)") set(${OS_VERSION} ${CMAKE_MATCH_1} PARENT_SCOPE) if(CMAKE_MATCH_2) set(${OS_VERSION} "${OS_VERSION}.${CMAKE_MATCH_2}" PARENT_SCOPE) endif() endif() endif() endif() endif() endfunction() #[[ Try to make up a descriptive build name (CTEST_BUILD_NAME) out of the operating system and the compiler. ]] function(set_default_build_name) unset(build_name) # Step 1/2: Determine operating system get_os(NAME os_name VERSION os_version) if(os_name AND os_version) set(build_name "${os_name} ${os_version}") else() # Fallback: use CMake variables that describe the system set(build_name ${CMAKE_SYSTEM_NAME}) if(CMAKE_SYSTEM_VERSION) # Not set in script mode. Give it a try, though. set(build_name "${build_name} ${CMAKE_SYSTEM_VERSION}") endif() endif() # Step 2/2: Determine compiler if(APPLE) # TODO elseif(UNIX) # TODO else() parse_visual_studio_generator(PRODUCT_LINE product_line MAJOR_VERSION version) if(product_line) set(build_name "${build_name} Visual Studio ${product_line}") vswhere(-version ${version} -property catalog_productDisplayVersion OUTPUT_VARIABLE exact_version) if(exact_version) set(build_name "${build_name} v${exact_version}") endif() endif() endif() set(CTEST_BUILD_NAME ${build_name} PARENT_SCOPE) endfunction() function(parse_mitk_extension) cmake_parse_arguments(EXTENSION "" "SOURCE_DIR;GIT_REPOSITORY;GIT_TAG" "" ${ARGN}) if(EXTENSION_UNPARSED_ARGUMENTS MATCHES "([^|]+)\\|([^|]+)\\|(.+)") if(EXTENSION_SOURCE_DIR) set(${EXTENSION_SOURCE_DIR} ${CMAKE_MATCH_1} PARENT_SCOPE) endif() if(EXTENSION_GIT_REPOSITORY) set(${EXTENSION_GIT_REPOSITORY} ${CMAKE_MATCH_2} PARENT_SCOPE) endif() if(EXTENSION_GIT_TAG) set(${EXTENSION_GIT_TAG} ${CMAKE_MATCH_3} PARENT_SCOPE) endif() endif() endfunction() #[[ Print colored text if terminal supports ANSI escape codes. Formatting is done with nested or interleaved HTML-style elements. Supported elements are , , , and . ]] function(print) set(text "${ARGV0}") if(UNIX OR (WIN32 AND "$ENV{MSYSTEM}" MATCHES "^MINGW")) set(stack "white") # Manage stack to handle nested/interleaved elements while(1) # Iterate over text and replace all tags with ANSI escape codes if(text MATCHES "<(/?)([a-z]+)>") # Find next element tag set(token "<${CMAKE_MATCH_1}${CMAKE_MATCH_2}>") if(NOT CMAKE_MATCH_1) # Start tag list(INSERT stack 0 "${CMAKE_MATCH_2}") # Push front else() # End tag list(FIND stack "${CMAKE_MATCH_2}" index) if(NOT index EQUAL -1) list(REMOVE_AT stack ${index}) # Pop first matching tag endif() endif() # Find same tag again but this time with position and length string(FIND "${text}" "${token}" position) string(LENGTH "${token}" length) # Slice text to eventually replace only the current tag string(SUBSTRING "${text}" 0 ${position} left) math(EXPR position "${position} + ${length}") string(SUBSTRING "${text}" ${position} -1 right) list(FIND stack "bold" bold) if(bold EQUAL -1) # Text is not bold, color at first index set(bold 0) set(index 0) elseif(bold EQUAL 0) # Text is bold, color at second index set(bold 1) set(index 1) else() # Text is bold, color at first index set(bold 1) set(index 0) endif() list(GET stack ${index} color) if(color STREQUAL "red") set(color_code 31) elseif(color STREQUAL "green") set(color_code 32) elseif(color STREQUAL "yellow") set(color_code 33) else() # "white" set(color_code 37) endif() string(ASCII 27 esc) set(text "${left}${esc}[${bold};${color_code}m${right}") else() break() endif() endwhile() else() string(REGEX REPLACE "<(/?)([a-z]+)>" "" text "${text}") endif() message("${text}") endfunction() #[===========================================================================[ Actual script ]===========================================================================] find_program(CTEST_GIT_COMMAND git) set(CTEST_CHECKOUT_COMMAND "\"${CTEST_GIT_COMMAND}\" clone") set(checkout_command "${CTEST_GIT_COMMAND}" clone --quiet) if(GIT_SHALLOW_CLONE) set(CTEST_CHECKOUT_COMMAND "${CTEST_CHECKOUT_COMMAND} --depth 1") list(APPEND checkout_command --depth 1) endif() set(CTEST_CHECKOUT_COMMAND "${CTEST_CHECKOUT_COMMAND} --branch ${MITK_TAG} ${MITK_REPOSITORY} MITK") set(CTEST_UPDATE_OPTIONS "--quiet") set(update_options --quiet) if(GIT_SHALLOW_CLONE) set(CTEST_UPDATE_OPTIONS "${CTEST_UPDATE_OPTIONS} --depth=1") list(APPEND update_options --depth=1) endif() set(CTEST_UPDATE_OPTIONS "${CTEST_UPDATE_OPTIONS} origin ${MITK_TAG}") list(APPEND update_options origin) set(CTEST_SOURCE_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/src/MITK") set(CTEST_BINARY_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/build") site_name(CTEST_SITE) if(NOT CTEST_BUILD_NAME) set_default_build_name() endif() -message(" Dashboard model: ${CTEST_DASHBOARD_MODEL}") -message(" Site: ${CTEST_SITE}") +print("The Medical Imaging Interaction Toolkit (MITK)") +set(indent " ") -print("MITK") +message("${indent}Site: ${CTEST_SITE}") +message("${indent}Dashboard model: ${CTEST_DASHBOARD_MODEL}") + +if(MITK_EXTENSIONS) + unset(extensions) + foreach(extension ${MITK_EXTENSIONS}) + if(extensions) + set(extensions "${extensions}, ") + endif() + parse_mitk_extension(${extension} SOURCE_DIR extension_dir) + set(extensions "${extensions}${extension_dir}") + endforeach() + message("${indent}Extensions: ${extensions}") +endif() + +print("MITK repository") if(NOT EXISTS "${CTEST_SOURCE_DIRECTORY}") - message(" Clone repository: ${MITK_REPOSITORY}") - message(" Git branch/tag/commit: ${MITK_TAG}") + message("${indent}Clone repository: ${MITK_REPOSITORY}") + message("${indent}Git branch/tag/commit: ${MITK_TAG}") ctest_start(${CTEST_DASHBOARD_MODEL}) else() unset(CTEST_CHECKOUT_COMMAND) # Do not clone if source directory already exists - message(" Update repository: ${CTEST_SOURCE_DIRECTORY}") - message(" Git branch/tag/commit: ${MITK_TAG}") - execute_process(COMMAND "${CTEST_GIT_COMMAND}" rev-parse HEAD + message("${indent}Update repository: ${CTEST_SOURCE_DIRECTORY}") + message("${indent}Git branch/tag/commit: ${MITK_TAG}") + execute_process(COMMAND "${CTEST_GIT_COMMAND}" rev-parse --short=7 HEAD WORKING_DIRECTORY "${CTEST_SOURCE_DIRECTORY}" OUTPUT_VARIABLE old_revision OUTPUT_STRIP_TRAILING_WHITESPACE) - message(" Old revision: ${old_revision}") + message("${indent}Old revision: ${old_revision}") ctest_start(${CTEST_DASHBOARD_MODEL}) - execute_process(COMMAND "${CTEST_GIT_COMMAND}" rev-parse HEAD + execute_process(COMMAND "${CTEST_GIT_COMMAND}" rev-parse --short=7 HEAD WORKING_DIRECTORY "${CTEST_SOURCE_DIRECTORY}" - OUTPUT_VARIABLE old_revision + OUTPUT_VARIABLE new_revision OUTPUT_STRIP_TRAILING_WHITESPACE) - message(" New revision: ${new_revision}") + message("${indent}New revision: ${new_revision}") ctest_update(RETURN_VALUE num_files_updated) if(num_files_updated EQUAL -1) return() # Nothing to submit, error message already printed endif() endif() unset(MITK_EXTENSION_DIRS) set(up_to_date TRUE) foreach(extension ${MITK_EXTENSIONS}) parse_mitk_extension(${extension} SOURCE_DIR extension_dir GIT_REPOSITORY extension_repo GIT_TAG extension_tag) - print("${extension_dir} extension") + print("${extension_dir} repository") set(absolute_extension_dir "${CMAKE_CURRENT_LIST_DIR}/src/${extension_dir}") list(APPEND MITK_EXTENSION_DIRS "${absolute_extension_dir}") if(EXISTS "${absolute_extension_dir}") - execute_process(COMMAND "${CTEST_GIT_COMMAND}" rev-parse HEAD + execute_process(COMMAND "${CTEST_GIT_COMMAND}" rev-parse --short=7 HEAD WORKING_DIRECTORY "${absolute_extension_dir}" OUTPUT_VARIABLE old_revision OUTPUT_STRIP_TRAILING_WHITESPACE) - message(" Update repository: ${absolute_extension_dir}") - message(" Git branch/tag/commit: ${extension_tag}") - message(" Old revision: ${old_revision}") + message("${indent}Update repository: ${absolute_extension_dir}") + message("${indent}Git branch/tag/commit: ${extension_tag}") + message("${indent}Old revision: ${old_revision}") execute_process(COMMAND "${CTEST_GIT_COMMAND}" fetch ${update_options} ${extension_tag} WORKING_DIRECTORY "${absolute_extension_dir}") execute_process(COMMAND "${CTEST_GIT_COMMAND}" diff --quiet HEAD FETCH_HEAD WORKING_DIRECTORY "${absolute_extension_dir}" RESULT_VARIABLE exit_code) if(NOT exit_code EQUAL 0) execute_process(COMMAND "${CTEST_GIT_COMMAND}" reset --hard FETCH_HEAD WORKING_DIRECTORY "${absolute_extension_dir}") set(up_to_date FALSE) endif() - execute_process(COMMAND "${CTEST_GIT_COMMAND}" rev-parse HEAD + execute_process(COMMAND "${CTEST_GIT_COMMAND}" rev-parse --short=7 HEAD WORKING_DIRECTORY "${absolute_extension_dir}" OUTPUT_VARIABLE new_revision OUTPUT_STRIP_TRAILING_WHITESPACE) - message(" New revision: ${new_revision}") + message("${indent}New revision: ${new_revision}") else() - message(" Clone repository: ${extension_repo}") - message(" Git branch/tag/commit: ${extension_tag}") + message("${indent}Clone repository: ${extension_repo}") + message("${indent}Git branch/tag/commit: ${extension_tag}") execute_process(COMMAND ${checkout_command} --branch ${extension_tag} ${extension_repo} "src/${extension_dir}" WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}") set(up_to_date FALSE) endif() endforeach() # ctest_submit(PARTS Update) set(cmake_options -D SUPERBUILD_EXCLUDE_MITKBUILD_TARGET:BOOL=TRUE -D MITK_CTEST_SCRIPT_MODE:STRING=${CTEST_DASHBOARD_MODEL} -D MITK_BUILD_CONFIGURATION:STRING=${MITK_BUILD_CONFIGURATION} ) if(MITK_EXTENSION_DIRS) string (REPLACE ";" "\\\;" MITK_EXTENSION_DIRS "${MITK_EXTENSION_DIRS}") list(APPEND cmake_options -D MITK_EXTENSION_DIRS:STRING=${MITK_EXTENSION_DIRS}) endif() print("MITK SuperBuild - ${MITK_BUILD_CONFIGURATION} configuration") ctest_configure( OPTIONS "${cmake_options}" RETURN_VALUE config_return_value) # ctest_submit(PARTS Configure) if(NOT config_return_value EQUAL 0) # ctest_submit(PARTS Done) return() endif() include("${CTEST_BINARY_DIRECTORY}/SuperBuildTargets.cmake") if(SUPERBUILD_TARGETS) list(LENGTH SUPERBUILD_TARGETS n) set(i 1) set(build_options "") foreach(target ${SUPERBUILD_TARGETS}) print("MITK SuperBuild - [${i}/${n}] Build ${target}") ctest_build(TARGET ${target} NUMBER_ERRORS num_build_errors NUMBER_WARNINGS num_build_warnings RETURN_VALUE build_return_value ${build_options}) # ctest_submit(PARTS Build) if(num_build_warnings GREATER 0) - print(" ${num_build_warnings} warning(s)") + print("${indent}${num_build_warnings} warning(s)") endif() if(NOT (build_return_value EQUAL 0 AND num_build_errors EQUAL 0)) # ctest_submit(PARTS Done) - print(" ${num_build_errors} error(s)") + print("${indent}${num_build_errors} error(s)") return() else() - print(" ${target} was built successfully") + print("${indent}${target} was built successfully") endif() if(NOT build_options) set(build_options APPEND) endif() math(EXPR i "${i} + 1") endforeach() else() # ctest_submit(PARTS Done) message(FATAL_ERROR "SUPERBUILD_TARGETS variable not set in SuperBuildTargets.cmake") endif() # ctest_submit(PARTS Done) return() #[[ ctest_build(TARGET MITK-Data NUMBER_ERRORS NUMBER_OF_BUILD_ERRORS RETURN_VALUE BUILD_RETURN_VALUE) ctest_submit(PARTS Build) if(BUILD_RETURN_VALUE EQUAL 0 AND NUMBER_OF_BUILD_ERRORS EQUAL 0) ctest_build(TARGET MITK-Configure APPEND NUMBER_ERRORS NUMBER_OF_BUILD_ERRORS RETURN_VALUE BUILD_RETURN_VALUE) ctest_submit(PARTS Build) if(BUILD_RETURN_VALUE EQUAL 0 AND NUMBER_OF_BUILD_ERRORS EQUAL 0) ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}/MITK-build" APPEND NUMBER_ERRORS NUMBER_OF_BUILD_ERRORS RETURN_VALUE BUILD_RETURN_VALUE) ctest_submit(PARTS Build) if(BUILD_RETURN_VALUE EQUAL 0 AND NUMBER_OF_BUILD_ERRORS EQUAL 0) ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}/MITK-build" EXCLUDE "(ProjectTemplate|Package)") ctest_submit(PARTS Test Done) else() ctest_submit(PARTS Done) # Error in Build Step (MITK) endif() else() ctest_submit(PARTS Done) # Error in Build step (Superbuild) endif() else() ctest_submit(PARTS Done) # Error in MITK-Data build step (Superbuild) endif() else() ctest_submit(PARTS Done) # Error in Configure step (Superbuild) endif() endif() ]]