PageRenderTime 750ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/cmake/LLAddBuildTest.cmake

https://bitbucket.org/lindenlab/viewer-beta/
CMake | 272 lines | 177 code | 25 blank | 70 comment | 5 complexity | 59482bf98124dde5c5cc80a717247cb5 MD5 | raw file
Possible License(s): LGPL-2.1
  1. # -*- cmake -*-
  2. include(LLTestCommand)
  3. include(GoogleMock)
  4. include(Tut)
  5. MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
  6. # Given a project name and a list of sourcefiles (with optional properties on each),
  7. # add targets to build and run the tests specified.
  8. # ASSUMPTIONS:
  9. # * this macro is being executed in the project file that is passed in
  10. # * current working SOURCE dir is that project dir
  11. # * there is a subfolder tests/ with test code corresponding to the filenames passed in
  12. # * properties for each sourcefile passed in indicate what libs to link that file with (MAKE NO ASSUMPTIONS ASIDE FROM TUT)
  13. #
  14. # More info and examples at: https://wiki.secondlife.com/wiki/How_to_add_unit_tests_to_indra_code
  15. #
  16. # WARNING: do NOT modify this code without working with poppy -
  17. # there is another branch that will conflict heavily with any changes here.
  18. INCLUDE(GoogleMock)
  19. IF(LL_TEST_VERBOSE)
  20. MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} sources: ${sources}")
  21. ENDIF(LL_TEST_VERBOSE)
  22. # Start with the header and project-wide setup before making targets
  23. #project(UNITTEST_PROJECT_${project})
  24. # Setup includes, paths, etc
  25. SET(alltest_SOURCE_FILES
  26. ${CMAKE_SOURCE_DIR}/test/test.cpp
  27. ${CMAKE_SOURCE_DIR}/test/lltut.cpp
  28. )
  29. SET(alltest_DEP_TARGETS
  30. # needed by the test harness itself
  31. ${APRUTIL_LIBRARIES}
  32. ${APR_LIBRARIES}
  33. llcommon
  34. )
  35. IF(NOT "${project}" STREQUAL "llmath")
  36. # add llmath as a dep unless the tested module *is* llmath!
  37. LIST(APPEND alltest_DEP_TARGETS
  38. llmath
  39. )
  40. ENDIF(NOT "${project}" STREQUAL "llmath")
  41. SET(alltest_INCLUDE_DIRS
  42. ${LLMATH_INCLUDE_DIRS}
  43. ${LLCOMMON_INCLUDE_DIRS}
  44. ${LIBS_OPEN_DIR}/test
  45. ${GOOGLEMOCK_INCLUDE_DIRS}
  46. )
  47. SET(alltest_LIBRARIES
  48. ${GOOGLEMOCK_LIBRARIES}
  49. ${PTHREAD_LIBRARY}
  50. ${WINDOWS_LIBRARIES}
  51. )
  52. # Headers, for convenience in targets.
  53. SET(alltest_HEADER_FILES
  54. ${CMAKE_SOURCE_DIR}/test/test.h
  55. )
  56. # start the source test executable definitions
  57. SET(${project}_TEST_OUTPUT "")
  58. FOREACH (source ${sources})
  59. STRING( REGEX REPLACE "(.*)\\.[^.]+$" "\\1" name ${source} )
  60. STRING( REGEX REPLACE ".*\\.([^.]+)$" "\\1" extension ${source} )
  61. IF(LL_TEST_VERBOSE)
  62. MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} individual source: ${source} (${name}.${extension})")
  63. ENDIF(LL_TEST_VERBOSE)
  64. #
  65. # Per-codefile additional / external source, header, and include dir property extraction
  66. #
  67. # Source
  68. GET_SOURCE_FILE_PROPERTY(${name}_test_additional_SOURCE_FILES ${source} LL_TEST_ADDITIONAL_SOURCE_FILES)
  69. IF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND)
  70. SET(${name}_test_additional_SOURCE_FILES "")
  71. ENDIF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND)
  72. SET(${name}_test_SOURCE_FILES ${source} tests/${name}_test.${extension} ${alltest_SOURCE_FILES} ${${name}_test_additional_SOURCE_FILES} )
  73. IF(LL_TEST_VERBOSE)
  74. MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_SOURCE_FILES ${${name}_test_SOURCE_FILES}")
  75. ENDIF(LL_TEST_VERBOSE)
  76. # Headers
  77. GET_SOURCE_FILE_PROPERTY(${name}_test_additional_HEADER_FILES ${source} LL_TEST_ADDITIONAL_HEADER_FILES)
  78. IF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND)
  79. SET(${name}_test_additional_HEADER_FILES "")
  80. ENDIF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND)
  81. SET(${name}_test_HEADER_FILES ${name}.h ${${name}_test_additional_HEADER_FILES})
  82. set_source_files_properties(${${name}_test_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE)
  83. LIST(APPEND ${name}_test_SOURCE_FILES ${${name}_test_HEADER_FILES})
  84. IF(LL_TEST_VERBOSE)
  85. MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_HEADER_FILES ${${name}_test_HEADER_FILES}")
  86. ENDIF(LL_TEST_VERBOSE)
  87. # Include dirs
  88. GET_SOURCE_FILE_PROPERTY(${name}_test_additional_INCLUDE_DIRS ${source} LL_TEST_ADDITIONAL_INCLUDE_DIRS)
  89. IF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND)
  90. SET(${name}_test_additional_INCLUDE_DIRS "")
  91. ENDIF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND)
  92. INCLUDE_DIRECTORIES(${alltest_INCLUDE_DIRS} ${${name}_test_additional_INCLUDE_DIRS} )
  93. IF(LL_TEST_VERBOSE)
  94. MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_INCLUDE_DIRS ${${name}_test_additional_INCLUDE_DIRS}")
  95. ENDIF(LL_TEST_VERBOSE)
  96. # Setup target
  97. ADD_EXECUTABLE(PROJECT_${project}_TEST_${name} ${${name}_test_SOURCE_FILES})
  98. SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}")
  99. #
  100. # Per-codefile additional / external project dep and lib dep property extraction
  101. #
  102. # WARNING: it's REALLY IMPORTANT to not mix these. I guarantee it will not work in the future. + poppy 2009-04-19
  103. # Projects
  104. GET_SOURCE_FILE_PROPERTY(${name}_test_additional_PROJECTS ${source} LL_TEST_ADDITIONAL_PROJECTS)
  105. IF(${name}_test_additional_PROJECTS MATCHES NOTFOUND)
  106. SET(${name}_test_additional_PROJECTS "")
  107. ENDIF(${name}_test_additional_PROJECTS MATCHES NOTFOUND)
  108. # Libraries
  109. GET_SOURCE_FILE_PROPERTY(${name}_test_additional_LIBRARIES ${source} LL_TEST_ADDITIONAL_LIBRARIES)
  110. IF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND)
  111. SET(${name}_test_additional_LIBRARIES "")
  112. ENDIF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND)
  113. IF(LL_TEST_VERBOSE)
  114. MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_PROJECTS ${${name}_test_additional_PROJECTS}")
  115. MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_LIBRARIES ${${name}_test_additional_LIBRARIES}")
  116. ENDIF(LL_TEST_VERBOSE)
  117. # Add to project
  118. TARGET_LINK_LIBRARIES(PROJECT_${project}_TEST_${name} ${alltest_LIBRARIES} ${alltest_DEP_TARGETS} ${${name}_test_additional_PROJECTS} ${${name}_test_additional_LIBRARIES} )
  119. # Compile-time Definitions
  120. GET_SOURCE_FILE_PROPERTY(${name}_test_additional_CFLAGS ${source} LL_TEST_ADDITIONAL_CFLAGS)
  121. IF(NOT ${name}_test_additional_CFLAGS MATCHES NOTFOUND)
  122. SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES COMPILE_FLAGS ${${name}_test_additional_CFLAGS} )
  123. IF(LL_TEST_VERBOSE)
  124. MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_CFLAGS ${${name}_test_additional_CFLAGS}")
  125. ENDIF(LL_TEST_VERBOSE)
  126. ENDIF(NOT ${name}_test_additional_CFLAGS MATCHES NOTFOUND)
  127. #
  128. # Setup test targets
  129. #
  130. GET_TARGET_PROPERTY(TEST_EXE PROJECT_${project}_TEST_${name} LOCATION)
  131. SET(TEST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/PROJECT_${project}_TEST_${name}_ok.txt)
  132. SET(TEST_CMD ${TEST_EXE} --touch=${TEST_OUTPUT} --sourcedir=${CMAKE_CURRENT_SOURCE_DIR})
  133. # daveh - what configuration does this use? Debug? it's cmake-time, not build time. + poppy 2009-04-19
  134. IF(LL_TEST_VERBOSE)
  135. MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_cmd = ${TEST_CMD}")
  136. ENDIF(LL_TEST_VERBOSE)
  137. SET_TEST_PATH(LD_LIBRARY_PATH)
  138. LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${TEST_CMD})
  139. IF(LL_TEST_VERBOSE)
  140. MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_script = ${TEST_SCRIPT_CMD}")
  141. ENDIF(LL_TEST_VERBOSE)
  142. # Add test
  143. ADD_CUSTOM_COMMAND(
  144. OUTPUT ${TEST_OUTPUT}
  145. COMMAND ${TEST_SCRIPT_CMD}
  146. DEPENDS PROJECT_${project}_TEST_${name}
  147. WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
  148. )
  149. # Why not add custom target and add POST_BUILD command?
  150. # Slightly less uncertain behavior
  151. # (OUTPUT commands run non-deterministically AFAIK) + poppy 2009-04-19
  152. # > I did not use a post build step as I could not make it notify of a
  153. # > failure after the first time you build and fail a test. - daveh 2009-04-20
  154. LIST(APPEND ${project}_TEST_OUTPUT ${TEST_OUTPUT})
  155. ENDFOREACH (source)
  156. # Add the test runner target per-project
  157. # (replaces old _test_ok targets all over the place)
  158. ADD_CUSTOM_TARGET(${project}_tests ALL DEPENDS ${${project}_TEST_OUTPUT})
  159. ADD_DEPENDENCIES(${project} ${project}_tests)
  160. ENDMACRO(LL_ADD_PROJECT_UNIT_TESTS)
  161. FUNCTION(LL_ADD_INTEGRATION_TEST
  162. testname
  163. additional_source_files
  164. library_dependencies
  165. # variable args
  166. )
  167. if(TEST_DEBUG)
  168. message(STATUS "Adding INTEGRATION_TEST_${testname} - debug output is on")
  169. endif(TEST_DEBUG)
  170. SET(source_files
  171. tests/${testname}_test.cpp
  172. ${CMAKE_SOURCE_DIR}/test/test.cpp
  173. ${CMAKE_SOURCE_DIR}/test/lltut.cpp
  174. ${additional_source_files}
  175. )
  176. SET(libraries
  177. ${library_dependencies}
  178. ${GOOGLEMOCK_LIBRARIES}
  179. ${PTHREAD_LIBRARY}
  180. )
  181. # Add test executable build target
  182. if(TEST_DEBUG)
  183. message(STATUS "ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})")
  184. endif(TEST_DEBUG)
  185. ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})
  186. SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}")
  187. if(STANDALONE)
  188. SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES COMPILE_FLAGS -I"${TUT_INCLUDE_DIR}")
  189. endif(STANDALONE)
  190. # Add link deps to the executable
  191. if(TEST_DEBUG)
  192. message(STATUS "TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})")
  193. endif(TEST_DEBUG)
  194. TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})
  195. # Create the test running command
  196. SET(test_command ${ARGN})
  197. GET_TARGET_PROPERTY(TEST_EXE INTEGRATION_TEST_${testname} LOCATION)
  198. LIST(FIND test_command "{}" test_exe_pos)
  199. IF(test_exe_pos LESS 0)
  200. # The {} marker means "the full pathname of the test executable."
  201. # test_exe_pos -1 means we didn't find it -- so append the test executable
  202. # name to $ARGN, the variable part of the arg list. This is convenient
  203. # shorthand for both straightforward execution of the test program (empty
  204. # $ARGN) and for running a "wrapper" program of some kind accepting the
  205. # pathname of the test program as the last of its args. You need specify
  206. # {} only if the test program's pathname isn't the last argument in the
  207. # desired command line.
  208. LIST(APPEND test_command "${TEST_EXE}")
  209. ELSE (test_exe_pos LESS 0)
  210. # Found {} marker at test_exe_pos. Remove the {}...
  211. LIST(REMOVE_AT test_command test_exe_pos)
  212. # ...and replace it with the actual name of the test executable.
  213. LIST(INSERT test_command test_exe_pos "${TEST_EXE}")
  214. ENDIF (test_exe_pos LESS 0)
  215. SET_TEST_PATH(LD_LIBRARY_PATH)
  216. LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${test_command})
  217. if(TEST_DEBUG)
  218. message(STATUS "TEST_SCRIPT_CMD: ${TEST_SCRIPT_CMD}")
  219. endif(TEST_DEBUG)
  220. ADD_CUSTOM_COMMAND(
  221. TARGET INTEGRATION_TEST_${testname}
  222. POST_BUILD
  223. COMMAND ${TEST_SCRIPT_CMD}
  224. )
  225. # Use CTEST? Not sure how to yet...
  226. # ADD_TEST(INTEGRATION_TEST_RUNNER_${testname} ${TEST_SCRIPT_CMD})
  227. ENDFUNCTION(LL_ADD_INTEGRATION_TEST)
  228. MACRO(SET_TEST_PATH LISTVAR)
  229. IF(WINDOWS)
  230. # We typically build/package only Release variants of third-party
  231. # libraries, so append the Release staging dir in case the library being
  232. # sought doesn't have a debug variant.
  233. set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR} ${SHARED_LIB_STAGING_DIR}/Release)
  234. ELSEIF(DARWIN)
  235. # We typically build/package only Release variants of third-party
  236. # libraries, so append the Release staging dir in case the library being
  237. # sought doesn't have a debug variant.
  238. set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/Resources ${SHARED_LIB_STAGING_DIR}/Release/Resources /usr/lib)
  239. ELSE(WINDOWS)
  240. # Linux uses a single staging directory anyway.
  241. IF (STANDALONE)
  242. set(${LISTVAR} ${CMAKE_BINARY_DIR}/llcommon /usr/lib /usr/local/lib)
  243. ELSE (STANDALONE)
  244. set(${LISTVAR} ${SHARED_LIB_STAGING_DIR} /usr/lib)
  245. ENDIF (STANDALONE)
  246. ENDIF(WINDOWS)
  247. ENDMACRO(SET_TEST_PATH)