Commit c96a9815 authored by Gregor Olenik's avatar Gregor Olenik
Browse files

Add basic cmake files

parent ec73a90c
list(APPEND CTEST_CUSTOM_COVERAGE_EXCLUDE
# Exclude list set by cmake
@CUSTOM_COVERAGE_EXCLUDE@
# Exclude try_compile sources from coverage results:
"/CMakeFiles/CMakeTmp/"
".*/third_party/.*"
".*/doc/.*"
".*/benchmark/.*"
".*/examples/.*"
".*/c\\+\\+/.*"
)
set(CTEST_SOURCE_DIRECTORY "@NLA4HPC_SOURCE_DIR@" CACHE STRING "" FORCE)
set(CTEST_BINARY_DIRECTORY "@NLA4HPC_BINARY_DIR@" CACHE STRING "" FORCE)
set(CTEST_COVERAGE_EXTRA_FLAGS "-p")
#.rst:
# Ginkgo CTestScript
# -------
#
# Runs our tests through CTest, with support for Coverage or memory checking.
#
# This script provides a full CTest run whith result submission to Ginkgo's
# CDash dashboard. The supported runs are:
# + With or without coverage, requires the gcov tool.
# + With or without address sanitizers.
# + With or without memory sanitizers.
# + With or without thread sanitizers.
# + With or without leak sanitizers.
# + With or without undefined behavior (UB) sanitizers.
# + With or without valgrind, requires the valgrind tool.
#
# Note that only one of these can be ran at once, as the build types
# conflict. Ginkgo is always configured with CUDA, HIP, OpenMP and Reference
# support, except for ThreadSanitizer, AddressSanitizer, LeakSanitizer,
# UndefinedBehaviorSanitizer builds. The results are always sent to the
# dashboard: https://my.cdash.org/index.php?project=Ginkgo+Project
#
# Running the script
# ^^^^^^^^^^^^^^^^^^
#
# To run the script, launch the command `ctest -S cmake/CTestScript.cmake`
# from the Ginkgo's source directory. The default settings are for the CI
# system's DEBUG tests run. To configure the script use standard CMake `-D`
# parameters. For example, the following command runs coverage.
#
# `ctest -S cmake/CTestScript.cmake -DCTEST_BUILD_CONFIGURATION=COVERAGE`
#
# Instead, this runs the ThreadSanitizer:
#
# `ctest -S cmake/CTestScript.cmake -DCTEST_BUILD_CONFIGURATION=TSAN
# -DCTEST_MEMORYCHECK_TYPE=ThreadSanitizer`
#
# Input Variables
# ^^^^^^^^^^^^^^^^
#
# This script can be configured with the following input variables:
#
# ``CTEST_SOURCE_DIRECTORY``
# Where the sources are located. By default, the current directory.
#
# ``CTEST_BINARY_DIRECTORY``
# In which directory should the sources be builts. Default, `./build`.
#
# ``CTEST_SITE``
# A string to describe the machine this is ran on. Default FineCI.
#
# ``CTEST_CMAKE_GENERATOR``
# Which generator should be used for the build. Default `Ninja`, except
# for COVERAGE builds where `Unix Makefiles` is used.
#
# ``CTEST_BUILD_CONFIGURATION``
# Which configuration should Ginkgo be built with. Default `DEBUG`.
# The supported values are: COVERAGE, TSAN, UBSAN, DEBUG, and
# RELEASE.
#
# ``CTEST_TEST_MODEL``
# Which CTest test model should be used. Default `Continuous`.
# The supported values are the same as CTest's, namely:
# Experimental, Nightly, Continuous.
#
# ``CTEST_BUILD_NAME``
# The name of the build being ran. Default: `CTEST_BUILD_CONFIGURATION`
#
# ``CTEST_MEMORYCHECK_TYPE``
# Whether memorycheck should be ran. Default: `NONE`. Supported values are:
# Valgrind, AddressSanitizer, LeakSanitizer, ThreadSanitizer,
# UndefinedBehaviorSanitizer and NONE.
#
if (NOT DEFINED CTEST_SOURCE_DIRECTORY)
set(CTEST_SOURCE_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/..")
endif()
if (NOT DEFINED CTEST_BINARY_DIRECTORY)
set(CTEST_BINARY_DIRECTORY "${CTEST_SOURCE_DIRECTORY}/build")
endif()
if (NOT DEFINED CTEST_SITE)
set(CTEST_SITE "Linux-FineCI")
endif()
if (NOT DEFINED CTEST_CMAKE_GENERATOR)
if (CTEST_BUILD_CONFIGURATION STREQUAL "COVERAGE")
set(CTEST_CMAKE_GENERATOR "Unix Makefiles")
else()
set(CTEST_CMAKE_GENERATOR "Ninja")
endif()
endif()
# Supported: COVERAGE, ASAN, LSAN, TSAN, UBSAN, DEBUG and RELEASE
if (NOT DEFINED CTEST_BUILD_CONFIGURATION)
set(CTEST_BUILD_CONFIGURATION "DEBUG")
endif()
if (NOT DEFINED CTEST_TEST_MODEL)
set(CTEST_TEST_MODEL "Continuous")
endif()
if (NOT DEFINED CTEST_BUILD_NAME)
set(CTEST_BUILD_NAME "${CTEST_BUILD_CONFIGURATION}")
endif()
#Supported: Valgrind, ThreadSanitizer, AddressSanitizer, LeakSanitizer
#and UndefinedBehaviorSanitizer.
if (NOT DEFINED CTEST_MEMORYCHECK_TYPE)
set(CTEST_MEMORYCHECK_TYPE "NONE")
endif()
# Find coverage and valgrind tools
if(CTEST_MEMORYCHECK_TYPE STREQUAL "Valgrind")
find_program(CTEST_MEMORYCHECK_COMMAND valgrind)
set(CTEST_BUILD_NAME "Valgrind")
set(CTEST_MEMORYCHECK_COMMAND_OPTIONS "--trace-children=yes --leak-check=full")
set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE "${CTEST_SOURCE_DIRECTORY}/dev_tools/valgrind/suppressions.supp")
endif()
if(CTEST_MEMORYCHECK_TYPE STREQUAL "CudaMemcheck")
find_program(CTEST_MEMORYCHECK_COMMAND cuda-memcheck)
set(CTEST_BUILD_NAME "CudaMemcheck")
endif()
if(CTEST_BUILD_CONFIGURATION STREQUAL "COVERAGE")
find_program(CTEST_COVERAGE_COMMAND gcov)
endif()
if(NOT CTEST_MEMORYCHECK_TYPE STREQUAL "Valgrind" AND NOT CTEST_MEMORYCHECK_TYPE STREQUAL "CudaMemcheck")
set(CTEST_MEMORYCHECK_SANITIZER_OPTIONS "${CTEST_MEMORYCHECK_SANITIZER_OPTIONS}:allocator_may_return_null=1:verbosity=1")
endif()
include(ProcessorCount)
ProcessorCount(PROC_COUNT)
if(NOT PROC_COUNT EQUAL 0)
if (DEFINED ENV{CI_PARALLELISM})
set(PROC_COUNT "$ENV{CI_PARALLELISM}")
elseif(PROC_COUNT LESS 4)
set(PROC_COUNT 1)
else()
set(PROC_COUNT 4)
endif()
if(NOT WIN32)
set(CTEST_BUILD_FLAGS "-j${PROC_COUNT}")
endif(NOT WIN32)
endif()
ctest_start("${CTEST_TEST_MODEL}")
ctest_submit(PARTS Start)
if (CTEST_MEMORYCHECK_TYPE STREQUAL "CudaMemcheck")
# generate line number information for CUDA
set(GINKGO_CONFIGURE_OPTIONS "-DGINKGO_DEVEL_TOOLS=OFF;-DGINKGO_BUILD_REFERENCE=ON;-DGINKGO_BUILD_OMP=OFF;-DGINKGO_BUILD_CUDA=ON;-DGINKGO_BUILD_HIP=ON;-DCMAKE_BUILD_TYPE=${CTEST_BUILD_CONFIGURATION};-DCMAKE_CUDA_FLAGS=-lineinfo")
elseif((NOT CTEST_MEMORYCHECK_TYPE STREQUAL "NONE" AND NOT CTEST_MEMORYCHECK_TYPE STREQUAL "Valgrind") OR CTEST_BUILD_CONFIGURATION STREQUAL "COVERAGE")
set(GINKGO_CONFIGURE_OPTIONS "-DGINKGO_DEVEL_TOOLS=OFF;-DGINKGO_BUILD_REFERENCE=ON;-DGINKGO_BUILD_OMP=ON;-DGINKGO_BUILD_CUDA=OFF;-DGINKGO_BUILD_HIP=OFF;-DCMAKE_BUILD_TYPE=${CTEST_BUILD_CONFIGURATION}")
else()
set(GINKGO_CONFIGURE_OPTIONS "-DGINKGO_DEVEL_TOOLS=OFF;-DGINKGO_BUILD_REFERENCE=ON;-DGINKGO_BUILD_OMP=ON;-DGINKGO_BUILD_CUDA=ON;-DGINKGO_BUILD_HIP=ON;-DCMAKE_BUILD_TYPE=${CTEST_BUILD_CONFIGURATION}")
endif()
# UBSAN needs gold linker
if (CTEST_MEMORYCHECK_TYPE STREQUAL "UndefinedBehaviorSanitizer")
set(GINKGO_CONFIGURE_OPTIONS "${GINKGO_CONFIGURE_OPTIONS};-DCMAKE_SHARED_LINKER_FLAGS=-fuse-ld=gold;-DCMAKE_EXE_LINKER_FLAGS=-fuse-ld=gold")
endif()
ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}" OPTIONS "${GINKGO_CONFIGURE_OPTIONS}" APPEND)
ctest_submit(PARTS Configure)
ctest_read_custom_files( ${CTEST_BINARY_DIRECTORY} )
if (DEFINED GINKGO_SONARQUBE_TEST)
set(CTEST_BUILD_COMMAND "build-wrapper-linux-x86-64 --out-dir bw-output make -j${PROC_COUNT}")
endif()
ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND)
ctest_submit(PARTS Build)
if (CTEST_MEMORYCHECK_TYPE STREQUAL "NONE")
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND)
ctest_submit(PARTS Test)
endif()
if (CTEST_BUILD_CONFIGURATION STREQUAL "COVERAGE")
ctest_coverage(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND)
ctest_submit(PARTS Coverage)
endif()
if(NOT CTEST_MEMORYCHECK_TYPE STREQUAL "NONE")
if(CTEST_MEMORYCHECK_TYPE STREQUAL "CudaMemcheck")
ctest_memcheck(BUILD "${CTEST_BINARY_DIRECTORY}" INCLUDE "^(cuda|hip).*" APPEND)
else()
ctest_memcheck(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND)
endif()
ctest_submit(PARTS MemCheck)
endif()
cmake_minimum_required(VERSION 3.9)
project(${package_name})
include(ExternalProject)
ExternalProject_Add(${package_name}
GIT_REPOSITORY "${package_url}"
GIT_TAG "${package_tag}"
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/build"
CMAKE_ARGS "-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}"
"-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}"
"-DCMAKE_BUILD_TYPE=${GINKGO_THIRD_PARTY_BUILD_TYPE}"
# These are only useful if you're cross-compiling.
# They, however, will not hurt regardless.
"-DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}"
"-DCMAKE_SYSTEM_PROCESSOR=${CMAKE_SYSTEM_PROCESSOR}"
"-DCMAKE_AR=${CMAKE_AR}"
"-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
"-DCMAKE_FIND_ROOT_PATH=${CMAKE_FIND_ROOT_PATH}"
"${ARGN}"
TEST_COMMAND ""
UPDATE_DISCONNECTED ${NLA4HPC_SKIP_DEPENDENCY_UPDATE}
)
cmake_minimum_required(VERSION 3.9)
project(${package_name})
include(ExternalProject)
ExternalProject_Add(${package_name}
GIT_REPOSITORY "${package_url}"
GIT_TAG "${package_tag}"
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/build"
CMAKE_ARGS "-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}"
"-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}"
"-DCMAKE_BUILD_TYPE=${GINKGO_THIRD_PARTY_BUILD_TYPE}"
# These are only useful if you're cross-compiling.
# They, however, will not hurt regardless.
"-DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}"
"-DCMAKE_SYSTEM_PROCESSOR=${CMAKE_SYSTEM_PROCESSOR}"
"-DCMAKE_AR=${CMAKE_AR}"
"-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
"-DCMAKE_FIND_ROOT_PATH=${CMAKE_FIND_ROOT_PATH}"
"${ARGN}"
TEST_COMMAND ""
INSTALL_COMMAND ""
UPDATE_DISCONNECTED ${NLA4HPC_SKIP_DEPENDENCY_UPDATE}
)
function(ginkgo_default_includes name)
# set include path depending on used interface
target_include_directories("${name}"
PUBLIC
$<BUILD_INTERFACE:${NLA4HPC_BINARY_DIR}/include>
$<BUILD_INTERFACE:${NLA4HPC_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${NLA4HPC_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>
)
endfunction()
function(ginkgo_compile_features name)
target_compile_features("${name}" PUBLIC cxx_std_14)
# Set an appropriate SONAME
set_property(TARGET "${name}" PROPERTY
SOVERSION "${NLA4HPC_VERSION}")
set_target_properties("${name}" PROPERTIES POSITION_INDEPENDENT_CODE ON)
endfunction()
macro(ginkgo_modify_flags name)
# add escape before "
# the result var is ${name}_MODIFY
string(REPLACE "\"" "\\\"" ${name}_MODIFY "${${name}}")
endmacro()
# Extract the clang version from a clang executable path
function(ginkgo_extract_clang_version CLANG_COMPILER GINKGO_CLANG_VERSION)
set(CLANG_VERSION_PROG "#include <cstdio>\n"
"int main() {printf(\"%d.%d.%d\", __clang_major__, __clang_minor__, __clang_patchlevel__)\;"
"return 0\;}")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/extract_clang_ver.cpp" ${CLANG_VERSION_PROG})
execute_process(COMMAND ${CLANG_COMPILER} ${CMAKE_CURRENT_BINARY_DIR}/extract_clang_ver.cpp
-o ${CMAKE_CURRENT_BINARY_DIR}/extract_clang_ver
ERROR_VARIABLE CLANG_EXTRACT_VER_ERROR)
execute_process(COMMAND ${CMAKE_CURRENT_BINARY_DIR}/extract_clang_ver
OUTPUT_VARIABLE FOUND_CLANG_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_STRIP_TRAILING_WHITESPACE
)
set (${GINKGO_CLANG_VERSION} "${FOUND_CLANG_VERSION}" PARENT_SCOPE)
file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/extract_clang_ver.cpp)
file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/extract_clang_ver)
endfunction()
# License:
#
# Copyright (C) 2017 Lectem <lectem@gmail.com>
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the 'Software') deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# Note: Lectem's original file has gone through several changes to adapt
# to our needs.
include(CMakeDependentOption)
set(${PROJECT_NAME}_CUSTOM_BUILD_TYPES "COVERAGE;TSAN;ASAN;LSAN;UBSAN" CACHE INTERNAL "")
# LLVM provides all sanitizers in a single library, but they are separate in GCC
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(GKO_TSAN_LIBRARIES "-static-libsan")
set(GKO_UBSAN_LIBRARIES "-static-libsan")
else()
set(GKO_TSAN_LIBRARIES "-static-libtsan")
set(GKO_UBSAN_LIBRARIES "-static-libubsan")
endif()
set(${PROJECT_NAME}_COVERAGE_COMPILER_FLAGS "-g -O0 --coverage" CACHE INTERNAL "")
set(${PROJECT_NAME}_COVERAGE_LINKER_FLAGS "--coverage" CACHE INTERNAL "")
set(${PROJECT_NAME}_TSAN_COMPILER_FLAGS "-g -O1 -fsanitize=thread -fno-omit-frame-pointer -fPIC" CACHE INTERNAL "")
set(${PROJECT_NAME}_TSAN_LINKER_FLAGS "-fsanitize=thread ${GKO_TSAN_LIBRARIES} -fno-omit-frame-pointer -fPIC" CACHE INTERNAL "")
set(${PROJECT_NAME}_ASAN_COMPILER_FLAGS "-g -O1 -fsanitize=address -fno-omit-frame-pointer" CACHE INTERNAL "")
set(${PROJECT_NAME}_ASAN_LINKER_FLAGS "-fsanitize=address -fno-omit-frame-pointer" CACHE INTERNAL "")
set(${PROJECT_NAME}_LSAN_COMPILER_FLAGS "-g -O1 -fsanitize=leak" CACHE INTERNAL "")
set(${PROJECT_NAME}_LSAN_LINKER_FLAGS "-fsanitize=leak" CACHE INTERNAL "")
set(${PROJECT_NAME}_UBSAN_COMPILER_FLAGS "-g -O1 -fsanitize=undefined ${GKO_UBSAN_LIBRARIES}" CACHE INTERNAL "")
set(${PROJECT_NAME}_UBSAN_LINKER_FLAGS "-fsanitize=undefined ${GKO_UBSAN_LIBRARIES}" CACHE INTERNAL "")
# We need to wrap all flags with `-Xcomplier` for HIP when using the NVCC backend
function(GKO_XCOMPILER varname varlist)
set(tmp "")
foreach(item IN LISTS varlist)
set(tmp "${tmp} -Xcompiler \\\\\\\"${item}\\\\\\\"")
endforeach()
set(${varname} "${tmp}" CACHE INTERNAL "")
endfunction()
GKO_XCOMPILER(${PROJECT_NAME}_NVCC_COVERAGE_COMPILER_FLAGS "-g;-O0;--coverage")
GKO_XCOMPILER(${PROJECT_NAME}_NVCC_COVERAGE_LINKER_FLAGS "--coverage")
GKO_XCOMPILER(${PROJECT_NAME}_NVCC_TSAN_COMPILER_FLAGS "-g;-O1;-fsanitize=thread;-fno-omit-frame-pointer;-fPIC")
GKO_XCOMPILER(${PROJECT_NAME}_NVCC_TSAN_LINKER_FLAGS "-fsanitize=thread;-static-libtsan;-fno-omit-frame-pointer;-fPIC")
GKO_XCOMPILER(${PROJECT_NAME}_NVCC_ASAN_COMPILER_FLAGS "-g;-O1;-fsanitize=address;-fno-omit-frame-pointer")
GKO_XCOMPILER(${PROJECT_NAME}_NVCC_ASAN_LINKER_FLAGS "-fsanitize=address;-fno-omit-frame-pointer")
GKO_XCOMPILER(${PROJECT_NAME}_NVCC_LSAN_COMPILER_FLAGS "-g;-O1;-fsanitize=leak")
GKO_XCOMPILER(${PROJECT_NAME}_NVCC_LSAN_LINKER_FLAGS "-fsanitize=leak")
GKO_XCOMPILER(${PROJECT_NAME}_NVCC_UBSAN_COMPILER_FLAGS "-g;-O1;-fsanitize=undefined;-static-libubsan")
GKO_XCOMPILER(${PROJECT_NAME}_NVCC_UBSAN_LINKER_FLAGS "-fsanitize=undefined;-static-libubsan")
get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
foreach(_LANG IN LISTS ENABLED_LANGUAGES ITEMS "HIP")
include(Check${_LANG}CompilerFlag OPTIONAL)
foreach(_TYPE IN LISTS ${PROJECT_NAME}_CUSTOM_BUILD_TYPES)
# Required for check_<LANG>_compiler_flag. Caution, this can break several
# CMake macros, therefore it is __important__ to reset this once we are done.
set(_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
set(CMAKE_REQUIRED_LIBRARIES ${${PROJECT_NAME}_${_TYPE}_LINKER_FLAGS})
if(_LANG STREQUAL "C")
check_c_compiler_flag("${${PROJECT_NAME}_${_TYPE}_LINKER_FLAGS}"
${PROJECT_NAME}_${_LANG}_${_TYPE}_SUPPORTED)
elseif(_LANG STREQUAL "CXX" OR _LANG STREQUAL "HIP")
check_cxx_compiler_flag("${${PROJECT_NAME}_${_TYPE}_LINKER_FLAGS}"
${PROJECT_NAME}_${_LANG}_${_TYPE}_SUPPORTED)
else()
if(DEFINED ${PROJECT_NAME}_${_LANG}_${_TYPE}_SUPPORTED)
message(STATUS "Skipping ${_LANG}, not supported by build_type.cmake script")
endif()
set(${PROJECT_NAME}_${_LANG}_${_TYPE}_SUPPORTED FALSE)
continue()
endif()
if(${PROJECT_NAME}_${_LANG}_${_TYPE}_SUPPORTED)
if(_LANG STREQUAL "HIP" AND GINKGO_HIP_PLATFORM STREQUAL "nvcc")
set(CMAKE_${_LANG}_FLAGS_${_TYPE}
${${PROJECT_NAME}_NVCC_${_TYPE}_COMPILER_FLAGS}
CACHE STRING "Flags used by the ${_LANG} compiler during ${_TYPE} builds." FORCE
)
mark_as_advanced(CMAKE_${_LANG}_FLAGS_${_TYPE})
set(${PROJECT_NAME}_${_TYPE}_SUPPORTED TRUE CACHE
STRING "Whether or not coverage is supported by at least one compiler." FORCE)
else()
set(CMAKE_${_LANG}_FLAGS_${_TYPE}
${${PROJECT_NAME}_${_TYPE}_COMPILER_FLAGS}
CACHE STRING "Flags used by the ${_LANG} compiler during ${_TYPE} builds." FORCE
)
mark_as_advanced(CMAKE_${_LANG}_FLAGS_${_TYPE})
set(${PROJECT_NAME}_${_TYPE}_SUPPORTED TRUE CACHE
STRING "Whether or not coverage is supported by at least one compiler." FORCE)
endif()
endif()
set(CMAKE_REQUIRED_LIBRARIES ${_CMAKE_REQUIRED_LIBRARIES})
endforeach()
endforeach()
foreach(_TYPE IN LISTS ${PROJECT_NAME}_CUSTOM_BUILD_TYPES)
cmake_dependent_option(${PROJECT_NAME}_${_TYPE}_IN_CONFIGURATION_TYPES
"Should the ${_TYPE} target be in the CMAKE_CONFIGURATION_TYPES list if supported ?" ON
# No need for this option if we are not using a multi-config generator
"CMAKE_CONFIGURATION_TYPES;${PROJECT_NAME}_${_TYPE}_SUPPORTED" OFF
)
if(${PROJECT_NAME}_${_TYPE}_IN_CONFIGURATION_TYPES)
# Modify this only if using a multi-config generator
# some modules rely on this variable to detect those generators.
if(CMAKE_CONFIGURATION_TYPES AND ${PROJECT_NAME}_${_TYPE}_SUPPORTED)
list(APPEND CMAKE_CONFIGURATION_TYPES ${_TYPE})
list(REMOVE_DUPLICATES CMAKE_CONFIGURATION_TYPES)
set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING
"Semicolon separated list of supported configuration types, only supports ${CMAKE_CONFIGURATION_TYPES} anything else will be ignored."
FORCE
)
endif()
else()
if(${_TYPE} IN_LIST CMAKE_CONFIGURATION_TYPES)
message(STATUS "Removing ${_TYPE} configuration type (${PROJECT_NAME}_${_TYPE}_IN_CONFIGURATION_TYPES is OFF)")
list(REMOVE_ITEM CMAKE_CONFIGURATION_TYPES ${_TYPE})
list(REMOVE_DUPLICATES CMAKE_CONFIGURATION_TYPES)
set(CMAKE_CONFIGURATION_TYPES
"${CMAKE_CONFIGURATION_TYPES}"
CACHE STRING
"Semicolon separated list of supported configuration types, only supports ${CMAKE_CONFIGURATION_TYPES} anything else will be ignored."
FORCE
)
endif()
endif()
endforeach()
function(ginkgo_create_test test_name)
file(RELATIVE_PATH REL_BINARY_DIR
${PROJECT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
string(REPLACE "/" "_" TEST_TARGET_NAME "${REL_BINARY_DIR}/${test_name}")
add_executable(${TEST_TARGET_NAME} ${test_name}.cpp)
target_compile_features("${TEST_TARGET_NAME}" PUBLIC cxx_std_14)
target_include_directories("${TEST_TARGET_NAME}"
PRIVATE
"$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>"
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>"
)
set_target_properties(${TEST_TARGET_NAME} PROPERTIES
OUTPUT_NAME ${test_name})
if (GINKGO_CHECK_CIRCULAR_DEPS)
target_link_libraries(${TEST_TARGET_NAME} PRIVATE "${GINKGO_CIRCULAR_DEPS_FLAGS}")
endif()
target_link_libraries(${TEST_TARGET_NAME} PUBLIC Ginkgo::ginkgo GTest::Main GTest::GTest ${ARGN})
add_test(NAME ${REL_BINARY_DIR}/${test_name} COMMAND ${TEST_TARGET_NAME})
endfunction(ginkgo_create_test)
function(ginkgo_create_gbench bench_name)
find_package(Threads REQUIRED)
find_package(CUDA REQUIRED)
enable_language(CUDA)
file(RELATIVE_PATH REL_BINARY_DIR
${PROJECT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
string(REPLACE "/" "_" TEST_TARGET_NAME "${REL_BINARY_DIR}/${bench_name}")
add_executable(${TEST_TARGET_NAME} ${bench_name}.cpp)
target_compile_features("${TEST_TARGET_NAME}" PUBLIC cxx_std_14)
target_include_directories("${TEST_TARGET_NAME}"
PRIVATE
"$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>"
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>"
)
set_target_properties(${TEST_TARGET_NAME} PROPERTIES
OUTPUT_NAME ${bench_name})
if (GINKGO_CHECK_CIRCULAR_DEPS)
target_link_libraries(${TEST_TARGET_NAME} PRIVATE "${GINKGO_CIRCULAR_DEPS_FLAGS}")
endif()
target_link_libraries(${TEST_TARGET_NAME} PUBLIC Ginkgo::ginkgo GTest::Main GTest::GTest GBenchmark::GBenchmark Threads::Threads ${ARGN} ${CUDA_LIBRARIES})
add_test(NAME ${REL_BINARY_DIR}/${bench_name} COMMAND ${TEST_TARGET_NAME})
endfunction(ginkgo_create_gbench)
function(ginkgo_create_thread_test test_name)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
file(RELATIVE_PATH REL_BINARY_DIR
${PROJECT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
string(REPLACE "/" "_" TEST_TARGET_NAME "${REL_BINARY_DIR}/${test_name}")
add_executable(${TEST_TARGET_NAME} ${test_name}.cpp)
target_compile_features("${TEST_TARGET_NAME}" PUBLIC cxx_std_14)
target_include_directories("${TEST_TARGET_NAME}"
PRIVATE
"$<BUILD_INTERFACE:${Ginkgo_BINARY_DIR}>"
)
set_target_properties(${TEST_TARGET_NAME} PROPERTIES
OUTPUT_NAME ${test_name})
if (GINKGO_CHECK_CIRCULAR_DEPS)
target_link_libraries(${TEST_TARGET_NAME} PRIVATE "${GINKGO_CIRCULAR_DEPS_FLAGS}")
endif()
target_link_libraries(${TEST_TARGET_NAME} PRIVATE Ginkgo::ginkgo GTest::Main GTest::GTest Threads::Threads ${ARGN})
add_test(NAME ${REL_BINARY_DIR}/${test_name} COMMAND ${TEST_TARGET_NAME})
endfunction(ginkgo_create_thread_test)
function(ginkgo_create_test_cpp_cuda_header test_name)
file(RELATIVE_PATH REL_BINARY_DIR
${PROJECT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
string(REPLACE "/" "_" TEST_TARGET_NAME "${REL_BINARY_DIR}/${test_name}")
add_executable(${TEST_TARGET_NAME} ${test_name}.cpp)
target_compile_features("${TEST_TARGET_NAME}" PUBLIC cxx_std_14)
target_include_directories("${TEST_TARGET_NAME}"
PRIVATE
"$<BUILD_INTERFACE:${Ginkgo_BINARY_DIR}>"
"${CUDA_INCLUDE_DIRS}"
)
set_target_properties(${TEST_TARGET_NAME} PROPERTIES
OUTPUT_NAME ${test_name})
if (GINKGO_CHECK_CIRCULAR_DEPS)
target_link_libraries(${TEST_TARGET_NAME} PRIVATE "${GINKGO_CIRCULAR_DEPS_FLAGS}")
endif()
target_link_libraries(${TEST_TARGET_NAME} PRIVATE Ginkgo::ginkgo GTest::Main GTest::GTest ${ARGN})
add_test(NAME ${REL_BINARY_DIR}/${test_name} COMMAND ${TEST_TARGET_NAME})
endfunction(ginkgo_create_test_cpp_cuda_header)
function(ginkgo_create_cuda_test test_name)
file(RELATIVE_PATH REL_BINARY_DIR
${PROJECT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
string(REPLACE "/" "_" TEST_TARGET_NAME "${REL_BINARY_DIR}/${test_name}")
add_executable(${TEST_TARGET_NAME} ${test_name}.cu)
target_compile_features("${TEST_TARGET_NAME}" PUBLIC cxx_std_14)
target_include_directories("${TEST_TARGET_NAME}"
PRIVATE
"$<BUILD_INTERFACE:${Ginkgo_BINARY_DIR}>"
)
cas_target_cuda_architectures(${TEST_TARGET_NAME}
ARCHITECTURES ${GINKGO_CUDA_ARCHITECTURES}
UNSUPPORTED "20" "21")
set_target_properties(${TEST_TARGET_NAME} PROPERTIES
OUTPUT_NAME ${test_name})
if (GINKGO_CHECK_CIRCULAR_DEPS)
target_link_libraries(${TEST_TARGET_NAME} PRIVATE "${GINKGO_CIRCULAR_DEPS_FLAGS}")
endif()
target_link_libraries(${TEST_TARGET_NAME} PRIVATE Ginkgo::ginkgo GTest::Main GTest::GTest ${ARGN})
add_test(NAME ${REL_BINARY_DIR}/${test_name} COMMAND ${TEST_TARGET_NAME})
endfunction(ginkgo_create_cuda_test)
function(ginkgo_create_mpi_test test_name num_mpi_procs)
file(RELATIVE_PATH REL_BINARY_DIR
${PROJECT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
string(REPLACE "/" "_" TEST_TARGET_NAME "${REL_BINARY_DIR}/${test_name}")
add_executable(${TEST_TARGET_NAME} ${test_name}.cpp)
target_include_directories("${TEST_TARGET_NAME}"
PRIVATE
"$<BUILD_INTERFACE:${Ginkgo_BINARY_DIR}>"
${MPI_INCLUDE_PATH}
)
set_target_properties(${TEST_TARGET_NAME} PROPERTIES
OUTPUT_NAME ${test_name})
if (GINKGO_CHECK_CIRCULAR_DEPS)
target_link_libraries(${TEST_TARGET_NAME} PRIVATE "${GINKGO_CIRCULAR_DEPS_FLAGS}")
endif()
if("${GINKGO_MPI_EXEC_SUFFIX}" MATCHES ".openmpi" AND MPI_RUN_AS_ROOT)
set(OPENMPI_RUN_AS_ROOT_FLAG "--allow-run-as-root")
else()
set(OPENMPI_RUN_AS_ROOT_FLAG "")
endif()
target_link_libraries(${TEST_TARGET_NAME} PRIVATE Ginkgo::ginkgo GTest::Main GTest::GTest ${ARGN})
target_link_libraries(${TEST_TARGET_NAME} PRIVATE ${MPI_C_LIBRARIES} ${MPI_CXX_LIBRARIES})
set(test_param ${MPIEXEC_NUMPROC_FLAG} ${num_mpi_procs} ${OPENMPI_RUN_AS_ROOT_FLAG} ${CMAKE_BINARY_DIR}/${REL_BINARY_DIR}/${test_name})
add_test(NAME ${REL_BINARY_DIR}/${test_name}
COMMAND ${MPIEXEC_EXECUTABLE} ${test_param} )
endfunction(ginkgo_create_mpi_test)
function(ginkgo_create_hip_test_special_linkage test_name)
# use gcc to compile but use hip to link
file(RELATIVE_PATH REL_BINARY_DIR
${PROJECT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
string(REPLACE "/" "_" TEST_TARGET_NAME "${REL_BINARY_DIR}/${test_name}")
add_executable(${TEST_TARGET_NAME} ${test_name}.cpp)
target_compile_features("${TEST_TARGET_NAME}" PUBLIC cxx_std_14)
# Fix the missing metadata when building static library.
if(GINKGO_HIP_PLATFORM MATCHES "hcc" AND NOT BUILD_SHARED_LIBS