Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
MITKDashboardDriverScript.cmake
Go to the documentation of this file.
1 
2 #
3 # Included from a dashboard script, this cmake file will drive the configure and build
4 # steps of MITK
5 #
6 
7 #-----------------------------------------------------------------------------
8 # The following variable are expected to be define in the top-level script:
9 set(expected_variables
10  CTEST_NOTES_FILES
11  CTEST_SITE
12  CTEST_DASHBOARD_ROOT
13  CTEST_CMAKE_COMMAND
14  CTEST_CMAKE_GENERATOR
15  WITH_MEMCHECK
16  WITH_COVERAGE
17  WITH_DOCUMENTATION
18  CTEST_BUILD_CONFIGURATION
19  CTEST_TEST_TIMEOUT
20  CTEST_BUILD_FLAGS
21  TEST_TO_EXCLUDE_REGEX
22  CTEST_SOURCE_DIRECTORY
23  CTEST_BINARY_DIRECTORY
24  CTEST_BUILD_NAME
25  SCRIPT_MODE
26  CTEST_COVERAGE_COMMAND
27  CTEST_MEMORYCHECK_COMMAND
28  CTEST_GIT_COMMAND
29  PROJECT_BUILD_DIR
30  )
31 
32 foreach(var ${expected_variables})
33  if(NOT DEFINED ${var})
34  message(FATAL_ERROR "Variable ${var} should be defined in top-level script !")
35  endif()
36 endforeach()
37 
38 string(REPLACE " " "%20" _build_name_escaped "${CTEST_BUILD_NAME}")
39 
40 # Check if "mbits" is reachable
41 file(DOWNLOAD "http://mbits" "${CTEST_SCRIPT_DIRECTORY}/mbits.html" TIMEOUT 2 STATUS _status)
42 list(GET _status 0 _status_code)
43 if(_status_code EQUAL 0) # successful completion
44  set(MBITS_AVAILABLE 1)
45 else()
46  set(MBITS_AVAILABLE 0)
47 endif()
48 
49 #
50 # Site specific options
51 #
52 if(NOT CDASH_ADMIN_URL_PREFIX AND MBITS_AVAILABLE)
53  set(CDASH_ADMIN_URL_PREFIX "http://mbits")
54 endif()
55 
56 if(NOT DEFINED GIT_BRANCH OR GIT_BRANCH STREQUAL "")
57  set(GIT_BRANCH "")
58 else()
59  set(GIT_BRANCH "-b ${GIT_BRANCH}")
60 endif()
61 
62 # Should binary directory be cleaned?
63 set(empty_binary_directory FALSE)
64 
65 # Attempt to build and test also if 'ctest_update' returned an error
66 set(initial_force_build FALSE)
67 
68 # Set model options
69 set(model "")
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)
77  set(model Continuous)
78 elseif(SCRIPT_MODE STREQUAL "nightly")
79  set(empty_binary_directory TRUE)
80  set(initial_force_build TRUE)
81  set(model Nightly)
82 else()
83  message(FATAL_ERROR "Unknown script mode: '${SCRIPT_MODE}'. Script mode should be either 'experimental', 'continuous' or 'nightly'")
84 endif()
85 
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}")
90 
91 set(CTEST_CONFIGURATION_TYPE ${CTEST_BUILD_CONFIGURATION})
92 
93 if(empty_binary_directory)
94  message("Directory ${CTEST_BINARY_DIRECTORY} cleaned !")
95  ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
96 endif()
97 
98 if(NOT DEFINED CTEST_CHECKOUT_DIR)
99  set(CTEST_CHECKOUT_DIR ${CTEST_SOURCE_DIRECTORY})
100 endif()
101 
102 if(NOT EXISTS "${CTEST_CHECKOUT_DIR}")
103  set(CTEST_CHECKOUT_COMMAND "\"${CTEST_GIT_COMMAND}\" clone ${GIT_BRANCH} ${GIT_REPOSITORY} \"${CTEST_CHECKOUT_DIR}\"")
104 endif()
105 
106 set(CTEST_UPDATE_TYPE "git")
107 set(CTEST_UPDATE_COMMAND "${CTEST_GIT_COMMAND}")
108 
109 #----------------------------------------------------------------------
110 # Utility macros
111 #----------------------------------------------------------------------
112 
113 function(func_build_target target build_dir)
114  set(CTEST_BUILD_TARGET ${target})
115  ctest_build(BUILD "${build_dir}" APPEND
116  RETURN_VALUE res
117  NUMBER_ERRORS num_errors
118  NUMBER_WARNINGS num_warnings)
119  ctest_submit(PARTS Build RETRY_DELAY 3 RETRY_COUNT 3)
120 
121  if(num_errors)
122  math(EXPR build_errors "${build_errors} + ${num_errors}")
123  set(build_errors ${build_errors} PARENT_SCOPE)
124  endif()
125  if(num_warnings)
126  math(EXPR build_warnings "${build_warnings} + ${num_warnings}")
127  set(build_warnings ${build_warnings} PARENT_SCOPE)
128  endif()
129 endfunction()
130 
131 function(func_test label build_dir)
132  if(NOT TESTING_PARALLEL_LEVEL)
133  set(TESTING_PARALLEL_LEVEL 8)
134  endif()
135 
136  if(label MATCHES "Unlabeled")
137  set(_include_label EXCLUDE_LABEL .*)
138  else()
139  set(_include_label INCLUDE_LABEL ${label})
140  endif()
141 
142  ctest_test(BUILD "${build_dir}"
143  ${_include_label}
144  PARALLEL_LEVEL ${TESTING_PARALLEL_LEVEL}
145  EXCLUDE ${TEST_TO_EXCLUDE_REGEX}
146  RETURN_VALUE res
147  )
148  ctest_submit(PARTS Test RETRY_DELAY 3 RETRY_COUNT 3)
149 
150  if(res)
151  math(EXPR test_errors "${test_errors} + 1")
152  set(test_errors ${test_errors} PARENT_SCOPE)
153  endif()
154 
155  if(ARG3)
156  set(WITH_COVERAGE ${ARG3})
157  endif()
158  if(ARG4)
159  set(WITH_MEMCHECK ${ARG4})
160  endif()
161 
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)
166  endif()
167 
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")
172  endif()
173  endif()
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")
176  endif()
177  ctest_memcheck(BUILD "${build_dir}" INCLUDE_LABEL ${label})
178  ctest_submit(PARTS MemCheck RETRY_DELAY 3 RETRY_COUNT 3)
179  endif()
180 
181 endfunction()
182 
183 macro(finalize_submission)
184 
185  # Note should be at the end
186  ctest_submit(PARTS Notes RETRY_DELAY 3 RETRY_COUNT 3)
187 
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}")
192  file(DOWNLOAD
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"
195  STATUS status
196  )
197  list(GET status 0 error_code)
198  list(GET status 1 error_msg)
199  if(error_code)
200  message(FATAL_ERROR "error: Failed to communicate with cdashadmin-web - ${error_msg}")
201  endif()
202  endif()
203 
204 endmacro()
205 
206 macro(check_for_errors)
207 
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}")
214  endif()
215  endif()
216 
217  if(build_errors OR test_errors)
218  finalize_submission()
219  # this should return from run_ctest()
220  return()
221  endif()
222 
223 endmacro()
224 
225 #---------------------------------------------------------------------
226 # run_ctest macro
227 #---------------------------------------------------------------------
228 function(run_ctest)
229 
230  set(build_warnings 0)
231  set(build_errors 0)
232  set(test_errors 0)
233 
234  ctest_start(${model})
235 
236  ctest_update(SOURCE "${CTEST_CHECKOUT_DIR}" RETURN_VALUE res)
237 
238  if(res LESS 0)
239  # update error
240  math(EXPR build_errors "${build_errors} + 1")
241  endif()
242 
243  set(force_build ${initial_force_build})
244 
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")
250  file(DOWNLOAD
251  "${cdash_rerun_url}"
252  "${CTEST_BINARY_DIRECTORY}/tmp.txt"
253  STATUS status
254  )
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)
258  set(force_build 1)
259  endif()
260  endif()
261 
262  if(COMMAND MITK_OVERRIDE_FORCE_BUILD)
263  MITK_OVERRIDE_FORCE_BUILD(force_build)
264  endif()
265 
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")
269  set(res 1)
270 
271  # Write initial cache.
272  if(NOT DEFINED BUILD_TESTING)
273  set(BUILD_TESTING ON)
274  endif()
275 
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}
286 ")
287  endif()
288 
289  if(res GREATER 0 OR force_build)
290 
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")
295  endif()
296 
297  if(CTEST_PROJECT_NAME_SUPERBUILD)
298  set(ctest_project_name_orig ${CTEST_PROJECT_NAME})
299  set(CTEST_PROJECT_NAME ${CTEST_PROJECT_NAME_SUPERBUILD})
300  endif()
301 
302  message("----------- [ Configure SuperBuild ] -----------")
303 
304  set_property(GLOBAL PROPERTY SubProject SuperBuild)
305  set_property(GLOBAL PROPERTY Label SuperBuild)
306 
307  ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res OPTIONS "${SUPERBUILD_CONFIG_OPTIONS}")
308 
309  if(res)
310  math(EXPR build_errors "${build_errors} + 1")
311  endif()
312 
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)
315 
316  ctest_read_custom_files("${CTEST_BINARY_DIRECTORY}")
317 
318  ctest_submit(PARTS Configure RETRY_DELAY 3 RETRY_COUNT 3)
319 
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)
324 
325  check_for_errors()
326 
327  # To get CTEST_PROJECT_SUBPROJECTS and CTEST_PROJECT_EXTERNALS definition
328  include("${CTEST_BINARY_DIRECTORY}/CTestConfigSubProject.cmake")
329 
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}")
338  endif()
339 
340  # Build top level (either all or the supplied targets at
341  # superbuild level
342  if(SUPERBUILD_TARGETS)
343  foreach(superbuild_target ${SUPERBUILD_TARGETS})
344 
345  message("----------- [ Build ${superbuild_target} - SuperBuild ] -----------")
346  func_build_target(${superbuild_target} "${CTEST_BINARY_DIRECTORY}")
347  check_for_errors(${superbuild_target})
348 
349  # runs only tests that have a LABELS property matching "SuperBuild"
350  func_test("SuperBuild" "${CTEST_BINARY_DIRECTORY}")
351  check_for_errors()
352  endforeach()
353 
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)
356 
357  # explicitly build requested external projects as subprojects
358  foreach(external_project_with_build_dir ${CTEST_PROJECT_EXTERNALS})
359 
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)
363 
364  set_property(GLOBAL PROPERTY SubProject ${external_project_name})
365  set_property(GLOBAL PROPERTY Label ${external_project_name})
366 
367  message("----------- [ Build ${external_project_name} ] -----------")
368 
369  func_build_target("${external_project_name}" "${CTEST_BINARY_DIRECTORY}")
370  check_for_errors()
371 
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}")
375 
376  message("----------- [ Test ${external_project_name} ] -----------")
377 
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}")
380 
381  # restore old coverage dirs
382  file(WRITE "${CTEST_BINARY_DIRECTORY}/CMakeFiles/TargetDirectories.txt" "${old_coverage_dirs}")
383 
384  endforeach()
385 
386  # switch back to SuperBuild label
387  set_property(GLOBAL PROPERTY SubProject SuperBuild)
388  set_property(GLOBAL PROPERTY Label SuperBuild)
389 
390  message("----------- [ Finish SuperBuild ] -----------")
391  else()
392  message("----------- [ Build SuperBuild ] -----------")
393  endif()
394 
395  # build everything at superbuild level which has not yet been built
396  func_build_target("" "${CTEST_BINARY_DIRECTORY}")
397  check_for_errors()
398 
399  # runs only tests that have a LABELS property matching "SuperBuild"
400  #func_test("SuperBuild" "${CTEST_BINARY_DIRECTORY}")
401 
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})
405  endif()
406 
407  message("----------- [ Configure ${build_dir} ] -----------")
408  # Configure target
409  ctest_configure(BUILD "${build_dir}"
410  OPTIONS "-DCTEST_USE_LAUNCHERS=${CTEST_USE_LAUNCHERS}"
411  RETURN_VALUE res
412  )
413  ctest_read_custom_files("${CTEST_BINARY_DIRECTORY}")
414  ctest_submit(PARTS Configure RETRY_DELAY 3 RETRY_COUNT 3)
415 
416  if(res)
417  math(EXPR build_errors "${build_errors} + 1")
418  endif()
419  check_for_errors()
420 
421  foreach(subproject ${CTEST_PROJECT_SUBPROJECTS})
422  set_property(GLOBAL PROPERTY SubProject ${subproject})
423  set_property(GLOBAL PROPERTY Label ${subproject})
424 
425  if(subproject MATCHES "Unlabeled")
426  message("----------- [ Build All (Unlabeled) ] -----------")
427  # Build target
428  func_build_target("" "${build_dir}")
429  else()
430  message("----------- [ Build ${subproject} ] -----------")
431  # Build target
432  func_build_target(${subproject} "${build_dir}")
433  endif()
434  check_for_errors()
435  endforeach()
436 
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}")
440 
441  foreach(subproject ${CTEST_PROJECT_SUBPROJECTS})
442  set_property(GLOBAL PROPERTY SubProject ${subproject})
443  set_property(GLOBAL PROPERTY Label ${subproject})
444  message("----------- [ Test ${subproject} ] -----------")
445 
446  # runs only tests that have a LABELS property matching "${subproject}"
447  func_test(${subproject} "${build_dir}")
448  endforeach()
449 
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})
456 
457  message("----------- [ Build ${additional_target} ] -----------")
458  func_build_target(${additional_target} "${build_dir}")
459  check_for_errors()
460 
461  message("----------- [ Test ${additional_target} ] -----------")
462  # runs only tests that have a LABELS property matching "${subproject}"
463  func_test(${additional_target} "${build_dir}")
464  endforeach()
465  endif()
466 
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})
476  endif()
477 
478  set_property(GLOBAL PROPERTY SubProject SuperBuild)
479  set_property(GLOBAL PROPERTY Label SuperBuild)
480 
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)
486  endif()
487 
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)
493  endif()
494 
495  check_for_errors()
496  finalize_submission()
497 
498  endif()
499 
500  # Clear the CTEST_CHECKOUT_COMMAND variable to prevent continuous clients
501  # to try to checkout again
502  set(CTEST_CHECKOUT_COMMAND "")
503 
504 endfunction()
505 
506 if(SCRIPT_MODE STREQUAL "continuous")
507  while(1)
508  run_ctest()
509  # Loop no faster than once every 5 minutes
510  message("Wait for 5 minutes ...")
511  ctest_sleep(300)
512  endwhile()
513 else()
514  run_ctest()
515 endif()
516