Select Git revision
CMakeLists.txt
-
Stéphane Del Pino authoredStéphane Del Pino authored
CMakeLists.txt 11.61 KiB
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 -----------------
#------------------------------------------------------
# custom variable allowing to define version suffixes such as -rc*, -beta*, ...
set(PUGS_VERSION "0.4.1")
# 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})
#------------------------------------------------------
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
#------------------------------------------------------
set(PUGS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(PUGS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
# Change RelWithDebInfo to compile assertions
SET("CMAKE_CXX_FLAGS_RELWITHDEBINFO"
"-g -O2"
CACHE STRING "Flags used by the compiler during release builds with debug info and assertions"
FORCE )
SET("CMAKE_C_FLAGS_RELWITHDEBINFO"
"-g -O2"
CACHE STRING "Flags used by the compiler during release builds with debug info and assertions"
FORCE )
# 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 "(Debug|Release|RelWithDebInfo|MinSizeRel|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 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()
#------------------------------------------------------
# Checks if compiler version is compatible with Pugs sources
set(GNU_CXX_MIN_VERSION "7.0.0")
set(CLANG_CXX_MIN_VERSION "5.0.0")
# Pugs default compiler flags
set(PUGS_CXX_FLAGS "${PUGS_CXX_FLAGS} -Wall -Wextra")
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} -Wsign-compare -Wunused -Wunused-member-function -Wunused-private-field")
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()
# checks for MPI
if (PUGS_ENABLE_MPI MATCHES "^(AUTO|ON)$")
find_package(MPI)
endif()
#------------------------------------------------------
# Search for ParMETIS
if(${MPI_FOUND})
find_package(ParMETIS)
if (NOT PARMETIS_LIBRARIES)
if(PUGS_ENABLE_MPI MATCHES "^AUTO$")
message(WARNING "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()
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 clang-format
find_program(CLANG_FORMAT clang-format)
if (CLANG_FORMAT)
add_custom_target(clang-format
COMMAND echo "running ${CLANG_FORMAT} ..."
COMMAND ${CMAKE_COMMAND}
-DPUGS_SOURCE_DIR="${PUGS_SOURCE_DIR}"
-DCLANG_FORMAT="${CLANG_FORMAT}"
-P ${PUGS_SOURCE_DIR}/cmake/ClangFormatProcess.cmake)
else ()
message(WARNING "clang-format no found!")
endif()
#------------------------------------------------------
# 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(${PUGS_SOURCE_DIR}/packages/kokkos)
include_directories(SYSTEM ${Kokkos_INCLUDE_DIRS_RET})
include(GetKokkosCompilerFlags)
# do not pollute compilation with Kokkos internal warnings
set_target_properties(kokkos PROPERTIES COMPILE_FLAGS "-w")
# 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(PUGS_CXX_FLAGS "${PUGS_CXX_FLAGS} -std=gnu++1z")
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(PUGS_CXX_FLAGS "${PUGS_CXX_FLAGS} -Wno-c++17-extensions")
endif()
else()
set(CMAKE_CXX_STANDARD "17")
endif()
# Compiler flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PUGS_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 ${PUGS_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -D_GLIBCXX_DEBUG -D_LIBCPP_DEBUG=1 ${PUGS_CXX_FLAGS}")
#------------------------------------------------------
# Rang (colors? Useless thus necessary!)
include_directories(${PUGS_SOURCE_DIR}/packages/rang/include)
# CLI11
include_directories(${PUGS_SOURCE_DIR}/packages/CLI11/include)
# PGETL
include_directories(${PUGS_SOURCE_DIR}/packages/PEGTL/include/tao)
# Pugs src
add_subdirectory(src)
include_directories(src)
include_directories(src/algebra)
include_directories(src/language)
include_directories(src/mesh)
include_directories(src/output)
include_directories(src/scheme)
include_directories(src/utils)
# Pugs generated sources
include_directories(${PUGS_BINARY_DIR}/src/utils)
# Pugs tests
set(CATCH_MODULE_PATH "${PUGS_SOURCE_DIR}/packages/Catch2")
include("${CATCH_MODULE_PATH}/contrib/ParseAndAddCatchTests.cmake")
add_subdirectory("${CATCH_MODULE_PATH}")
add_subdirectory(tests)
enable_testing()
add_custom_target(run_unit_tests
COMMAND ${CMAKE_CTEST_COMMAND} -j ${PROCESSOR_COUNT}
DEPENDS unit_tests mpi_unit_tests
COMMENT "Executing unit tests."
)
# unit tests coverage
if("${CMAKE_BUILD_TYPE}" STREQUAL "Coverage")
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()
add_custom_target(coverage
ALL # in coverage mode we do coverage!
# Cleanup previously generated profiling data
COMMAND ${LCOV} -q --gcov "${GCOV_BIN}" --base-directory "${PUGS_SOURCE_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_SOURCE_DIR}/src" --directory "${PUGS_BINARY_DIR}" --capture --initial --output-file coverage_base.info
# Run tests
COMMAND ${CMAKE_CTEST_COMMAND} -j ${PROCESSOR_COUNT}
# Collect data from executions
COMMAND ${LCOV} --gcov "${GCOV_BIN}" --base-directory "${PUGS_SOURCE_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}/utils/BacktraceManager.*'
COMMAND ${LCOV} --gcov "${GCOV_BIN}" --list coverage.info
DEPENDS unit_tests mpi_unit_tests
COMMENT "Running test coverage."
WORKING_DIRECTORY "${PUGS_BINARY_DIR}"
)
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} -q -o coverage -t "${CMAKE_PROJECT_NAME} test coverage" --ignore-errors source --legend --num-spaces 4 coverage.info
DEPENDS coverage
COMMENT "Building coverage html report."
WORKING_DIRECTORY "${PUGS_BINARY_DIR}"
)
endif()
endif()
# -----------------------------------------------------
link_libraries("-rdynamic")
# ------------------- Source files --------------------
# Pugs binary
add_executable(
pugs
src/main.cpp)
# Libraries
target_link_libraries(
pugs
PugsMesh
PugsUtils
PugsLanguage
kokkos
${PARMETIS_LIBRARIES}
${MPI_CXX_LINK_FLAGS} ${MPI_CXX_LIBRARIES}
)