Select Git revision
CMakeLists.txt
-
Stéphane Del Pino authored
Also removed explicit warnings messages. This warning had a spurious effects in IDE compilation (counted as compilation warnings for instance)
Stéphane Del Pino authoredAlso removed explicit warnings messages. This warning had a spurious effects in IDE compilation (counted as compilation warnings for instance)
CMakeLists.txt 15.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)$")
set(MPI_DETERMINE_LIBRARY_VERSION TRUE)
find_package(MPI)
endif()
#------------------------------------------------------
# Search for ParMETIS
if(${MPI_FOUND})
find_package(ParMETIS)
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()
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(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++ 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()
message("")
message("====== pugs build options ======")
message(STATUS "version: ${PUGS_VERSION}")
message(STATUS "build type: ${CMAKE_BUILD_TYPE}")
message(STATUS "compiler: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
message(STATUS "kokkos devices: ${PUGS_BUILD_KOKKOS_DEVICES}")
if (MPI_FOUND)
message(STATUS "MPI: ${MPI_CXX_LIBRARY_VERSION_STRING}")
else()
if(NOT PARMETIS_LIBRARIES)
message(STATUS "MPI: deactivated: ParMETIS cannot be found!")
else()
message(STATUS "MPI: not found!")
endif()
endif()
if(CLANG_FORMAT)
message(STATUS "clang-format: ${CLANG_FORMAT}")
else()
message(STATUS "clang-format: not found!")
endif()
if(CLAZY_STANDALONE)
message(STATUS "clazy-standalone: ${CLAZY_STANDALONE}")
else()
message(STATUS "clazy-standalone: no found!")
endif()
if (DOXYGEN_FOUND)
message(STATUS "doxygen: ${DOXYGEN_EXECUTABLE}")
else()
message(STATUS "doxygen: no found!")
endif()
message("================================")
message("")