cmake_minimum_required (VERSION 3.4) # CMake utils list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") # Forbids in-source builds include(CheckNotInSources) #------------------------------------------------------ #----------------- Main configuration ----------------- #------------------------------------------------------ project (Pastis VERSION 0.3.0) #------------------------------------------------------ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) #------------------------------------------------------ set(PASTIS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") set(PASTIS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}") # Add new build types message("* Adding build types...") SET(CMAKE_CXX_FLAGS_COVERAGE "-g -Wall -O0 --coverage" CACHE STRING "Flags used by the C++ compiler during coverage builds." FORCE ) SET(CMAKE_C_FLAGS_COVERAGE "-g -Wall -O0 --coverage" CACHE STRING "Flags used by the C compiler during coverage builds." FORCE ) SET(CMAKE_EXE_LINKER_FLAGS_COVERAGE "--coverage" CACHE STRING "Flags used for linking binaries during coverage builds." FORCE ) SET(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "--coverage" CACHE STRING "Flags used by the shared libraries linker during coverage builds." FORCE ) MARK_AS_ADVANCED( CMAKE_CXX_FLAGS_COVERAGE CMAKE_C_FLAGS_COVERAGE CMAKE_EXE_LINKER_FLAGS_COVERAGE CMAKE_SHARED_LINKER_FLAGS_COVERAGE ) # Default build type is RelWIthDebInfo if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build: Debug Release RelWithDebInfo MinSizeRel Coverage." FORCE) endif(NOT CMAKE_BUILD_TYPE) #------------------------------------------------------ # Checks if compiler version is compatible with Pastis sources set(GNU_CXX_MIN_VERSION "7.0.0") set(CLANG_CXX_MIN_VERSION "5.0.0") # Pastis default compiler flags set(PASTIS_CXX_FLAGS "${PASTIS_CXX_FLAGS} -Wall") if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "${GNU_CXX_MIN_VERSION}") message(FATAL_ERROR "Pastis build requires at least g++-${GNU_CXX_MIN_VERSION}") endif() elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "${CLANG_CXX_MIN_VERSION}") message(FATAL_ERROR "Pastis build requires at least llvm/clang ++-${CLANG_CXX_MIN_VERSION}") endif() set(PASTIS_CXX_FLAGS "${PASTIS_CXX_FLAGS} -Wsign-compare -Wunused -Wunused-member-function -Wunused-private-field") endif() #------------------------------------------------------ # defaults use of MPI set(PASTIS_ENABLE_MPI AUTO CACHE STRING "Choose one of: AUTO ON OFF") if (NOT PASTIS_ENABLE_MPI MATCHES "^(AUTO|ON|OFF)$") message(FATAL_ERROR "PASTIS_ENABLE_MPI='${PASTIS_ENABLE_MPI}'. Must be set to one of AUTO, ON or OFF") endif() # checks for MPI if (PASTIS_ENABLE_MPI MATCHES "^(AUTO|ON)$") find_package(MPI) endif() if (${MPI_FOUND}) set(PASTIS_CXX_FLAGS "${PASTIS_CXX_FLAGS} ${MPI_CXX_COMPILER_FLAGS}") include_directories(${MPI_CXX_INCLUDE_DIRS}) elseif(PASTIS_ENABLE_MPI STREQUAL "ON") message(FATAL_ERROR "Could not find MPI library while requested") endif() set(PASTIS_HAS_MPI ${MPI_FOUND}) #------------------------------------------------------ # setting Kokkos defaults to OpenMP when available include(FindOpenMP) if(${OPENMP_FOUND}) set(KOKKOS_ENABLE_OPENMP ON CACHE BOOL "") endif() # do not build ETI by default set(KOKKOS_ENABLE_EXPLICIT_INSTANTIATION OFF CACHE BOOL "") # do not use Kokkos deprecated code set(KOKKOS_ENABLE_DEPRECATED_CODE OFF CACHE BOOL "") # Kokkos compiler flags add_subdirectory(${PASTIS_SOURCE_DIR}/packages/kokkos) include_directories(${Kokkos_INCLUDE_DIRS_RET}) include(GetKokkosCompilerFlags) # sets Kokkos debug flags when non release build if (CMAKE_BUILD_TYPE MATCHES "^Release$") set (KOKKOS_ENABLE_DEBUG OFF) else() set (KOKKOS_ENABLE_DEBUG ON) endif() # C++ 17 flags if(${CMAKE_VERSION} VERSION_LESS "3.8.0") message(WARNING "Please consider to switch to CMake >= 3.8") set(PASTIS_CXX_FLAGS "${PASTIS_CXX_FLAGS} -std=gnu++1z") if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") set(PASTIS_CXX_FLAGS "${PASTIS_CXX_FLAGS} -Wno-c++17-extensions") endif() else() set(CMAKE_CXX_STANDARD "17") endif() # Compiler flags set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PASTIS_CXX_FLAGS}") # Add debug mode for Standard C++ library set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_GLIBCXX_DEBUG -D_LIBCPP_DEBUG=1 ${PASTIS_CXX_FLAGS}") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -D_GLIBCXX_DEBUG -D_LIBCPP_DEBUG=1 ${PASTIS_CXX_FLAGS}") #------------------------------------------------------ # Rang (colors? Useless thus necessary!) include_directories(${PASTIS_SOURCE_DIR}/packages/rang/include) # CLI11 include_directories(${PASTIS_SOURCE_DIR}/packages/CLI11/include) # Pastis src add_subdirectory(src) include_directories(src) include_directories(src/algebra) include_directories(src/mesh) include_directories(src/output) include_directories(src/utils) include_directories(src/scheme) # Pastis tests set(CATCH_MODULE_PATH "${PASTIS_SOURCE_DIR}/packages/Catch2") set(CATCH_INCLUDE_PATH "${CATCH_MODULE_PATH}/single_include") include("${CATCH_MODULE_PATH}/contrib/ParseAndAddCatchTests.cmake") add_subdirectory("${CATCH_MODULE_PATH}") add_subdirectory(tests) enable_testing() # unit tests coverage if("${CMAKE_BUILD_TYPE}" STREQUAL "Coverage") find_program(GCOVR gcovr) if(NOT GCOVR) message(FATAL_ERROR "gcovr not found, cannot perform coverage.") endif() if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") string(REPLACE "clang++" "llvm-cov" LLVM_COV "${CMAKE_CXX_COMPILER}") if(NOT EXISTS "${LLVM_COV}") message(FATAL_ERROR "could not find ${LLVM_COV}, cannot perform coverage (using g++ for coverage is recommended).") endif() set(GCOVR_EXTRA "--gcov-executable=${LLVM_COV} gcov") endif() set (GCOVR_EXCLUDE -e "${PASTIS_SOURCE_DIR}/src/main.cpp" -e "${PASTIS_SOURCE_DIR}/src/utils/BacktraceManager.cpp" -e "${PASTIS_SOURCE_DIR}/src/utils/BacktraceManager.hpp" ) set(GCOVR_OPTIONS --object-directory="${PASTIS_BINARY_DIR}" -r "${PASTIS_SOURCE_DIR}/src" ${GCOVR_EXCLUDE} ${GCOVR_EXTRA}) add_custom_target(run_unit_tests ALL COMMAND ${CMAKE_CTEST_COMMAND} -j ${PROCESSOR_COUNT} DEPENDS unit_tests pastis COMMENT "Executing unit tests." ) add_custom_target(coverage ALL COMMAND ${GCOVR} ${GCOVR_OPTIONS} DEPENDS run_unit_tests COMMENT "Running gcovr to build coverage report." ) add_custom_target(coverage-report ALL COMMAND ${CMAKE_COMMAND} -E remove_directory "${PASTIS_BINARY_DIR}/coverage" COMMAND ${CMAKE_COMMAND} -E make_directory "${PASTIS_BINARY_DIR}/coverage" COMMAND ${GCOVR} ${GCOVR_OPTIONS} --delete --html --html-details -o "${PASTIS_BINARY_DIR}/coverage/index.html" DEPENDS coverage COMMENT "Building coverage html report." WORKING_DIRECTORY "${PASTIS_BINARY_DIR}" ) endif() #------------------------------------------------------ # Search for ParMETIS if(${MPI_FOUND}) find_path(PARMETIS_INCLUDE_DIR parmetis.h PATH_SUFFIX include parmetis NO_DEFAULT_PATH DOC "Custom include directory for parmetis.h") find_path(PARMETIS_INCLUDE_DIR parmetis.h PATH_SUFFIX include parmetis) if (EXISTS "${PARMETIS_INCLUDE_DIR}/parmetis.h") message("-- Found parmetis.h in ${PARMETIS_INCLUDE_DIR}") find_library(LIB_PARMETIS parmetis) if("${LIB_PARMETIS}" STREQUAL "LIB_PARMETIS-NOTFOUND") message(FATAL_ERROR "Could not find parmetis library") endif() find_library(LIB_METIS metis) if("${LIB_PARMETIS}" STREQUAL "LIB_METIS-NOTFOUND") message(FATAL_ERROR "Could not find metis library") endif() set(PARMETIS_LIBRARIES ${LIB_PARMETIS} ${LIB_METIS}) message("-- Found parmetis/metis libraries ${PARMETIS_LIBRARIES}") else() message(FATAL_ERROR "Could not find parmetis.h") endif() endif() # ----------------------------------------------------- link_libraries("-rdynamic") # ------------------- Source files -------------------- # Pastis binary add_executable( pastis src/main.cpp) # Libraries target_link_libraries( pastis kokkos ${PARMETIS_LIBRARIES} ${MPI_CXX_LINK_FLAGS} ${MPI_CXX_LIBRARIES} PastisUtils PastisMesh)