Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow HIGHFIVE_USE_INSTALL_DEPS only at install time #710

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CMake/HighFiveConfigFixed.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@PACKAGE_INIT@

include("${CMAKE_CURRENT_LIST_DIR}/HighFiveTargets.cmake")
check_required_components("@PROJECT_NAME@")
Original file line number Diff line number Diff line change
@@ -1,26 +1,14 @@
function(copy_interface_properties target source)
foreach(prop
INTERFACE_COMPILE_DEFINITIONS
INTERFACE_COMPILE_FEATURES
INTERFACE_COMPILE_OPTIONS
INTERFACE_INCLUDE_DIRECTORIES
INTERFACE_LINK_LIBRARIES
INTERFACE_SOURCES
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES)
set_property(TARGET ${target} APPEND PROPERTY ${prop} $<TARGET_PROPERTY:${source},${prop}>)
endforeach()
endfunction()
@PACKAGE_INIT@

if(TARGET HighFive)
return()
endif()

# Get HighFive targets
include("${CMAKE_CURRENT_LIST_DIR}/HighFiveTargets.cmake")

# Recreate combined HighFive
add_library(HighFive INTERFACE IMPORTED)
set_property(TARGET HighFive APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS MPI_NO_CPPBIND) # No c++ bindings
# PACKAGE_PREFIX_DIR comes from the expanded PACKAGE_INIT
target_include_directories(HighFive INTERFACE "${PACKAGE_PREFIX_DIR}/include")

# Ensure we activate required C++ std
if(NOT DEFINED CMAKE_CXX_STANDARD)
Expand All @@ -33,19 +21,6 @@ if(NOT DEFINED CMAKE_CXX_STANDARD)
endif()
endif()

# If the user sets this flag, all dependencies are preserved.
# Useful in central deployments where dependencies are not prepared later
set(HIGHFIVE_USE_INSTALL_DEPS @HIGHFIVE_USE_INSTALL_DEPS@ CACHE BOOL "Use original Highfive dependencies")
if(HIGHFIVE_USE_INSTALL_DEPS)
# If enabled in the deploy config, request c++14
if(@HIGHFIVE_USE_XTENSOR@ AND NOT CMAKE_VERSION VERSION_LESS 3.8)
set_property(TARGET HighFive APPEND PROPERTY INTERFACE_COMPILE_FEATURES cxx_std_14)
endif()
message(STATUS "HIGHFIVE @PROJECT_VERSION@: Using original dependencies (HIGHFIVE_USE_INSTALL_DEPS=YES)")
copy_interface_properties(HighFive HighFive_HighFive)
return()
endif()

# When not using the pre-built dependencies, give user options
if(DEFINED HIGHFIVE_USE_BOOST)
set(HIGHFIVE_USE_BOOST ${HIGHFIVE_USE_BOOST} CACHE BOOL "Enable Boost Support")
Expand All @@ -63,6 +38,6 @@ endif()

message(STATUS "HIGHFIVE @PROJECT_VERSION@: (Re)Detecting Highfive dependencies (HIGHFIVE_USE_INSTALL_DEPS=NO)")
include("${CMAKE_CURRENT_LIST_DIR}/HighFiveTargetDeps.cmake")
foreach(dependency HighFive_libheaders libdeps)
copy_interface_properties(HighFive ${dependency})
endforeach()

# This seems canonical to check that no unnecessary components were passed
check_required_components("HighFive")
193 changes: 93 additions & 100 deletions CMake/HighFiveTargetDeps.cmake
Original file line number Diff line number Diff line change
@@ -1,115 +1,108 @@
# Link against target system libs
# -------------------------------

if(NOT TARGET libdeps)

# Independent target to make it possible to have new dependencies each build
add_library(libdeps INTERFACE)

if(HIGHFIVE_VERBOSE)
target_compile_definitions(libdeps INTERFACE -DHIGHFIVE_LOG_LEVEL=0)
endif()

if(HIGHFIVE_GLIBCXX_ASSERTIONS)
target_compile_definitions(libdeps INTERFACE -D_GLIBCXX_ASSERTIONS)
endif()
if(HIGHFIVE_VERBOSE)
target_compile_definitions(HighFive INTERFACE -DHIGHFIVE_LOG_LEVEL=0)
endif()

