3 # Included from a dashboard script, this cmake file will drive the configure and build
7 #-----------------------------------------------------------------------------
8 # The following variable are expected to be define in the top-level script:
18 CTEST_BUILD_CONFIGURATION
22 CTEST_SOURCE_DIRECTORY
23 CTEST_BINARY_DIRECTORY
26 CTEST_COVERAGE_COMMAND
27 CTEST_MEMORYCHECK_COMMAND
32 foreach(var ${expected_variables})
33 if(NOT DEFINED ${var})
34 message(FATAL_ERROR
"Variable ${var} should be defined in top-level script !")
38 string(REPLACE " " "%20" _build_name_escaped "${CTEST_BUILD_NAME}
")
40 # Check if "mbits
" is reachable
42 list(GET _status 0 _status_code)
43 if(_status_code EQUAL 0) # successful completion
44 set(MBITS_AVAILABLE 1)
46 set(MBITS_AVAILABLE 0)
50 # Site specific options
52 if(NOT CDASH_ADMIN_URL_PREFIX AND MBITS_AVAILABLE)
53 set(CDASH_ADMIN_URL_PREFIX
"http://mbits")
56 if(NOT DEFINED GIT_BRANCH OR GIT_BRANCH STREQUAL "")
59 set(GIT_BRANCH "-b ${GIT_BRANCH}
")
62 # Should binary directory be cleaned?
63 set(empty_binary_directory FALSE)
65 # Attempt to build and test also if 'ctest_update' returned an error
66 set(initial_force_build FALSE)
70 if(SCRIPT_MODE STREQUAL "experimental
")
71 set(empty_binary_directory FALSE)
72 set(initial_force_build TRUE)
73 set(model Experimental)
74 elseif(SCRIPT_MODE STREQUAL "continuous
")
75 set(empty_binary_directory FALSE)
76 set(initial_force_build FALSE)
78 elseif(SCRIPT_MODE STREQUAL "nightly
")
79 set(empty_binary_directory TRUE)
80 set(initial_force_build TRUE)
83 message(FATAL_ERROR "Unknown script mode:
'${SCRIPT_MODE}'. Script mode should be either
'experimental',
'continuous' or
'nightly'")
86 #message("script_mode:${SCRIPT_MODE}
")
87 #message("model:${model}
")
88 #message("empty_binary_directory:${empty_binary_directory}
")
89 #message("force_build:${initial_force_build}
")
91 set(CTEST_CONFIGURATION_TYPE ${CTEST_BUILD_CONFIGURATION})
93 if(empty_binary_directory)
94 message("Directory ${CTEST_BINARY_DIRECTORY} cleaned !
")
95 ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
98 if(NOT DEFINED CTEST_CHECKOUT_DIR)
99 set(CTEST_CHECKOUT_DIR ${CTEST_SOURCE_DIRECTORY})
102 if(NOT EXISTS "${CTEST_CHECKOUT_DIR}
")
103 set(CTEST_CHECKOUT_COMMAND "\
"${CTEST_GIT_COMMAND}\" clone ${GIT_BRANCH} ${GIT_REPOSITORY} \"${CTEST_CHECKOUT_DIR}\"")
106 set(CTEST_UPDATE_TYPE "git")
107 set(CTEST_UPDATE_COMMAND "${CTEST_GIT_COMMAND}
")
109 #----------------------------------------------------------------------
111 #----------------------------------------------------------------------
113 function(func_build_target target build_dir)
114 set(CTEST_BUILD_TARGET ${target})
115 ctest_build(BUILD "${build_dir}
" APPEND
117 NUMBER_ERRORS num_errors
118 NUMBER_WARNINGS num_warnings)
119 ctest_submit(PARTS Build RETRY_DELAY 3 RETRY_COUNT 3)
122 math(EXPR build_errors "${build_errors} + ${num_errors}
")
123 set(build_errors ${build_errors} PARENT_SCOPE)
126 math(EXPR build_warnings "${build_warnings} + ${num_warnings}
")
127 set(build_warnings ${build_warnings} PARENT_SCOPE)
131 function(func_test label build_dir)
132 if(NOT TESTING_PARALLEL_LEVEL)
133 set(TESTING_PARALLEL_LEVEL 8)
136 if(label MATCHES "Unlabeled
")
137 set(_include_label EXCLUDE_LABEL .*)
139 set(_include_label INCLUDE_LABEL ${label})
142 ctest_test(BUILD "${build_dir}
"
144 PARALLEL_LEVEL ${TESTING_PARALLEL_LEVEL}
145 EXCLUDE ${TEST_TO_EXCLUDE_REGEX}
148 ctest_submit(PARTS Test RETRY_DELAY 3 RETRY_COUNT 3)
151 math(EXPR test_errors "${test_errors} + 1
")
152 set(test_errors ${test_errors} PARENT_SCOPE)
156 set(WITH_COVERAGE ${ARG3})
159 set(WITH_MEMCHECK ${ARG4})
162 if(WITH_COVERAGE AND CTEST_COVERAGE_COMMAND)
163 message("----------- [ Coverage ${label} ] -----------
")
164 ctest_coverage(BUILD "${build_dir}
" LABELS ${label})
165 ctest_submit(PARTS Coverage RETRY_DELAY 3 RETRY_COUNT 3)
168 if(WITH_MEMCHECK AND CTEST_MEMORYCHECK_COMMAND)
169 if(NOT CTEST_MEMORYCHECK_SUPPRESSIONS_FILE)
170 if(EXISTS "${CTEST_SOURCE_DIRECTORY}/
CMake/valgrind.supp
")
171 set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE "${CTEST_SOURCE_DIRECTORY}/
CMake/valgrind.supp
")
174 if(NOT CTEST_MEMORYCHECK_COMMAND_OPTIONS)
175 set(CTEST_MEMORYCHECK_COMMAND_OPTIONS "-q --tool=memcheck --leak-check=yes --show-reachable=no --show-possibly-lost=no --workaround-gcc296-bugs=yes --num-callers=50
")
177 ctest_memcheck(BUILD "${build_dir}
" INCLUDE_LABEL ${label})
178 ctest_submit(PARTS MemCheck RETRY_DELAY 3 RETRY_COUNT 3)
183 macro(finalize_submission)
185 # Note should be at the end
186 ctest_submit(PARTS Notes RETRY_DELAY 3 RETRY_COUNT 3)
188 # Send status to the "CDash Web Admin
"
189 if(CDASH_ADMIN_URL_PREFIX)
190 set(cdash_admin_url "${CDASH_ADMIN_URL_PREFIX}/cdashadmin-web/index.php?pw=4da12ca9c06d46d3171d7f73974c900f
")
191 string(REGEX REPLACE ".*\\?project=(.*)&?
" "\\1
" _ctest_project "${CTEST_DROP_LOCATION}
")
193 "${cdash_admin_url}&action=submit&name=${_build_name_escaped}&hasTestErrors=${test_errors}&hasBuildErrors=${build_errors}&hasBuildWarnings=${build_warnings}&ctestDropSite=${CTEST_DROP_SITE}&ctestProject=${_ctest_project}
"
194 "${CTEST_BINARY_DIRECTORY}/cdashadmin.txt
"
197 list(GET status 0 error_code)
198 list(GET status 1 error_msg)
200 message(FATAL_ERROR "error: Failed to communicate with cdashadmin-web - ${error_msg}
")
206 macro(check_for_errors)
208 set(_curr_target ${ARGV0})
209 if(build_errors AND _curr_target)
210 # try to remove the stamp file for external projects
211 set(_stamp_file "${CTEST_BINARY_DIRECTORY}/ep/src/${_curr_target}-stamp/${_curr_target}-configure
")
212 if(EXISTS "${_stamp_file}
")
213 file(REMOVE "${_stamp_file}
")
217 if(build_errors OR test_errors)
218 finalize_submission()
219 # this should return from run_ctest()
225 #---------------------------------------------------------------------
227 #---------------------------------------------------------------------
230 set(build_warnings 0)
234 ctest_start(${model})
236 ctest_update(SOURCE "${CTEST_CHECKOUT_DIR}
" RETURN_VALUE res)
240 math(EXPR build_errors "${build_errors} + 1
")
243 set(force_build ${initial_force_build})
245 # Check if a forced run was requested
246 set(cdash_remove_rerun_url )
247 if(CDASH_ADMIN_URL_PREFIX)
248 set(cdash_rerun_url "${CDASH_ADMIN_URL_PREFIX}/rerun/${_build_name_escaped}
")
249 set(cdash_remove_rerun_url "${CDASH_ADMIN_URL_PREFIX}/rerun/rerun.php?name=${_build_name_escaped}&
remove=1
")
252 "${CTEST_BINARY_DIRECTORY}/tmp.txt
"
255 list(GET status 0 error_code)
256 file(READ "${CTEST_BINARY_DIRECTORY}/tmp.txt
" rerun_content LIMIT 1)
257 if(NOT error_code AND NOT rerun_content)
262 if(COMMAND MITK_OVERRIDE_FORCE_BUILD)
263 MITK_OVERRIDE_FORCE_BUILD(force_build)
266 # force a build if this is the first run and the build dir is empty
267 if(NOT EXISTS "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt
")
268 message("First time build - Initialize CMakeCache.txt
")
271 # Write initial cache.
272 if(NOT DEFINED BUILD_TESTING)
273 set(BUILD_TESTING ON)
276 # Write initial cache.
277 file(WRITE "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt
" "
278 CTEST_USE_LAUNCHERS:BOOL=${CTEST_USE_LAUNCHERS}
279 CTEST_PROJECT_ADDITIONAL_TARGETS:INTERNAL=${CTEST_PROJECT_ADDITIONAL_TARGETS}
280 BUILD_TESTING:BOOL=${BUILD_TESTING}
281 MITK_CTEST_SCRIPT_MODE:STRING=${SCRIPT_MODE}
282 CMAKE_BUILD_TYPE:STRING=${CTEST_BUILD_CONFIGURATION}
283 WITH_COVERAGE:BOOL=${WITH_COVERAGE}
284 MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL:STRING=${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}
285 ${INITIAL_CMAKECACHE_OPTIONS}
289 if(res GREATER 0 OR force_build)
291 # Clear the forced rerun request
292 if(CDASH_ADMIN_URL_PREFIX AND cdash_remove_rerun_url)
293 file(DOWNLOAD "${cdash_remove_rerun_url}
" "${CTEST_BINARY_DIRECTORY}/tmp.txt
")
294 file(REMOVE "${CTEST_BINARY_DIRECTORY}/tmp.txt
")
297 if(CTEST_PROJECT_NAME_SUPERBUILD)
298 set(ctest_project_name_orig ${CTEST_PROJECT_NAME})
299 set(CTEST_PROJECT_NAME ${CTEST_PROJECT_NAME_SUPERBUILD})
302 message("----------- [ Configure SuperBuild ] -----------
")
304 set_property(GLOBAL PROPERTY SubProject SuperBuild)
305 set_property(GLOBAL PROPERTY Label SuperBuild)
307 ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}
" RETURN_VALUE res OPTIONS "${SUPERBUILD_CONFIG_OPTIONS}
")
310 math(EXPR build_errors "${build_errors} + 1
")
313 # Project.xml is generated during the superbuild configure step
314 ctest_submit(FILES "${CTEST_BINARY_DIRECTORY}/Project.xml
" RETRY_DELAY 3 RETRY_COUNT 3)
316 ctest_read_custom_files("${CTEST_BINARY_DIRECTORY}
")
318 ctest_submit(PARTS Configure RETRY_DELAY 3 RETRY_COUNT 3)
320 # submit the update results *after* the submitting the Configure info,
321 # otherwise CDash is somehow confused and cannot add the update info
322 # to the superbuild project
323 ctest_submit(PARTS Update RETRY_DELAY 3 RETRY_COUNT 3)
327 # To get CTEST_PROJECT_SUBPROJECTS and CTEST_PROJECT_EXTERNALS definition
328 include("${CTEST_BINARY_DIRECTORY}/CTestConfigSubProject.cmake
")
330 # Read in a list of super-build targets (SUPERBUILD_TARGETS). If an error
331 # occurs in one of the listed projects, the ctest superbuild make step stops
332 # and the error is reported in the dashboard. If this variable would be empty
333 # the errors are still reported but make would keep building external
334 # projects which leads to potentially more errors because of dependencies.
335 set(MITK_SUPERBUILD_TARGETS_FILE "${CTEST_BINARY_DIRECTORY}/SuperBuildTargets.cmake
")
336 if(EXISTS "${MITK_SUPERBUILD_TARGETS_FILE}
")
337 include("${MITK_SUPERBUILD_TARGETS_FILE}
")
340 # Build top level (either all or the supplied targets at
342 if(SUPERBUILD_TARGETS)
343 foreach(superbuild_target ${SUPERBUILD_TARGETS})
345 message("----------- [ Build ${superbuild_target} - SuperBuild ] -----------
")
346 func_build_target(${superbuild_target} "${CTEST_BINARY_DIRECTORY}
")
347 check_for_errors(${superbuild_target})
349 # runs only tests that have a LABELS property matching "SuperBuild
"
350 func_test("SuperBuild
" "${CTEST_BINARY_DIRECTORY}
")
354 # HACK Unfortunately ctest_coverage ignores the build argument, back-up the original dirs
355 file(READ "${CTEST_BINARY_DIRECTORY}/CMakeFiles/TargetDirectories.txt
" old_coverage_dirs)
357 # explicitly build requested external projects as subprojects
358 foreach(external_project_with_build_dir ${CTEST_PROJECT_EXTERNALS})
360 string(REPLACE "^^
" ";
" external_project_with_build_dir_list "${external_project_with_build_dir}
")
361 list(GET external_project_with_build_dir_list 0 external_project_name)
362 list(GET external_project_with_build_dir_list 1 external_project_builddir)
364 set_property(GLOBAL PROPERTY SubProject ${external_project_name})
365 set_property(GLOBAL PROPERTY Label ${external_project_name})
367 message("----------- [ Build ${external_project_name} ] -----------
")
369 func_build_target("${external_project_name}
" "${CTEST_BINARY_DIRECTORY}
")
372 # HACK Unfortunately ctest_coverage ignores the build argument, try to force it...
373 file(READ "${CTEST_BINARY_DIRECTORY}/${external_project_builddir}/CMakeFiles/TargetDirectories.txt
" mitk_build_coverage_dirs)
374 file(APPEND "${CTEST_BINARY_DIRECTORY}/CMakeFiles/TargetDirectories.txt
" "${mitk_build_coverage_dirs}
")
376 message("----------- [ Test ${external_project_name} ] -----------
")
378 # runs only tests that have a LABELS property matching "${external_project_name}
"
379 func_test(${external_project_name} "${CTEST_BINARY_DIRECTORY}/${external_project_builddir}
")
381 # restore old coverage dirs
382 file(WRITE "${CTEST_BINARY_DIRECTORY}/CMakeFiles/TargetDirectories.txt
" "${old_coverage_dirs}
")
386 # switch back to SuperBuild label
387 set_property(GLOBAL PROPERTY SubProject SuperBuild)
388 set_property(GLOBAL PROPERTY Label SuperBuild)
390 message("----------- [ Finish SuperBuild ] -----------
")
392 message("----------- [ Build SuperBuild ] -----------
")
395 # build everything at superbuild level which has not yet been built
396 func_build_target("" "${CTEST_BINARY_DIRECTORY}
")
399 # runs only tests that have a LABELS property matching "SuperBuild
"
400 #func_test("SuperBuild
" "${CTEST_BINARY_DIRECTORY}
")
402 set(build_dir "${CTEST_BINARY_DIRECTORY}/${PROJECT_BUILD_DIR}
")
403 if(CTEST_PROJECT_NAME_SUPERBUILD)
404 set(CTEST_PROJECT_NAME ${ctest_project_name_orig})
407 message("----------- [ Configure ${build_dir} ] -----------
")
409 ctest_configure(BUILD "${build_dir}
"
410 OPTIONS "-DCTEST_USE_LAUNCHERS=${CTEST_USE_LAUNCHERS}
"
413 ctest_read_custom_files("${CTEST_BINARY_DIRECTORY}
")
414 ctest_submit(PARTS Configure RETRY_DELAY 3 RETRY_COUNT 3)
417 math(EXPR build_errors "${build_errors} + 1
")
421 foreach(subproject ${CTEST_PROJECT_SUBPROJECTS})
422 set_property(GLOBAL PROPERTY SubProject ${subproject})
423 set_property(GLOBAL PROPERTY Label ${subproject})
425 if(subproject MATCHES "Unlabeled
")
426 message("----------- [ Build All (Unlabeled) ] -----------
")
428 func_build_target("" "${build_dir}
")
430 message("----------- [ Build ${subproject} ] -----------
")
432 func_build_target(${subproject} "${build_dir}
")
437 # HACK Unfortunately ctest_coverage ignores the build argument, try to force it...
438 file(READ ${build_dir}/CMakeFiles/TargetDirectories.txt mitk_build_coverage_dirs)
439 file(APPEND "${CTEST_BINARY_DIRECTORY}/CMakeFiles/TargetDirectories.txt
" "${mitk_build_coverage_dirs}
")
441 foreach(subproject ${CTEST_PROJECT_SUBPROJECTS})
442 set_property(GLOBAL PROPERTY SubProject ${subproject})
443 set_property(GLOBAL PROPERTY Label ${subproject})
444 message("----------- [ Test ${subproject} ] -----------
")
446 # runs only tests that have a LABELS property matching "${subproject}
"
447 func_test(${subproject} "${build_dir}
")
450 # Build any additional target which is not build by "all
"
451 # i.e. the "package
" target
452 if(CTEST_PROJECT_ADDITIONAL_TARGETS)
453 foreach(additional_target ${CTEST_PROJECT_ADDITIONAL_TARGETS})
454 set_property(GLOBAL PROPERTY SubProject ${additional_target})
455 set_property(GLOBAL PROPERTY Label ${additional_target})
457 message("----------- [ Build ${additional_target} ] -----------
")
458 func_build_target(${additional_target} "${build_dir}
")
461 message("----------- [ Test ${additional_target} ] -----------
")
462 # runs only tests that have a LABELS property matching "${subproject}
"
463 func_test(${additional_target} "${build_dir}
")
467 if(WITH_DOCUMENTATION)
468 message("----------- [ Build Documentation ] -----------
")
469 set(ctest_use_launchers_orig ${CTEST_USE_LAUNCHERS})
470 set(CTEST_USE_LAUNCHERS 0)
471 # Build Documentation target
472 set_property(GLOBAL PROPERTY SubProject Documentation)
473 set_property(GLOBAL PROPERTY Label Documentation)
474 func_build_target("doc
" "${build_dir}
")
475 set(CTEST_USE_LAUNCHERS ${ctest_use_launchers_orig})
478 set_property(GLOBAL PROPERTY SubProject SuperBuild)
479 set_property(GLOBAL PROPERTY Label SuperBuild)
481 # Global coverage ...
482 if(WITH_COVERAGE AND CTEST_COVERAGE_COMMAND)
483 message("----------- [ Global coverage ] -----------
")
484 ctest_coverage(BUILD "${build_dir}
" APPEND)
485 ctest_submit(PARTS Coverage RETRY_DELAY 3 RETRY_COUNT 3)
488 # Global dynamic analysis ...
489 if(WITH_MEMCHECK AND CTEST_MEMORYCHECK_COMMAND)
490 message("----------- [ Global memcheck ] -----------
")
491 ctest_memcheck(BUILD "${build_dir}
")
492 ctest_submit(PARTS MemCheck RETRY_DELAY 3 RETRY_COUNT 3)
496 finalize_submission()
500 # Clear the CTEST_CHECKOUT_COMMAND variable to prevent continuous clients
501 # to try to checkout again
502 set(CTEST_CHECKOUT_COMMAND "")
506 if(SCRIPT_MODE STREQUAL "continuous
")
509 # Loop no faster than once every 5 minutes
510 message("Wait
for 5 minutes ...
")