363 lines
14 KiB
CMake
363 lines
14 KiB
CMake
# - Build satellites that are dependent of main library
|
|
|
|
option(ADD_DISABLED_CTESTS "Add the tests which are disabled due to failed preconditions to the ctest output (this makes ctest return an error if such a test is present)" ON)
|
|
mark_as_advanced(ADD_DISABLED_CTESTS)
|
|
|
|
#
|
|
# Enumerate all source code in a "satellite" directory such as tests/,
|
|
# compile each of them and optionally set them as a test for CTest to
|
|
# run. They will be linked to the main library created by the project.
|
|
#
|
|
# The following suffices must be defined for the opm prefix passed as
|
|
# parameter:
|
|
#
|
|
# _LINKER_FLAGS Necessary flags to link with this library
|
|
# _TARGET CMake target which creates the library
|
|
# _LIBRARIES Other dependencies that must also be linked
|
|
|
|
# Synopsis:
|
|
# opm_compile_satellites (opm satellite excl_all test_regexp)
|
|
#
|
|
# Parameters:
|
|
# opm Prefix of the variable which contain information
|
|
# about the library these satellites depends on, e.g.
|
|
# pass "opm-core" if opm-core_TARGET is the name of
|
|
# the target the builds this library. Variables with
|
|
# suffixes _TARGET and _LIBRARIES must exist.
|
|
#
|
|
# satellite Prefix of variable which contain the names of the
|
|
# files, e.g. pass "tests" if the files are in the
|
|
# variable tests_SOURCES. Variables with suffixes
|
|
# _DATAFILES, _SOURCES and _DIR should exist. This
|
|
# name is also used as name of the target that builds
|
|
# all these files.
|
|
#
|
|
# excl_all EXCLUDE_FROM_ALL if these targets should not be built by
|
|
# default, otherwise empty string.
|
|
#
|
|
# test_regexp Regular expression which picks the name of a test
|
|
# out of the filename, or blank if no test should be
|
|
# setup.
|
|
#
|
|
# Example:
|
|
# opm_compile_satellites (opm-core test "" "^test_([^/]*)$")
|
|
#
|
|
macro (opm_compile_satellites opm satellite excl_all test_regexp)
|
|
# if we are going to build the tests always, then make sure that
|
|
# the datafiles are present too
|
|
if (NOT (${excl_all} MATCHES "EXCLUDE_FROM_ALL"))
|
|
set (_incl_all "ALL")
|
|
else (NOT (${excl_all} MATCHES "EXCLUDE_FROM_ALL"))
|
|
set (_incl_all "")
|
|
endif (NOT (${excl_all} MATCHES "EXCLUDE_FROM_ALL"))
|
|
|
|
# if a set of datafiles has been setup, pull those in
|
|
add_custom_target (${satellite} ${_incl_all})
|
|
if (${satellite}_DATAFILES)
|
|
add_dependencies (${satellite} ${${satellite}_DATAFILES})
|
|
endif (${satellite}_DATAFILES)
|
|
|
|
# compile each of these separately
|
|
foreach (_sat_FILE IN LISTS ${satellite}_SOURCES)
|
|
get_filename_component (_sat_NAME "${_sat_FILE}" NAME_WE)
|
|
add_executable (${_sat_NAME} ${excl_all} ${_sat_FILE})
|
|
add_dependencies (${satellite} ${_sat_NAME})
|
|
set_target_properties (${_sat_NAME} PROPERTIES
|
|
LINK_FLAGS "${${opm}_LINKER_FLAGS_STR}"
|
|
)
|
|
# are we building a test? luckily, the testing framework doesn't
|
|
# require anything else, so we don't have to figure out where it
|
|
# should go in the library list
|
|
if (NOT "${test_regexp}" STREQUAL "")
|
|
set (_test_lib "${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}")
|
|
else (NOT "${test_regexp}" STREQUAL "")
|
|
set (_test_lib "")
|
|
add_static_analysis_tests(_sat_FILE ${opm}_INCLUDE_DIRS)
|
|
endif (NOT "${test_regexp}" STREQUAL "")
|
|
target_link_libraries (${_sat_NAME} ${${opm}_TARGET} ${${opm}_LIBRARIES} ${_test_lib})
|
|
if (STRIP_DEBUGGING_SYMBOLS)
|
|
strip_debug_symbols (${_sat_NAME} _sat_DEBUG)
|
|
list (APPEND ${satellite}_DEBUG ${_sat_DEBUG})
|
|
endif()
|
|
|
|
# variable with regular expression doubles as a flag for
|
|
# whether tests should be setup or not
|
|
if (NOT "${test_regexp}" STREQUAL "")
|
|
foreach (_regexp IN ITEMS ${test_regexp})
|
|
if ("${_sat_NAME}" MATCHES "${_regexp}")
|
|
string (REGEX REPLACE "${_regexp}" "\\1" _sat_FANCY "${_sat_NAME}")
|
|
endif ("${_sat_NAME}" MATCHES "${_regexp}")
|
|
endforeach (_regexp)
|
|
get_target_property (_sat_LOC ${_sat_NAME} LOCATION)
|
|
# Run tests through mpi-run. Ubuntu 14.04 provided mpi libs will crash
|
|
# in the MPI_Finalize() call otherwise.
|
|
if(MPI_FOUND)
|
|
set(_sat_LOC ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} 1 ${_sat_LOC})
|
|
endif()
|
|
if (CMAKE_VERSION VERSION_LESS "2.8.4")
|
|
add_test (
|
|
NAME ${_sat_FANCY}
|
|
COMMAND ${CMAKE_COMMAND} -E chdir "${PROJECT_BINARY_DIR}/${${satellite}_DIR}" ${_sat_LOC}
|
|
)
|
|
else (CMAKE_VERSION VERSION_LESS "2.8.4")
|
|
add_test (${_sat_FANCY} ${_sat_LOC})
|
|
# run the test in the directory where the data files are
|
|
set_tests_properties (${_sat_FANCY} PROPERTIES
|
|
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/${${satellite}_DIR}
|
|
)
|
|
endif (CMAKE_VERSION VERSION_LESS "2.8.4")
|
|
if(NOT TARGET test-suite)
|
|
add_custom_target(test-suite)
|
|
endif()
|
|
add_dependencies(test-suite "${_sat_NAME}")
|
|
endif(NOT "${test_regexp}" STREQUAL "")
|
|
|
|
# if this program on the list of files that should be distributed?
|
|
# we check by the name of the source file
|
|
list (FIND ${satellite}_SOURCES_DIST "${_sat_FILE}" _is_util)
|
|
if (NOT (_is_util EQUAL -1))
|
|
install (TARGETS ${_sat_NAME} RUNTIME
|
|
DESTINATION bin${${opm}_VER_DIR}/
|
|
)
|
|
endif (NOT (_is_util EQUAL -1))
|
|
endforeach (_sat_FILE)
|
|
endmacro (opm_compile_satellites opm prefix)
|
|
|
|
# Synopsis:
|
|
# opm_data (satellite target dirname files)
|
|
#
|
|
# provides these output variables:
|
|
#
|
|
# ${satellite}_INPUT_FILES List of all files that are copied
|
|
# ${satellite}_DATAFILES Name of target which copies these files
|
|
#
|
|
# Example:
|
|
#
|
|
# opm_data (tests datafiles "tests/")
|
|
#
|
|
macro (opm_data satellite target dirname)
|
|
# even if there are no datafiles, create the directory so the
|
|
# satellite programs have a homedir to run in
|
|
execute_process (
|
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${dirname}
|
|
)
|
|
|
|
# if ever huge test datafiles are necessary, then change this
|
|
# into "create_symlink" (on UNIX only, apparently)
|
|
set (make_avail "copy")
|
|
|
|
# provide datafiles as inputs for the tests, by copying them
|
|
# to a tests/ directory in the output tree (if different)
|
|
set (${satellite}_INPUT_FILES)
|
|
if (NOT PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
|
|
foreach (input_datafile IN LISTS ${satellite}_DATA)
|
|
file (RELATIVE_PATH rel_datafile "${PROJECT_SOURCE_DIR}" ${input_datafile})
|
|
set (output_datafile "${PROJECT_BINARY_DIR}/${rel_datafile}")
|
|
add_custom_command (
|
|
OUTPUT ${output_datafile}
|
|
COMMAND ${CMAKE_COMMAND}
|
|
ARGS -E ${make_avail} ${input_datafile} ${output_datafile}
|
|
DEPENDS ${input_datafile}
|
|
VERBATIM
|
|
)
|
|
list (APPEND ${satellite}_INPUT_FILES "${output_datafile}")
|
|
endforeach (input_datafile)
|
|
endif(NOT PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
|
|
|
|
# setup a target which does all the copying
|
|
set (${satellite}_DATAFILES "${target}")
|
|
add_custom_target (${${satellite}_DATAFILES}
|
|
DEPENDS ${${satellite}_INPUT_FILES}
|
|
COMMENT "Making \"${satellite}\" data available in output tree"
|
|
)
|
|
if(NOT TARGET test-suite)
|
|
add_custom_target(test-suite)
|
|
endif()
|
|
add_dependencies(test-suite ${${satellite}_DATAFILES})
|
|
endmacro (opm_data satellite target dirname files)
|
|
|
|
# Add a single unit test (can be orchestrated by the 'ctest' command)
|
|
#
|
|
# Synopsis:
|
|
# opm_add_test(TestName)
|
|
#
|
|
# Parameters:
|
|
# TestName Name of test
|
|
# ONLY_COMPILE Only build test but do not run it (optional)
|
|
# ALWAYS_ENABLE Force enabling test even if -DBUILD_TESTING=OFF was set (optional)
|
|
# EXE_NAME Name of test executable (optional, default: ./bin/${TestName})
|
|
# CONDITION Condition to enable test (optional, cmake code)
|
|
# DEPENDS Targets which the test depends on (optional)
|
|
# DRIVER The script which supervises the test (optional, default: ${OPM_TEST_DRIVER})
|
|
# DRIVER_ARGS The script which supervises the test (optional, default: ${OPM_TEST_DRIVER_ARGS})
|
|
# TEST_ARGS Arguments to pass to test's binary (optional, default: empty)
|
|
# SOURCES Source files for the test (optional, default: ${EXE_NAME}.cpp)
|
|
# PROCESSORS Number of processors to run test on (optional, default: 1)
|
|
# TEST_DEPENDS Other tests which must be run before running this test (optional, default: None)
|
|
# LIBRARIES Libraries to link test against (optional)
|
|
# WORKING_DIRECTORY Working directory for test (optional, default: ${PROJECT_BINARY_DIR})
|
|
#
|
|
# Example:
|
|
#
|
|
# opm_add_test(funky_test
|
|
# ALWAYS_ENABLE
|
|
# CONDITION FUNKY_GRID_FOUND
|
|
# SOURCES tests/MyFunkyTest.cpp
|
|
# LIBRARIES -lgmp -lm)
|
|
include(CMakeParseArguments)
|
|
|
|
macro(opm_add_test TestName)
|
|
cmake_parse_arguments(CURTEST
|
|
"NO_COMPILE;ONLY_COMPILE;ALWAYS_ENABLE" # flags
|
|
"EXE_NAME;PROCESSORS;WORKING_DIRECTORY" # one value args
|
|
"CONDITION;TEST_DEPENDS;DRIVER;DRIVER_ARGS;DEPENDS;TEST_ARGS;SOURCES;LIBRARIES" # multi-value args
|
|
${ARGN})
|
|
|
|
set(BUILD_TESTING "${BUILD_TESTING}")
|
|
|
|
# set the default values for optional parameters
|
|
if (NOT CURTEST_EXE_NAME)
|
|
set(CURTEST_EXE_NAME ${TestName})
|
|
endif()
|
|
|
|
# try to auto-detect the name of the source file if SOURCES are not
|
|
# explicitly specified.
|
|
if (NOT CURTEST_SOURCES)
|
|
set(CURTEST_SOURCES "")
|
|
set(_SDir "${PROJECT_SOURCE_DIR}")
|
|
foreach(CURTEST_CANDIDATE "${CURTEST_EXE_NAME}.cpp"
|
|
"${CURTEST_EXE_NAME}.cc"
|
|
"tests/${CURTEST_EXE_NAME}.cpp"
|
|
"tests/${CURTEST_EXE_NAME}.cc")
|
|
if (EXISTS "${_SDir}/${CURTEST_CANDIDATE}")
|
|
set(CURTEST_SOURCES "${_SDir}/${CURTEST_CANDIDATE}")
|
|
endif()
|
|
endforeach()
|
|
endif()
|
|
|
|
# the default working directory is the content of
|
|
# OPM_TEST_DEFAULT_WORKING_DIRECTORY or the source directory if this
|
|
# is unspecified
|
|
if (NOT CURTEST_WORKING_DIRECTORY)
|
|
if (OPM_TEST_DEFAULT_WORKING_DIRECTORY)
|
|
set(CURTEST_WORKING_DIRECTORY ${OPM_TEST_DEFAULT_WORKING_DIRECTORY})
|
|
else()
|
|
set(CURTEST_WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
|
endif()
|
|
endif()
|
|
|
|
# don't build the tests by _default_ if BUILD_TESTING is false,
|
|
# i.e., when typing 'make' the tests are not build in that
|
|
# case. They can still be build using 'make test-suite' and they can
|
|
# be build and run using 'make check'
|
|
set(CURTEST_EXCLUDE_FROM_ALL "")
|
|
if (NOT BUILD_TESTING AND NOT CURTEST_ALWAYS_ENABLE)
|
|
set(CURTEST_EXCLUDE_FROM_ALL "EXCLUDE_FROM_ALL")
|
|
endif()
|
|
|
|
# figure out the test driver script and its arguments. (the variable
|
|
# for the driver script may be empty. In this case the binary is run
|
|
# "bare metal".)
|
|
if (NOT CURTEST_DRIVER)
|
|
set(CURTEST_DRIVER "${OPM_TEST_DRIVER}")
|
|
endif()
|
|
if (NOT CURTEST_DRIVER_ARGS)
|
|
set(CURTEST_DRIVER_ARGS "${OPM_TEST_DRIVER_ARGS}")
|
|
endif()
|
|
|
|
# the libraries to link against
|
|
if (NOT CURTEST_LIBRARIES)
|
|
SET(CURTEST_LIBRARIES "${${CMAKE_PROJECT_NAME}_LIBRARIES}")
|
|
endif()
|
|
|
|
# determine if the test should be completely ignored, i.e., the
|
|
# CONDITION argument evaluates to false. the "AND OR " is a hack
|
|
# which is required to prevent CMake from evaluating the condition
|
|
# in the string. (which might evaluate to an empty string even
|
|
# though "${CURTEST_CONDITION}" is not empty.)
|
|
if ("AND OR ${CURTEST_CONDITION}" STREQUAL "AND OR ")
|
|
set(SKIP_CUR_TEST "0")
|
|
elseif(${CURTEST_CONDITION})
|
|
set(SKIP_CUR_TEST "0")
|
|
else()
|
|
set(SKIP_CUR_TEST "1")
|
|
endif()
|
|
|
|
if (NOT SKIP_CUR_TEST)
|
|
if (CURTEST_ONLY_COMPILE)
|
|
# only compile the binary but do not run it as a test
|
|
add_executable("${CURTEST_EXE_NAME}" ${CURTEST_EXCLUDE_FROM_ALL} ${CURTEST_SOURCES})
|
|
target_link_libraries (${CURTEST_EXE_NAME} ${CURTEST_LIBRARIES})
|
|
|
|
if(CURTEST_DEPENDS)
|
|
add_dependencies("${CURTEST_EXE_NAME}" ${CURTEST_DEPENDS})
|
|
endif()
|
|
else()
|
|
if (NOT CURTEST_NO_COMPILE)
|
|
# in addition to being run, the test must be compiled. (the
|
|
# run-only case occurs if the binary is already compiled by an
|
|
# earlier test.)
|
|
add_executable("${CURTEST_EXE_NAME}" ${CURTEST_EXCLUDE_FROM_ALL} ${CURTEST_SOURCES})
|
|
target_link_libraries (${CURTEST_EXE_NAME} ${CURTEST_LIBRARIES})
|
|
|
|
if(CURTEST_DEPENDS)
|
|
add_dependencies("${CURTEST_EXE_NAME}" ${CURTEST_DEPENDS})
|
|
endif()
|
|
|
|
if(NOT TARGET test-suite)
|
|
add_custom_target(test-suite)
|
|
endif()
|
|
add_dependencies(test-suite "${CURTEST_EXE_NAME}")
|
|
endif()
|
|
|
|
# figure out how the test should be run. if a test driver script
|
|
# has been specified to supervise the test binary, use it else
|
|
# run the test binary "naked".
|
|
if (CURTEST_DRIVER)
|
|
set(CURTEST_COMMAND ${CURTEST_DRIVER} ${CURTEST_DRIVER_ARGS} ${CURTEST_EXE_NAME} ${CURTEST_TEST_ARGS})
|
|
else()
|
|
set(CURTEST_COMMAND ${PROJECT_BINARY_DIR}/bin/${CURTEST_EXE_NAME})
|
|
if (CURTEST_TEST_ARGS)
|
|
list(APPEND CURTEST_COMMAND ${CURTEST_TEST_ARGS})
|
|
endif()
|
|
endif()
|
|
|
|
add_test(NAME ${TestName}
|
|
WORKING_DIRECTORY "${CURTEST_WORKING_DIRECTORY}"
|
|
COMMAND ${CURTEST_COMMAND})
|
|
|
|
# specify the dependencies between the tests
|
|
if (CURTEST_TEST_DEPENDS)
|
|
set_tests_properties(${TestName} PROPERTIES DEPENDS "${CURTEST_TEST_DEPENDS}")
|
|
endif()
|
|
|
|
# tell ctest how many cores it should reserve to run the test
|
|
if (CURTEST_PROCESSORS)
|
|
set_tests_properties(${TestName} PROPERTIES PROCESSORS "${CURTEST_PROCESSORS}")
|
|
endif()
|
|
endif()
|
|
|
|
else() # test is skipped
|
|
|
|
# the following causes the test to appear as 'skipped' in the
|
|
# CDash dashboard. it this is removed, the test is just silently
|
|
# ignored.
|
|
if (NOT CURTEST_ONLY_COMPILE AND ADD_DISABLED_CTESTS)
|
|
add_test(${TestName} skip_test_dummy)
|
|
endif()
|
|
endif()
|
|
endmacro()
|
|
|
|
# macro to set the default test driver script and the its default
|
|
# arguments
|
|
macro(opm_set_test_driver DriverBinary DriverDefaultArgs)
|
|
set(OPM_TEST_DRIVER "${DriverBinary}")
|
|
set(OPM_TEST_DRIVER_ARGS "${DriverDefaultArgs}")
|
|
endmacro()
|
|
|
|
# macro to set the default test driver script and the its default
|
|
# arguments
|
|
macro(opm_set_test_default_working_directory Dir)
|
|
set(OPM_TEST_DEFAULT_WORKING_DIRECTORY "${Dir}")
|
|
endmacro()
|