if(HIGHFIVE_SANITIZER)
target_compile_options(libdeps INTERFACE -fsanitize=${HIGHFIVE_SANITIZER})
target_link_options(libdeps INTERFACE -fsanitize=${HIGHFIVE_SANITIZER})
endif()
if(HIGHFIVE_GLIBCXX_ASSERTIONS)
target_compile_definitions(HighFive INTERFACE -D_GLIBCXX_ASSERTIONS)
endif()

# HDF5
if(NOT DEFINED HDF5_C_LIBRARIES)
set(HDF5_PREFER_PARALLEL ${HIGHFIVE_PARALLEL_HDF5})
find_package(HDF5 REQUIRED)
endif()
if(HIGHFIVE_SANITIZER)
target_compile_options(HighFive INTERFACE -fsanitize=${HIGHFIVE_SANITIZER})
target_link_options(HighFive INTERFACE -fsanitize=${HIGHFIVE_SANITIZER})
endif()

if(HIGHFIVE_PARALLEL_HDF5 AND NOT HDF5_IS_PARALLEL)
message(WARNING "Parallel HDF5 requested but libhdf5 doesnt support it")
endif()
# HDF5
if(NOT DEFINED HDF5_C_LIBRARIES)
set(HDF5_PREFER_PARALLEL ${HIGHFIVE_PARALLEL_HDF5})
find_package(HDF5 REQUIRED)
endif()

target_include_directories(libdeps SYSTEM INTERFACE ${HDF5_INCLUDE_DIRS})
target_link_libraries(libdeps INTERFACE ${HDF5_LIBRARIES})
target_compile_definitions(libdeps INTERFACE ${HDF5_DEFINITIONS})
if(HIGHFIVE_PARALLEL_HDF5 AND NOT HDF5_IS_PARALLEL)
message(WARNING "Parallel HDF5 requested but libhdf5 doesnt support it")
endif()

# Boost
if(HIGHFIVE_USE_BOOST)
if(NOT DEFINED Boost_NO_BOOST_CMAKE)
# HighFive deactivated finding Boost via Boost's own CMake files
# in Oct 2016 (commit '25627b085'). Likely to appease one cluster.
# Boost's CMake support has since improved and likely this setting
# isn't needed anymore. It is kept for backwards compatibility.
# However, a rework of HighFive's CMake code should consider removing
# this default. Hard coding this to true has been reported to cause
# build failures.
set(Boost_NO_BOOST_CMAKE TRUE)
endif()
find_package(Boost REQUIRED COMPONENTS system serialization)
# Dont use imported targets yet, not avail before cmake 3.5
target_include_directories(libdeps SYSTEM INTERFACE ${Boost_INCLUDE_DIR})
target_compile_definitions(libdeps INTERFACE BOOST_ALL_NO_LIB H5_USE_BOOST)
endif()
target_include_directories(HighFive SYSTEM INTERFACE ${HDF5_INCLUDE_DIRS})
target_link_libraries(HighFive INTERFACE ${HDF5_LIBRARIES})
target_compile_definitions(HighFive INTERFACE ${HDF5_DEFINITIONS})

# Half
if(HIGHFIVE_USE_HALF_FLOAT)
find_file(FOUND_HALF half.hpp)
if (NOT FOUND_HALF)
message(FATAL_ERROR "Half-precision floating-point support requested but file half.hpp not found")
endif()
target_compile_definitions(libdeps INTERFACE H5_USE_HALF_FLOAT)
endif()
# Boost
if(HIGHFIVE_USE_BOOST)
if(NOT DEFINED Boost_NO_BOOST_CMAKE)
# HighFive deactivated finding Boost via Boost's own CMake files
# in Oct 2016 (commit '25627b085'). Likely to appease one cluster.
# Boost's CMake support has since improved and likely this setting
# isn't needed anymore. It is kept for backwards compatibility.
# However, a rework of HighFive's CMake code should consider removing
# this default. Hard coding this to true has been reported to cause
# build failures.
set(Boost_NO_BOOST_CMAKE TRUE)
endif()
find_package(Boost REQUIRED COMPONENTS system serialization)
# Dont use imported targets yet, not avail before cmake 3.5
target_include_directories(HighFive SYSTEM INTERFACE ${Boost_INCLUDE_DIR})
target_compile_definitions(HighFive INTERFACE BOOST_ALL_NO_LIB H5_USE_BOOST)
endif()

