Select Git revision
gcc10-mpi-coverage.yml
-
Stéphane Del Pino authoredStéphane Del Pino authored
CMakeLists.txt 14.26 KiB
cmake_minimum_required (VERSION 3.10)
# 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 "8.0.0")
set(CLANG_CXX_MIN_VERSION "8.0.0")
# Pugs default compiler flags
set(PUGS_CXX_FLAGS "${PUGS_CXX_FLAGS} -Wall -Wextra -pedantic")
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()
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "9.0.0")
set(PUGS_STD_LINK_FLAGS "-lstdc++fs")
endif()
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 ${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(WARNING "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(WARNING "clazy-standalone no found!")
endif()
#------------------------------------------------------
# C++ 17 flags
set(CMAKE_CXX_STANDARD "17")
#------------------------------------------------------
# Kokkos configuration
set(KOKKOS_SOURCE_DIR "${PUGS_SOURCE_DIR}/packages/kokkos")
set(KOKKOS_BINARY_DIR "${PUGS_BINARY_DIR}/packages/kokkos")
# 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_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}")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${PUGS_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")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -D_GLIBCXX_DEBUG -D_LIBCPP_DEBUG=1")
endif()
#------------------------------------------------------
# Rang (colors? Useless thus necessary!)
include_directories(${PUGS_SOURCE_DIR}/packages/rang/include)
# CLI11
include_directories(${PUGS_SOURCE_DIR}/packages/CLI11/include)
# 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")
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}
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()
find_program(FASTCOV fastcov fastcov.py)
if (FASTCOV AND (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "9"))
add_custom_target(coverage
ALL # in coverage mode we do coverage!
# zero all counters
COMMAND ${FASTCOV} -q -z
# Run tests
COMMAND ${CMAKE_CTEST_COMMAND}
COMMAND ${FASTCOV} -q --gcov "${GCOV_BIN}"
--include "${PUGS_SOURCE_DIR}/src"
--exclude "${PUGS_SOURCE_DIR}/src/main.cpp" "${PUGS_SOURCE_DIR}/src/utils/BacktraceManager.*"
--lcov -o coverage.info -n
COMMAND ${LCOV} --gcov "${GCOV_BIN}" --list coverage.info
DEPENDS unit_tests mpi_unit_tests
COMMENT "Running test coverage."
WORKING_DIRECTORY "${PUGS_BINARY_DIR}"
)
else()
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_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
# Run tests
COMMAND ${CMAKE_CTEST_COMMAND}
# 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 unit_tests mpi_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()
# -----------------------------------------------------
link_libraries("-rdynamic")
# ------------------- Source files --------------------
# Pugs binary
add_executable(
pugs
src/main.cpp)
# Libraries
target_link_libraries(
pugs
PugsMesh
PugsUtils
PugsLanguage
PugsLanguageAST
PugsLanguageModules
PugsLanguageAlgorithms
PugsMesh
PugsUtils
PugsLanguageUtils
kokkos
${PARMETIS_LIBRARIES}
${MPI_CXX_LINK_FLAGS} ${MPI_CXX_LIBRARIES}
${KOKKOS_CXX_FLAGS}
${OPENMP_LINK_FLAGS}
${PUGS_STD_LINK_FLAGS}
stdc++fs
)
# ---------------------- Doxygen ----------------------
include(PugsDoxygen)
# ------------------- Installation --------------------
# temporary version workaround
if(${CMAKE_VERSION} VERSION_LESS "3.13.0")
install(TARGETS pugs
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
else()
install(TARGETS pugs PugsMesh PugsUtils PugsLanguage
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
endif()