1396 lines
55 KiB
CMake
1396 lines
55 KiB
CMake
CMAKE_MINIMUM_REQUIRED(VERSION 3.10.0)
|
|
CMAKE_POLICY( SET CMP0057 NEW )
|
|
if( ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.20.0")
|
|
CMAKE_POLICY( SET CMP0115 OLD )
|
|
endif()
|
|
|
|
INCLUDE(CheckCCompilerFlag)
|
|
INCLUDE(CheckCSourceCompiles)
|
|
INCLUDE(CheckCXXCompilerFlag)
|
|
INCLUDE(CheckCXXSourceCompiles)
|
|
IF ( NOT TEST_FAIL_REGULAR_EXPRESSION )
|
|
# Note: we cannot check for "handles are still allocated" due to PETSc. See static variable
|
|
# Petsc_Reduction_keyval on line 234 of comb.c
|
|
#SET( TEST_FAIL_REGULAR_EXPRESSION "(FAILED)|(leaked context IDs detected)|(handles are still allocated)" )
|
|
SET( TEST_FAIL_REGULAR_EXPRESSION "(FAILED)" )
|
|
ENDIF()
|
|
|
|
|
|
# Check that the PROJ and ${PROJ}_INSTALL_DIR variables are set
|
|
# These variables are used to generate the ADD_PROJ_TEST macros
|
|
IF ( NOT PROJ )
|
|
MESSAGE(FATAL_ERROR "PROJ must be set before including macros.cmake")
|
|
ENDIF()
|
|
IF ( NOT ${PROJ}_INSTALL_DIR )
|
|
MESSAGE(FATAL_ERROR "${PROJ}_INSTALL_DIR must be set before including macros.cmake")
|
|
ENDIF()
|
|
IF ( NOT CMAKE_BUILD_TYPE )
|
|
MESSAGE(FATAL_ERROR "CMAKE_BUILD_TYPE must be set before including macros.cmake")
|
|
ENDIF()
|
|
|
|
|
|
# Enable json
|
|
SET( CMAKE_EXPORT_COMPILE_COMMANDS ON )
|
|
|
|
|
|
# Check for link time optimization (LTO)
|
|
IF ( ${CMAKE_BUILD_TYPE} STREQUAL "Release" AND ${CMAKE_VERSION} VERSION_GREATER 3.9.4
|
|
AND NOT DISABLE_LTO AND NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION )
|
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.9)
|
|
INCLUDE( CheckIPOSupported )
|
|
CHECK_IPO_SUPPORTED(RESULT supported OUTPUT error)
|
|
IF( supported )
|
|
MESSAGE(STATUS "IPO / LTO enabled")
|
|
SET( LTO TRUE )
|
|
SET( CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE )
|
|
ELSE()
|
|
SET( LTO FALSE )
|
|
MESSAGE(STATUS "IPO / LTO not supported")
|
|
ENDIF()
|
|
ELSEIF( NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION )
|
|
SET( LTO FALSE )
|
|
MESSAGE(STATUS "IPO / LTO disabled")
|
|
ENDIF()
|
|
|
|
|
|
# Check for gold linker
|
|
IF ( UNIX AND NOT APPLE AND NOT DISABLE_GOLD )
|
|
EXECUTE_PROCESS( COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION )
|
|
IF ( "${LD_VERSION}" MATCHES "GNU gold" )
|
|
MESSAGE( "Using gold linker" )
|
|
SET( GOLD_LINK_FLAGS "-fuse-ld=gold -Wl,--disable-new-dtags -Wl,--no-map-whole-files" )
|
|
SET( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GOLD_LINK_FLAGS}" )
|
|
SET( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GOLD_LINK_FLAGS}" )
|
|
ENDIF()
|
|
ENDIF()
|
|
|
|
|
|
# Add some default targets if they do not exist
|
|
IF ( NOT TARGET copy-${PROJ}-Data )
|
|
ADD_CUSTOM_TARGET( copy-${PROJ}-Data ALL )
|
|
ENDIF()
|
|
IF ( NOT TARGET copy-${PROJ}-include )
|
|
ADD_CUSTOM_TARGET( copy-${PROJ}-include ALL )
|
|
ENDIF()
|
|
|
|
|
|
# Dummy use to prevent unused cmake variable warning
|
|
MACRO( NULL_USE VAR )
|
|
IF ( "${${VAR}}" STREQUAL "dummy" )
|
|
MESSAGE( FATAL_ERROR "NULL_USE fail" )
|
|
ENDIF()
|
|
ENDMACRO()
|
|
NULL_USE( CMAKE_C_FLAGS )
|
|
|
|
|
|
# Macro to set a global variable
|
|
MACRO(GLOBAL_SET VARNAME)
|
|
SET(${VARNAME} ${ARGN} CACHE INTERNAL "")
|
|
ENDMACRO()
|
|
|
|
|
|
# Macro to print all variables
|
|
MACRO( PRINT_ALL_VARIABLES )
|
|
GET_CMAKE_PROPERTY(_variableNames VARIABLES)
|
|
FOREACH(_variableName ${_variableNames})
|
|
MESSAGE(STATUS "${_variableName}=${${_variableName}}")
|
|
ENDFOREACH()
|
|
ENDMACRO()
|
|
|
|
|
|
# CMake assert
|
|
MACRO(ASSERT test comment)
|
|
IF (NOT ${test})
|
|
MESSSAGE(FATAL_ERROR "Assertion failed: ${comment}")
|
|
ENDIF(NOT ${test})
|
|
ENDMACRO(ASSERT)
|
|
|
|
|
|
# Set the maximum number of processors
|
|
IF ( NOT TEST_MAX_PROCS )
|
|
INCLUDE(ProcessorCount)
|
|
ProcessorCount( TEST_MAX_PROCS )
|
|
IF ( ${TEST_MAX_PROCS} EQUAL 0 )
|
|
SET( TEST_MAX_PROCS 16 )
|
|
ENDIF()
|
|
ENDIF()
|
|
|
|
|
|
# Macro to convert a m4 file
|
|
# This command converts a file of the format "global_path/file.m4"
|
|
# and convertes it to file.F. It also requires the path.
|
|
MACRO( CONVERT_M4_FORTRAN IN LOCAL_PATH OUT_PATH )
|
|
STRING(REGEX REPLACE ${LOCAL_PATH} "" OUT ${IN} )
|
|
STRING(REGEX REPLACE "/" "" OUT ${OUT} )
|
|
STRING(REGEX REPLACE "(.fm4)|(.m4)" ".F" OUT "${CMAKE_CURRENT_BINARY_DIR}/${OUT_PATH}/${OUT}" )
|
|
IF ( NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/${OUT_PATH}" )
|
|
FILE(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${OUT_PATH}" )
|
|
ENDIF()
|
|
CONFIGURE_FILE( ${IN} ${IN} COPYONLY )
|
|
IF ("${CMAKE_GENERATOR}" STREQUAL "Xcode")
|
|
STRING(REGEX REPLACE ".F" ".o" OUT2 "${OUT}" )
|
|
STRING(REGEX REPLACE ";" " " COMPILE_CMD "${CMAKE_Fortran_COMPILER} -c ${OUT} ${CMAKE_Fortran_FLAGS} -o ${OUT2}")
|
|
STRING(REGEX REPLACE "\\\\" "" COMPILE_CMD "${COMPILE_CMD}")
|
|
MESSAGE("COMPILE_CMD = ${COMPILE_CMD}")
|
|
SET( COMPILE_CMD ${COMPILE_CMD} )
|
|
ADD_CUSTOM_COMMAND(
|
|
OUTPUT ${OUT2}
|
|
COMMAND m4 -I${LOCAL_PATH} -I${SAMRAI_FORTDIR} ${M4DIRS} ${IN} > ${OUT}
|
|
COMMAND ${COMPILE_CMD}
|
|
DEPENDS ${IN}
|
|
)
|
|
SET_SOURCE_FILES_PROPERTIES(${OUT2} PROPERTIES GENERATED true)
|
|
SET( SOURCES ${SOURCES} "${OUT2}" )
|
|
ELSE()
|
|
ADD_CUSTOM_COMMAND(
|
|
OUTPUT ${OUT}
|
|
COMMAND m4 -I${LOCAL_PATH} -I${SAMRAI_FORTDIR} ${M4DIRS} ${M4_OPTIONS} ${IN} > ${OUT}
|
|
DEPENDS ${IN}
|
|
)
|
|
SET_SOURCE_FILES_PROPERTIES(${OUT} PROPERTIES GENERATED true)
|
|
SET( SOURCES ${SOURCES} "${OUT}" )
|
|
ENDIF()
|
|
ENDMACRO()
|
|
|
|
|
|
# Add a package to the project's library
|
|
MACRO( ADD_${PROJ}_LIBRARY PACKAGE )
|
|
SET( CURRENT_LIBRARY ${PACKAGE} )
|
|
ADD_SUBDIRECTORY( ${PACKAGE} )
|
|
SET( CURRENT_LIBRARY )
|
|
ENDMACRO()
|
|
|
|
|
|
# Add a project executable
|
|
MACRO( ADD_${PROJ}_EXECUTABLE EXEFILE )
|
|
IF ( TARGET ${EXEFILE} AND NOT INCLUDE_${EXEFILE} )
|
|
MESSAGE( FATAL_ERROR "ADD_${PROJ}_EXECUTABLE should be called before adding tests" )
|
|
ENDIF()
|
|
SET( INCLUDE_${EXEFILE} TRUE )
|
|
ADD_PROJ_PROVISIONAL_TEST( ${EXEFILE} )
|
|
INSTALL( TARGETS ${EXEFILE} DESTINATION ${${PROJ}_INSTALL_DIR}/bin )
|
|
ENDMACRO()
|
|
|
|
|
|
# Initialize a package
|
|
MACRO (BEGIN_PACKAGE_CONFIG PACKAGE)
|
|
SET( HEADERS "" )
|
|
SET( CXXSOURCES "" )
|
|
SET( CSOURCES "" )
|
|
SET( FSOURCES "" )
|
|
SET( M4FSOURCES "" )
|
|
SET( CUDASOURCES "" )
|
|
SET( SOURCES "" )
|
|
SET( CURPACKAGE ${PACKAGE} )
|
|
ENDMACRO ()
|
|
|
|
|
|
# Find the source files
|
|
MACRO( FIND_FILES )
|
|
# Find the C/C++ headers
|
|
SET( T_HEADERS "" )
|
|
FILE( GLOB T_HEADERS "*.h" "*.H" "*.hh" "*.hpp" "*.I" )
|
|
# Find the CUDA sources
|
|
SET( T_CUDASOURCES "" )
|
|
FILE( GLOB T_CUDASOURCES "*.cu" )
|
|
# Find the HIP sources
|
|
SET( T_HIPSOURCES "" )
|
|
FILE( GLOB T_HIPSOURCES "*.hip" )
|
|
# Find the C sources
|
|
SET( T_CSOURCES "" )
|
|
FILE( GLOB T_CSOURCES "*.c" )
|
|
# Find the C++ sources
|
|
SET( T_CXXSOURCES "" )
|
|
FILE( GLOB T_CXXSOURCES "*.cc" "*.cpp" "*.cxx" "*.C" )
|
|
# Find the Fortran sources
|
|
SET( T_FSOURCES "" )
|
|
FILE( GLOB T_FSOURCES "*.f" "*.f90" "*.F" "*.F90" )
|
|
# Find the m4 fortran source (and convert)
|
|
SET( T_M4FSOURCES "" )
|
|
FILE( GLOB T_M4FSOURCES "*.m4" "*.fm4" )
|
|
FOREACH( m4file ${T_M4FSOURCES} )
|
|
CONVERT_M4_FORTRAN( ${m4file} ${CMAKE_CURRENT_SOURCE_DIR} "" )
|
|
ENDFOREACH()
|
|
# Add all found files to the current lists
|
|
SET( HEADERS ${HEADERS} ${T_HEADERS} )
|
|
SET( CXXSOURCES ${CXXSOURCES} ${T_CXXSOURCES} )
|
|
SET( CUDASOURCES ${CUDASOURCES} ${T_CUDASOURCES} )
|
|
SET( HIPSOURCES ${HIPSOURCES} ${T_HIPSOURCES} )
|
|
SET( CSOURCES ${CSOURCES} ${T_CSOURCES} )
|
|
SET( FSOURCES ${FSOURCES} ${T_FSOURCES} )
|
|
SET( M4FSOURCES ${M4FSOURCES} ${T_M4FSOURCES} )
|
|
SET( SOURCES ${SOURCES} ${T_CXXSOURCES} ${T_CSOURCES} ${T_FSOURCES} ${T_M4FSOURCES} ${CUDASOURCES} ${HIPSOURCES} )
|
|
ENDMACRO()
|
|
|
|
|
|
# Find the source files
|
|
MACRO( FIND_FILES_PATH IN_PATH )
|
|
# Find the C/C++ headers
|
|
SET( T_HEADERS "" )
|
|
FILE( GLOB T_HEADERS "${IN_PATH}/*.h" "${IN_PATH}/*.H" "${IN_PATH}/*.hh" "${IN_PATH}/*.hpp" "${IN_PATH}/*.I" )
|
|
# Find the CUDA sources
|
|
SET( T_CUDASOURCES "" )
|
|
FILE( GLOB T_CUDASOURCES "${IN_PATH}/*.cu" )
|
|
# Find the HIP sources
|
|
SET( T_HIPSOURCES "" )
|
|
FILE( GLOB T_HIPSOURCES "${IN_PATH}/*.hip" )
|
|
# Find the C sources
|
|
SET( T_CSOURCES "" )
|
|
FILE( GLOB T_CSOURCES "${IN_PATH}/*.c" )
|
|
# Find the C++ sources
|
|
SET( T_CXXSOURCES "" )
|
|
FILE( GLOB T_CXXSOURCES "${IN_PATH}/*.cc" "${IN_PATH}/*.cpp" "${IN_PATH}/*.cxx" "${IN_PATH}/*.C" )
|
|
# Find the Fortran sources
|
|
SET( T_FSOURCES "" )
|
|
FILE( GLOB T_FSOURCES "${IN_PATH}/*.f" "${IN_PATH}/*.f90" "${IN_PATH}/*.F" "${IN_PATH}/*.F90" )
|
|
# Find the m4 fortran source (and convert)
|
|
SET( T_M4FSOURCES "" )
|
|
FILE( GLOB T_M4FSOURCES "${IN_PATH}/*.m4" "${IN_PATH}/*.fm4" )
|
|
FOREACH( m4file ${T_M4FSOURCES} )
|
|
CONVERT_M4_FORTRAN( ${m4file} ${CMAKE_CURRENT_SOURCE_DIR}/${IN_PATH} ${IN_PATH} )
|
|
ENDFOREACH ()
|
|
# Add all found files to the current lists
|
|
SET( HEADERS ${HEADERS} ${T_HEADERS} )
|
|
SET( CXXSOURCES ${CXXSOURCES} ${T_CXXSOURCES} )
|
|
SET( CUDASOURCES ${CUDASOURCES} ${T_CUDASOURCES} )
|
|
SET( HIPSOURCES ${HIPSOURCES} ${T_HIPSOURCES} )
|
|
SET( CSOURCES ${CSOURCES} ${T_CSOURCES} )
|
|
SET( FSOURCES ${FSOURCES} ${T_FSOURCES} )
|
|
SET( SOURCES ${SOURCES} ${T_CXXSOURCES} ${T_CSOURCES} ${T_FSOURCES} ${CUDASOURCES} ${HIPSOURCES} )
|
|
ENDMACRO()
|
|
|
|
|
|
# Add a subdirectory
|
|
MACRO( ADD_PACKAGE_SUBDIRECTORY SUBDIR )
|
|
FIND_FILES_PATH( ${SUBDIR} )
|
|
ENDMACRO()
|
|
|
|
|
|
# Add an external directory
|
|
# Note: this will add the files to compile but will not copy the headers
|
|
MACRO( ADD_EXTERNAL_DIRECTORY SUBDIR )
|
|
FIND_FILES_PATH( ${SUBDIR} )
|
|
ENDMACRO()
|
|
|
|
|
|
# Install a package
|
|
MACRO( INSTALL_${PROJ}_TARGET PACKAGE )
|
|
# Find all files in the current directory
|
|
FIND_FILES()
|
|
# Create the copy target
|
|
STRING(REGEX REPLACE "${${PROJ}_SOURCE_DIR}/" "" COPY_TARGET "copy-${PROJ}-${CMAKE_CURRENT_SOURCE_DIR}-include" )
|
|
STRING(REGEX REPLACE "/" "-" COPY_TARGET ${COPY_TARGET} )
|
|
IF( NOT TARGET ${COPY_TARGET} )
|
|
ADD_CUSTOM_TARGET( ${COPY_TARGET} ALL )
|
|
ADD_DEPENDENCIES( copy-${PROJ}-include ${COPY_TARGET} )
|
|
ENDIF()
|
|
# Copy the header files to the include path
|
|
IF ( HEADERS )
|
|
FILE( GLOB HFILES RELATIVE "${${PROJ}_SOURCE_DIR}" ${HEADERS} )
|
|
FOREACH( HFILE ${HFILES} )
|
|
SET( SRC_FILE "${${PROJ}_SOURCE_DIR}/${HFILE}" )
|
|
SET( DST_FILE "${${PROJ}_INSTALL_DIR}/include/${${PROJ}_INC}/${HFILE}" )
|
|
# Only copy the headers if the exisit in the project source directory
|
|
IF ( EXISTS "${SRC_FILE}" )
|
|
ADD_CUSTOM_COMMAND(TARGET ${COPY_TARGET}
|
|
PRE_BUILD
|
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${SRC_FILE}" "${DST_FILE}"
|
|
DEPENDS "${SRC_FILE}"
|
|
)
|
|
ENDIF()
|
|
ENDFOREACH()
|
|
ENDIF()
|
|
# Add the library and install the package
|
|
IF ( NOT ONLY_BUILD_DOCS AND SOURCES )
|
|
# Set RPATH variables
|
|
IF ( NOT CMAKE_RPATH_VARIABLES_SET AND NOT USE_STATIC )
|
|
SET(CMAKE_RPATH_VARIABLES_SET ON)
|
|
SET(CMAKE_SKIP_BUILD_RPATH FALSE)
|
|
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
|
|
SET(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_RPATH} "${CMAKE_INSTALL_PREFIX}/lib")
|
|
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
|
SET(MACOSX_RPATH 0)
|
|
LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir)
|
|
ENDIF()
|
|
# Add the library to the project libs list
|
|
SET( ${PROJ}_LIBS ${${PROJ}_LIBS} ${PACKAGE} CACHE INTERNAL "")
|
|
LIST( REMOVE_DUPLICATES ${PROJ}_LIBS )
|
|
SET( ${PROJ}_LIBS ${${PROJ}_LIBS} CACHE INTERNAL "")
|
|
# Create the library
|
|
IF ( ${PROJ}_LIB )
|
|
# We are using a single project library
|
|
ADD_LIBRARY( ${PACKAGE} OBJECT ${SOURCES} )
|
|
ELSE()
|
|
# We are creating individual libraries
|
|
ADD_LIBRARY( ${PACKAGE} ${LIB_TYPE} ${SOURCES} ${CUBINS} )
|
|
TARGET_LINK_EXTERNAL_LIBRARIES( ${PACKAGE} )
|
|
ENDIF()
|
|
# Add coverage flags to target
|
|
IF ( NOT DISABLE_TARGET_COVERAGE )
|
|
TARGET_COMPILE_DEFINITIONS( ${PACKAGE} PUBLIC ${COVERAGE_FLAGS} )
|
|
ENDIF()
|
|
# Add target dependencies
|
|
IF ( TARGET write_repo_version )
|
|
ADD_DEPENDENCIES( ${PACKAGE} write_repo_version )
|
|
ENDIF()
|
|
ADD_DEPENDENCIES( ${PACKAGE} copy-${PROJ}-include )
|
|
IF ( NOT ${PROJ}_LIB )
|
|
INSTALL( TARGETS ${PACKAGE} DESTINATION ${${PROJ}_INSTALL_DIR}/lib )
|
|
ENDIF()
|
|
ELSE()
|
|
ADD_CUSTOM_TARGET( ${PACKAGE} ALL )
|
|
ENDIF()
|
|
# Clear the sources
|
|
SET( HEADERS "" )
|
|
SET( CSOURCES "" )
|
|
SET( CXXSOURCES "" )
|
|
ENDMACRO()
|
|
|
|
|
|
# Install the project library
|
|
MACRO( INSTALL_PROJ_LIB )
|
|
SET( tmp_link_list )
|
|
FOREACH ( tmp ${${PROJ}_LIBS} )
|
|
SET( tmp_link_list ${tmp_link_list} $<TARGET_OBJECTS:${tmp}> )
|
|
ENDFOREACH()
|
|
ADD_LIBRARY( ${${PROJ}_LIB} ${LIB_TYPE} ${tmp_link_list} )
|
|
TARGET_LINK_EXTERNAL_LIBRARIES( ${${PROJ}_LIB} LINK_PUBLIC )
|
|
INSTALL( TARGETS ${${PROJ}_LIB} DESTINATION ${${PROJ}_INSTALL_DIR}/lib )
|
|
ENDMACRO()
|
|
|
|
|
|
# Macro to verify that a variable has been set
|
|
MACRO( VERIFY_VARIABLE VARIABLE_NAME )
|
|
IF ( NOT ${VARIABLE_NAME} )
|
|
MESSAGE( FATAL_ERROR "Please set: " ${VARIABLE_NAME} )
|
|
ENDIF()
|
|
ENDMACRO()
|
|
|
|
|
|
# Macro to verify that a path has been set
|
|
MACRO( VERIFY_PATH PATH_NAME )
|
|
IF ("${PATH_NAME}" STREQUAL "")
|
|
MESSAGE( FATAL_ERROR "Path is not set: ${PATH_NAME}" )
|
|
ENDIF()
|
|
IF ( NOT EXISTS "${PATH_NAME}" )
|
|
MESSAGE( FATAL_ERROR "Path does not exist: ${PATH_NAME}" )
|
|
ENDIF()
|
|
ENDMACRO()
|
|
|
|
|
|
# Macro to tell cmake to use static libraries
|
|
MACRO( SET_STATIC_FLAGS )
|
|
# Remove extra library links
|
|
SET(CMAKE_EXE_LINK_DYNAMIC_C_FLAGS) # remove -Wl,-Bdynamic
|
|
SET(CMAKE_EXE_LINK_DYNAMIC_CXX_FLAGS)
|
|
# Add the static flag if necessary
|
|
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") # Add static flag
|
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static ")
|
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static ")
|
|
ENDMACRO()
|
|
|
|
|
|
# Macro to identify the compiler
|
|
MACRO( IDENTIFY_COMPILER )
|
|
# SET the C/C++ compiler
|
|
IF ( CMAKE_C_COMPILER_WORKS OR CMAKE_CXX_COMPILER_WORKS )
|
|
IF( USING_GCC OR CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR
|
|
(${CMAKE_C_COMPILER_ID} MATCHES "GNU") OR (${CMAKE_CXX_COMPILER_ID} MATCHES "GNU") )
|
|
SET( USING_GCC TRUE )
|
|
ADD_DEFINITIONS( -DUSING_GCC )
|
|
MESSAGE("Using gcc")
|
|
ELSEIF( USING_MSVC OR MSVC OR MSVC_IDE OR MSVC60 OR MSVC70 OR MSVC71 OR MSVC80 OR CMAKE_COMPILER_2005 OR MSVC90 OR MSVC10 )
|
|
IF( NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Windows" )
|
|
MESSAGE( FATAL_ERROR "Using microsoft compilers on non-windows system?" )
|
|
ENDIF()
|
|
SET( USING_MSVC TRUE )
|
|
ADD_DEFINITIONS( -DUSING_MSVC )
|
|
MESSAGE("Using Microsoft")
|
|
ELSEIF( USING_ICC OR (${CMAKE_C_COMPILER_ID} MATCHES "Intel") OR (${CMAKE_CXX_COMPILER_ID} MATCHES "Intel") )
|
|
SET(USING_ICC TRUE)
|
|
ADD_DEFINITIONS( -DUSING_ICC )
|
|
MESSAGE("Using icc")
|
|
ELSEIF( USING_PGCC OR (${CMAKE_C_COMPILER_ID} MATCHES "PGI") OR (${CMAKE_CXX_COMPILER_ID} MATCHES "PGI") )
|
|
SET(USING_PGCC TRUE)
|
|
ADD_DEFINITIONS( -DUSING_PGCC )
|
|
MESSAGE("Using pgCC")
|
|
ELSEIF( USING_CRAY OR (${CMAKE_C_COMPILER_ID} MATCHES "CRAY") OR (${CMAKE_CXX_COMPILER_ID} MATCHES "CRAY") OR
|
|
(${CMAKE_C_COMPILER_ID} MATCHES "Cray") OR (${CMAKE_CXX_COMPILER_ID} MATCHES "Cray") )
|
|
SET(USING_CRAY TRUE)
|
|
ADD_DEFINITIONS( -DUSING_CRAY )
|
|
MESSAGE("Using Cray")
|
|
ELSEIF( USING_CLANG OR (${CMAKE_C_COMPILER_ID} MATCHES "CLANG") OR (${CMAKE_CXX_COMPILER_ID} MATCHES "CLANG") OR
|
|
(${CMAKE_C_COMPILER_ID} MATCHES "Clang") OR (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") )
|
|
SET(USING_CLANG TRUE)
|
|
ADD_DEFINITIONS( -DUSING_CLANG )
|
|
MESSAGE("Using Clang")
|
|
ELSEIF( USING_XL OR (${CMAKE_C_COMPILER_ID} MATCHES "XL") OR (${CMAKE_CXX_COMPILER_ID} MATCHES "XL") )
|
|
SET(USING_XL TRUE)
|
|
ADD_DEFINITIONS( -DUSING_XL )
|
|
MESSAGE("Using XL")
|
|
ELSE()
|
|
MESSAGE( "CMAKE_C_COMPILER=${CMAKE_C_COMPILER}")
|
|
MESSAGE( "CMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}")
|
|
MESSAGE( "CMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}")
|
|
MESSAGE( "CMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID}")
|
|
MESSAGE(FATAL_ERROR "Unknown C/C++ compiler")
|
|
ENDIF()
|
|
ENDIF()
|
|
# SET the Fortran compiler
|
|
IF ( CMAKE_Fortran_COMPILER_WORKS )
|
|
IF( CMAKE_COMPILER_IS_GNUG77 OR (${CMAKE_Fortran_COMPILER_ID} MATCHES "GNU") )
|
|
SET( USING_GFORTRAN TRUE )
|
|
MESSAGE("Using gfortran")
|
|
IF ( NOT USING_GCC )
|
|
LIST( REMOVE_ITEM CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES gcc )
|
|
ENDIF()
|
|
ELSEIF ( (${CMAKE_Fortran_COMPILER_ID} MATCHES "Intel") )
|
|
SET(USING_IFORT TRUE)
|
|
MESSAGE("Using ifort")
|
|
ELSEIF ( ${CMAKE_Fortran_COMPILER_ID} MATCHES "PGI")
|
|
SET(USING_PGF90 TRUE)
|
|
MESSAGE("Using pgf90")
|
|
ELSEIF( (${CMAKE_Fortran_COMPILER_ID} MATCHES "CRAY") OR (${CMAKE_Fortran_COMPILER_ID} MATCHES "Cray") )
|
|
SET(USING_CRAY TRUE)
|
|
MESSAGE("Using Cray")
|
|
ELSEIF ( (${CMAKE_Fortran_COMPILER_ID} MATCHES "CLANG") OR (${CMAKE_Fortran_COMPILER_ID} MATCHES "Clang") OR
|
|
(${CMAKE_Fortran_COMPILER_ID} MATCHES "FLANG") OR (${CMAKE_Fortran_COMPILER_ID} MATCHES "Flang") )
|
|
SET(USING_FLANG TRUE)
|
|
MESSAGE("Using flang")
|
|
ELSE()
|
|
MESSAGE( "CMAKE_Fortran_COMPILER=${CMAKE_Fortran_COMPILER}")
|
|
MESSAGE( "CMAKE_Fortran_COMPILER_ID=${CMAKE_Fortran_COMPILER_ID}")
|
|
MESSAGE(FATAL_ERROR "Unknown Fortran compiler (${CMAKE_Fortran_COMPILER_ID})")
|
|
ENDIF()
|
|
ENDIF()
|
|
ENDMACRO()
|
|
|
|
|
|
# Macro to set the proper warnings
|
|
MACRO( SET_WARNINGS )
|
|
IF ( USING_GCC )
|
|
# Add gcc specific compiler options
|
|
# Note: adding -Wlogical-op causes a wierd linking error on Titan using the nvcc wrapper:
|
|
# /usr/bin/ld: cannot find gical-op: No such file or directory
|
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra")
|
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Woverloaded-virtual -Wsign-compare -Wformat-security")
|
|
ELSEIF ( USING_MSVC )
|
|
# Add Microsoft specifc compiler options
|
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _SCL_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_WARNINGS /D _ITERATOR_DEBUG_LEVEL=0 /wd4267" )
|
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D _SCL_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_WARNINGS /D _ITERATOR_DEBUG_LEVEL=0 /wd4267" )
|
|
ELSEIF ( USING_ICC )
|
|
# Add Intel specifc compiler options
|
|
SET(CMAKE_C_FLAGS " ${CMAKE_C_FLAGS} -Wall" )
|
|
SET(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -Wall -wd1011" )
|
|
ELSEIF ( USING_CRAY )
|
|
# Add default compiler options
|
|
SET(CMAKE_C_FLAGS " ${CMAKE_C_FLAGS}")
|
|
SET(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS}")
|
|
ELSEIF ( USING_PGCC )
|
|
# Add default compiler options
|
|
SET(CMAKE_C_FLAGS " ${CMAKE_C_FLAGS} -lpthread")
|
|
SET(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -lpthread -Minform=inform -Mlist --display_error_number")
|
|
# Suppress unreachable code warning, it causes non-useful warnings with some tests/templates
|
|
SET(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} --diag_suppress 111,128,185")
|
|
ELSEIF ( USING_CLANG )
|
|
# Add default compiler options
|
|
SET(CMAKE_C_FLAGS " ${CMAKE_C_FLAGS} -Wall -Wextra")
|
|
SET(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic -Wno-missing-braces -Wmissing-field-initializers -ftemplate-depth=1024")
|
|
ELSEIF ( USING_XL )
|
|
# Add default compiler options
|
|
SET(CMAKE_C_FLAGS " ${CMAKE_C_FLAGS} -Wall")
|
|
SET(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -Wall -ftemplate-depth=512")
|
|
ELSE ( )
|
|
MESSAGE("Compiler specific features are not set for this compiler")
|
|
ENDIF()
|
|
ENDMACRO()
|
|
|
|
|
|
# Macro to add user compile flags
|
|
MACRO( ADD_USER_FLAGS )
|
|
STRING( STRIP "${CMAKE_C_FLAGS} ${CFLAGS} ${CFLAGS_EXTRA}" CMAKE_C_FLAGS )
|
|
STRING( STRIP "${CMAKE_CXX_FLAGS} ${CXXFLAGS} ${CXXFLAGS_EXTRA}" CMAKE_CXX_FLAGS )
|
|
STRING( STRIP "${CMAKE_Fortran_FLAGS} ${FFLAGS} ${FFLAGS_EXTRA}" CMAKE_Fortran_FLAGS )
|
|
STRING( STRIP "${LDFLAGS} ${LDFLAGS_EXTRA}" LDFLAGS )
|
|
STRING( STRIP "${LDLIBS} ${LDLIBS_EXTRA}" LDLIBS )
|
|
ENDMACRO()
|
|
|
|
|
|
# Macro to set the compile/link flags
|
|
MACRO( SET_COMPILER_FLAGS )
|
|
# Initilaize the compiler
|
|
IDENTIFY_COMPILER()
|
|
# Set the default flags for each build type
|
|
IF ( USING_MSVC )
|
|
SET(CMAKE_C_FLAGS_DEBUG "-D_DEBUG /DEBUG /Od /EHsc /MDd /Z7" )
|
|
SET(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG /DEBUG /Od /EHsc /MDd /Z7" )
|
|
SET(CMAKE_C_FLAGS_RELEASE "/O2 /EHsc /MD" )
|
|
SET(CMAKE_CXX_FLAGS_RELEASE "/O2 /EHsc /MD" )
|
|
ELSE()
|
|
ENDIF()
|
|
# Set the behavior of GLIBCXX flags
|
|
CHECK_ENABLE_FLAG( ENABLE_GXX_DEBUG 0 )
|
|
IF ( ENABLE_GXX_DEBUG )
|
|
# Enable GLIBCXX_DEBUG flags
|
|
SET( CMAKE_C_FLAGS_DEBUG " ${CMAKE_C_FLAGS_DEBUG} -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC" )
|
|
SET( CMAKE_CXX_FLAGS_DEBUG " ${CMAKE_CXX_FLAGS_DEBUG} -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC" )
|
|
SET( DISABLE_GXX_DEBUG OFF )
|
|
ELSEIF ( DISABLE_GXX_DEBUG )
|
|
# Disable GLIBCXX_DEBUG flags
|
|
SET( DISABLE_GXX_DEBUG OFF )
|
|
ELSE()
|
|
# Default
|
|
SET( DISABLE_GXX_DEBUG ON )
|
|
ENDIF()
|
|
# Set debug definitions
|
|
IF ( ${CMAKE_BUILD_TYPE} STREQUAL "Debug" AND NOT ("${CMAKE_CXX_FLAGS_DEBUG}" MATCHES "-D_DEBUG") )
|
|
SET( CMAKE_C_FLAGS_DEBUG " ${CMAKE_C_FLAGS_DEBUG} -DDEBUG -D_DEBUG" )
|
|
SET( CMAKE_CXX_FLAGS_DEBUG " ${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG -D_DEBUG" )
|
|
ENDIF()
|
|
# Save the debug/release specific flags to the cache
|
|
SET( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}" CACHE STRING "Debug flags" FORCE)
|
|
SET( CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}" CACHE STRING "Release flags" FORCE)
|
|
SET( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING "Debug flags" FORCE)
|
|
SET( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}" CACHE STRING "Release flags" FORCE)
|
|
# Add the user flags
|
|
ADD_USER_FLAGS()
|
|
# Set the warnings to use
|
|
SET_WARNINGS()
|
|
# Test the compile flags
|
|
IF ( CMAKE_C_COMPILER_WORKS )
|
|
CHECK_C_COMPILER_FLAG( "${CMAKE_C_FLAGS}" CHECK_C_FLAGS )
|
|
ENDIF()
|
|
IF ( CMAKE_CXX_COMPILER_WORKS )
|
|
CHECK_CXX_COMPILER_FLAG( "${CMAKE_CXX_FLAGS}" CHECK_CXX_FLAGS )
|
|
ENDIF()
|
|
IF ( ( NOT CHECK_C_FLAGS ) OR ( NOT CHECK_CXX_FLAGS ) )
|
|
IF ( USING_CRAY )
|
|
MESSAGE(WARNING "Invalid C/CXX flags detected:\n"
|
|
"C flags: ${CMAKE_C_FLAGS}\n" "CXX flags: ${CMAKE_CXX_FLAGS}\n" )
|
|
ENDIF()
|
|
ENDIF()
|
|
ENDMACRO()
|
|
|
|
|
|
# Macro to copy data file at build time
|
|
MACRO( COPY_DATA_FILE SRC_FILE DST_FILE )
|
|
STRING(REGEX REPLACE "${${PROJ}_SOURCE_DIR}/" "" COPY_TARGET "copy-${PROJ}-${CMAKE_CURRENT_SOURCE_DIR}" )
|
|
STRING(REGEX REPLACE "-${${PROJ}_SOURCE_DIR}" "" COPY_TARGET "${COPY_TARGET}" )
|
|
STRING(REGEX REPLACE "/" "-" COPY_TARGET ${COPY_TARGET} )
|
|
IF ( NOT TARGET ${COPY_TARGET} )
|
|
ADD_CUSTOM_TARGET( ${COPY_TARGET} ALL )
|
|
ADD_DEPENDENCIES( copy-${PROJ}-Data ${COPY_TARGET} )
|
|
ENDIF()
|
|
ADD_CUSTOM_COMMAND( TARGET ${COPY_TARGET}
|
|
PRE_BUILD
|
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${SRC_FILE}" "${DST_FILE}"
|
|
DEPENDS "${SRC_FILE}"
|
|
)
|
|
ENDMACRO()
|
|
|
|
|
|
# Macro to copy a data or input file
|
|
FUNCTION( COPY_TEST_FILE FILENAME ${ARGN} )
|
|
SET( SEARCH_PATHS "${CMAKE_CURRENT_SOURCE_DIR}" )
|
|
SET( SEARCH_PATHS ${SEARCH_PATHS} "${CMAKE_CURRENT_SOURCE_DIR}/data" )
|
|
SET( SEARCH_PATHS ${SEARCH_PATHS} "${CMAKE_CURRENT_SOURCE_DIR}/inputs" )
|
|
FOREACH( tmp ${ARGN} )
|
|
SET( SEARCH_PATHS ${SEARCH_PATHS} "${tmp}" )
|
|
SET( SEARCH_PATHS ${SEARCH_PATHS} "${CMAKE_CURRENT_SOURCE_DIR}/${tmp}" )
|
|
ENDFOREACH()
|
|
SET( FILE_TO_COPY )
|
|
FOREACH( tmp ${SEARCH_PATHS} )
|
|
IF ( EXISTS "${tmp}/${FILENAME}" )
|
|
SET( FILE_TO_COPY "${tmp}/${FILENAME}" )
|
|
ENDIF()
|
|
ENDFOREACH()
|
|
IF ( FILE_TO_COPY )
|
|
SET( DESTINATION_NAME "${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}" )
|
|
COPY_DATA_FILE( ${FILE_TO_COPY} ${DESTINATION_NAME} )
|
|
ELSE()
|
|
SET( MSG_STR "Cannot find file: ${FILENAME}, searched:\n" )
|
|
FOREACH( tmp ${SEARCH_PATHS} )
|
|
SET( MSG_STR "${MSG_STR} ${tmp}\n" )
|
|
ENDFOREACH()
|
|
MESSAGE( WARNING "test ${MSG_STR}" )
|
|
ENDIF()
|
|
ENDFUNCTION()
|
|
|
|
|
|
# Macro to copy a data file
|
|
FUNCTION( RENAME_TEST_FILE SRC_NAME DST_NAME ${ARGN} )
|
|
SET( SEARCH_PATHS "${CMAKE_CURRENT_SOURCE_DIR}" )
|
|
SET( SEARCH_PATHS ${SEARCH_PATHS} "${CMAKE_CURRENT_SOURCE_DIR}/data" )
|
|
SET( SEARCH_PATHS ${SEARCH_PATHS} "${CMAKE_CURRENT_SOURCE_DIR}/inputs" )
|
|
FOREACH( tmp ${ARGN} )
|
|
SET( SEARCH_PATHS ${SEARCH_PATHS} "${tmp}" )
|
|
SET( SEARCH_PATHS ${SEARCH_PATHS} "${CMAKE_CURRENT_SOURCE_DIR}/${tmp}" )
|
|
ENDFOREACH()
|
|
SET( FILE_TO_COPY )
|
|
FOREACH( tmp ${SEARCH_PATHS} )
|
|
IF ( EXISTS "${tmp}/${SRC}" )
|
|
SET( FILE_TO_COPY "${tmp}/${SRC_NAME}" )
|
|
ENDIF()
|
|
ENDFOREACH()
|
|
IF ( FILE_TO_COPY )
|
|
SET( DESTINATION_NAME ${CMAKE_CURRENT_BINARY_DIR}/${DST_NAME} )
|
|
COPY_DATA_FILE( ${FILE_TO_COPY} ${DESTINATION_NAME} )
|
|
ELSE()
|
|
SET( MSG_STR "Cannot find file: ${SRC_NAME}, searched:\n" )
|
|
FOREACH( tmp ${SEARCH_PATHS} )
|
|
SET( MSG_STR "${MSG_STR} ${tmp}\n" )
|
|
ENDFOREACH()
|
|
MESSAGE( WARNING "test ${MSG_STR}" )
|
|
ENDIF()
|
|
ENDFUNCTION()
|
|
|
|
|
|
# Macro to copy a data file
|
|
FUNCTION( COPY_EXAMPLE_DATA_FILE FILENAME )
|
|
SET( FILE_TO_COPY ${CMAKE_CURRENT_SOURCE_DIR}/data/${FILENAME} )
|
|
SET( DESTINATION1 ${CMAKE_CURRENT_BINARY_DIR}/${FILENAME} )
|
|
SET( DESTINATION2 ${EXAMPLE_INSTALL_DIR}/${FILENAME} )
|
|
IF ( EXISTS ${FILE_TO_COPY} )
|
|
COPY_DATA_FILE( ${FILE_TO_COPY} ${DESTINATION1} )
|
|
COPY_DATA_FILE( ${FILE_TO_COPY} ${DESTINATION2} )
|
|
ELSE()
|
|
MESSAGE( WARNING "Cannot find file: " ${FILE_TO_COPY} )
|
|
ENDIF()
|
|
ENDFUNCTION()
|
|
|
|
|
|
# Macro to copy a mesh file
|
|
MACRO( COPY_MESH_FILE MESHNAME )
|
|
# Check the local data directory
|
|
FILE( GLOB MESHPATH "${CMAKE_CURRENT_SOURCE_DIR}/data/${MESHNAME}" )
|
|
# Search all data paths
|
|
FOREACH ( path ${${PROJ}_DATA} )
|
|
# Check the DATA directory
|
|
IF ( NOT MESHPATH )
|
|
FILE( GLOB MESHPATH "${path}/${MESHNAME}" )
|
|
ENDIF()
|
|
# Check the DATA/vvu directory
|
|
IF ( NOT MESHPATH )
|
|
FILE( GLOB MESHPATH "${path}/vvu/meshes/${MESHNAME}" )
|
|
ENDIF()
|
|
# Check the DATA/meshes directory
|
|
IF ( NOT MESHPATH )
|
|
FILE( GLOB_RECURSE MESHPATH "${path}/meshes/*/${MESHNAME}" )
|
|
ENDIF()
|
|
# Check the entire DATA directory
|
|
IF ( NOT MESHPATH )
|
|
FILE( GLOB_RECURSE MESHPATH "${path}/*/${MESHNAME}" )
|
|
ENDIF()
|
|
ENDFOREACH()
|
|
# We have either found the mesh or failed
|
|
IF ( NOT MESHPATH )
|
|
MESSAGE( WARNING "Cannot find mesh: " ${MESHNAME} )
|
|
ELSE ()
|
|
SET( MESHPATH2 )
|
|
FOREACH( tmp ${MESHPATH} )
|
|
SET( MESHPATH2 "${tmp}" )
|
|
ENDFOREACH()
|
|
STRING(REGEX REPLACE "//${MESHNAME}" "" MESHPATH "${MESHPATH2}" )
|
|
STRING(REGEX REPLACE "${MESHNAME}" "" MESHPATH "${MESHPATH}" )
|
|
COPY_DATA_FILE( "${MESHPATH}/${MESHNAME}" "${CMAKE_CURRENT_BINARY_DIR}/${MESHNAME}" )
|
|
ENDIF()
|
|
ENDMACRO()
|
|
|
|
|
|
# Link the libraries to the given target
|
|
MACRO( TARGET_LINK_EXTERNAL_LIBRARIES TARGET_NAME )
|
|
# Include external libraries
|
|
FOREACH ( tmp ${EXTERNAL_LIBS} )
|
|
TARGET_LINK_LIBRARIES( ${TARGET_NAME} ${ARGN} ${tmp} )
|
|
ENDFOREACH()
|
|
# Include libraries found through the TPL builder
|
|
FOREACH ( tmp ${TPL_LIBS} )
|
|
TARGET_LINK_LIBRARIES( ${TARGET_NAME} ${ARGN} ${tmp} )
|
|
ENDFOREACH()
|
|
# Include CMake implicit libraries
|
|
FOREACH ( tmp ${CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES} ${CMAKE_C_IMPLICIT_LINK_LIBRARIES}
|
|
${CMAKE_CXX_IMPLICIT_LINK_LIBRARIES} ${CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES} )
|
|
TARGET_LINK_LIBRARIES( ${TARGET_NAME} ${ARGN} ${tmp} )
|
|
ENDFOREACH()
|
|
ENDMACRO()
|
|
|
|
|
|
# Choose the debug or optimized library based on the build type
|
|
FUNCTION( KEEP_BUILD_LIBRARIES VAR )
|
|
IF ( ${CMAKE_BUILD_TYPE} STREQUAL "Debug" )
|
|
SET( build_type debug )
|
|
ELSE()
|
|
SET( build_type optimized )
|
|
ENDIF()
|
|
SET( build ${build_type} )
|
|
SET( LIBS )
|
|
FOREACH ( tmp ${${VAR}} )
|
|
IF ( ( ${tmp} STREQUAL debug ) OR ( ${tmp} STREQUAL optimized ) )
|
|
SET( build ${tmp} )
|
|
ELSEIF ( ${build} STREQUAL ${build_type} )
|
|
SET( LIBS ${LIBS} ${tmp} )
|
|
ENDIF()
|
|
ENDFOREACH()
|
|
SET( ${VAR} ${LIBS} PARENT_SCOPE )
|
|
ENDFUNCTION()
|
|
|
|
|
|
# Macro to add the dependencies and libraries to an executable
|
|
MACRO( ADD_PROJ_EXE_DEP EXE )
|
|
# Add the package dependencies
|
|
IF( ${PROJ}_TEST_LIB_EXISTS )
|
|
ADD_DEPENDENCIES( ${EXE} ${PACKAGE_TEST_LIB} )
|
|
TARGET_LINK_LIBRARIES( ${EXE} ${PACKAGE_TEST_LIB} )
|
|
ENDIF()
|
|
# Add the executable to the dependencies of check and build-test
|
|
ADD_DEPENDENCIES( check ${EXE} )
|
|
ADD_DEPENDENCIES( build-test ${EXE} )
|
|
# Add the file copy targets to the dependency list
|
|
IF ( TARGET copy-${PROJ}-Data )
|
|
ADD_DEPENDENCIES( ${EXE} copy-${PROJ}-Data )
|
|
ENDIF()
|
|
# Add the project libraries
|
|
IF ( ${PROJ}_LIB )
|
|
TARGET_LINK_LIBRARIES( ${EXE} ${${PROJ}_LIB} )
|
|
ELSE()
|
|
TARGET_LINK_LIBRARIES( ${EXE} ${${PROJ}_LIBS} ${${PROJ}_LIBS} )
|
|
ENDIF()
|
|
TARGET_LINK_LIBRARIES( ${EXE} ${${PROJECT_NAME}_LIBRARIES} )
|
|
# Add coverage flags to target
|
|
IF ( NOT DISABLE_TARGET_COVERAGE )
|
|
TARGET_COMPILE_DEFINITIONS( ${EXE} PUBLIC ${COVERAGE_FLAGS} )
|
|
ENDIF()
|
|
# Link to external libraries
|
|
TARGET_LINK_LIBRARIES( ${EXE} ${LINK_LIBRARIES} )
|
|
TARGET_LINK_EXTERNAL_LIBRARIES( ${EXE} )
|
|
TARGET_LINK_LIBRARIES( ${EXE} ${COVERAGE_LIBS} ${LDLIBS} ${LDLIBS_EXTRA} )
|
|
TARGET_LINK_LIBRARIES( ${EXE} ${SYSTEM_LIBS} ${SYSTEM_LDFLAGS} )
|
|
# Set extra link flags
|
|
IF ( USE_MPI OR USE_EXT_MPI OR HAVE_MPI )
|
|
SET_TARGET_PROPERTIES( ${EXE} PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS} ${LDFLAGS} ${LDFLAGS_EXTRA}" )
|
|
ELSE()
|
|
SET_TARGET_PROPERTIES( ${EXE} PROPERTIES LINK_FLAGS "${LDFLAGS} ${LDFLAGS_EXTRA}" )
|
|
ENDIF()
|
|
ENDMACRO()
|
|
|
|
|
|
# Check if we want to keep the test
|
|
FUNCTION( KEEP_TEST RESULT )
|
|
SET( ${RESULT} 1 PARENT_SCOPE )
|
|
IF ( NOT DEFINED ${PACKAGE_NAME}_ENABLE_TESTS )
|
|
SET( ${PACKAGE_NAME}_ENABLE_TESTS 1 )
|
|
ENDIF()
|
|
IF ( NOT ${PACKAGE_NAME}_ENABLE_TESTS )
|
|
SET( ${RESULT} 0 PARENT_SCOPE )
|
|
ENDIF()
|
|
IF ( ONLY_BUILD_DOCS )
|
|
SET( ${RESULT} 0 PARENT_SCOPE )
|
|
ENDIF()
|
|
ENDFUNCTION()
|
|
|
|
|
|
# Add a provisional test
|
|
FUNCTION( ADD_PROJ_PROVISIONAL_TEST EXEFILE )
|
|
# Check if we actually want to add the test
|
|
KEEP_TEST( RESULT )
|
|
IF ( NOT RESULT )
|
|
RETURN()
|
|
ENDIF()
|
|
# Check if the target does not exist (may not be added yet or we are re-configuring)
|
|
IF ( NOT TARGET ${EXEFILE} )
|
|
GLOBAL_SET( ${EXEFILE}-BINDIR )
|
|
ENDIF()
|
|
# Check if test has already been added
|
|
IF ( NOT ${EXEFILE}-BINDIR )
|
|
GLOBAL_SET( ${EXEFILE}-BINDIR "${CMAKE_CURRENT_BINARY_DIR}" )
|
|
# The target has not been added
|
|
SET( CXXFILE ${EXEFILE} )
|
|
SET( TESTS_SO_FAR ${TESTS_SO_FAR} ${EXEFILE} )
|
|
# Check if we want to add the test to all
|
|
IF ( NOT EXCLUDE_TESTS_FROM_ALL OR INCLUDE_${EXEFILE} )
|
|
ADD_EXECUTABLE( ${EXEFILE} ${CXXFILE} )
|
|
ELSE()
|
|
ADD_EXECUTABLE( ${EXEFILE} EXCLUDE_FROM_ALL ${CXXFILE} )
|
|
ENDIF()
|
|
ADD_PROJ_EXE_DEP( ${EXEFILE} )
|
|
IF ( CURRENT_LIBRARY )
|
|
IF ( NOT TARGET ${CURRENT_LIBRARY}-test )
|
|
ADD_CUSTOM_TARGET( ${CURRENT_LIBRARY}-test )
|
|
ENDIF()
|
|
ADD_DEPENDENCIES( ${CURRENT_LIBRARY}-test ${EXEFILE} )
|
|
ENDIF()
|
|
ELSEIF ( NOT ${EXEFILE-BINDIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR} )
|
|
# We are trying to add 2 different tests with the same name
|
|
MESSAGE( "Existing test: ${EXEFILE-BINDIR}/${EXEFILE}" )
|
|
MESSAGE( "New test: ${CMAKE_CURRENT_BINARY_DIR}/${EXEFILE}" )
|
|
MESSAGE( FATAL_ERROR "Trying to add 2 different tests with the same name" )
|
|
ENDIF()
|
|
SET( LAST_TEST ${EXEFILE} PARENT_SCOPE )
|
|
ENDFUNCTION()
|
|
FUNCTION( ADD_${PROJ}_PROVISIONAL_TEST EXEFILE )
|
|
ADD_PROJ_PROVISIONAL_TEST( ${EXEFILE} )
|
|
ENDFUNCTION()
|
|
|
|
|
|
# Macro to create the test name
|
|
MACRO( CREATE_TEST_NAME TEST ${ARGN} )
|
|
IF ( PACKAGE )
|
|
SET( TESTNAME "${PACKAGE}::${TEST}" )
|
|
ELSE()
|
|
SET( TESTNAME "${TEST}" )
|
|
ENDIF()
|
|
FOREACH( tmp ${ARGN})
|
|
SET( TESTNAME "${TESTNAME}--${tmp}")
|
|
endforeach()
|
|
SET( LAST_TESTNAME ${TESTNAME} PARENT_SCOPE )
|
|
ENDMACRO()
|
|
|
|
|
|
# Function to add the resource locks to an executable
|
|
FUNCTION( ADD_RESOURCE TESTNAME RESOURCE )
|
|
SET_TESTS_PROPERTIES( ${TESTNAME} PROPERTIES RESOURCE_LOCK ${RESOURCE} )
|
|
ENDFUNCTION()
|
|
FUNCTION( ADD_RESOURCE_LOCKS TESTNAME EXEFILE ${ARGN} )
|
|
IF ( NOT DISABLE_RESOURCE_LOCK )
|
|
IF ( NOT ARGN )
|
|
ADD_RESOURCE( ${TESTNAME} ${EXEFILE} )
|
|
ELSE()
|
|
FOREACH( tmp ${ARGN} )
|
|
ADD_RESOURCE( ${TESTNAME} ${tmp} )
|
|
ENDFOREACH()
|
|
ENDIF()
|
|
ENDIF()
|
|
ENDFUNCTION()
|
|
|
|
|
|
# Function to add a test
|
|
FUNCTION( CALL_ADD_TEST EXEFILE PROCS THREADS WEEKLY TESTBUILDER ${ARGN} )
|
|
# Check if we actually want to add the test
|
|
KEEP_TEST( RESULT )
|
|
IF ( NOT RESULT )
|
|
MESSAGE( "Discarding test: ${EXEFILE}" )
|
|
RETURN()
|
|
ENDIF()
|
|
# Check if we are dealing with a TestBuilder test
|
|
IF ( ${TESTBUILDER} )
|
|
# Add the test to the TestBuilder sources
|
|
SET( TESTBUILDER_SOURCES ${TESTBUILDER_SOURCES} ${EXEFILE} PARENT_SCOPE )
|
|
ELSE()
|
|
# Add the provisional test
|
|
ADD_PROJ_PROVISIONAL_TEST( ${EXEFILE} )
|
|
ENDIF()
|
|
# Create the test name
|
|
SET( TESTNAME ${EXEFILE} )
|
|
#IF ( ${TESTBUILDER} )
|
|
# SET( TESTNAME TB_${TESTNAME} )
|
|
#ENDIF()
|
|
IF ( "${PROCS}" GREATER "1")
|
|
SET( TESTNAME ${TESTNAME}_${PROCS}procs )
|
|
ENDIF()
|
|
IF ( "${THREADS}" GREATER "1")
|
|
SET( TESTNAME ${TESTNAME}_${THREADS}threads )
|
|
ENDIF()
|
|
IF ( ${WEEKLY} )
|
|
SET( TESTNAME ${TESTNAME}_WEEKLY )
|
|
ENDIF()
|
|
CREATE_TEST_NAME( ${TESTNAME} ${ARGN} )
|
|
# Create the tests for ctest
|
|
MATH( EXPR TOT_PROCS "${PROCS} * ${THREADS}" )
|
|
IF ( ${TOT_PROCS} EQUAL 0 )
|
|
# Skip test (provisional)
|
|
ELSEIF ( ${TOT_PROCS} GREATER ${TEST_MAX_PROCS} )
|
|
MESSAGE("Disabling test ${TESTNAME} (exceeds maximum number of processors ${TEST_MAX_PROCS})")
|
|
ELSEIF ( ( ${PROCS} STREQUAL "1" ) AND NOT USE_MPI_FOR_SERIAL_TESTS )
|
|
IF ( ${TESTBUILDER} )
|
|
ADD_TEST( NAME ${TESTNAME} COMMAND $<TARGET_FILE:${TB_TARGET}> ${EXEFILE} ${ARGN} )
|
|
ELSE()
|
|
ADD_TEST( NAME ${TESTNAME} COMMAND $<TARGET_FILE:${LAST_TEST}> ${ARGN} )
|
|
ENDIF()
|
|
SET_TESTS_PROPERTIES( ${TESTNAME} PROPERTIES FAIL_REGULAR_EXPRESSION "${TEST_FAIL_REGULAR_EXPRESSION}" PROCESSORS ${TOT_PROCS} )
|
|
ADD_RESOURCE_LOCKS( ${TESTNAME} ${EXEFILE} ${ARGN} )
|
|
ELSEIF ( USE_MPI OR USE_EXT_MPI )
|
|
IF ( ${TESTBUILDER} )
|
|
ADD_TEST( NAME ${TESTNAME} COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${PROCS} $<TARGET_FILE:${TB_TARGET}> ${EXEFILE} ${ARGN} )
|
|
ELSE()
|
|
ADD_TEST( NAME ${TESTNAME} COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${PROCS} $<TARGET_FILE:${LAST_TEST}> ${ARGN} )
|
|
ENDIF()
|
|
SET_PROPERTY( TEST ${TESTNAME} APPEND PROPERTY ENVIRONMENT OMPI_MCA_hwloc_base_binding_policy=none )
|
|
SET_TESTS_PROPERTIES( ${TESTNAME} PROPERTIES FAIL_REGULAR_EXPRESSION "${TEST_FAIL_REGULAR_EXPRESSION}" PROCESSORS ${TOT_PROCS} )
|
|
ADD_RESOURCE_LOCKS( ${TESTNAME} ${EXEFILE} ${ARGN} )
|
|
ENDIF()
|
|
ENDFUNCTION()
|
|
|
|
|
|
# Functions to create a test builder
|
|
FUNCTION( INITIALIZE_TESTBUILDER )
|
|
SET( TESTBUILDER_SOURCES PARENT_SCOPE )
|
|
# Check if we actually want to add the test
|
|
KEEP_TEST( RESULT )
|
|
IF ( NOT RESULT )
|
|
RETURN()
|
|
ENDIF()
|
|
# Check if the target does not exist (may not be added yet or we are re-configuring)
|
|
STRING(REGEX REPLACE "${${PROJ}_SOURCE_DIR}/" "" TB_TARGET "TB-${PROJ}-${CMAKE_CURRENT_SOURCE_DIR}" )
|
|
STRING(REGEX REPLACE "/" "-" TB_TARGET ${TB_TARGET} )
|
|
IF ( NOT TARGET ${TB_TARGET} )
|
|
GLOBAL_SET( ${TB_TARGET}-BINDIR )
|
|
ENDIF()
|
|
# Check if test has already been added
|
|
IF ( NOT ${TB_TARGET}-BINDIR )
|
|
GLOBAL_SET( ${TB_TARGET}-BINDIR "${CMAKE_CURRENT_BINARY_DIR}" )
|
|
# Create the initial file
|
|
IF ( NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/TestBuilder.cpp" )
|
|
FILE( WRITE "${CMAKE_CURRENT_BINARY_DIR}/TestBuilder.cpp" "// Auto generated file\n\n" )
|
|
ENDIF()
|
|
# The target has not been added
|
|
SET( CXXFILE "${CMAKE_CURRENT_BINARY_DIR}/TestBuilder.cpp" )
|
|
SET( TESTS_SO_FAR ${TESTS_SO_FAR} ${TB_TARGET} )
|
|
# Check if we want to add the test to all
|
|
IF ( NOT EXCLUDE_TESTS_FROM_ALL )
|
|
ADD_EXECUTABLE( ${TB_TARGET} ${CXXFILE} )
|
|
ELSE()
|
|
ADD_EXECUTABLE( ${TB_TARGET} EXCLUDE_FROM_ALL ${CXXFILE} )
|
|
ENDIF()
|
|
SET_TARGET_PROPERTIES( ${TB_TARGET} PROPERTIES OUTPUT_NAME "TB" )
|
|
ELSEIF ( NOT ${TB-BINDIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR} )
|
|
# We are trying to add 2 different tests with the same name
|
|
MESSAGE( "Existing test: ${TB-BINDIR}/${TB_TARGET}" )
|
|
MESSAGE( "New test: ${CMAKE_CURRENT_BINARY_DIR}/${TB_TARGET}}" )
|
|
MESSAGE( FATAL_ERROR "Trying to add 2 different tests with the same name" )
|
|
ENDIF()
|
|
SET( TB_TARGET ${TB_TARGET} PARENT_SCOPE )
|
|
ENDFUNCTION()
|
|
FUNCTION( FINALIZE_TESTBUILDER )
|
|
# Check if we actually want to add the test
|
|
KEEP_TEST( RESULT )
|
|
IF ( NOT RESULT )
|
|
RETURN()
|
|
ENDIF()
|
|
# Create the library for the test builder
|
|
IF ( TESTBUILDER_SOURCES )
|
|
LIST( REMOVE_DUPLICATES TESTBUILDER_SOURCES )
|
|
SET( TB_TARGET_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/TestBuilder.cpp" )
|
|
FOREACH ( tmp ${TESTBUILDER_SOURCES} )
|
|
GET_FILENAME_COMPONENT( tmp ${tmp} ABSOLUTE )
|
|
SET( TB_TARGET_SOURCES ${TB_TARGET_SOURCES} ${tmp} )
|
|
ENDFOREACH()
|
|
TARGET_SOURCES( ${TB_TARGET} PUBLIC ${TB_TARGET_SOURCES} )
|
|
ADD_DEPENDENCIES( ${TB_TARGET} copy-${PROJ}-include )
|
|
ENDIF()
|
|
# Add the dependencies to the test builder
|
|
ADD_PROJ_EXE_DEP( ${TB_TARGET} )
|
|
IF ( CURRENT_LIBRARY )
|
|
IF ( NOT TARGET ${CURRENT_LIBRARY}-test )
|
|
ADD_CUSTOM_TARGET( ${CURRENT_LIBRARY}-test )
|
|
ENDIF()
|
|
ADD_DEPENDENCIES( ${CURRENT_LIBRARY}-test ${TB_TARGET} )
|
|
ENDIF()
|
|
SET( TB_TARGET ${TB_TARGET} PARENT_SCOPE )
|
|
# Finish generating TestBuilder.cpp
|
|
SET( TB_FILE "${CMAKE_CURRENT_BINARY_DIR}/TestBuilder-tmp.cpp" )
|
|
FILE( WRITE "${TB_FILE}" "// Auto generated file\n\n" )
|
|
FILE( APPEND "${TB_FILE}" "#include <cstring>\n" )
|
|
FILE( APPEND "${TB_FILE}" "#include <iostream>\n\n" )
|
|
FOREACH( tmp ${TESTBUILDER_SOURCES} )
|
|
FILE( APPEND "${TB_FILE}" "extern int ${tmp}( int argc, char *argv[] );\n" )
|
|
ENDFOREACH()
|
|
FILE( APPEND "${TB_FILE}" "\n\n// Main Program\n" )
|
|
FILE( APPEND "${TB_FILE}" "int main( int argc, char *argv[] )\n" )
|
|
FILE( APPEND "${TB_FILE}" "{\n" )
|
|
FILE( APPEND "${TB_FILE}" " if ( argc < 2 ) {\n" )
|
|
FILE( APPEND "${TB_FILE}" " std::cerr << \"Invaild number of arguments for TestBuilder\";\n " )
|
|
FILE( APPEND "${TB_FILE}" " return 1;\n" )
|
|
FILE( APPEND "${TB_FILE}" " }\n\n" )
|
|
FILE( APPEND "${TB_FILE}" " int rtn = 0;\n" )
|
|
FILE( APPEND "${TB_FILE}" " if ( strcmp( argv[1], \"NULL\" ) == 0 ) {\n" )
|
|
FOREACH( tmp ${TESTBUILDER_SOURCES} )
|
|
FILE( APPEND "${TB_FILE}" " } else if ( strcmp( argv[1], \"${tmp}\" ) == 0 ) {\n" )
|
|
FILE( APPEND "${TB_FILE}" " rtn = ${tmp}( argc-1, &argv[1] );\n" )
|
|
ENDFOREACH()
|
|
FILE( APPEND "${TB_FILE}" " } else {\n" )
|
|
FILE( APPEND "${TB_FILE}" " std::cerr << \"Unknown test\";\n" )
|
|
FILE( APPEND "${TB_FILE}" " return 1;\n" )
|
|
FILE( APPEND "${TB_FILE}" " }\n\n" )
|
|
FILE( APPEND "${TB_FILE}" " return rtn;\n" )
|
|
FILE( APPEND "${TB_FILE}" "}\n" )
|
|
EXECUTE_PROCESS( COMMAND ${CMAKE_COMMAND} -E copy_if_different "${TB_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/TestBuilder.cpp" )
|
|
ENDFUNCTION()
|
|
|
|
|
|
# Convience functions to add a test
|
|
MACRO( ADD_${PROJ}_TEST EXEFILE ${ARGN} )
|
|
CALL_ADD_TEST( ${EXEFILE} 1 1 FALSE FALSE ${ARGN} )
|
|
ENDMACRO()
|
|
MACRO( ADD_${PROJ}_TEST_PARALLEL EXEFILE PROCS ${ARGN} )
|
|
CALL_ADD_TEST( ${EXEFILE} ${PROCS} 1 FALSE FALSE ${ARGN} )
|
|
ENDMACRO()
|
|
MACRO( ADD_${PROJ}_WEEKLY_TEST EXEFILE PROCS ${ARGN} )
|
|
CALL_ADD_TEST( ${EXEFILE} ${PROCS} 1 TRUE FALSE ${ARGN} )
|
|
ENDMACRO()
|
|
MACRO( ADD_${PROJ}_TEST_THREAD_MPI EXEFILE PROCS THREADS ${ARGN} )
|
|
CALL_ADD_TEST( ${EXEFILE} ${PROCS} ${THREADS} FALSE FALSE ${ARGN} )
|
|
ENDMACRO()
|
|
MACRO( ADD_${PROJ}_TEST_1_2_4 EXEFILE ${ARGN} )
|
|
CALL_ADD_TEST( ${EXEFILE} 1 1 FALSE FALSE ${ARGN} )
|
|
CALL_ADD_TEST( ${EXEFILE} 2 1 FALSE FALSE ${ARGN} )
|
|
CALL_ADD_TEST( ${EXEFILE} 4 1 FALSE FALSE ${ARGN} )
|
|
ENDMACRO()
|
|
MACRO( ADD_TB_PROVISIONAL_TEST EXEFILE ${ARGN} )
|
|
CALL_ADD_TEST( ${EXEFILE} 0 1 FALSE TRUE ${ARGN} )
|
|
ENDMACRO()
|
|
MACRO( ADD_TB_TEST EXEFILE ${ARGN} )
|
|
CALL_ADD_TEST( ${EXEFILE} 1 1 FALSE TRUE ${ARGN} )
|
|
ENDMACRO()
|
|
MACRO( ADD_TB_TEST_PARALLEL EXEFILE PROCS ${ARGN} )
|
|
CALL_ADD_TEST( ${EXEFILE} ${PROCS} 1 FALSE TRUE ${ARGN} )
|
|
ENDMACRO()
|
|
MACRO( ADD_TB_WEEKLY_TEST EXEFILE PROCS ${ARGN} )
|
|
CALL_ADD_TEST( ${EXEFILE} ${PROCS} 1 TRUE TRUE ${ARGN} )
|
|
ENDMACRO()
|
|
MACRO( ADD_TB_TEST_THREAD_MPI EXEFILE PROCS THREADS ${ARGN} )
|
|
CALL_ADD_TEST( ${EXEFILE} ${PROCS} ${THREADS} FALSE TRUE ${ARGN} )
|
|
ENDMACRO()
|
|
MACRO( ADD_TB_TEST_1_2_4 EXEFILE ${ARGN} )
|
|
CALL_ADD_TEST( ${EXEFILE} 1 1 FALSE TRUE ${ARGN} )
|
|
CALL_ADD_TEST( ${EXEFILE} 2 1 FALSE TRUE ${ARGN} )
|
|
CALL_ADD_TEST( ${EXEFILE} 4 1 FALSE TRUE ${ARGN} )
|
|
ENDMACRO()
|
|
|
|
|
|
# Add a executable as an example
|
|
FUNCTION( ADD_${PROJ}_EXAMPLE EXEFILE PROCS ${ARGN} )
|
|
# Add the file to the example doxygen file
|
|
SET( VALUE 0 )
|
|
FOREACH(_variableName ${EXAMPLE_LIST})
|
|
IF ( "${_variableName}" STREQUAL "${EXEFILE}" )
|
|
SET( VALUE 1 )
|
|
ENDIF()
|
|
ENDFOREACH()
|
|
IF ( NOT ${VALUE} )
|
|
FILE(APPEND ${EXAMPLE_INSTALL_DIR}/examples.h "* \\ref ${EXEFILE} \"${EXEFILE}\"\n" )
|
|
SET( EXAMPLE_LIST ${EXAMPLE_LIST} ${EXEFILE} CACHE INTERNAL "example_list" FORCE )
|
|
ENDIF()
|
|
# Check if we actually want to add the test
|
|
IF ( ONLY_BUILD_DOCS )
|
|
RETURN()
|
|
ENDIF()
|
|
# Add the provisional test
|
|
ADD_PROJ_PROVISIONAL_TEST( ${EXEFILE} )
|
|
ADD_DEPENDENCIES( build-examples ${EXEFILE} )
|
|
ADD_CUSTOM_COMMAND( TARGET ${EXEFILE} POST_BUILD
|
|
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${LAST_TEST}> "${EXAMPLE_INSTALL_DIR}/${EXEFILE}"
|
|
)
|
|
IF( ${PROCS} STREQUAL "1" AND (NOT USE_MPI_FOR_SERIAL_TESTS) )
|
|
CREATE_TEST_NAME( "example--${EXEFILE}" ${ARGN} )
|
|
ADD_TEST( NAME ${TESTNAME} COMMAND $<TARGET_FILE:${LAST_TEST}> ${ARGN} )
|
|
ELSEIF ( USE_EXT_MPI AND NOT (${PROCS} GREATER ${TEST_MAX_PROCS}) )
|
|
CREATE_TEST_NAME( "example--${EXEFILE}_${PROCS}procs" ${ARGN} )
|
|
ADD_TEST( NAME ${TESTNAME} COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${PROCS} $<TARGET_FILE:${LAST_TEST}> ${ARGN} )
|
|
SET_PROPERTY( TEST ${TESTNAME} APPEND PROPERTY ENVIRONMENT OMPI_MCA_hwloc_base_binding_policy=none )
|
|
ENDIF()
|
|
SET_TESTS_PROPERTIES( ${TESTNAME} PROPERTIES FAIL_REGULAR_EXPRESSION "${TEST_FAIL_REGULAR_EXPRESSION}" PROCESSORS ${PROCS} )
|
|
SET_TESTS_PROPERTIES( ${TESTNAME} PROPERTIES RESOURCE_LOCK ${EXEFILE} )
|
|
ENDFUNCTION()
|
|
|
|
|
|
# Begin configure for the examples for a package
|
|
MACRO( BEGIN_EXAMPLE_CONFIG PACKAGE )
|
|
# Set example install dir
|
|
SET( EXAMPLE_INSTALL_DIR ${${PROJ}_INSTALL_DIR}/examples/${PACKAGE} )
|
|
# Create list of examples
|
|
SET( EXAMPLE_LIST "dummy" CACHE INTERNAL "example_list" FORCE )
|
|
# Create doxygen input file for examples
|
|
SET( DOXYFILE_EXTRA_SOURCES ${DOXYFILE_EXTRA_SOURCES} ${EXAMPLE_INSTALL_DIR} CACHE INTERNAL "doxyfile_extra_sources")
|
|
FILE(WRITE ${EXAMPLE_INSTALL_DIR}/examples.h "// Include file for doxygen providing the examples for ${PACKAGE}\n")
|
|
FILE(APPEND ${EXAMPLE_INSTALL_DIR}/examples.h "/*! \\page Examples_${PACKAGE}\n" )
|
|
ENDMACRO()
|
|
|
|
|
|
# Install the examples
|
|
MACRO( INSTALL_${PROJ}_EXAMPLE PACKAGE )
|
|
FILE(APPEND ${EXAMPLE_INSTALL_DIR}/examples.h "*/\n" )
|
|
SET( EXAMPLE_INSTALL_DIR "" )
|
|
ENDMACRO()
|
|
|
|
|
|
# Macro to check if a flag is enabled
|
|
MACRO( CHECK_ENABLE_FLAG FLAG DEFAULT )
|
|
IF( NOT DEFINED ${FLAG} )
|
|
SET( ${FLAG} ${DEFAULT} )
|
|
ELSEIF( ${FLAG} STREQUAL "" )
|
|
SET( ${FLAG} ${DEFAULT} )
|
|
ELSEIF( ( ${${FLAG}} STREQUAL "FALSE" ) OR ( ${${FLAG}} STREQUAL "false" ) OR ( ${${FLAG}} STREQUAL "0" ) OR ( ${${FLAG}} STREQUAL "OFF" ) )
|
|
SET( ${FLAG} 0 )
|
|
ELSEIF( ( ${${FLAG}} STREQUAL "TRUE" ) OR ( ${${FLAG}} STREQUAL "true" ) OR ( ${${FLAG}} STREQUAL "1" ) OR ( ${${FLAG}} STREQUAL "ON" ) )
|
|
SET( ${FLAG} 1 )
|
|
ELSE()
|
|
MESSAGE( "Bad value for ${FLAG} (${${FLAG}}); use true or false" )
|
|
ENDIF()
|
|
ENDMACRO()
|
|
|
|
|
|
# Macro to add a latex file to the build
|
|
MACRO( ADD_LATEX_DOCS FILE )
|
|
GET_FILENAME_COMPONENT(LATEX_TARGET ${FILE} NAME_WE)
|
|
ADD_CUSTOM_TARGET(
|
|
${LATEX_TARGET}_pdf
|
|
${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${FILE} ${CMAKE_CURRENT_BINARY_DIR}/.
|
|
COMMAND pdflatex -interaction=batchmode -draftmode ${FILE} ";" echo ""
|
|
COMMAND bibtex -terse ${LATEX_TARGET} ";" echo ""
|
|
COMMAND pdflatex -interaction=batchmode ${FILE} ";" echo ""
|
|
SOURCES ${FILE}
|
|
)
|
|
ADD_CUSTOM_COMMAND(
|
|
TARGET ${LATEX_TARGET}_pdf
|
|
POST_BUILD
|
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/${LATEX_TARGET}.pdf ${${PROJ}_INSTALL_DIR}/doc/.
|
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
|
)
|
|
ADD_DEPENDENCIES( latex_docs ${LATEX_TARGET}_pdf )
|
|
ENDMACRO()
|
|
|
|
|
|
# Add a matlab mex file
|
|
FUNCTION( ADD_MATLAB_MEX SOURCE )
|
|
STRING( REGEX REPLACE "[.]cpp" "" TARGET ${SOURCE} )
|
|
STRING( REGEX REPLACE "[.]c" "" TARGET ${TARGET} )
|
|
MATLAB_ADD_MEX(
|
|
NAME ${TARGET}
|
|
SRC ${SOURCE}
|
|
MODULE
|
|
R2017b
|
|
)
|
|
TARGET_LINK_LIBRARIES( ${TARGET} ${MATLAB_TARGET} )
|
|
ADD_PROJ_EXE_DEP( ${TARGET} )
|
|
ADD_DEPENDENCIES( mex ${TARGET} )
|
|
INSTALL( TARGETS ${TARGET} DESTINATION ${${PROJ}_INSTALL_DIR}/mex )
|
|
ADD_DEPENDENCIES( mex ${TARGET} )
|
|
SET( MEX_FILES2 ${MEX_FILES} "${${PROJ}_INSTALL_DIR}/mex/${TARGET}.${Matlab_MEX_EXTENSION}" )
|
|
LIST( REMOVE_DUPLICATES MEX_FILES2 )
|
|
SET( MEX_FILES ${MEX_FILES2} CACHE INTERNAL "" )
|
|
ENDFUNCTION()
|
|
|
|
|
|
# Add a matlab test
|
|
MACRO( ADD_MATLAB_TEST EXEFILE ${ARGN} )
|
|
IF ( NOT MATLAB_EXE )
|
|
MESSAGE( FATAL_ERROR "MATLAB_EXE not set, did you call CREATE_MATLAB_WRAPPER()" )
|
|
ENDIF()
|
|
CONFIGURE_FILE( ${EXEFILE}.m ${CMAKE_CURRENT_BINARY_DIR}/${EXEFILE}.m )
|
|
CREATE_TEST_NAME( MATLAB ${EXEFILE} ${ARGN} )
|
|
IF ( USING_MSVC )
|
|
SET( MATLAB_OPTIONS "-logfile" "log_${EXEFILE}" )
|
|
ENDIF()
|
|
SET( MATLAB_COMMAND "try, ${EXEFILE}, catch ME, disp(getReport(ME)), clear all global, exit(1), end, disp('ALL TESTS PASSED'); exit(0)" )
|
|
SET( MATLAB_DEBUGGER_OPTIONS )
|
|
IF ( MATLAB_DEBUGGER )
|
|
SET( MATLAB_DEBUGGER_OPTIONS -D${MATLAB_DEBUGGER} )
|
|
STRING(REPLACE "\"" "" MATLAB_DEBUGGER_OPTIONS "${MATLAB_DEBUGGER_OPTIONS}")
|
|
ENDIF()
|
|
ADD_TEST( NAME ${TESTNAME} COMMAND "${MATLAB_EXE}" ${MATLAB_OPTIONS} -r "${MATLAB_COMMAND}" ${MATLAB_DEBUGGER_OPTIONS} )
|
|
SET_TESTS_PROPERTIES( ${TESTNAME} PROPERTIES PASS_REGULAR_EXPRESSION "ALL TESTS PASSED" FAIL_REGULAR_EXPRESSION "FAILED" )
|
|
SET_PROPERTY(TEST ${TESTNAME} APPEND PROPERTY ENVIRONMENT RATES_DIRECTORY=${RATES_DIRECTORY} )
|
|
ENDMACRO()
|
|
|
|
|
|
# Create a script to start matlab preloading libraries
|
|
FUNCTION( CREATE_MATLAB_WRAPPER )
|
|
SET( MATLABPATH ${MATLABPATH} "${${PROJ}_INSTALL_DIR}/mex" )
|
|
SET( tmp_libs ${MEX_LIBCXX} ${MEX_FILES} )
|
|
LIST( REMOVE_DUPLICATES MATLABPATH )
|
|
STRING( REGEX REPLACE ";" ":" tmp_libs "${tmp_libs}" )
|
|
STRING( REGEX REPLACE ";" ":" tmp_path "${MATLABPATH}" )
|
|
IF ( USING_MSVC )
|
|
# Create a matlab wrapper for windows
|
|
SET( MATLAB_GUI "${CMAKE_CURRENT_BINARY_DIR}/tmp/matlab-gui.bat" )
|
|
SET( MATLAB_CMD "${CMAKE_CURRENT_BINARY_DIR}/tmp/matlab-cmd.bat" )
|
|
SET( MATLAB_INSTALL_CMD "matlab-cmd.bat" )
|
|
FILE( WRITE "${MATLAB_GUI}" "@echo off\n")
|
|
FILE( WRITE "${MATLAB_CMD}" "@echo off\n")
|
|
FILE( APPEND "${MATLAB_GUI}" "matlab -singleCompThread -nosplash %*\n")
|
|
FILE( APPEND "${MATLAB_CMD}" "matlab -singleCompThread -nosplash -nodisplay -nodesktop -wait %*\n")
|
|
FILE( WRITE "${MATLAB_GUI}" "@echo on\n")
|
|
FILE( WRITE "$${MATLAB_CMD}" "@echo on\n")
|
|
ELSE()
|
|
# Create a matlab wrapper for linux/mac
|
|
SET( MATLAB_GUI "${CMAKE_CURRENT_BINARY_DIR}/tmp/matlab-gui" )
|
|
SET( MATLAB_CMD "${CMAKE_CURRENT_BINARY_DIR}/tmp/matlab-cmd" )
|
|
SET( MATLAB_INSTALL_CMD "matlab-cmd" )
|
|
FILE( WRITE "${MATLAB_GUI}" "LD_PRELOAD=\"${tmp_libs}\" MKL_NUM_THREADS=1 MATLABPATH=\"${tmp_path}\" \"${Matlab_MAIN_PROGRAM}\" -singleCompThread -nosplash \"$@\"\n")
|
|
FILE( WRITE "${MATLAB_CMD}" "LD_PRELOAD=\"${tmp_libs}\" MKL_NUM_THREADS=1 MATLABPATH=\"${tmp_path}\" \"${Matlab_MAIN_PROGRAM}\" -singleCompThread -nosplash -nodisplay -nojvm \"$@\"\n")
|
|
ENDIF()
|
|
FILE( COPY "${MATLAB_GUI}" DESTINATION "${${PROJ}_INSTALL_DIR}/mex"
|
|
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
|
|
FILE( COPY "${MATLAB_CMD}" DESTINATION "${${PROJ}_INSTALL_DIR}/mex"
|
|
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE )
|
|
SET( MATLAB_EXE "${${PROJ}_INSTALL_DIR}/mex/${MATLAB_INSTALL_CMD}" CACHE INTERNAL "" )
|
|
ENDFUNCTION()
|
|
|
|
|
|
# Macro to change the classification of a package
|
|
MACRO( SET_PACKAGE_CLASSIFICATION PACKAGE_LIST PACKAGE_NAME CLASS )
|
|
LIST(FIND ${PACKAGE_LIST} ${PACKAGE_NAME} PACKAGE_NAME_IDX)
|
|
IF (PACKAGE_NAME_IDX EQUAL -1)
|
|
MESSAGE(FATAL_ERROR "Package ${PACKAGE_NAME} not found in list of packages!")
|
|
ELSE()
|
|
MATH(EXPR PACKAGE_CLASSIFICATION_IDX "${PACKAGE_NAME_IDX}+2")
|
|
LIST(INSERT ${PACKAGE_LIST} ${PACKAGE_CLASSIFICATION_IDX} ${CLASS})
|
|
MATH(EXPR PACKAGE_CLASSIFICATION_IDX "${PACKAGE_CLASSIFICATION_IDX} + 1")
|
|
LIST(REMOVE_AT ${PACKAGE_LIST} ${PACKAGE_CLASSIFICATION_IDX})
|
|
ENDIF()
|
|
ENDMACRO()
|
|
|
|
|
|
# Macro to "disable" a package on the given platform (this mearly changes it to experimental)
|
|
MACRO( PACKAGE_DISABLE_ON_PLATFORMS PACKAGE_LIST PACKAGE_NAME )
|
|
FOREACH(HOSTTYPE ${ARGN})
|
|
IF (${PROJECT_NAME}_HOSTTYPE STREQUAL ${HOSTTYPE})
|
|
SET_PACKAGE_CLASSIFICATION(${PACKAGE_LIST} ${PACKAGE_NAME} EX)
|
|
IF (${PROJECT_NAME}_ENABLE_${PACKAGE_NAME})
|
|
MESSAGE(
|
|
"\n***"
|
|
"\n*** WARNING: User has set ${PROJECT_NAME}_ENABLE_${PACKAGE_NAME}=ON but the"
|
|
"\n*** package ${PACKAGE_NAME} is not supported on this platform type '${HOSTTYPE}'!"
|
|
"\n***\n"
|
|
)
|
|
ENDIF()
|
|
ENDIF()
|
|
ENDFOREACH()
|
|
ENDMACRO()
|
|
|
|
|
|
# Append a list to a file
|
|
FUNCTION( APPEND_LIST FILENAME VARS PREFIX POSTFIX )
|
|
FOREACH( tmp ${VARS} )
|
|
FILE( APPEND "${FILENAME}" "${PREFIX}" )
|
|
FILE( APPEND "${FILENAME}" "${tmp}" )
|
|
FILE( APPEND "${FILENAME}" "${POSTFIX}" )
|
|
ENDFOREACH ()
|
|
ENDFUNCTION()
|
|
|
|
|
|
# add custom target distclean
|
|
# cleans and removes cmake generated files etc.
|
|
MACRO( ADD_DISTCLEAN ${ARGN} )
|
|
SET(DISTCLEANED
|
|
cmake.depends
|
|
cmake.check_depends
|
|
CMakeCache.txt
|
|
CMakeFiles
|
|
CMakeTmp
|
|
CMakeDoxy*
|
|
cmake.check_cache
|
|
*.cmake
|
|
compile.log
|
|
Doxyfile
|
|
Makefile
|
|
core core.*
|
|
DartConfiguration.tcl
|
|
install_manifest.txt
|
|
Testing
|
|
include
|
|
doc
|
|
docs
|
|
examples
|
|
latex_docs
|
|
lib
|
|
Makefile.config
|
|
install_manifest.txt
|
|
test
|
|
matlab
|
|
Matlab
|
|
mex
|
|
tmp
|
|
#tmp#
|
|
bin
|
|
cmake
|
|
cppclean
|
|
compile_commands.json
|
|
${ARGN}
|
|
)
|
|
ADD_CUSTOM_TARGET(distclean @echo cleaning for source distribution)
|
|
IF (UNIX)
|
|
ADD_CUSTOM_COMMAND(
|
|
DEPENDS clean
|
|
COMMENT "distribution clean"
|
|
COMMAND rm
|
|
ARGS -Rf ${DISTCLEANED}
|
|
TARGET distclean
|
|
)
|
|
ELSE()
|
|
SET( DISTCLEANED
|
|
${DISTCLEANED}
|
|
*.vcxproj*
|
|
ipch
|
|
x64
|
|
Debug
|
|
)
|
|
SET( DISTCLEAN_FILE "${CMAKE_CURRENT_BINARY_DIR}/distclean.bat" )
|
|
FILE( WRITE "${DISTCLEAN_FILE}" "del /s /q /f " )
|
|
APPEND_LIST( "${DISTCLEAN_FILE}" "${DISTCLEANED}" " " " " )
|
|
FILE( APPEND "${DISTCLEAN_FILE}" "\n" )
|
|
APPEND_LIST( "${DISTCLEAN_FILE}" "${DISTCLEANED}" "for /d %%x in (" ") do rd /s /q \"%%x\"\n" )
|
|
ADD_CUSTOM_COMMAND(
|
|
DEPENDS clean
|
|
COMMENT "distribution clean"
|
|
COMMAND distclean.bat & del /s/q/f distclean.bat
|
|
TARGET distclean
|
|
)
|
|
ENDIF()
|
|
ENDMACRO()
|
|
|
|
|
|
# add custom target mex_clean
|
|
MACRO( ADD_MEXCLEAN )
|
|
IF (UNIX)
|
|
ADD_CUSTOM_TARGET( mexclean
|
|
COMMENT "mex clean"
|
|
COMMAND rm
|
|
ARGS -Rf libmatlab.* *.mex* test/*.mex*
|
|
)
|
|
ENDIF(UNIX)
|
|
ENDMACRO()
|
|
|
|
|
|
# Print the current repo version and create target to write to a file
|
|
SET( WriteRepoVersionCmakeFile "${CMAKE_CURRENT_LIST_DIR}/WriteRepoVersion.cmake" )
|
|
FUNCTION( WRITE_REPO_VERSION FILENAME )
|
|
SET( CMD ${CMAKE_COMMAND} -Dfilename="${FILENAME}" -Dsrc_dir="${${PROJ}_SOURCE_DIR}"
|
|
-Dtmp_file="${CMAKE_CURRENT_BINARY_DIR}/tmp/version.h" -DPROJ=${PROJ}
|
|
-P "${WriteRepoVersionCmakeFile}" )
|
|
EXECUTE_PROCESS( COMMAND ${CMD} )
|
|
ADD_CUSTOM_TARGET( write_repo_version COMMENT "Write repo version" COMMAND ${CMD} )
|
|
ENDFUNCTION()
|
|
|
|
|
|
# Check if we can include a python module
|
|
FUNCTION( FIND_PYTHON_MODULE MODULE)
|
|
STRING(TOUPPER ${MODULE} MODULE2)
|
|
SET( PY_${MODULE}_FOUND FALSE )
|
|
IF ( NOT PY_${MODULE2} )
|
|
IF ( ARGC GREATER 1 AND ARGV1 STREQUAL "REQUIRED" )
|
|
SET(PY_${MODULE2}_FIND_REQUIRED TRUE)
|
|
ENDIF()
|
|
SET( CMD "import ${MODULE}; print('Success')" )
|
|
EXECUTE_PROCESS(COMMAND "${PYTHON_EXECUTABLE}" "-c" "${CMD}"
|
|
RESULT_VARIABLE _${MODULE2}_status
|
|
OUTPUT_VARIABLE _${MODULE2}_output
|
|
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE )
|
|
IF ( "${_${MODULE2}_output}" STREQUAL "Success" )
|
|
SET( PY_${MODULE2}_FOUND TRUE )
|
|
ENDIF()
|
|
ELSE()
|
|
SET( PY_${MODULE2}_FOUND TRUE )
|
|
ENDIF()
|
|
IF ( PY_${MODULE2}_FOUND )
|
|
MESSAGE( STATUS "Performing Test PYTHON_${MODULE2} - Success" )
|
|
ELSE()
|
|
MESSAGE( STATUS "Performing Test PYTHON_${MODULE2} - Failure" )
|
|
ENDIF()
|
|
IF ( NOT PY_${MODULE2}_FOUND AND PY_${MODULE2}_FIND_REQUIRED )
|
|
MESSAGE( FATAL_ERROR "Unable to find required python module: ${MODULE2}" )
|
|
ENDIF()
|
|
SET( PY_${MODULE2}_FOUND ${PY_${MODULE2}_FOUND} PARENT_SCOPE )
|
|
ENDFUNCTION(FIND_PYTHON_MODULE)
|
|
|