# Eigen
if(HIGHFIVE_USE_EIGEN)
if (NOT EIGEN3_INCLUDE_DIRS)
find_package(Eigen3 NO_MODULE)
if(Eigen3_FOUND)
message(STATUS "Found Eigen ${Eigen3_VERSION}: ${EIGEN3_INCLUDE_DIRS}")
else()
find_package(PkgConfig)
pkg_check_modules(EIGEN3 REQUIRED eigen3)
endif()
endif()
if (NOT EIGEN3_INCLUDE_DIRS)
message(FATAL_ERROR "Eigen was requested but could not be found")
endif()
target_include_directories(libdeps SYSTEM INTERFACE ${EIGEN3_INCLUDE_DIRS})
target_compile_definitions(libdeps INTERFACE H5_USE_EIGEN)
endif()
# Half
if(HIGHFIVE_USE_HALF_FLOAT)
find_file(FOUND_HALF half.hpp)
if (NOT FOUND_HALF)
message(FATAL_ERROR "Half-precision floating-point support requested but file half.hpp not found")
endif()
target_compile_definitions(HighFive INTERFACE H5_USE_HALF_FLOAT)
endif()

# xtensor
if(HIGHFIVE_USE_XTENSOR)
if (NOT xtensor_INCLUDE_DIRS)
find_package(xtensor REQUIRED)
endif()
if (NOT xtl_INCLUDE_DIRS)
find_package(xtl REQUIRED)
endif()
target_include_directories(libdeps SYSTEM INTERFACE ${xtensor_INCLUDE_DIRS} ${xtl_INCLUDE_DIRS})
target_compile_definitions(libdeps INTERFACE H5_USE_XTENSOR)
endif()
# Eigen
if(HIGHFIVE_USE_EIGEN)
if (NOT EIGEN3_INCLUDE_DIRS)
find_package(Eigen3 NO_MODULE)
if(Eigen3_FOUND)
message(STATUS "Found Eigen ${Eigen3_VERSION}: ${EIGEN3_INCLUDE_DIRS}")
else()
find_package(PkgConfig)
pkg_check_modules(EIGEN3 REQUIRED eigen3)
endif()
endif()
if (NOT EIGEN3_INCLUDE_DIRS)
message(FATAL_ERROR "Eigen was requested but could not be found")
endif()
target_include_directories(HighFive SYSTEM INTERFACE ${EIGEN3_INCLUDE_DIRS})
target_compile_definitions(HighFive INTERFACE H5_USE_EIGEN)
endif()

# OpenCV
if(HIGHFIVE_USE_OPENCV)
if (NOT OpenCV_INCLUDE_DIRS)
find_package(OpenCV REQUIRED)
endif()
target_include_directories(libdeps SYSTEM INTERFACE ${OpenCV_INCLUDE_DIRS})
target_link_libraries(libdeps INTERFACE ${OpenCV_LIBS})
target_compile_definitions(libdeps INTERFACE H5_USE_OPENCV)
endif()
# xtensor
if(HIGHFIVE_USE_XTENSOR)
if (NOT xtensor_INCLUDE_DIRS)
find_package(xtensor REQUIRED)
endif()
if (NOT xtl_INCLUDE_DIRS)
find_package(xtl REQUIRED)
endif()
target_include_directories(HighFive SYSTEM INTERFACE ${xtensor_INCLUDE_DIRS} ${xtl_INCLUDE_DIRS})
target_compile_definitions(HighFive INTERFACE H5_USE_XTENSOR)
endif()

# MPI
if(HIGHFIVE_PARALLEL_HDF5 OR HDF5_IS_PARALLEL)
find_package(MPI REQUIRED)
target_include_directories(libdeps SYSTEM INTERFACE ${MPI_CXX_INCLUDE_PATH})
target_link_libraries(libdeps INTERFACE ${MPI_CXX_LIBRARIES})
if(CMAKE_VERSION VERSION_LESS 3.13)
target_link_libraries(libdeps INTERFACE ${MPI_CXX_LINK_FLAGS})
else()
target_link_options(libdeps INTERFACE "SHELL:${MPI_CXX_LINK_FLAGS}")
endif()
endif()
# OpenCV
if(HIGHFIVE_USE_OPENCV)
if (NOT OpenCV_INCLUDE_DIRS)
find_package(OpenCV REQUIRED)
endif()
target_include_directories(HighFive SYSTEM INTERFACE ${OpenCV_INCLUDE_DIRS})
target_link_libraries(HighFive INTERFACE ${OpenCV_LIBS})
target_compile_definitions(HighFive INTERFACE H5_USE_OPENCV)
endif()

