1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
|
# This file defines the two macros below for easily adding groups of unit tests and scripts,
# as well as sets up unit testing and defines several cache options used to control how
# tests and scripts are built and run.
###############################################################################
# Macro:
#
# gtsamAddTestsGlob(groupName globPatterns excludedFiles linkLibraries)
#
# Add a group of unit tests. A list of unit test .cpp files or glob patterns specifies the
# tests to create. Tests are assigned into a group name so they can easily by run
# independently with a make target. Running 'make check' builds and runs all tests.
#
# Usage example:
# gtsamAddTestsGlob(basic "test*.cpp" "testBroken.cpp" "gtsam;GeographicLib")
#
# Arguments:
# groupName: A name that will allow this group of tests to be run independently, e.g.
# 'basic' causes a 'check.basic' target to be created to run this test
# group.
# globPatterns: The list of files or glob patterns from which to create unit tests, with
# one test created for each cpp file. e.g. "test*.cpp", or
# "testA*.cpp;testB*.cpp;testOneThing.cpp".
# excludedFiles: A list of files or globs to exclude, e.g. "testC*.cpp;testBroken.cpp".
# Pass an empty string "" if nothing needs to be excluded.
# linkLibraries: The list of libraries to link to in addition to CppUnitLite.
macro(gtsamAddTestsGlob groupName globPatterns excludedFiles linkLibraries)
gtsamAddTestsGlob_impl("${groupName}" "${globPatterns}" "${excludedFiles}" "${linkLibraries}")
endmacro()
###############################################################################
# Macro:
#
# gtsamAddExamplesGlob(globPatterns excludedFiles linkLibraries)
#
# Add scripts that will serve as examples of how to use the library. A list of files or
# glob patterns is specified, and one executable will be created for each matching .cpp
# file. These executables will not be installed. They are built with 'make all' if
# GTSAM_BUILD_EXAMPLES_ALWAYS is enabled. They may also be built with 'make examples'.
#
# Usage example:
# gtsamAddExamplesGlob("*.cpp" "BrokenExample.cpp" "gtsam;GeographicLib")
#
# Arguments:
# globPatterns: The list of files or glob patterns from which to create examples, with
# one program created for each cpp file. e.g. "*.cpp", or
# "A*.cpp;B*.cpp;MyExample.cpp".
# excludedFiles: A list of files or globs to exclude, e.g. "C*.cpp;BrokenExample.cpp". Pass
# an empty string "" if nothing needs to be excluded.
# linkLibraries: The list of libraries to link to.
macro(gtsamAddExamplesGlob globPatterns excludedFiles linkLibraries)
gtsamAddExesGlob_impl("${globPatterns}" "${excludedFiles}" "${linkLibraries}" "examples" ${GTSAM_BUILD_EXAMPLES_ALWAYS})
endmacro()
###############################################################################
# Macro:
#
# gtsamAddTimingGlob(globPatterns excludedFiles linkLibraries)
#
# Add scripts that time aspects of the library. A list of files or
# glob patterns is specified, and one executable will be created for each matching .cpp
# file. These executables will not be installed. They are not built with 'make all',
# but they may be built with 'make timing'.
#
# Usage example:
# gtsamAddTimingGlob("*.cpp" "DisabledTimingScript.cpp" "gtsam;GeographicLib")
#
# Arguments:
# globPatterns: The list of files or glob patterns from which to create programs, with
# one program created for each cpp file. e.g. "*.cpp", or
# "A*.cpp;B*.cpp;MyExample.cpp".
# excludedFiles: A list of files or globs to exclude, e.g. "C*.cpp;BrokenExample.cpp". Pass
# an empty string "" if nothing needs to be excluded.
# linkLibraries: The list of libraries to link to.
macro(gtsamAddTimingGlob globPatterns excludedFiles linkLibraries)
gtsamAddExesGlob_impl("${globPatterns}" "${excludedFiles}" "${linkLibraries}" "timing" ${GTSAM_BUILD_TIMING_ALWAYS})
endmacro()
# Implementation follows:
# Build macros for using tests
enable_testing()
option(GTSAM_BUILD_TESTS "Enable/Disable building of tests" ON)
option(GTSAM_BUILD_EXAMPLES_ALWAYS "Build examples with 'make all' (build with 'make examples' if not)" ON)
option(GTSAM_BUILD_TIMING_ALWAYS "Build timing scripts with 'make all' (build with 'make timing' if not" OFF)
# Add option for combining unit tests
if(MSVC OR XCODE_VERSION)
option(GTSAM_SINGLE_TEST_EXE "Combine unit tests into single executable (faster compile)" ON)
else()
option(GTSAM_SINGLE_TEST_EXE "Combine unit tests into single executable (faster compile)" OFF)
endif()
mark_as_advanced(GTSAM_SINGLE_TEST_EXE)
# Enable make check (http://www.cmake.org/Wiki/CMakeEmulateMakeCheck)
if(GTSAM_BUILD_TESTS)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> --output-on-failure)
# Also add alternative checks using valgrind.
# We don't look for valgrind being installed in the system, since these
# targets are not invoked unless directly instructed by the user.
if (UNIX)
# Run all tests using valgrind:
add_custom_target(check_valgrind)
endif()
# Add target to build tests without running
add_custom_target(all.tests)
endif()
# Add examples target
add_custom_target(examples)
# Add timing target
add_custom_target(timing)
# Implementations of this file's macros:
macro(gtsamAddTestsGlob_impl groupName globPatterns excludedFiles linkLibraries)
if(GTSAM_BUILD_TESTS)
# Add group target if it doesn't already exist
if(NOT TARGET check.${groupName})
add_custom_target(check.${groupName} COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> --output-on-failure)
set_property(TARGET check.${groupName} PROPERTY FOLDER "Unit tests")
endif()
# Get all script files
file(GLOB script_files ${globPatterns})
# Remove excluded scripts from the list
if(NOT "${excludedFiles}" STREQUAL "")
file(GLOB excludedFilePaths ${excludedFiles})
if("${excludedFilePaths}" STREQUAL "")
message(WARNING "The pattern '${excludedFiles}' for excluding tests from group ${groupName} did not match any files")
else()
list(REMOVE_ITEM script_files ${excludedFilePaths})
endif()
endif()
# Separate into source files and headers (allows for adding headers to show up in
# MSVC and Xcode projects).
set(script_srcs "")
set(script_headers "")
foreach(script_file IN ITEMS ${script_files})
get_filename_component(script_ext ${script_file} EXT)
if(script_ext MATCHES "(h|H)")
list(APPEND script_headers ${script_file})
else()
list(APPEND script_srcs ${script_file})
endif()
endforeach()
# Don't put test files in folders in MSVC and Xcode because they're already grouped
source_group("" FILES ${script_srcs} ${script_headers})
if(NOT GTSAM_SINGLE_TEST_EXE)
# Default for Makefiles - each test in its own executable
foreach(script_src IN ITEMS ${script_srcs})
# Get test base name
get_filename_component(script_name ${script_src} NAME_WE)
# Add executable
add_executable(${script_name} ${script_src} ${script_headers})
target_link_libraries(${script_name} CppUnitLite ${linkLibraries})
# Apply user build flags from CMake cache variables:
gtsam_apply_build_flags(${script_name})
# Add target dependencies
add_test(NAME ${script_name} COMMAND ${script_name})
set_tests_properties(${script_name} PROPERTIES ENVIRONMENT
GTSAM_SOURCE_TREE_DATASET_DIR=${CMAKE_SOURCE_DIR}/examples/Data)
add_dependencies(check.${groupName} ${script_name})
add_dependencies(check ${script_name})
add_dependencies(all.tests ${script_name})
if(NOT MSVC AND NOT XCODE_VERSION)
# Regular test run:
add_custom_target(${script_name}.run
COMMAND ${EXECUTABLE_OUTPUT_PATH}${script_name}
DEPENDS ${script_name}
)
# Run with valgrind:
set(GENERATED_EXE "$<TARGET_FILE:${script_name}>")
add_custom_target(${script_name}.valgrind
COMMAND "valgrind" "--error-exitcode=1" ${GENERATED_EXE}
DEPENDS ${script_name}
)
add_dependencies(check_valgrind ${script_name}.valgrind)
endif()
# Add TOPSRCDIR
set_property(SOURCE ${script_src} APPEND PROPERTY COMPILE_DEFINITIONS "TOPSRCDIR=\"${GTSAM_SOURCE_DIR}\"")
# Exclude from 'make all' and 'make install'
set_target_properties(${script_name} PROPERTIES EXCLUDE_FROM_ALL ON)
# Configure target folder (for MSVC and Xcode)
set_property(TARGET ${script_name} PROPERTY FOLDER "Unit tests/${groupName}")
endforeach()
else()
#skip folders which don't have any tests
if(NOT script_srcs)
return()
endif()
# Default on MSVC and XCode - combine test group into a single exectuable
set(target_name check_${groupName}_program)
# Add executable
add_executable(${target_name} "${script_srcs}" ${script_headers})
target_link_libraries(${target_name} CppUnitLite ${linkLibraries})
# Apply user build flags from CMake cache variables:
gtsam_apply_build_flags(${target_name})
set_property(TARGET check_${groupName}_program PROPERTY FOLDER "Unit tests")
# Only have a main function in one script - use preprocessor
set(rest_script_srcs ${script_srcs})
list(REMOVE_AT rest_script_srcs 0)
set_property(SOURCE ${rest_script_srcs} APPEND PROPERTY COMPILE_DEFINITIONS "main=inline no_main")
# Add target dependencies
add_test(NAME ${target_name} COMMAND ${target_name})
set_tests_properties(${target_name} PROPERTIES ENVIRONMENT
GTSAM_SOURCE_TREE_DATASET_DIR=${CMAKE_SOURCE_DIR}/examples/Data)
add_dependencies(check.${groupName} ${target_name})
add_dependencies(check ${target_name})
if(NOT XCODE_VERSION)
add_dependencies(all.tests ${target_name})
endif()
# Add TOPSRCDIR
set_property(SOURCE ${script_srcs} APPEND PROPERTY COMPILE_DEFINITIONS "TOPSRCDIR=\"${GTSAM_SOURCE_DIR}\"")
# Exclude from 'make all' and 'make install'
set_target_properties(${target_name} PROPERTIES EXCLUDE_FROM_ALL ON)
# Configure target folder (for MSVC and Xcode)
set_property(TARGET ${script_name} PROPERTY FOLDER "Unit tests")
endif()
endif()
endmacro()
macro(gtsamAddExesGlob_impl globPatterns excludedFiles linkLibraries groupName buildWithAll)
# Get all script files
file(GLOB script_files ${globPatterns})
# Remove excluded scripts from the list
if(NOT "${excludedFiles}" STREQUAL "")
file(GLOB excludedFilePaths ${excludedFiles})
if("${excludedFilePaths}" STREQUAL "")
message(WARNING "The script exclusion pattern '${excludedFiles}' did not match any files")
else()
list(REMOVE_ITEM script_files ${excludedFilePaths})
endif()
endif()
# Separate into source files and headers (allows for adding headers to show up in
# MSVC and Xcode projects).
set(script_srcs "")
set(script_headers "")
foreach(script_file IN ITEMS ${script_files})
get_filename_component(script_ext ${script_file} EXT)
if(script_ext MATCHES "(h|H)")
list(APPEND script_headers ${script_file})
else()
list(APPEND script_srcs ${script_file})
endif()
endforeach()
# Don't put test files in folders in MSVC and Xcode because they're already grouped
source_group("" FILES ${script_srcs} ${script_headers})
# Create executables
foreach(script_src IN ITEMS ${script_srcs})
# Get script base name
get_filename_component(script_name ${script_src} NAME_WE)
# Add executable
add_executable(${script_name} ${script_src} ${script_headers})
target_link_libraries(${script_name} ${linkLibraries})
# Apply user build flags from CMake cache variables:
gtsam_apply_build_flags(${script_name})
# Add target dependencies
add_dependencies(${groupName} ${script_name})
if(NOT MSVC AND NOT XCODE_VERSION)
add_custom_target(${script_name}.run ${EXECUTABLE_OUTPUT_PATH}${script_name} DEPENDS ${script_name})
endif()
# Add TOPSRCDIR
set_property(SOURCE ${script_src} APPEND PROPERTY COMPILE_DEFINITIONS "TOPSRCDIR=\"${GTSAM_SOURCE_DIR}\"")
# Exclude from all or not - note weird variable assignment because we're in a macro
set(buildWithAll_on ${buildWithAll})
if(NOT buildWithAll_on)
# Exclude from 'make all' and 'make install'
set_target_properties("${script_name}" PROPERTIES EXCLUDE_FROM_ALL ON)
endif()
# Configure target folder (for MSVC and Xcode)
set_property(TARGET ${script_name} PROPERTY FOLDER "${groupName}")
endforeach()
endmacro()
|