vtk-m/vtkm/thirdparty/diy/vtkmdiy/CMakeLists.txt
Vicente Adolfo Bolea Sanchez 188e5080bd Merge branch 'upstream-diy' into update-diy
# By Diy Upstream
* upstream-diy:
  diy 2023-06-16 (3ee23f39)
2023-06-19 20:07:20 -04:00

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)