mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
307 lines
13 KiB
CMake
307 lines
13 KiB
CMake
#=============================================================================
|
|
# Adds the following DIY library targets:
|
|
# 1. diy: The main diy interface library and the only target for
|
|
# header-only mode.
|
|
# 2. diympi: Generated when `build_diy_mpi_lib` and `mpi` are turned on.
|
|
# Isolates the MPI dependent part of diy into a library.
|
|
# 3. diympi_nompi: Generated when `build_diy_mpi_lib` is on and either `mpi`
|
|
# is off or `build_diy_nompi_lib` is on.
|
|
#
|
|
# Both mpi and non-mpi libraries can be generated by turning on `build_diy_mpi_lib`
|
|
# and `build_diy_nompi_lib`. In this case, one of these targets must be explicitly
|
|
# specified when linking againts diy.
|
|
#=============================================================================
|
|
|
|
project (DIY)
|
|
cmake_minimum_required (VERSION 3.9)
|
|
|
|
list (APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
|
|
|
include(CMakeDependentOption)
|
|
|
|
# Provides an option if it is not already defined.
|
|
# This can be replaced when CMake 3.13 is our cmake_minimum_required
|
|
macro (diy_option variable)
|
|
if (NOT DEFINED "${variable}")
|
|
option("${variable}" ${ARGN})
|
|
endif ()
|
|
endmacro ()
|
|
|
|
macro (diy_dependent_option variable)
|
|
if (NOT DEFINED "${variable}")
|
|
cmake_dependent_option("${variable}" ${ARGN})
|
|
endif ()
|
|
endmacro ()
|
|
|
|
set (compiler_supports_sanitizers OFF)
|
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR
|
|
CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR
|
|
CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|
set (compiler_supports_sanitizers ON)
|
|
endif ()
|
|
|
|
diy_option (threads "Build DIY with threading" ON)
|
|
diy_option (log "Build DIY with logging" OFF)
|
|
diy_option (profile "Build DIY with profiling" OFF)
|
|
diy_option (caliper "Build DIY with caliper" OFF)
|
|
diy_option (mpi "Build DIY with mpi" ON)
|
|
diy_option (wrapped_mpi "MPI compiler wrapper requires no further MPI libraries" OFF)
|
|
diy_option (build_diy_mpi_lib "Build diy::mpi as a library" OFF)
|
|
diy_dependent_option (BUILD_SHARED_LIBS "Create shared libraries if on" ON "build_diy_mpi_lib" OFF)
|
|
diy_dependent_option (build_diy_nompi_lib "Also build the nompi version of diy::mpi" OFF "mpi;build_diy_mpi_lib" OFF)
|
|
diy_option (build_examples "Build DIY examples" ON)
|
|
diy_option (build_tests "Build DIY tests" ON)
|
|
diy_option (python "Build Python bindings" OFF)
|
|
cmake_dependent_option (enable_sanitizers "Build DIY with sanitizer support" OFF "compiler_supports_sanitizers" OFF)
|
|
|
|
# Default to Release
|
|
if (NOT CMAKE_BUILD_TYPE)
|
|
set (CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
|
|
set_property (CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
|
|
endif (NOT CMAKE_BUILD_TYPE)
|
|
|
|
set (diy_definitions "")
|
|
set (diy_include_directories "")
|
|
set (diy_include_thirdparty_directories "")
|
|
set (diy_libraries "")
|
|
|
|
# Debugging
|
|
if (${CMAKE_BUILD_TYPE} STREQUAL "Debug" OR
|
|
${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo")
|
|
list (APPEND diy_definitions "-DVTKMDIY_DEBUG")
|
|
endif ()
|
|
|
|
# Logging
|
|
if (log)
|
|
list (APPEND diy_definitions "-DVTMDIY_USE_SPDLOG")
|
|
find_package (spdlog REQUIRED)
|
|
endif()
|
|
|
|
# Profiling
|
|
if (profile)
|
|
list (APPEND diy_definitions "-DVTKMDIY_PROFILE")
|
|
endif()
|
|
|
|
if (caliper)
|
|
list (APPEND diy_definitions "-DVTKMDIY_USE_CALIPER")
|
|
|
|
find_package (caliper)
|
|
list (APPEND diy_include_thirdparty_directories $<BUILD_INTERFACE:${caliper_INCLUDE_DIR}>)
|
|
list (APPEND diy_libraries caliper caliper-mpi)
|
|
endif()
|
|
|
|
# Threads
|
|
if (NOT threads)
|
|
list (APPEND diy_definitions "-DVTKMDIY_NO_THREADS")
|
|
else (NOT threads)
|
|
find_package (Threads)
|
|
list (APPEND diy_libraries ${CMAKE_THREAD_LIBS_INIT})
|
|
endif (NOT threads)
|
|
|
|
# MPI
|
|
if (mpi AND NOT wrapped_mpi)
|
|
find_package(MPI REQUIRED)
|
|
endif()
|
|
|
|
# configuration variables for diy build and install
|
|
# if diy is a sub-project, the following variables allow the parent project to
|
|
# easily customize the library
|
|
if (NOT DEFINED diy_prefix)
|
|
set(diy_prefix "diy")
|
|
endif()
|
|
if (NOT DEFINED diy_install_include_dir)
|
|
set(diy_install_include_dir "include")
|
|
endif()
|
|
if (NOT DEFINED diy_install_bin_dir)
|
|
set(diy_install_bin_dir "bin")
|
|
endif()
|
|
if (NOT DEFINED diy_install_lib_dir)
|
|
set(diy_install_lib_dir "lib")
|
|
endif()
|
|
if (NOT DEFINED diy_export_name)
|
|
set(diy_export_name "diy_targets")
|
|
endif()
|
|
if (NOT DEFINED diy_development_component)
|
|
set(diy_development_component "development")
|
|
endif()
|
|
if (NOT DEFINED diy_runtime_component)
|
|
set(diy_runtime_component "runtime")
|
|
endif()
|
|
|
|
if (NOT DEFINED CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
|
|
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
|
|
endif()
|
|
if (NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY)
|
|
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
|
|
endif()
|
|
|
|
# for diy_developer_flags
|
|
include(DIYCompilerFlags)
|
|
|
|
function(add_diy_mpi_library use_mpi)
|
|
set (sources
|
|
"include/${diy_prefix}/mpi/collectives.cpp"
|
|
"include/${diy_prefix}/mpi/communicator.cpp"
|
|
"include/${diy_prefix}/mpi/datatypes.cpp"
|
|
"include/${diy_prefix}/mpi/environment.cpp"
|
|
"include/${diy_prefix}/mpi/io.cpp"
|
|
"include/${diy_prefix}/mpi/operations.cpp"
|
|
"include/${diy_prefix}/mpi/point-to-point.cpp"
|
|
"include/${diy_prefix}/mpi/request.cpp"
|
|
"include/${diy_prefix}/mpi/status.cpp"
|
|
"include/${diy_prefix}/mpi/window.cpp")
|
|
|
|
if (use_mpi)
|
|
set (lib_name ${diy_prefix}mpi)
|
|
set (has_mpi_val 1)
|
|
else()
|
|
set (lib_name ${diy_prefix}mpi_nompi)
|
|
set (has_mpi_val 0)
|
|
endif()
|
|
|
|
add_library(${lib_name} ${sources})
|
|
set_target_properties(${lib_name} PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
|
target_compile_features(${lib_name} PRIVATE cxx_std_14)
|
|
target_compile_definitions(${lib_name}
|
|
PRIVATE -DVTKMDIY_HAS_MPI=${has_mpi_val}
|
|
PRIVATE -Ddiy=${diy_prefix} # mangle diy namespace
|
|
PRIVATE ${diy_definitions})
|
|
target_include_directories(${lib_name} SYSTEM PRIVATE ${PROJECT_SOURCE_DIR}/include) # for types.hpp
|
|
target_include_directories(${lib_name} SYSTEM PRIVATE ${diy_include_directories}) # for mpitypes.hpp
|
|
target_include_directories(${lib_name} SYSTEM PRIVATE ${diy_include_thirdparty_directories})
|
|
target_link_libraries(${lib_name} PRIVATE diy_developer_flags)
|
|
if (log)
|
|
target_link_libraries(${lib_name} PUBLIC spdlog::spdlog_header_only)
|
|
endif ()
|
|
if (use_mpi AND TARGET MPI::MPI_CXX)
|
|
target_link_libraries(${lib_name} PRIVATE MPI::MPI_CXX)
|
|
endif()
|
|
endfunction()
|
|
|
|
# create the targets
|
|
set (diy_targets)
|
|
|
|
if (build_diy_mpi_lib)
|
|
include(DIYConfigureMPI)
|
|
|
|
# To be interchangeable, these libraries should only have PRIVATE properties.
|
|
# Properties that should be public should also be part of the core diy target.
|
|
list(APPEND diy_definitions -DVTKMDIY_MPI_AS_LIB)
|
|
list(APPEND diy_include_directories
|
|
"$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include/${diy_prefix}/mpi>"
|
|
"$<INSTALL_INTERFACE:${diy_install_include_dir}/${diy_prefix}/mpi>")
|
|
|
|
# macro required for proper export macros for static vs shared builds
|
|
if (NOT BUILD_SHARED_LIBS)
|
|
list(APPEND diy_definitions -DVTKMDIY_MPI_STATIC_BUILD)
|
|
endif()
|
|
|
|
if (mpi)
|
|
add_diy_mpi_library(ON)
|
|
list(APPEND diy_targets ${diy_prefix}mpi)
|
|
endif()
|
|
if ((NOT mpi) OR build_diy_nompi_lib)
|
|
add_diy_mpi_library(OFF)
|
|
list(APPEND diy_targets ${diy_prefix}mpi_nompi)
|
|
endif()
|
|
endif() # build_diy_mpi_lib
|
|
|
|
add_library(${diy_prefix} INTERFACE)
|
|
target_compile_features(${diy_prefix} INTERFACE cxx_std_14)
|
|
target_compile_definitions(${diy_prefix} INTERFACE ${diy_definitions})
|
|
target_include_directories(${diy_prefix} SYSTEM INTERFACE
|
|
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>"
|
|
"$<INSTALL_INTERFACE:${diy_install_include_dir}>")
|
|
target_include_directories(${diy_prefix} SYSTEM INTERFACE ${diy_include_thirdparty_directories})
|
|
if (diy_include_directories)
|
|
target_include_directories(${diy_prefix} SYSTEM INTERFACE ${diy_include_directories})
|
|
endif()
|
|
if (log)
|
|
target_link_libraries(${diy_prefix} INTERFACE spdlog::spdlog_header_only)
|
|
endif ()
|
|
target_link_libraries(${diy_prefix} INTERFACE ${diy_libraries})
|
|
if (NOT build_diy_mpi_lib)
|
|
if (mpi)
|
|
target_compile_definitions(${diy_prefix} INTERFACE -DVTKMDIY_HAS_MPI=1)
|
|
if (TARGET MPI::MPI_CXX)
|
|
target_link_libraries(${diy_prefix} INTERFACE MPI::MPI_CXX)
|
|
endif()
|
|
else()
|
|
target_compile_definitions(${diy_prefix} INTERFACE -DVTKMDIY_HAS_MPI=0)
|
|
endif()
|
|
elseif (NOT build_diy_nompi_lib)
|
|
if (mpi)
|
|
target_link_libraries(${diy_prefix} INTERFACE ${diy_prefix}mpi)
|
|
else()
|
|
target_link_libraries(${diy_prefix} INTERFACE ${diy_prefix}mpi_nompi)
|
|
endif()
|
|
endif()
|
|
|
|
list(APPEND diy_targets ${diy_prefix} diy_developer_flags)
|
|
|
|
# libraries used by examples and tests
|
|
set(libraries ${diy_prefix})
|
|
if (${diy_prefix}mpi IN_LIST diy_targets)
|
|
list(APPEND libraries ${diy_prefix}mpi)
|
|
elseif (${diy_prefix}mpi_nompi IN_LIST diy_targets)
|
|
list(APPEND libraries ${diy_prefix}mpi_nompi)
|
|
endif()
|
|
list(APPEND libraries diy_developer_flags)
|
|
|
|
# Sanitizers
|
|
if (enable_sanitizers)
|
|
set(sanitizer "address" CACHE STRING "The sanitizer to use")
|
|
|
|
string (APPEND CMAKE_CXX_FLAGS " -fsanitize=${sanitizer}")
|
|
string (APPEND CMAKE_C_FLAGS " -fsanitize=${sanitizer}")
|
|
string (APPEND CMAKE_EXE_LINKER_FLAGS " -fsanitize=${sanitizer}")
|
|
string (APPEND CMAKE_SHARED_LINKER_FLAGS " -fsanitize=${sanitizer}")
|
|
endif ()
|
|
|
|
# enable testing and CDash dashboard submission
|
|
enable_testing ()
|
|
include (CTest)
|
|
|
|
if (build_examples)
|
|
add_subdirectory (examples)
|
|
endif (build_examples)
|
|
|
|
if (build_tests)
|
|
add_subdirectory (tests)
|
|
endif (build_tests)
|
|
|
|
# configure find_package script
|
|
include(CMakePackageConfigHelpers)
|
|
configure_package_config_file(
|
|
"${PROJECT_SOURCE_DIR}/cmake/diy-config.cmake.in"
|
|
"${PROJECT_BINARY_DIR}/diy-config.cmake"
|
|
INSTALL_DESTINATION ".")
|
|
|
|
# install targets
|
|
if (NOT DEFINED diy_install_only_libraries) # defined by parent project if building for binary distribution
|
|
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/${diy_prefix}
|
|
DESTINATION ${diy_install_include_dir}
|
|
COMPONENT ${diy_development_component})
|
|
|
|
if (build_diy_mpi_lib)
|
|
install(FILES ${PROJECT_BINARY_DIR}/include/${diy_prefix}/mpi/mpitypes.hpp
|
|
DESTINATION ${diy_install_include_dir}/${diy_prefix}/mpi
|
|
COMPONENT ${diy_development_component})
|
|
endif()
|
|
endif()
|
|
|
|
install(TARGETS ${diy_targets} EXPORT ${diy_export_name}
|
|
ARCHIVE DESTINATION ${diy_install_lib_dir} COMPONENT ${diy_development_component}
|
|
LIBRARY DESTINATION ${diy_install_lib_dir} COMPONENT ${diy_runtime_component}
|
|
RUNTIME DESTINATION ${diy_install_bin_dir} COMPONENT ${diy_runtime_component})
|
|
|
|
if (CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) # Only generate these files when diy is the main project
|
|
export(EXPORT ${diy_export_name} NAMESPACE DIY:: FILE "${PROJECT_BINARY_DIR}/diy-targets.cmake")
|
|
install(EXPORT ${diy_export_name} NAMESPACE DIY:: DESTINATION "." FILE diy-targets.cmake COMPONENT ${diy_development_component})
|
|
install(FILES "${PROJECT_BINARY_DIR}/diy-config.cmake" DESTINATION "." COMPONENT ${diy_development_component})
|
|
endif()
|
|
|
|
if (python)
|
|
add_subdirectory(bindings/python)
|
|
endif (python)
|