PageRenderTime 29ms CodeModel.GetById 2ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 1ms

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