CMakeLists.txt 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. REGEX_ESCAPE_STRING(CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
  2. foreach (_retval 0 1)
  3. configure_file("${CMAKE_CURRENT_SOURCE_DIR}/memtester.cxx.in" "${CMAKE_CURRENT_BINARY_DIR}/ret${_retval}.cxx" @ONLY)
  4. endforeach ()
  5. include_directories(${CMake_SOURCE_DIR}/Source ${CMake_BINARY_DIR}/Source)
  6. # create binaries that we will use as a pseudo memory checker
  7. add_executable(pseudo_valgrind "${CMAKE_CURRENT_BINARY_DIR}/ret0.cxx")
  8. set_target_properties(pseudo_valgrind PROPERTIES OUTPUT_NAME valgrind)
  9. target_link_libraries(pseudo_valgrind CMakeLib)
  10. # Xcode 2.x forgets to create the output directory before linking
  11. # the individual architectures.
  12. if(CMAKE_OSX_ARCHITECTURES AND XCODE AND NOT "${XCODE_VERSION}" MATCHES "^[^12]")
  13. add_custom_command(TARGET pseudo_valgrind
  14. PRE_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CFG_INTDIR}"
  15. )
  16. endif()
  17. add_executable(pseudo_purify "${CMAKE_CURRENT_BINARY_DIR}/ret0.cxx")
  18. set_target_properties(pseudo_purify PROPERTIES OUTPUT_NAME purify)
  19. target_link_libraries(pseudo_purify CMakeLib)
  20. add_executable(pseudo_BC "${CMAKE_CURRENT_BINARY_DIR}/ret0.cxx")
  21. set_target_properties(pseudo_BC PROPERTIES OUTPUT_NAME BC)
  22. target_link_libraries(pseudo_BC CMakeLib)
  23. # binary to be used as pre- and post-memcheck command that fails
  24. add_executable(memcheck_fail "${CMAKE_CURRENT_BINARY_DIR}/ret1.cxx")
  25. target_link_libraries(memcheck_fail CMakeLib)
  26. # Binaries that are used as memchecker that do not write the expected
  27. # output file. Need to be in their own subdirectory as they have the
  28. # same filenames.
  29. add_subdirectory(NoLogDummyChecker)
  30. if(APPLE)
  31. # filter out additional messages by Guard Malloc integrated in Xcode
  32. set(guard_malloc_msg "ctest\\([0-9]+\\) malloc: ")
  33. set(guard_malloc_lines "(${guard_malloc_msg}[^\n]*\n)*")
  34. set(guard_malloc_output "${guard_malloc_msg}|")
  35. else()
  36. set(guard_malloc_msg "")
  37. set(guard_malloc_lines "")
  38. set(guard_malloc_output "")
  39. endif()
  40. # When this entire test runs under coverage or memcheck tools
  41. # they may add output to the end, so match known cases:
  42. # - Bullseye adds a "BullseyeCoverage..." line.
  43. # - Valgrind memcheck may add extra "==..." lines.
  44. set(other_tool_output "((${guard_malloc_output}BullseyeCoverage|==)[^\n]*\n)*")
  45. string(REPLACE "\r\n" "\n" ctest_and_tool_outputs "
  46. 1/1 MemCheck #1: RunCMake \\.+ Passed +[0-9]+\\.[0-9]+ sec
  47. ${guard_malloc_lines}
  48. 100% tests passed, 0 tests failed out of 1
  49. .*
  50. -- Processing memory checking output:( )
  51. ${guard_malloc_lines}Memory checking results:
  52. ${other_tool_output}")
  53. function(gen_mc_test_internal NAME CHECKER)
  54. set(SUBTEST_NAME "${NAME}")
  55. set(CHECKER_COMMAND "${CHECKER}")
  56. foreach(_file IN ITEMS CMakeLists.txt CTestConfig.cmake test.cmake)
  57. configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${_file}.in"
  58. "${CMAKE_CURRENT_BINARY_DIR}/${NAME}/${_file}" @ONLY)
  59. endforeach()
  60. add_test(NAME CTestTestMemcheck${NAME}
  61. COMMAND ${CMAKE_CTEST_COMMAND}
  62. -C $<CONFIGURATION>
  63. -S "${CMAKE_CURRENT_BINARY_DIR}/${NAME}/test.cmake" -V
  64. --output-log "${CMAKE_CURRENT_BINARY_DIR}/${NAME}/testOutput.log"
  65. ${ARGN}
  66. )
  67. endfunction(gen_mc_test_internal)
  68. function(gen_mc_test NAME CHECKER)
  69. gen_mc_test_internal(${NAME} "${CHECKER}"
  70. -D PSEUDO_BC=$<TARGET_FILE:pseudo_BC>
  71. -D PSEUDO_PURIFY=$<TARGET_FILE:pseudo_purify>
  72. -D PSEUDO_VALGRIND=$<TARGET_FILE:pseudo_valgrind>
  73. -D ERROR_COMMAND=$<TARGET_FILE:memcheck_fail>
  74. ${ARGN}
  75. )
  76. endfunction(gen_mc_test)
  77. function(gen_mcnl_test NAME CHECKER)
  78. gen_mc_test_internal(${NAME} ${CHECKER}
  79. -D PSEUDO_BC=$<TARGET_FILE:pseudonl_BC>
  80. -D PSEUDO_PURIFY=$<TARGET_FILE:pseudonl_purify>
  81. -D PSEUDO_VALGRIND=$<TARGET_FILE:pseudonl_valgrind>
  82. ${ARGN}
  83. )
  84. set_tests_properties(CTestTestMemcheck${NAME}
  85. PROPERTIES
  86. PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/${NAME}/Testing/Temporary/MemoryChecker.1.log\n(.*\n)?Error in read script: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/${NAME}/test.cmake\n")
  87. endfunction(gen_mcnl_test)
  88. unset(CTEST_EXTRA_CONFIG)
  89. unset(CTEST_EXTRA_CODE)
  90. unset(CMAKELISTS_EXTRA_CODE)
  91. gen_mc_test(DummyPurify "\${PSEUDO_PURIFY}")
  92. gen_mc_test(DummyValgrind "\${PSEUDO_VALGRIND}")
  93. gen_mc_test(DummyBC "\${PSEUDO_BC}")
  94. gen_mcnl_test(DummyPurifyNoLogfile "\${PSEUDO_PURIFY}")
  95. gen_mcnl_test(DummyValgrindNoLogfile "\${PSEUDO_VALGRIND}")
  96. gen_mcnl_test(DummyBCNoLogfile "\${PSEUDO_BC}")
  97. set(CTEST_EXTRA_CODE "string(REPLACE \" \" \"\\\\ \" PRE_POST_COMMAND \"\${CTEST_MEMORYCHECK_COMMAND}\")
  98. set(CTEST_CUSTOM_PRE_MEMCHECK \"\${PRE_POST_COMMAND} pre command\")
  99. set(CTEST_CUSTOM_POST_MEMCHECK \"\${PRE_POST_COMMAND} post command \")
  100. ")
  101. gen_mc_test(DummyValgrindPrePost "\${PSEUDO_VALGRIND}")
  102. set(CTEST_EXTRA_CODE "set(CTEST_CUSTOM_POST_MEMCHECK \"\${ERROR_COMMAND}\")")
  103. gen_mc_test(DummyValgrindFailPost "\${PSEUDO_VALGRIND}")
  104. set(CTEST_EXTRA_CODE "set(CTEST_CUSTOM_PRE_MEMCHECK \"\${ERROR_COMMAND}\")")
  105. gen_mc_test(DummyValgrindFailPre "\${PSEUDO_VALGRIND}")
  106. unset(CTEST_EXTRA_CODE)
  107. set(CTEST_EXTRA_CONFIG "set(CTEST_CUSTOM_MEMCHECK_IGNORE RunCMakeAgain)\n")
  108. set(CMAKELISTS_EXTRA_CODE "add_test(NAME RunCMakeAgain COMMAND \"\${CMAKE_COMMAND}\" --version)")
  109. gen_mc_test(DummyValgrindIgnoreMemcheck "\${PSEUDO_VALGRIND}")
  110. unset(CTEST_EXTRA_CONFIG)
  111. gen_mc_test(DummyValgrindTwoTargets "\${PSEUDO_VALGRIND}" "-VV")
  112. set(CTEST_EXTRA_CONFIG "set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE \"\${CMAKE_CURRENT_BINARY_DIR}/does-not-exist\")")
  113. unset(CMAKELISTS_EXTRA_CODE)
  114. gen_mc_test(DummyValgrindInvalidSupFile "\${PSEUDO_VALGRIND}")
  115. # CTest will add the logfile option before any custom options. Set the logfile
  116. # again, this time to an empty string. This will cause the logfile to be
  117. # missing, which will be the prove for us that the custom option is indeed used.
  118. set(CTEST_EXTRA_CONFIG "set(CTEST_MEMORYCHECK_COMMAND_OPTIONS \"--log-file=\")")
  119. gen_mc_test(DummyValgrindCustomOptions "\${PSEUDO_VALGRIND}")
  120. unset(CTEST_EXTRA_CONFIG)
  121. gen_mc_test(NotExist "\${CTEST_BINARY_DIRECTORY}/no-memcheck-exe")
  122. gen_mc_test(Unknown "${CMAKE_COMMAND}")
  123. string(REPLACE "\\" "\\\\" CMAKE_COMMAND_ESCAPED "${CMAKE_COMMAND}")
  124. string(REPLACE "(" "\\(" CMAKE_COMMAND_ESCAPED "${CMAKE_COMMAND_ESCAPED}")
  125. string(REPLACE ")" "\\)" CMAKE_COMMAND_ESCAPED "${CMAKE_COMMAND_ESCAPED}")
  126. string(REPLACE "+" "\\+" CMAKE_COMMAND_ESCAPED "${CMAKE_COMMAND_ESCAPED}")
  127. set_tests_properties(CTestTestMemcheckUnknown PROPERTIES
  128. PASS_REGULAR_EXPRESSION "Do not understand memory checker: ${CMAKE_COMMAND_ESCAPED}\n(.*\n)?Error in read script: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/Unknown/test.cmake\n")
  129. set_tests_properties(CTestTestMemcheckNotExist PROPERTIES
  130. PASS_REGULAR_EXPRESSION "Memory checker \\(MemoryCheckCommand\\) not set, or cannot find the specified program.")
  131. # It is a valid result if valgrind does not output any files (can e.g. happen
  132. # if you have not compiled in debug mode), so these tests will not fail.
  133. set_tests_properties(CTestTestMemcheckDummyValgrind
  134. CTestTestMemcheckDummyValgrindPrePost
  135. CTestTestMemcheckDummyPurify
  136. PROPERTIES
  137. PASS_REGULAR_EXPRESSION "${ctest_and_tool_outputs}$")
  138. foreach (_pp Pre Post)
  139. string(TOLOWER ${_pp} _pp_lower)
  140. set_tests_properties(CTestTestMemcheckDummyValgrindFail${_pp}
  141. PROPERTIES
  142. PASS_REGULAR_EXPRESSION "\nProblem running command: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}[^\n]*fail[^\n]*\n(.*\n)?Problem executing ${_pp_lower}-memcheck command\\(s\\\).\n(.*\n)?Error in read script: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindFail${_pp}/test.cmake\n")
  143. endforeach ()
  144. set_tests_properties(CTestTestMemcheckDummyValgrindIgnoreMemcheck
  145. PROPERTIES
  146. PASS_REGULAR_EXPRESSION "\n2/2 Test #2: RunCMakeAgain .*${ctest_and_tool_outputs}$")
  147. set_tests_properties(CTestTestMemcheckDummyBC PROPERTIES
  148. PASS_REGULAR_EXPRESSION "\n1/1 MemCheck #1: RunCMake \\.+ Passed +[0-9]+.[0-9]+ sec\n\n100% tests passed, 0 tests failed out of 1\n(.*\n)?Error parsing XML in stream at line 1: no element found\n")
  149. set_tests_properties(CTestTestMemcheckDummyValgrindInvalidSupFile PROPERTIES
  150. PASS_REGULAR_EXPRESSION "\nCannot find memory checker suppression file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/does-not-exist\n")
  151. set_tests_properties(CTestTestMemcheckDummyValgrindCustomOptions PROPERTIES
  152. PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindCustomOptions/Testing/Temporary/MemoryChecker.1.log\n(.*\n)?Error in read script: ${CMAKE_CURRENT_BINARY_DIR}/DummyValgrindCustomOptions/test.cmake\n")
  153. set_tests_properties(CTestTestMemcheckDummyValgrindTwoTargets PROPERTIES
  154. PASS_REGULAR_EXPRESSION
  155. "\nMemory check project ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindTwoTargets\n.*\n *Start 1: RunCMake\n(.*\n)?Memory check command: .* \"--log-file=${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindTwoTargets/Testing/Temporary/MemoryChecker.1.log\" \"-q\".*\n *Start 2: RunCMakeAgain\n(.*\n)?Memory check command: .* \"--log-file=${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindTwoTargets/Testing/Temporary/MemoryChecker.2.log\" \"-q\".*\n")