# MPI
if(HIGHFIVE_PARALLEL_HDF5 OR HDF5_IS_PARALLEL)
find_package(MPI REQUIRED)
target_include_directories(HighFive SYSTEM INTERFACE ${MPI_CXX_INCLUDE_PATH})
target_link_libraries(HighFive INTERFACE ${MPI_CXX_LIBRARIES})
if(CMAKE_VERSION VERSION_LESS 3.13)
target_link_libraries(HighFive INTERFACE ${MPI_CXX_LINK_FLAGS})
else()
target_link_options(HighFive INTERFACE "SHELL:${MPI_CXX_LINK_FLAGS}")
endif()
endif()
62 changes: 26 additions & 36 deletions CMake/HighFiveTargetExport.cmake
Original file line number Diff line number Diff line change
@@ -1,48 +1,38 @@

# Define the HighFive INTERFACE library
add_library(libheaders INTERFACE)

target_include_directories(libheaders INTERFACE
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:include>")

# Combined HighFive
add_library(HighFive INTERFACE)
target_compile_definitions(HighFive INTERFACE MPI_NO_CPPBIND) # No c++ bindings
target_link_libraries(HighFive INTERFACE libheaders libdeps)


# Generate ${PROJECT_NAME}Config.cmake

include(CMakePackageConfigHelpers)
configure_package_config_file(${CMAKE_CURRENT_LIST_DIR}/HighFiveConfig.cmake.in
${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
INSTALL_DESTINATION share/${PROJECT_NAME}/CMake)

write_basic_package_version_file(
${PROJECT_NAME}ConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion)

install(FILES
CMake/HighFiveTargetDeps.cmake
${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
DESTINATION share/${PROJECT_NAME}/CMake)


# Provides IMPORTED targets when using this project from build/install trees.

# Specify targets to include in the HighFive Exports
install(TARGETS HighFive libheaders libdeps
EXPORT HighFiveTargets)
install(TARGETS HighFive
EXPORT HighFiveTargets)

# Generate & install the Export for the INSTALL_INTERFACE
install(EXPORT HighFiveTargets
NAMESPACE HighFive_
FILE HighFiveTargets.cmake
DESTINATION share/${PROJECT_NAME}/CMake)
if(${HIGHFIVE_USE_INSTALL_DEPS})
# Generate & install the Export for the INSTALL_INTERFACE
install(EXPORT HighFiveTargets
FILE HighFiveTargets.cmake
DESTINATION share/${PROJECT_NAME}/CMake)

# Generate the Export for the BUILD_INTERACE (hardly used)
export(EXPORT HighFiveTargets
FILE "${PROJECT_BINARY_DIR}/HighFiveTargets.cmake")
configure_package_config_file(${CMAKE_CURRENT_LIST_DIR}/HighFiveConfigFixed.cmake.in
${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
INSTALL_DESTINATION share/${PROJECT_NAME}/CMake)

install(FILES
${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
DESTINATION share/${PROJECT_NAME}/CMake)
else()
configure_package_config_file(${CMAKE_CURRENT_LIST_DIR}/HighFiveConfigFlexible.cmake.in
${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
INSTALL_DESTINATION share/${PROJECT_NAME}/CMake)

install(FILES
CMake/HighFiveTargetDeps.cmake
${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
DESTINATION share/${PROJECT_NAME}/CMake)
endif()
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ endif()

add_compile_definitions(HIGHFIVE_CXX_STD=${CMAKE_CXX_STANDARD})

# Define the HighFive INTERFACE library
add_library(HighFive INTERFACE)

target_include_directories(HighFive INTERFACE
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:include>")
target_compile_definitions(HighFive INTERFACE MPI_NO_CPPBIND) # No c++ bindings
# Search dependencies (hdf5, boost, eigen, xtensor, mpi) and build target highfive_deps
include(${PROJECT_SOURCE_DIR}/CMake/HighFiveTargetDeps.cmake)

Expand Down