Select Git revision
CMakeLists.txt
-
Stéphane Del Pino authoredStéphane Del Pino authored
CMakeLists.txt 26.22 KiB
cmake_minimum_required (VERSION 3.19)
# CMake utils
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
# Forbids in-source builds
include(CheckNotInSources)
# use PkgConfig to find packages
find_package(PkgConfig REQUIRED)
#------------------------------------------------------
#----------------- Main configuration -----------------
#------------------------------------------------------
# custom variable allowing to define version suffixes such as -rc*, -beta*, ...
set(PUGS_VERSION "0.5.0")
# deduce PUGS_SHORT_VERSION using regex
string(REGEX MATCH "^[0-9]+\.[0-9]+\.[0-9]+" PUGS_SHORT_VERSION ${PUGS_VERSION})
if("${PUGS_SHORT_VERSION}" STREQUAL "")
message(FATAL_ERROR "Unable to compute short version from PUGS_VERSION=${PUGS_VERSION}")
endif()
# set project version as PUGS_SHORT_VERSION
project (Pugs VERSION ${PUGS_SHORT_VERSION})
# -----------------------------------------------------
# dynamic libraries
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
link_libraries("-rdynamic")
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
#------------------------------------------------------
set(CMAKE_CONFIGURATION_TYPES "Release;Debug;Coverage" CACHE STRING INTERNAL FORCE )
#------------------------------------------------------
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
#------------------------------------------------------
set(PUGS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(PUGS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
# Add new build types
set(CMAKE_CXX_FLAGS_COVERAGE
"-g -O0 --coverage"
CACHE STRING "Flags used by the C++ compiler during coverage builds."
FORCE )
set(CMAKE_C_FLAGS_COVERAGE
"-g -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 )
if(CMAKE_BUILD_TYPE)
string(REGEX MATCH "^(Release|Debug|Coverage)$" VALID_BUILD_TYPE "${CMAKE_BUILD_TYPE}")
if(NOT VALID_BUILD_TYPE)
message(FATAL_ERROR "Invalid CMAKE_BUILD_TYPE: '${CMAKE_BUILD_TYPE}'")
endif()
endif()
# Default build type is Release
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING
"Choose the type of build: Release Debug Coverage."
FORCE)
endif()
#------------------------------------------------------
# default build shared libraries
if (NOT BUILD_SHARED_LIBS)
set(BUILD_SHARED_LIBS ON CACHE STRING "" FORCE)
endif()
#------------------------------------------------------
# Checks if compiler version is compatible with Pugs sources
set(GNU_CXX_MIN_VERSION "10.0.0")
set(CLANG_CXX_MIN_VERSION "11.0.0")
#------------------------------------------------------
# Change Kokkos namespace to avoid conflicts
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DKokkos=InlineKokkos")
#------------------------------------------------------
# Pugs default compiler flags
set(PUGS_CXX_FLAGS "${PUGS_CXX_FLAGS} -Wall -Wextra -pedantic -Wshadow -Wsign-compare -Wunused")
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "${GNU_CXX_MIN_VERSION}")
message(FATAL_ERROR "Pugs 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 "Pugs build requires at least llvm/clang ++-${CLANG_CXX_MIN_VERSION}")
endif()
set(PUGS_CXX_FLAGS "${PUGS_CXX_FLAGS} -Wunused-member-function -Wunused-private-field")
endif()
#------------------------------------------------------
include (TestBigEndian)
TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
if(IS_BIG_ENDIAN)
set(PUGS_LITTLE_ENDIAN FALSE)
else()
set(PUGS_LITTLE_ENDIAN TRUE)
endif()
#------------------------------------------------------
# defaults use of MPI
set(PUGS_ENABLE_MPI AUTO CACHE STRING
"Choose one of: AUTO ON OFF")
if (NOT PUGS_ENABLE_MPI MATCHES "^(AUTO|ON|OFF)$")
message(FATAL_ERROR "PUGS_ENABLE_MPI='${PUGS_ENABLE_MPI}'. Must be set to one of AUTO, ON or OFF")
endif()
# Check for MPI
if (PUGS_ENABLE_MPI MATCHES "^(AUTO|ON)$")
set(MPI_DETERMINE_LIBRARY_VERSION TRUE)
find_package(MPI)
endif()
#------------------------------------------------------
# Search for ParMETIS
find_package(ParMETIS)
if(PARMETIS_LIBRARIES)
add_library(PkgConfig::ParMETIS STATIC IMPORTED)
set_property(TARGET PkgConfig::ParMETIS PROPERTY
IMPORTED_LOCATION "${PARMETIS_LIBRARIES}")
set(PARMETIS_TARGET PkgConfig::ParMETIS)
endif()
if(${MPI_FOUND})
if (NOT PARMETIS_LIBRARIES)
if(PUGS_ENABLE_MPI MATCHES "^AUTO$")
message(STATUS "MPI support deactivated: ParMETIS cannot be found!")
unset(MPI_FOUND)
unset(MPI_CXX_LINK_FLAGS)
unset(MPI_CXX_LIBRARIES)
else()
message(FATAL_ERROR "MPI support requires ParMETIS which cannot be found!")
endif()
endif()
else()
if(PUGS_ENABLE_MPI MATCHES "^ON$")
message(FATAL_ERROR "Cannot find MPI!")
endif()
endif()
#------------------------------------------------------
# Check for PETSc
# defaults use PETSc
set(PUGS_ENABLE_PETSC AUTO CACHE STRING
"Choose one of: AUTO ON OFF")
if (PUGS_ENABLE_PETSC MATCHES "^(AUTO|ON)$")
if (MPI_FOUND)
# PETSc support is deactivated if MPI is not found
pkg_check_modules(PETSC IMPORTED_TARGET GLOBAL PETSc)
set_property(TARGET PkgConfig::PETSC PROPERTY
IMPORTED_LOCATION "${PETSC_LIBRARIES}"
)
set_property(TARGET PkgConfig::PETSC PROPERTY
INTERFACE_INCLUDE_DIRECTORIES "${PETSC_INCLUDE_DIRS}"
)
set(PETSC_TARGET PkgConfig::PETSC)
else()
message(STATUS "PETSc support is deactivated since pugs will not be build with MPI support")
set(PETSC_FOUND FALSE)
unset(PUGS_HAS_PETSC)
endif()
set(PUGS_HAS_PETSC ${PETSC_FOUND})
else()
unset(PUGS_HAS_PETSC)
endif()
if (${PETSC_FOUND})
include_directories(SYSTEM "${PETSC_INCLUDE_DIRS}")
else()
if (PUGS_ENABLE_PETSC MATCHES "^ON$")
message(FATAL_ERROR "Could not find PETSc!")
endif()
endif()
#------------------------------------------------------
# Check for SLEPc
# defaults use SLEPc
set(PUGS_ENABLE_SLEPC AUTO CACHE STRING
"Choose one of: AUTO ON OFF")
if (PUGS_ENABLE_SLEPC MATCHES "^(AUTO|ON)$")
if (PETSC_FOUND)
# SLEPc support is deactivated if PETSc is not found
pkg_check_modules(SLEPC IMPORTED_TARGET GLOBAL SLEPc)
set_property(TARGET PkgConfig::SLEPC PROPERTY
IMPORTED_LOCATION "${SLEPC_LIBRARIES}"
)
set_property(TARGET PkgConfig::SLEPC PROPERTY
INTERFACE_INCLUDE_DIRECTORIES "${SLEPC_INCLUDE_DIRS}"
)
set(SLEPC_TARGET PkgConfig::SLEPC)
else()
message(STATUS "SLEPc support is deactivated since pugs will not be build with PETSc support")
set(SLEPC_FOUND FALSE)
unset(PUGS_HAS_SLEPC)
endif()
set(PUGS_HAS_SLEPC ${SLEPC_FOUND})
else()
unset(PUGS_HAS_SLEPC)
endif()
if (${SLEPC_FOUND})
include_directories(SYSTEM "${SLEPC_INCLUDE_DIRS}")
else()
if (PUGS_ENABLE_SLEPC MATCHES "^ON$")
message(FATAL_ERROR "Could not find SLEPc!")
endif()
endif()
# -----------------------------------------------------
if (${MPI_FOUND})
set(PUGS_CXX_FLAGS "${PUGS_CXX_FLAGS} ${MPI_CXX_COMPILER_FLAGS}")
include_directories(SYSTEM "${MPI_CXX_INCLUDE_DIRS}")
elseif(PUGS_ENABLE_MPI STREQUAL "ON")
message(FATAL_ERROR "Could not find MPI library while requested")
endif()
set(PUGS_HAS_MPI ${MPI_FOUND})
#------------------------------------------------------
# search for HDF5
set(PUGS_ENABLE_HDF5 AUTO CACHE STRING
"Choose one of: AUTO ON OFF")
if (PUGS_ENABLE_HDF5 MATCHES "^(AUTO|ON)$")
if (MPI_FOUND)
# May be risky. (make to show pugs build options)
set(HDF5_PREFER_PARALLEL TRUE)
find_package(HDF5)
if (HDF5_FOUND)
# HighFive
set(HIGHFIVE_USE_BOOST OFF) # no Boost
set(HIGHFIVE_BUILD_DOCS OFF) # no doc
set(HIGHFIVE_UNIT_TESTS OFF) # no unit tests
set(HIGHFIVE_UNIT_TESTS OFF) # no unit tests
set(HIGHFIVE_EXAMPLES OFF) # no examples
add_subdirectory(${PUGS_SOURCE_DIR}/packages/HighFive/)
set(HIGHFIVE_TARGET HighFive::HighFive)
add_library(PkgConfig::HDF5 STATIC IMPORTED)
set_property(TARGET PkgConfig::HDF5 PROPERTY
IMPORTED_LOCATION "${HDF5_LIBRARIES}")
set_property(TARGET PkgConfig::HDF5 PROPERTY
INTERFACE_INCLUDE_DIRECTORIES "${HDF5_INCLUDE_DIRS}")
set(HDF5_TARGET PkgConfig::HDF5)
endif()
else()
message(STATUS "HDF5 support is deactivated since pugs will not be build with MPI support")
set(HDF5_FOUND FALSE)
endif()
set(PUGS_HAS_HDF5 ${HDF5_FOUND})
else()
unset(HIGHFIVE_TARGET)
unset(HDF5_TARGET)
unset(PUGS_HAS_HDF5)
endif()
#------------------------------------------------------
# search for libslurm
find_package(Slurm)
set(PUGS_HAS_SLURM ${SLURM_FOUND})
if (SLURM_FOUND)
add_library(PkgConfig::Slurm STATIC IMPORTED)
set_property(TARGET PkgConfig::Slurm PROPERTY
IMPORTED_LOCATION "${SLURM_LIBRARY}")
set_property(TARGET PkgConfig::Slurm PROPERTY
INTERFACE_INCLUDE_DIRECTORIES "${SLURM_INCLUDE_DIR}")
set(SLURM_TARGET PkgConfig::Slurm)
include_directories(SYSTEM "${SLURM_INCLUDE_DIR}")
else()
set(SLURM_LIBRARY "")
endif()
#------------------------------------------------------
# search for clang-format
find_program(CLANG_FORMAT clang-format)
if (CLANG_FORMAT)
add_custom_target(clang-format
COMMAND ${CMAKE_COMMAND}
-DPUGS_SOURCE_DIR="${PUGS_SOURCE_DIR}"
-DCLANG_FORMAT="${CLANG_FORMAT}"
-P ${PUGS_SOURCE_DIR}/cmake/ClangFormatProcess.cmake
COMMENT "running ${CLANG_FORMAT} ...")
else ()
message(STATUS "clang-format no found!")
endif()
#------------------------------------------------------
# search for clazy-standalone
find_program(CLAZY_STANDALONE clazy-standalone)
if (CLAZY_STANDALONE)
add_custom_target(clazy-standalone
COMMAND ${CMAKE_COMMAND}
-DPUGS_SOURCE_DIR="${PUGS_SOURCE_DIR}"
-DPUGS_BINARY_DIR="${PUGS_BINARY_DIR}"
-DCLAZY_STANDALONE="${CLAZY_STANDALONE}"
-P ${PUGS_SOURCE_DIR}/cmake/ClazyStandaloneProcess.cmake
COMMENT "running ${CLAZY_STANDALONE} ..."
)
else ()
message(STATUS "clazy-standalone no found!")
endif()
#------------------------------------------------------
# C++ 20 flags
set(CMAKE_CXX_STANDARD "20")
#------------------------------------------------------
# Kokkos configuration
set(KOKKOS_SOURCE_DIR "${PUGS_SOURCE_DIR}/packages/kokkos")
set(KOKKOS_BINARY_DIR "${PUGS_BINARY_DIR}/packages/kokkos")
# disable Kokkos deprecation warnings by default
set(Kokkos_ENABLE_DEPRECATION_WARNINGS OFF CACHE BOOL "")
# setting Kokkos defaults to OpenMP when available
find_package(OpenMP)
if(OpenMP_CXX_FOUND)
set(Kokkos_ENABLE_OPENMP ON CACHE BOOL "")
endif()
if("${Kokkos_ENABLE_OPENMP}" STREQUAL "ON")
set(PUGS_CXX_FLAGS "${PUGS_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
set(OPENMP_LINK_FLAGS OpenMP::OpenMP_CXX)
endif()
add_subdirectory("${PUGS_SOURCE_DIR}/packages/kokkos")
# set as SYSTEM for static analysis
include_directories(SYSTEM "${KOKKOS_SOURCE_DIR}/core/src")
include_directories(SYSTEM "${KOKKOS_SOURCE_DIR}/containers/src")
include_directories(SYSTEM "${KOKKOS_SOURCE_DIR}/tpls/desul/include")
include_directories(SYSTEM "${KOKKOS_BINARY_DIR}/core/src")
include_directories(SYSTEM "${KOKKOS_BINARY_DIR}")
set(PUGS_BUILD_KOKKOS_DEVICES "")
if(${Kokkos_ENABLE_PTHREAD})
list(APPEND PUGS_BUILD_KOKKOS_DEVICES "Threads")
endif()
if(${Kokkos_ENABLE_CUDA})
list(APPEND PUGS_BUILD_KOKKOS_DEVICES "CUDA")
endif()
if(${Kokkos_ENABLE_QTHREADS})
list(APPEND PUGS_BUILD_KOKKOS_DEVICES "QThreads")
endif()
if(${Kokkos_ENABLE_HPX})
list(APPEND PUGS_BUILD_KOKKOS_DEVICES "HPX")
endif()
if(${Kokkos_ENABLE_OPENMP})
list(APPEND PUGS_BUILD_KOKKOS_DEVICES "OpenMP")
endif()
if(${Kokkos_ENABLE_OPENMPTARGET})
list(APPEND PUGS_BUILD_KOKKOS_DEVICES "OpenMPTarget")
endif()
if(${Kokkos_ENABLE_HWLOC})
list(APPEND PUGS_BUILD_KOKKOS_DEVICES "HWLoc")
endif()
if(${Kokkos_ENABLE_MPI})
list(APPEND PUGS_BUILD_KOKKOS_DEVICES "Kokkos/MPI")
endif()
if(${Kokkos_ENABLE_CUDA_UVM})
list(APPEND PUGS_BUILD_KOKKOS_DEVICES "CUDA UVM")
endif()
#------------------------------------------------------
# Compiler flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PUGS_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${PUGS_CXX_FLAGS}")
message(STATUS "CMAKE_CXX_FLAGS = ${CMAKE_CXX_FLAGS}")
# Add debug mode for Standard C++ library (not for AppleClang since it is broken)
if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_GLIBCXX_DEBUG -D_LIBCPP_DEBUG=1")
endif()
#------------------------------------------------------
# Rang (colors? Useless thus necessary!)
add_subdirectory(${PUGS_SOURCE_DIR}/packages/rang/)
include_directories(SYSTEM "${PUGS_SOURCE_DIR}/packages/rang/include")
# CLI11
include_directories(SYSTEM "${PUGS_SOURCE_DIR}/packages/CLI11/include")
# PEGTL
add_subdirectory(${PUGS_SOURCE_DIR}/packages/PEGTL/)
include_directories(SYSTEM "${PUGS_SOURCE_DIR}/packages/PEGTL/include/tao")
# Pugs src
add_subdirectory("${PUGS_SOURCE_DIR}/src")
include_directories("${PUGS_SOURCE_DIR}/src")
include_directories("${PUGS_BINARY_DIR}/src")
# Pugs tests
set(CATCH_MODULE_PATH "${PUGS_SOURCE_DIR}/packages/Catch2")
add_subdirectory("${CATCH_MODULE_PATH}")
target_compile_options(Catch2 PRIVATE "-w")
target_compile_options(Catch2WithMain PRIVATE "-w")
add_subdirectory(tests)
if(${PUGS_HAS_MPI})
set(MPIEXEC_OPTION_FLAGS --oversubscribe)
if (NOT "$ENV{GITLAB_CI}" STREQUAL "")
set(MPIEXEC_OPTION_FLAGS ${MPIEXEC_OPTION_FLAGS} --allow-run-as-root)
endif()
set(MPIEXEC_NUMPROC 3)
set(MPIEXEC_PATH_FLAG --path)
set(MPI_LAUNCHER ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_NUMPROC} ${MPIEXEC_OPTION_FLAGS})
endif()
add_custom_target(all_unit_tests
DEPENDS unit_tests mpi_unit_tests
)
add_custom_target(check
DEPENDS test
)
add_custom_target(test
DEPENDS run_all_unit_tests
)
add_custom_target(run_all_unit_tests
DEPENDS run_mpi_unit_tests
)
if(PUGS_HAS_MPI)
set(RUN_MPI_UNIT_TESTS_COMMENT "Running mpi_unit_tests [using ${MPIEXEC_NUMPROC} procs]")
else()
set(RUN_MPI_UNIT_TESTS_COMMENT "Running mpi_unit_tests [sequentially]")
endif()
add_custom_target(run_mpi_unit_tests
COMMAND ${MPI_LAUNCHER} "${PUGS_BINARY_DIR}/mpi_unit_tests"
WORKING_DIRECTORY ${PUGS_BINARY_DIR}
DEPENDS run_unit_tests
COMMENT ${RUN_MPI_UNIT_TESTS_COMMENT}
)
add_custom_target(run_unit_tests
COMMAND "${PUGS_BINARY_DIR}/unit_tests"
DEPENDS all_unit_tests
COMMENT "Running unit_tests"
)
# unit tests coverage
if("${CMAKE_BUILD_TYPE}" STREQUAL "Coverage")
file(GLOB_RECURSE GCNO_FILE_LIST RELATIVE "${PUGS_BINARY_DIR}" "*.gcno")
list(FILTER GCNO_FILE_LIST EXCLUDE REGEX "^\.\./.*" )
file(GLOB_RECURSE GCDA_FILE_LIST RELATIVE "${PUGS_BINARY_DIR}" "*.gcda")
list(FILTER GCDA_FILE_LIST EXCLUDE REGEX "^\.\./.*" )
foreach(COV_INFO_FILE IN LISTS GCNO_FILE_LIST GCDA_FILE_LIST)
string(REGEX REPLACE "/CMakeFiles/.*\.dir/" "/" COV_SRC_FILE "${PUGS_SOURCE_DIR}/${COV_INFO_FILE}")
string(REGEX REPLACE "\.gcda$" "" COV_SRC_FILE "${COV_SRC_FILE}")
string(REGEX REPLACE "\.gcno$" "" COV_SRC_FILE "${COV_SRC_FILE}")
if (NOT EXISTS "${COV_SRC_FILE}")
file(REMOVE "${PUGS_BINARY_DIR}/${COV_INFO_FILE}")
message(STATUS "removed file ${COV_INFO_FILE}: no longer needed")
endif()
endforeach()
find_program(LCOV lcov)
if(NOT LCOV)
message(FATAL_ERROR "lcov not found, cannot perform coverage.")
endif()
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
string(REGEX MATCH "^[0-9]+" GCC_VERSION
"${CMAKE_CXX_COMPILER_VERSION}")
find_program(GCOV_BIN NAMES gcov-${GCC_VERSION} gcov
HINTS ${COMPILER_PATH})
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
string(REGEX MATCH "^[0-9]+" LLVM_VERSION
"${CMAKE_CXX_COMPILER_VERSION}")
if(LLVM_VERSION VERSION_GREATER 7)
find_program(LLVM_COV_BIN NAMES "llvm-cov-${LLVM_VERSION}"
"llvm-cov" HINTS ${COMPILER_PATH})
mark_as_advanced(LLVM_COV_BIN)
if (LLVM_COV_BIN)
file(MAKE_DIRECTORY "${PUGS_BINARY_DIR}/tools/tmp")
file(WRITE "${PUGS_BINARY_DIR}/tools/tmp/llvm-cov.sh" "#! /bin/sh\n")
file(APPEND "${PUGS_BINARY_DIR}/tools/tmp/llvm-cov.sh" "'${LLVM_COV_BIN}' gcov \"\$@\"\n")
file(COPY "${PUGS_BINARY_DIR}/tools/tmp/llvm-cov.sh"
DESTINATION "${PUGS_BINARY_DIR}/tools"
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
set(GCOV_BIN "${PUGS_BINARY_DIR}/tools/llvm-cov.sh")
endif()
endif()
endif()
if(NOT GCOV_BIN)
message(FATAL_ERROR "Cannot find a proper gcov tool, cannot perform coverage.")
endif()
find_program(FASTCOV fastcov fastcov.py)
add_custom_target(coverage_unit_tests
ALL # in coverage mode we do coverage!
COMMAND "${PUGS_BINARY_DIR}/unit_tests"
COMMENT "Running unit_tests"
DEPENDS coverage_zero_counters
)
add_custom_target(coverage_mpi_unit_tests
ALL # in coverage mode we do coverage!
COMMAND ${MPI_LAUNCHER} "mpi_unit_tests"
COMMENT "Running mpi_unit_tests"
DEPENDS coverage_unit_tests
)
add_custom_target(coverage_run_all_unit_tests
ALL # in coverage mode we do coverage!
DEPENDS coverage_mpi_unit_tests
)
if (FASTCOV AND (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "9"))
add_custom_target(coverage_zero_counters
ALL # in coverage mode we do coverage!
# zero all counters
COMMAND ${FASTCOV} -q -z --gcov "${GCOV_BIN}"
DEPENDS all_unit_tests
)
add_custom_target(coverage
ALL # in coverage mode we do coverage!
COMMAND ${FASTCOV} --gcov "${GCOV_BIN}"
--include "${PUGS_SOURCE_DIR}/src"
--exclude "${PUGS_SOURCE_DIR}/src/main.cpp" "${PUGS_SOURCE_DIR}/src/utils/BacktraceManager.*" "${PUGS_SOURCE_DIR}/src/utils/FPEManager.*" "${PUGS_SOURCE_DIR}/src/utils/SignalManager.*" "${PUGS_SOURCE_DIR}/src/utils/checkpointing/pugs_checkpoint_main.cpp"
--lcov -o coverage.info -n
COMMAND ${LCOV} --gcov "${GCOV_BIN}" --list coverage.info
DEPENDS coverage_run_all_unit_tests
COMMENT "Running test coverage."
WORKING_DIRECTORY "${PUGS_BINARY_DIR}"
)
else()
add_custom_target(coverage_zero_counters
ALL # in coverage mode we do coverage!
# Cleanup previously generated profiling data
COMMAND ${LCOV} -q --gcov "${GCOV_BIN}" --base-directory "${PUGS_BINARY_DIR}/src" --directory "${PUGS_BINARY_DIR}" --zerocounters
# Initialize profiling data with zero coverage for every instrumented line of the project
# This way the percentage of total lines covered will always be correct, even when not all source code files were loaded during the test(s)
COMMAND ${LCOV} -q --gcov "${GCOV_BIN}" --base-directory "${PUGS_BINARY_DIR}/src" --directory "${PUGS_BINARY_DIR}" --capture --initial --output-file coverage_base.info
DEPENDS all_unit_tests
)
add_custom_target(coverage
# Collect data from executions
COMMAND ${LCOV} --gcov "${GCOV_BIN}" --base-directory "${PUGS_BINARY_DIR}/src" --directory "${PUGS_BINARY_DIR}" --capture --output-file coverage_ctest.info
# Combine base and ctest results
COMMAND ${LCOV} --gcov "${GCOV_BIN}" -q --add-tracefile coverage_base.info --add-tracefile coverage_ctest.info --output-file coverage_full.info
# Extract only project data (--no-capture or --remove options may be used to select collected data)
COMMAND ${LCOV} --gcov "${GCOV_BIN}" -q --extract coverage_full.info "'${PUGS_SOURCE_DIR}/src/*'" --output-file coverage_extract.info
# Remove unwanted stuff
COMMAND ${LCOV} --gcov "${GCOV_BIN}" --remove coverage_extract.info --output-file coverage.info
'${PUGS_SOURCE_DIR}/src/main.cpp'
'${PUGS_SOURCE_DIR}/src/utils/BacktraceManager.*'
COMMAND ${LCOV} --gcov "${GCOV_BIN}" --list coverage.info
DEPENDS coverage_run_all_unit_tests
COMMENT "Running test coverage."
WORKING_DIRECTORY "${PUGS_BINARY_DIR}"
)
endif()
find_program(GENHTML genhtml)
if(NOT GENHTML)
message(WARNING "genhtml not found, cannot perform report-coverage.")
else()
add_custom_target(coverage-report
ALL
COMMAND ${CMAKE_COMMAND} -E remove_directory "${PUGS_BINARY_DIR}/coverage"
COMMAND ${CMAKE_COMMAND} -E make_directory "${PUGS_BINARY_DIR}/coverage"
COMMAND ${GENHTML} --demangle-cpp -q -o coverage -t "${CMAKE_PROJECT_NAME} test coverage" --ignore-errors source --legend --num-spaces 2 coverage.info
DEPENDS coverage
COMMENT "Building coverage html report."
WORKING_DIRECTORY "${PUGS_BINARY_DIR}"
)
endif()
endif()
# ------------------- Source files --------------------
# Pugs binary
add_executable(
pugs
src/main.cpp)
# Libraries
target_link_libraries(
pugs
PugsMesh
PugsAlgebra
PugsAnalysis
PugsCheckpointing
PugsDev
PugsUtils
PugsLanguage
PugsLanguageAST
PugsLanguageModules
PugsLanguageAlgorithms
PugsMesh
PugsAlgebra
PugsScheme
PugsUtils
PugsOutput
PugsLanguageUtils
PugsCheckpointing
Kokkos::kokkos
${PETSC_TARGET}
${SLEPC_TARGET}
${PARMETIS_TARGET}
${MPI_CXX_LINK_FLAGS} ${MPI_CXX_LIBRARIES}
${KOKKOS_CXX_FLAGS}
${OPENMP_LINK_FLAGS}
${PUGS_STD_LINK_FLAGS}
${HIGHFIVE_TARGET}
${SLURM_TARGET}
stdc++fs
)
target_include_directories(pugs PUBLIC ${PETSC_INCLUDE_DIRS})
target_include_directories(pugs PUBLIC ${HDF5_INCLUDE_DIRS})
# Checkpoint management tool
add_executable(
pugs_checkpoint
src/utils/checkpointing/pugs_checkpoint_main.cpp
)
target_link_libraries(
pugs_checkpoint
PugsCheckpointing
PugsUtils
PugsMesh
PugsOutput
PugsLanguage
PugsLanguageAST
PugsLanguageModules
PugsLanguageUtils
PugsScheme
PugsDev
PugsAnalysis
PugsAlgebra
PugsMesh
PugsOutput
Kokkos::kokkos
${PETSC_TARGET}
${SLEPC_TARGET}
${PARMETIS_TARGET}
${MPI_CXX_LINK_FLAGS} ${MPI_CXX_LIBRARIES}
${KOKKOS_CXX_FLAGS}
${OPENMP_LINK_FLAGS}
${PUGS_STD_LINK_FLAGS}
${HIGHFIVE_TARGET}
${SLURM_TARGET}
stdc++fs
)
# -------------------- Documentation --------------------
include(PugsDoc)
# -------------------- Doxygen --------------------------
include(PugsDoxygen)
# -------------------- Installation ---------------------
install(TARGETS
pugs
pugs_checkpoint
PugsAlgebra
PugsAnalysis
PugsCheckpointing
PugsDev
PugsUtils
PugsLanguage
PugsLanguageAST
PugsLanguageModules
PugsLanguageUtils
PugsMesh
PugsOutput
PugsScheme
kokkos
Catch2
EXPORT "${PROJECT_NAME}Targets"
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
PugsConfigVersion.cmake
VERSION ${PACKAGE_VERSION}
COMPATIBILITY AnyNewerVersion
)
install(EXPORT PugsTargets
FILE PugsTargets.cmake
NAMESPACE Pugs::
DESTINATION lib/cmake/pugs
)
# ------------------- Build options -------------------
message("")
message("====== pugs build options ======")
message(" version: ${PUGS_VERSION}")
message(" build type: ${CMAKE_BUILD_TYPE}")
message(" compiler: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
message(" kokkos devices: ${PUGS_BUILD_KOKKOS_DEVICES}")
if (MPI_FOUND)
message(" MPI: ${MPI_CXX_LIBRARY_VERSION_STRING}")
else()
if (PUGS_ENABLE_MPI MATCHES "^OFF$")
message(" MPI: deactivated!")
elseif(NOT PARMETIS_LIBRARIES)
message(" MPI: deactivated: ParMETIS cannot be found!")
else()
if (PUGS_ENABLE_MPI MATCHES "^(AUTO|ON)$")
message(" MPI: not found!")
else()
message(" MPI: explicitly deactivated!")
endif()
endif()
endif()
if (PETSC_FOUND)
message(" PETSc: ${PETSC_VERSION}")
else()
if (PUGS_ENABLE_PETSC MATCHES "^(AUTO|ON)$")
message(" PETSc: not found!")
else()
message(" PETSc: explicitly deactivated!")
endif()
endif()
if (SLEPC_FOUND)
message(" SLEPc: ${SLEPC_VERSION}")
else()
if (PUGS_ENABLE_SLEPC MATCHES "^(AUTO|ON)$")
message(" SLEPc: not found!")
else()
message(" SLEPc: explicitly deactivated!")
endif()
endif()
if (HDF5_FOUND)
message(" HDF5: ${HDF5_VERSION} parallel: ${HDF5_IS_PARALLEL}")
else()
if (PUGS_ENABLE_HDF5 MATCHES "^(AUTO|ON)$")
message(" HDF5: not found!")
else()
message(" HDF5: explicitly deactivated!")
endif()
endif()
if (SLURM_FOUND)
message(" SLURM library: ${SLURM_LIBRARY}")
else()
message(" SLURM library: not found!")
endif()
message("----------- utilities ----------")
if(CLANG_FORMAT)
message(" clang-format: ${CLANG_FORMAT}")
else()
message(" clang-format: not found!")
endif()
if(CLAZY_STANDALONE)
message(" clazy-standalone: ${CLAZY_STANDALONE}")
else()
message(" clazy-standalone: not found!")
endif()
if (DOXYGEN_FOUND)
message(" doxygen: ${DOXYGEN_EXECUTABLE}")
else()
message(" doxygen: not found!")
endif()
if (EMACS)
message(" emacs: ${EMACS}")
else()
message(" emacs: not found!")
endif()
if (GNUPLOT_FOUND)
message(" gnuplot: ${GNUPLOT}")
else()
message(" gnuplot: not found!")
endif()
if (GMSH)
message(" gmsh: ${GMSH}")
else()
message(" gmsh: not found!")
endif()
if (PYGMENTIZE)
message(" pygmentize: ${PYGMENTIZE}")
else()
message(" pygmentize: not found!")
endif()
if (LATEX_PDFLATEX_FOUND)
message(" pdflatex: ${PDFLATEX_COMPILER}")
else()
message(" pdflatex: not found!")
endif()
if (NOT EMACS OR NOT GNUPLOT_FOUND OR NOT GMSH)
message(" ** Cannot build documentation: missing ")
elseif(NOT LATEX_PDFLATEX_FOUND OR NOT PYGMENTIZE)
message(" ** Cannot build pdf documentation: missing")
endif()
if (NOT EMACS)
message(" - emacs")
endif()
if (NOT GNUPLOT_FOUND)
message(" - gnuplot")
endif()
if (NOT GMSH)
message(" - gmsh")
endif()
if (NOT LATEX_PDFLATEX_FOUND)
message(" - pdflatex")
endif()
if (NOT PYGMENTIZE)
message(" - pygmentize")
endif()
message("================================")
message("")
configure_file(
${PUGS_SOURCE_DIR}/cmake/PugsCompileFlags.cmake.in
${PUGS_BINARY_DIR}/cmake/PugsCompileFlags.cmake
@ONLY
)
install(
FILES ${PUGS_BINARY_DIR}/cmake/PugsCompileFlags.cmake
DESTINATION lib/cmake/pugs
)
# Ugly patch to install user headers for Catch2 (for plugins)
install(
DIRECTORY
"${PUGS_BINARY_DIR}/packages/Catch2/generated-includes/catch2" # Also install the generated header
DESTINATION
"include"
FILES_MATCHING
PATTERN "*.hpp"
)