diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a5e9bf99a..0e19074fa7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,9 @@ ## Release 1.6.2 Date: 10/12/2022 +### Revert to standard `hdf5` handling +- [[PR198]](https://github.com/lanl/singularity-eos/pull/198) Use a more robust HDF5 handling that eliminates some edge breaks + ### Updated `hdf5` handling in the build - [[PR181]](https://github.com/lanl/singularity-eos/pull/181) change from manual dependecy handling to using hdf5 interface targets diff --git a/CMakeLists.txt b/CMakeLists.txt index 73523acf36..93949b4de5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -208,7 +208,7 @@ if(SINGULARITY_USE_KOKKOS) # type: soft submodule singularity_import_dependency( PKG Kokkos - TARGET Kokkos::kokkos + TARGETS Kokkos::kokkos SUBDIR ${PROJECT_SOURCE_DIR}/utils/kokkos ) set(PORTABILITY_STRATEGY "Kokkos") @@ -241,14 +241,14 @@ if (SINGULARITY_BUILD_CLOSURE) # type: external singularity_import_dependency( PKG KokkosKernels - TARGET Kokkos::kokkoskernels + TARGETS Kokkos::kokkoskernels ) list(APPEND SINGULARITY_PUBLIC_DEFINES SINGULARITY_USE_KOKKOSKERNELS) else() # type: soft submodule singularity_import_dependency( PKG Eigen3 - TARGET Eigen3::Eigen + TARGETS Eigen3::Eigen SUBDIR ${PROJECT_SOURCE_DIR}/utils/eigen ) endif() #SINGULARITY_USE_KOKKOS_KERNELS @@ -258,7 +258,7 @@ endif() #SINGULARITY_BUILD_CLOSURE # type: soft submodule singularity_import_dependency( PKG mpark_variant - TARGET mpark_variant + TARGETS mpark_variant SUBDIR ${PROJECT_SOURCE_DIR}/utils/variant ) @@ -266,7 +266,7 @@ singularity_import_dependency( # type: ghost submodule singularity_import_dependency( PKG ports-of-call - TARGET ports-of-call::ports-of-call + TARGETS ports-of-call::ports-of-call SUBDIR ${PROJECT_SOURCE_DIR}/utils/ports-of-call ) @@ -274,7 +274,7 @@ singularity_import_dependency( # type: soft submodule singularity_import_dependency( PKG spiner - TARGET spiner::spiner + TARGETS spiner::spiner SUBDIR ${PROJECT_SOURCE_DIR}/utils/spiner ) @@ -285,22 +285,12 @@ if (SINGULARITY_USE_HDF5) enable_language(C) singularity_import_dependency( PKG HDF5 - COMPONENTS "C;HL" + COMPONENTS C HL + TARGETS hdf5::hdf5 hdf5::hdf5_hl ) - # For the moment, there are several versions of - # HDF5 that are necessary to support, but they - # have incompatible build targets. - # So, for now, we roll a custom `FindHDF5.cmake`, - # and then explicilty pull out the libraries. - # CMM: I don't love this, but trying to get things - # moving for now - #TODO: Move this into `cmake/FindHDF5.cmake` - get_target_property(_seosh5ll HDF5::HDF5 INTERFACE_LINK_LIBRARIES) - get_target_property(_seosh5ic HDF5::HDF5 INTERFACE_INCLUDE_DIRECTORIES) - list(APPEND SINGULARITY_PUBLIC_LIBS ${_seosh5ll}) - list(APPEND SINGULARITY_PUBLIC_INCS ${_seosh5ic}) + # make sure we use MPI - if (HDF5_parallel_FOUND) + if (HDF5_IS_PARALLEL) # Message passing interface # type: external singularity_import_dependency( diff --git a/cmake/FindHDF5.cmake b/cmake/FindHDF5.cmake deleted file mode 100644 index da03d2d80a..0000000000 --- a/cmake/FindHDF5.cmake +++ /dev/null @@ -1,919 +0,0 @@ -# From https://github.com/geospace-code/h5fortran/blob/main/cmake/FindHDF5.cmake - -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: - -FindHDF5 ---------- - -by Michael Hirsch www.scivision.dev - -Finds HDF5 library for C, CXX, Fortran. Serial or parallel HDF5. - -Environment variable ``HDF5MPI_ROOT`` or CMake variable HDF5MPI_ROOT can -specify the location of the HDF5-MPI parallel library. - - -Result Variables -^^^^^^^^^^^^^^^^ - -``HDF5_FOUND`` - HDF5 libraries were found - -``HDF5_INCLUDE_DIRS`` - HDF5 include directory - -``HDF5_LIBRARIES`` - HDF5 library files - -``HDF5__COMPILER_EXECUTABLE`` - wrapper compiler for HDF5 - -``HDF5_HAVE_PARALLEL`` - HDF5 links the MPI library (thus user program must link MPI as well) - -Components -========== - -``C`` - C is normally available for all HDF5 library installs - -``CXX`` - C++ is an optional feature that not all HDF5 library installs are built with - -``Fortran`` - Fortran is an optional feature that not all HDF5 library installs are built with - -``parallel`` - checks that the optional MPI parallel HDF5 layer is enabled. NOTE: if HDF5_parallel_FOUND is true, - the user program MUST link MPI::MPI_C and/or MPI::MPI_Fortran. - -``HL`` - always implied and silently accepted to keep compatibility with factory FindHDF5.cmake - - -Targets -^^^^^^^ - -``HDF5::HDF5`` - HDF5 Imported Target -#]=======================================================================] - -include(CheckSymbolExists) -include(CheckCSourceCompiles) -include(CheckFortranSourceCompiles) - -function(get_flags exec outvar) - -execute_process(COMMAND ${exec} -show -OUTPUT_STRIP_TRAILING_WHITESPACE -OUTPUT_VARIABLE ret -RESULT_VARIABLE code -TIMEOUT 10 -ERROR_QUIET -) - -if(code EQUAL 0) - set(${outvar} ${ret} PARENT_SCOPE) -endif() - -endfunction(get_flags) - - -function(pop_flag raw flag outvar) -# this gives the argument to flags to get their paths like -I or -l or -L - -set(_v) -string(REGEX MATCHALL "(^| )${flag} *([^\" ]+|\"[^\"]+\")" _vars "${raw}") -foreach(_p IN LISTS _vars) - string(REGEX REPLACE "(^| )${flag} *" "" _p "${_p}") - list(APPEND _v "${_p}") -endforeach() - -set(${outvar} ${_v} PARENT_SCOPE) - -endfunction(pop_flag) - -macro(find_mpi) -# non-cache set by FindMPI are not visible outside function -- need macro just to see within that function -set(mpi_comp C) -if(Fortran IN_LIST HDF5_FIND_COMPONENTS) - list(APPEND mpi_comp Fortran) -endif() -if(HDF5_FIND_REQUIRED) - find_package(MPI COMPONENTS ${mpi_comp} REQUIRED) -else() - find_package(MPI COMPONENTS ${mpi_comp}) -endif() - -endmacro(find_mpi) - - -macro(detect_config) - -set(CMAKE_REQUIRED_INCLUDES ${HDF5_C_INCLUDE_DIR}) - -find_file(h5_conf -NAMES H5pubconf.h H5pubconf-64.h -HINTS ${HDF5_C_INCLUDE_DIR} -NO_DEFAULT_PATH -) - -if(NOT h5_conf) - set(HDF5_C_FOUND false) - return() -endif() - -# check HDF5 features that require link of external libraries. -check_symbol_exists(H5_HAVE_FILTER_SZIP ${h5_conf} hdf5_have_szip) -check_symbol_exists(H5_HAVE_FILTER_DEFLATE ${h5_conf} hdf5_have_zlib) - -# Always check for HDF5 MPI support because HDF5 link fails if MPI is linked into HDF5. -check_symbol_exists(H5_HAVE_PARALLEL ${h5_conf} HDF5_HAVE_PARALLEL) - -set(HDF5_parallel_FOUND false) - -if(HDF5_HAVE_PARALLEL) - find_mpi() - if(NOT MPI_FOUND) - return() - endif() - - set(HDF5_parallel_FOUND true) -endif() - -# get version -# from CMake/Modules/FindHDF5.cmake -file(STRINGS ${h5_conf} _def -REGEX "^[ \t]*#[ \t]*define[ \t]+H5_VERSION[ \t]+" ) -if("${_def}" MATCHES -"H5_VERSION[ \t]+\"([0-9]+\\.[0-9]+\\.[0-9]+)(-patch([0-9]+))?\"" ) - set(HDF5_VERSION "${CMAKE_MATCH_1}" ) - if(CMAKE_MATCH_3) - set(HDF5_VERSION ${HDF5_VERSION}.${CMAKE_MATCH_3}) - endif() -endif() - -# avoid picking up incompatible zlib over the desired zlib -if(CMAKE_VERSION VERSION_LESS 3.20) - get_filename_component(zlib_dir ${HDF5_C_INCLUDE_DIR} DIRECTORY) -else() - cmake_path(GET HDF5_C_INCLUDE_DIR PARENT_PATH zlib_dir) -endif() -if(NOT ZLIB_ROOT) - set(ZLIB_ROOT "${HDF5_ROOT};${zlib_dir}") -endif() - - -if(hdf5_have_zlib) - - if(HDF5_FIND_REQUIRED) - find_package(ZLIB REQUIRED) - else() - find_package(ZLIB) - endif() - if(NOT ZLIB_FOUND) - return() - endif() - - if(hdf5_have_szip) - # Szip even though not used by default. - # If system HDF5 dynamically links libhdf5 with szip, our builds will fail if we don't also link szip. - # however, we don't require SZIP for this case as other HDF5 libraries may statically link SZIP. - - find_library(SZIP_LIBRARY - NAMES szip sz - NAMES_PER_DIR - HINTS ${SZIP_ROOT} ${ZLIB_ROOT} - DOC "SZIP API" - ) - - find_path(SZIP_INCLUDE_DIR - NAMES szlib.h - HINTS ${SZIP_ROOT} ${ZLIB_ROOT} - DOC "SZIP header" - ) - - if(NOT SZIP_LIBRARY AND SZIP_INCLUDE_DIR) - return() - endif() - - list(APPEND CMAKE_REQUIRED_INCLUDES ${SZIP_INCLUDE_DIR}) - list(APPEND CMAKE_REQUIRED_LIBRARIES ${SZIP_LIBRARY}) - endif() - - list(APPEND CMAKE_REQUIRED_INCLUDES ${ZLIB_INCLUDE_DIRS}) - list(APPEND CMAKE_REQUIRED_LIBRARIES ${ZLIB_LIBRARIES}) -endif() - -list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS}) - -find_package(Threads) -list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) - -if(UNIX) - list(APPEND CMAKE_REQUIRED_LIBRARIES m) -endif() - -endmacro(detect_config) - - -function(find_hdf5_fortran) -# NOTE: the "lib*" are for Windows Intel compiler, even for self-built HDF5. -# CMake won't look for lib prefix automatically. - -if(parallel IN_LIST HDF5_FIND_COMPONENTS AND NOT HDF5_parallel_FOUND) - # this avoids expensive Fortran find when MPI isn't linked properly - return() -endif() - -hdf5_fortran_wrap(hdf5_lib_dirs hdf5_inc_dirs) - -if(MSVC) - set(CMAKE_FIND_LIBRARY_PREFIXES lib) -endif() - -set(_names hdf5_fortran) -set(_hl_names hdf5_hl_fortran hdf5hl_fortran) -set(_hl_stub_names hdf5_hl_f90cstub) -set(_stub_names hdf5_f90cstub) - -# distro names (Ubuntu) -if(parallel IN_LIST HDF5_FIND_COMPONENTS) - list(APPEND _names hdf5_openmpi_fortran hdf5_mpich_fortran) - list(APPEND _hl_names hdf5_openmpihl_fortran hdf5_mpichhl_fortran) -else() - list(APPEND _names hdf5_serial_fortran) - list(APPEND _hl_names hdf5_serialhl_fortran) -endif() - -# Debug names -if(MSVC) - list(APPEND _names hdf5_fortran_D) - list(APPEND _hl_names hdf5_hl_fortran_D) - list(APPEND _hl_stub_names hdf5_hl_f90cstub_D) - list(APPEND _stub_names hdf5_f90cstub_D) -else() - list(APPEND _names hdf5_fortran_debug) - list(APPEND _hl_names hdf5_hl_fortran_debug) - list(APPEND _hl_stub_names hdf5_hl_f90cstub_debug) - list(APPEND _stub_names hdf5_f90cstub_debug) -endif() - -find_library(HDF5_Fortran_LIBRARY -NAMES ${_names} -HINTS ${HDF5_ROOT} ${hdf5_lib_dirs} -PATH_SUFFIXES ${hdf5_lsuf} -NAMES_PER_DIR -DOC "HDF5 Fortran API" -) - -find_library(HDF5_Fortran_HL_LIBRARY -NAMES ${_hl_names} -HINTS ${HDF5_ROOT} ${hdf5_lib_dirs} -PATH_SUFFIXES ${hdf5_lsuf} -NAMES_PER_DIR -DOC "HDF5 Fortran HL high-level API" -) - -# not all platforms have this stub -find_library(HDF5_Fortran_HL_stub -NAMES ${_hl_stub_names} -HINTS ${HDF5_ROOT} ${hdf5_lib_dirs} -PATH_SUFFIXES ${hdf5_lsuf} -NAMES_PER_DIR -DOC "Fortran C HL interface, not all HDF5 implementations have/need this" -) - -find_library(HDF5_Fortran_stub -NAMES ${_stub_names} -HINTS ${HDF5_ROOT} ${hdf5_lib_dirs} -PATH_SUFFIXES ${hdf5_lsuf} -NAMES_PER_DIR -DOC "Fortran C interface, not all HDF5 implementations have/need this" -) - -set(HDF5_Fortran_LIBRARIES ${HDF5_Fortran_HL_LIBRARY} ${HDF5_Fortran_LIBRARY}) -if(HDF5_Fortran_HL_stub AND HDF5_Fortran_stub) - list(APPEND HDF5_Fortran_LIBRARIES ${HDF5_Fortran_HL_stub} ${HDF5_Fortran_stub}) -endif() - -if(HDF5_ROOT) - find_path(HDF5_Fortran_INCLUDE_DIR - NAMES hdf5.mod - NO_DEFAULT_PATH - HINTS ${HDF5_C_INCLUDE_DIR} ${HDF5_ROOT} - DOC "HDF5 Fortran module path" - ) -else() - if(parallel IN_LIST HDF5_FIND_COMPONENTS) - # HDF5-MPI system library presents a unique challenge, as when non-MPI HDF5 is - # also installed, which is typically necessary for other system libraries, the - # HDF5-MPI compiler wrapper often includes that wrong non-MPI include dir first. - # The most general approach seemed to be the following: - # search in a for loop and do a link check. - if(NOT HDF5_Fortran_INCLUDE_DIR) - foreach(i IN LISTS HDF5_C_INCLUDE_DIR hdf5_inc_dirs) - find_path(HDF5_Fortran_INCLUDE_DIR - NAMES hdf5.mod - NO_DEFAULT_PATH - HINTS ${i} - DOC "HDF5 Fortran module path" - ) - message(VERBOSE "FindHDF5: trying hdf5.mod in ${i} - got: ${HDF5_Fortran_INCLUDE_DIR}") - if(HDF5_Fortran_INCLUDE_DIR) - check_fortran_links() - if(HDF5_Fortran_links) - break() - else() - unset(HDF5_Fortran_INCLUDE_DIR CACHE) - unset(HDF5_Fortran_links CACHE) - endif() - endif() - endforeach() - endif() - - if(NOT HDF5_Fortran_INCLUDE_DIR) - # last resort, might give incompatible non-MPI hdf5.mod - find_path(HDF5_Fortran_INCLUDE_DIR - NAMES hdf5.mod - HINTS ${HDF5_C_INCLUDE_DIR} ${hdf5_inc_dirs} - PATHS ${hdf5_binpref} - PATH_SUFFIXES ${hdf5_msuf} - DOC "HDF5 Fortran module path" - ) - endif() - else() - find_path(HDF5_Fortran_INCLUDE_DIR - NAMES hdf5.mod - HINTS ${HDF5_C_INCLUDE_DIR} ${hdf5_inc_dirs} - PATHS ${hdf5_binpref} - PATH_SUFFIXES ${hdf5_msuf} - DOC "HDF5 Fortran module path" - ) - endif() -endif() - -if(HDF5_Fortran_LIBRARY AND HDF5_Fortran_HL_LIBRARY AND HDF5_Fortran_INCLUDE_DIR) - set(HDF5_Fortran_LIBRARIES ${HDF5_Fortran_LIBRARIES} PARENT_SCOPE) - set(HDF5_Fortran_FOUND true PARENT_SCOPE) - set(HDF5_HL_FOUND true PARENT_SCOPE) -endif() - -endfunction(find_hdf5_fortran) - - -function(find_hdf5_cxx) - -hdf5_cxx_wrap(hdf5_lib_dirs hdf5_inc_dirs) - -if(MSVC) - set(CMAKE_FIND_LIBRARY_PREFIXES lib) -endif() - -set(_names hdf5_cpp) -set(_hl_names hdf5_hl_cpp) - -# distro names (Ubuntu) -if(parallel IN_LIST HDF5_FIND_COMPONENTS) - list(APPEND _names hdf5_openmpi_cpp hdf5_mpich_cpp) - list(APPEND _hl_names hdf5_openmpi_hl_cpp hdf5_mpich_hl_cpp) -else() - list(APPEND _names hdf5_serial_cpp) - list(APPEND _hl_names hdf5_serial_hl_cpp) -endif() - -# Debug names -if(MSVC) - list(APPEND _names hdf5_cpp_D) - list(APPEND _hl_names hdf5_hl_cpp_D) -else() - list(APPEND _names hdf5_cpp_debug) - list(APPEND _hl_names hdf5_hl_cpp_debug) -endif() - -find_library(HDF5_CXX_LIBRARY -NAMES ${_names} -HINTS ${HDF5_ROOT} ${hdf5_lib_dirs} -PATH_SUFFIXES ${hdf5_lsuf} -NAMES_PER_DIR -DOC "HDF5 C++ API" -) - -find_library(HDF5_CXX_HL_LIBRARY -NAMES ${_hl_names} -HINTS ${HDF5_ROOT} ${hdf5_lib_dirs} -PATH_SUFFIXES ${hdf5_lsuf} -NAMES_PER_DIR -DOC "HDF5 C++ high-level API" -) - -find_path(HDF5_CXX_INCLUDE_DIR -NAMES hdf5.h -HINTS ${HDF5_C_INCLUDE_DIR} ${HDF5_ROOT} ${hdf5_inc_dirs} -PATH_SUFFIXES ${hdf5_isuf} -DOC "HDF5 C header" -) - -if(HDF5_CXX_LIBRARY AND HDF5_CXX_HL_LIBRARY AND HDF5_CXX_INCLUDE_DIR) - set(HDF5_CXX_LIBRARIES ${HDF5_CXX_HL_LIBRARY} ${HDF5_CXX_LIBRARY} PARENT_SCOPE) - set(HDF5_CXX_FOUND true PARENT_SCOPE) - set(HDF5_HL_FOUND true PARENT_SCOPE) -endif() - -endfunction(find_hdf5_cxx) - - -function(find_hdf5_c) - -hdf5_c_wrap(hdf5_lib_dirs hdf5_inc_dirs) - -if(MSVC) - set(CMAKE_FIND_LIBRARY_PREFIXES lib) -endif() - -set(_names hdf5) -set(_hl_names hdf5_hl) - -# distro names (Ubuntu) -if(parallel IN_LIST HDF5_FIND_COMPONENTS) - list(APPEND _names hdf5_openmpi hdf5_mpich) - list(APPEND _hl_names hdf5_openmpi_hl hdf5_mpich_hl) -else() - list(APPEND _names hdf5_serial) - list(APPEND _hl_names hdf5_serial_hl) -endif() - -# debug names -if(MSVC) - list(APPEND _names hdf5_D) - list(APPEND _hl_names hdf5_hl_D) -else() - list(APPEND _names hdf5_debug) - list(APPEND _hl_names hdf5_hl_debug) -endif() - -# MUST have HDF5_ROOT in HINTS here since it was set in this script -find_library(HDF5_C_LIBRARY -NAMES ${_names} -HINTS ${HDF5_ROOT} ${hdf5_lib_dirs} -PATH_SUFFIXES ${hdf5_lsuf} -NAMES_PER_DIR -DOC "HDF5 C library (necessary for all languages)" -) - -find_library(HDF5_C_HL_LIBRARY -NAMES ${_hl_names} -HINTS ${HDF5_ROOT} ${hdf5_lib_dirs} -PATH_SUFFIXES ${hdf5_lsuf} -NAMES_PER_DIR -DOC "HDF5 C high level interface" -) - -find_path(HDF5_C_INCLUDE_DIR -NAMES hdf5.h -HINTS ${HDF5_ROOT} ${hdf5_inc_dirs} -PATH_SUFFIXES ${hdf5_isuf} -DOC "HDF5 C header" -) - -if(HDF5_C_HL_LIBRARY AND HDF5_C_LIBRARY AND HDF5_C_INCLUDE_DIR) - set(HDF5_C_LIBRARIES ${HDF5_C_HL_LIBRARY} ${HDF5_C_LIBRARY} PARENT_SCOPE) - set(HDF5_C_FOUND true PARENT_SCOPE) - set(HDF5_HL_FOUND true PARENT_SCOPE) -endif() - -endfunction(find_hdf5_c) - - -function(hdf5_fortran_wrap lib_var inc_var) - -set(lib_dirs) -set(inc_dirs) - -if(parallel IN_LIST HDF5_FIND_COMPONENTS) - set(wrapper_names h5pfc h5pfc.openmpi h5pfc.mpich) -else() - set(wrapper_names h5fc) -endif() - -if(HDF5_ROOT) - find_program(HDF5_Fortran_COMPILER_EXECUTABLE - NAMES ${wrapper_names} - NAMES_PER_DIR - NO_DEFAULT_PATH - HINTS ${HDF5_ROOT} - PATH_SUFFIXES ${hdf5_binsuf} - ) -else() - find_program(HDF5_Fortran_COMPILER_EXECUTABLE - NAMES ${wrapper_names} - NAMES_PER_DIR - PATHS ${hdf5_binpref} - PATH_SUFFIXES ${hdf5_binsuf} - ) -endif() - -if(NOT HDF5_Fortran_COMPILER_EXECUTABLE) - return() -endif() - -get_flags(${HDF5_Fortran_COMPILER_EXECUTABLE} f_raw) -if(f_raw) - pop_flag(${f_raw} -L lib_dirs) - pop_flag(${f_raw} -I inc_dirs) - if(NOT inc_dirs AND parallel IN_LIST HDF5_FIND_COMPONENTS) - get_flags(${MPI_Fortran_COMPILER} f_raw) - if(f_raw) - pop_flag(${f_raw} -I inc_dirs) - endif(f_raw) - endif() -endif(f_raw) - -if(inc_dirs) - set(${inc_var} ${inc_dirs} PARENT_SCOPE) -endif() - -if(lib_dirs) - set(${lib_var} ${lib_dirs} PARENT_SCOPE) -endif() - -endfunction(hdf5_fortran_wrap) - - -function(hdf5_cxx_wrap lib_var inc_var) - -set(lib_dirs) -set(inc_dirs) - -if(parallel IN_LIST HDF5_FIND_COMPONENTS) - set(wrapper_names h5c++.openmpi h5c++.mpich) -else() - set(wrapper_names h5c++) -endif() - -if(HDF5_ROOT) - find_program(HDF5_CXX_COMPILER_EXECUTABLE - NAMES ${wrapper_names} - NAMES_PER_DIR - NO_DEFAULT_PATH - HINTS ${HDF5_ROOT} - PATH_SUFFIXES ${hdf5_binsuf} - ) -else() - find_program(HDF5_CXX_COMPILER_EXECUTABLE - NAMES ${wrapper_names} - NAMES_PER_DIR - PATHS ${hdf5_binpref} - PATH_SUFFIXES ${hdf5_binsuf} - ) -endif() - -if(NOT HDF5_CXX_COMPILER_EXECUTABLE) - return() -endif() - -get_flags(${HDF5_CXX_COMPILER_EXECUTABLE} cxx_raw) -if(cxx_raw) - pop_flag(${cxx_raw} -L lib_dirs) - pop_flag(${cxx_raw} -I inc_dirs) -endif(cxx_raw) - -if(inc_dirs) - set(${inc_var} ${inc_dirs} PARENT_SCOPE) -endif() - -if(lib_dirs) - set(${lib_var} ${lib_dirs} PARENT_SCOPE) -endif() - -endfunction(hdf5_cxx_wrap) - - -function(hdf5_c_wrap lib_var inc_var) - -set(lib_dirs) -set(inc_dirs) - -if(parallel IN_LIST HDF5_FIND_COMPONENTS) - set(wrapper_names h5pcc h5pcc.openmpi h5pcc.mpich) -else() - set(wrapper_names h5cc) -endif() - -if(HDF5_ROOT) - find_program(HDF5_C_COMPILER_EXECUTABLE - NAMES ${wrapper_names} - NAMES_PER_DIR - NO_DEFAULT_PATH - HINTS ${HDF5_ROOT} - PATH_SUFFIXES ${hdf5_binsuf} - ) -else() - find_program(HDF5_C_COMPILER_EXECUTABLE - NAMES ${wrapper_names} - NAMES_PER_DIR - PATHS ${hdf5_binpref} - PATH_SUFFIXES ${hdf5_binsuf} - ) -endif() - -if(NOT HDF5_C_COMPILER_EXECUTABLE) - return() -endif() - -get_flags(${HDF5_C_COMPILER_EXECUTABLE} c_raw) -if(c_raw) - pop_flag(${c_raw} -L lib_dirs) - pop_flag(${c_raw} -I inc_dirs) - if(NOT inc_dirs AND parallel IN_LIST HDF5_FIND_COMPONENTS) - get_flags(${MPI_C_COMPILER} c_raw) - if(c_raw) - pop_flag(${c_raw} -I inc_dirs) - endif(c_raw) - endif() -endif(c_raw) - - -if(inc_dirs) - set(${inc_var} ${inc_dirs} PARENT_SCOPE) -endif() - -if(lib_dirs) - set(${lib_var} ${lib_dirs} PARENT_SCOPE) -endif() - - -endfunction(hdf5_c_wrap) - - -function(check_c_links) - -list(INSERT CMAKE_REQUIRED_LIBRARIES 0 ${HDF5_C_LIBRARIES}) -set(CMAKE_REQUIRED_INCLUDES ${HDF5_C_INCLUDE_DIR}) - -if(HDF5_parallel_FOUND) - find_mpi() - - list(APPEND CMAKE_REQUIRED_INCLUDES ${MPI_C_INCLUDE_DIRS}) - list(APPEND CMAKE_REQUIRED_LIBRARIES ${MPI_C_LIBRARIES}) - - check_symbol_exists(H5Pset_fapl_mpio hdf5.h HAVE_H5Pset_fapl_mpio) - if(NOT HAVE_H5Pset_fapl_mpio) - return() - endif() - - set(src [=[ - #include "hdf5.h" - #include "mpi.h" - - int main(void){ - MPI_Init(NULL, NULL); - - hid_t plist_id = H5Pcreate(H5P_FILE_ACCESS); - H5Pset_fapl_mpio(plist_id, MPI_COMM_WORLD, MPI_INFO_NULL); - - H5Pclose(plist_id); - - MPI_Finalize(); - - return 0; - } - ]=]) - -else() - set(src [=[ - #include "hdf5.h" - - int main(void){ - hid_t f = H5Fcreate("junk.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - herr_t status = H5Fclose (f); - return 0;} - ]=]) -endif(HDF5_parallel_FOUND) - -check_c_source_compiles("${src}" HDF5_C_links) - -endfunction(check_c_links) - - -function(check_fortran_links) - -list(INSERT CMAKE_REQUIRED_LIBRARIES 0 ${HDF5_Fortran_LIBRARIES} ${HDF5_C_LIBRARIES}) -set(CMAKE_REQUIRED_INCLUDES ${HDF5_Fortran_INCLUDE_DIR} ${HDF5_C_INCLUDE_DIR}) - -if(HDF5_parallel_FOUND) - find_mpi() - - list(APPEND CMAKE_REQUIRED_INCLUDES ${MPI_Fortran_INCLUDE_DIRS}) - list(APPEND CMAKE_REQUIRED_LIBRARIES ${MPI_Fortran_LIBRARIES}) - - set(src "program test - use hdf5 - use mpi - implicit none - integer :: ierr, mpi_id - integer(HID_T) :: fapl, xfer_id - call mpi_init(ierr) - call h5open_f(ierr) - call h5pcreate_f(H5P_FILE_ACCESS_F, fapl, ierr) - call h5pset_fapl_mpio_f(fapl, MPI_COMM_WORLD, MPI_INFO_NULL, ierr) - call h5pcreate_f(H5P_DATASET_XFER_F, xfer_id, ierr) - call h5pset_dxpl_mpio_f(xfer_id, H5FD_MPIO_COLLECTIVE_F, ierr) - call mpi_finalize(ierr) - end program") -else() - set(src "program test_minimal - use hdf5, only : h5open_f, h5close_f - use h5lt, only : h5ltmake_dataset_f - implicit none - integer :: i - call h5open_f(i) - call h5close_f(i) - end program") -endif() - -check_fortran_source_compiles(${src} HDF5_Fortran_links SRC_EXT f90) - -endfunction(check_fortran_links) - - -function(check_hdf5_link) - -if(NOT HDF5_C_FOUND) - return() -endif() - -if(parallel IN_LIST HDF5_FIND_COMPONENTS AND NOT HDF5_parallel_FOUND) - return() -endif() - -check_c_links() - -if(NOT HDF5_C_links) - return() -endif() - -if(HDF5_Fortran_FOUND) - check_fortran_links() - - if(NOT HDF5_Fortran_links) - return() - endif() -endif() - -set(HDF5_links true PARENT_SCOPE) - -endfunction(check_hdf5_link) - -# === main program - -set(CMAKE_REQUIRED_LIBRARIES) - -if(NOT HDF5MPI_ROOT AND DEFINED ENV{HDF5MPI_ROOT}) - set(HDF5MPI_ROOT $ENV{HDF5MPI_ROOT}) -endif() - -if(NOT HDF5_ROOT) - if(HDF5MPI_ROOT AND parallel IN_LIST HDF5_FIND_COMPONENTS) - set(HDF5_ROOT ${HDF5MPI_ROOT}) - elseif(DEFINED ENV{HDF5_ROOT}) - set(HDF5_ROOT $ENV{HDF5_ROOT}) - endif() -endif() - -# Conda causes numerous problems with finding HDF5, so exclude from search -if(DEFINED ENV{CONDA_PREFIX}) - set(h5_ignore_path - $ENV{CONDA_PREFIX}/bin $ENV{CONDA_PREFIX}/lib $ENV{CONDA_PREFIX}/include - $ENV{CONDA_PREFIX}/Library/bin $ENV{CONDA_PREFIX}/Library/lib $ENV{CONDA_PREFIX}/Library/include - ) - list(APPEND CMAKE_IGNORE_PATH ${h5_ignore_path}) -endif() - -# --- library suffixes - -set(hdf5_lsuf lib hdf5/lib) # need explicit "lib" for self-built HDF5 -if(NOT HDF5_ROOT) - if(parallel IN_LIST HDF5_FIND_COMPONENTS) - list(INSERT hdf5_lsuf 0 hdf5/openmpi hdf5/mpich) # Ubuntu - list(INSERT hdf5_lsuf 0 openmpi/lib mpich/lib) # CentOS - else() - list(INSERT hdf5_lsuf 0 hdf5/serial) # Ubuntu - endif() -endif() - -# --- include and modules suffixes - -if(BUILD_SHARED_LIBS) - set(hdf5_isuf shared include) - set(hdf5_msuf shared include) -else() - set(hdf5_isuf static include) - set(hdf5_msuf static include) -endif() - -if(parallel IN_LIST HDF5_FIND_COMPONENTS) - list(APPEND hdf5_isuf hdf5/openmpi hdf5/mpich) # Ubuntu - list(APPEND hdf5_msuf hdf5/openmpi hdf5/mpich) # Ubuntu -else() - list(APPEND hdf5_isuf hdf5/serial) # Ubuntu - list(APPEND hdf5_msuf hdf5/serial) # Ubuntu -endif() - -if(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64|AMD64)") - list(APPEND hdf5_isuf openmpi-x86_64 mpich-x86_64) # CentOS -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(aarch64|arm64)") - list(APPEND hdf5_isuf openmpi-aarch64 mpich-aarch64) # CentOS -endif() - -if(NOT HDF5_ROOT AND CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") - # CentOS paths - if(parallel IN_LIST HDF5_FIND_COMPONENTS) - list(INSERT hdf5_msuf 0 gfortran/modules/openmpi gfortran/modules/mpich) - else() - list(APPEND hdf5_msuf gfortran/modules) - endif() -endif() - -# --- binary prefix / suffix -set(hdf5_binpref) -if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(hdf5_binpref /usr/lib64) -endif() - -set(hdf5_binsuf bin) -if(NOT HDF5_ROOT AND parallel IN_LIST HDF5_FIND_COMPONENTS) - # CentOS paths - list(APPEND hdf5_binsuf openmpi/bin mpich/bin) -endif() - -# ---- -# May not help, as we'd have to foreach() a priori names, like we already do with find_library() -# find_package(hdf5 CONFIG) -# ---- - -# C is always needed -find_hdf5_c() - -# required libraries -if(HDF5_C_FOUND) - detect_config() -endif(HDF5_C_FOUND) - -if(HDF5_C_FOUND AND CXX IN_LIST HDF5_FIND_COMPONENTS) - find_hdf5_cxx() -endif() - -if(HDF5_C_FOUND AND Fortran IN_LIST HDF5_FIND_COMPONENTS) - find_hdf5_fortran() -endif() - -# --- configure time checks -# these checks avoid messy, confusing errors at build time -check_hdf5_link() - -set(CMAKE_REQUIRED_LIBRARIES) -set(CMAKE_REQUIRED_INCLUDES) - -# pop off ignored paths so rest of script can find Python -if(DEFINED CMAKE_IGNORE_PATH) - list(REMOVE_ITEM CMAKE_IGNORE_PATH "${h5_ignore_path}") -endif() - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(HDF5 -REQUIRED_VARS HDF5_C_LIBRARIES HDF5_links -VERSION_VAR HDF5_VERSION -HANDLE_COMPONENTS -) - -if(HDF5_FOUND) - set(HDF5_INCLUDE_DIRS ${HDF5_Fortran_INCLUDE_DIR} ${HDF5_CXX_INCLUDE_DIR} ${HDF5_C_INCLUDE_DIR}) - set(HDF5_LIBRARIES ${HDF5_Fortran_LIBRARIES} ${HDF5_CXX_LIBRARIES} ${HDF5_C_LIBRARIES}) - - if(NOT TARGET HDF5::HDF5) - add_library(HDF5::HDF5 INTERFACE IMPORTED) - set_property(TARGET HDF5::HDF5 PROPERTY INTERFACE_LINK_LIBRARIES "${HDF5_LIBRARIES}") - set_property(TARGET HDF5::HDF5 PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${HDF5_INCLUDE_DIRS}") - - target_include_directories(HDF5::HDF5 INTERFACE - $<$:${SZIP_INCLUDE_DIR}> - ) - target_link_libraries(HDF5::HDF5 INTERFACE - $<$:ZLIB::ZLIB> - $<$:${SZIP_LIBRARY}> - ${CMAKE_THREAD_LIBS_INIT} - ${CMAKE_DL_LIBS} - $<$:m> - ) - - endif() -endif(HDF5_FOUND) - -mark_as_advanced(HDF5_Fortran_LIBRARY HDF5_Fortran_HL_LIBRARY -HDF5_C_LIBRARY HDF5_C_HL_LIBRARY -HDF5_CXX_LIBRARY HDF5_CXX_HL_LIBRARY -HDF5_C_INCLUDE_DIR HDF5_CXX_INCLUDE_DIR HDF5_Fortran_INCLUDE_DIR) diff --git a/cmake/dependency.cmake b/cmake/dependency.cmake index 867cf5daf7..1dd369ba48 100644 --- a/cmake/dependency.cmake +++ b/cmake/dependency.cmake @@ -27,8 +27,6 @@ include(cmake/submodule_configs.cmake) # - PKG: the name of the package (e.g. `find_package()`) # - SUBDIR (optional): directory of submodule where to find package # source tree -# - TARGET: the target to import(/export later mayber). -# CANNOT be used with `TARGETS` # keyword arguments, multi-values: # - TARGETS: list of targets to import(/export later mayber). # CANNOT be used with `TARGET` @@ -74,7 +72,6 @@ macro(singularity_import_dependency) ) set(one_value_args PKG - TARGET SUBDIR ) set(multi_value_args @@ -84,11 +81,21 @@ macro(singularity_import_dependency) cmake_parse_arguments(dep "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN}) set(_SMSG_PREFIX "[IMPORT ${dep_PKG}]") + set(_SMSG_METHOD "undetermined") + set(_SMSG_CONTINUE TRUE) - # first, if this target is already defined, then ignore figuring out imports - if(TARGET ${dep_TARGET}) - singularity_msg(STATUS "Detected ${dep_TARGET} present, no further processing for this dependency.") - else() + # first, if targets are already defined, then ignore figuring out imports + foreach(_tar ${dep_TARGETS}) + if(TARGET ${_tar}) + singularity_msg(VERBOSE "Requested target ${_tar} present, no further processing for this dependency.") + set(_SMSG_METHOD "target(s) already present") + set(_SMSG_CONTINUE FALSE) + break() + endif() + endforeach() + + # if requested targets absent, try and find them + if(_SMSG_CONTINUE) # check for user overrides # sets `SINGULARITY_IMPORT_USER_OVERRIDE_${dep_PKG}` # if that user requests import @@ -99,42 +106,56 @@ macro(singularity_import_dependency) # if only use submodule, or user requests import of external source if(dep_SUBMODULE_ONLY OR SINGULARITY_IMPORT_USER_OVERRIDE_${dep_PKG}) + singularity_msg(VERBOSE "User override of ${dep_PKG} requested") singularity_import_submodule( PKG ${dep_PKG} SUBDIR ${dep_SUBDIR} ) + set(_SMSG_METHOD "user override") else() # the standard path of dependency importing. # check if pkg can be found in environment - singularity_msg(STATUS "Attempting \"find_package(${dep_PKG})\"") + singularity_msg(VERBOSE "Attempting find_package(${dep_PKG} COMPONENTS ${dep_COMPONENTS})") find_package(${dep_PKG} QUIET COMPONENTS ${dep_COMPONENTS}) # if we fail to find the package, try a submodule if (NOT ${dep_PKG}_FOUND) + singularity_msg(VERBOSE "\"find_package(${dep_PKG})\" did not detect ${dep_PKG}, proceeding to try \"add_subdirectory(${dep_SUBDIR})\"") # does `add_subdirectory` with ${SUBDIR} singularity_import_submodule( PKG ${dep_PKG} SUBDIR ${dep_SUBDIR} ) + set(_SMSG_METHOD "add_subdirectory") else() - singularity_msg(STATUS "Found with find_package() [${${dep_PKG}_DIR}]") + singularity_msg(VERBOSE "Found with find_package() [${${dep_PKG}_DIR}]") + set(_SMSG_METHOD "find_package") endif() # NOT FOUND endif() # SUBMODULE ONLY - endif() # TARGET + endif() # CONTINUE + + # do some robustness checks + foreach(_tar ${dep_TARGETS}) + if(NOT TARGET ${_tar}) + message(FATAL_ERROR "${dep_PKG} declared target ${_tar}, but after processing that target is not defined") + endif() + endforeach() + singularity_msg(STATUS "successfuly configured ${dep_PKG}, method used: ${_SMSG_METHOD}") # if we made it hear, there should be valid imports available. # we record these to the global scope for later use and processing # TODO: split out public/private libs list(APPEND SINGULARITY_PUBLIC_LIBS ${dep_TARGETS}) - list(APPEND SINGULARITY_PUBLIC_LIBS ${dep_TARGET}) list(APPEND SINGULARITY_DEP_PKGS ${dep_PKG}) if(dep_COMPONENTS) list(APPEND SINGULARITY_DEP_PKGS_${dep_PKG} "${dep_COMPONENTS}") endif() - if(dep_TARGET) - set(SINGULARITY_DEP_TARGET_${dep_PKG} ${dep_TARGET}) + if(dep_TARGETS) + set(SINGULARITY_DEP_TARGETS_${dep_PKG} ${dep_TARGETS}) endif() unset(_SMSG_PREFIX) + unset(_SMSG_METHOD) + unset(_SMSG_CONTINUE) endmacro() # singularity_import_dependency #------------------------------------------------------------------------------ @@ -164,9 +185,12 @@ macro(singularity_import_check_user_override) NO_DEFAULT_PATH ) if(NOT ${dep_PKG}_ROOT) + #TODO: this is actaully where fails all funnel to, so it can be + # confusing - the error is real, but it may be due to an issue + # find_package() for instance. singularity_msg(FATAL_ERROR "SINGULARITY_${dep_VARCASE}_INSTALL_DIR [${SINGULARITY_${dep_CAP}_INSTALL_DIR}] set, but did not find an installed CMake package. Use a valid install path or unset this variable.") else() - singularity_msg(STATUS "located user-provided install, ${dep_PKG}_ROOT = ${${dep_PKG}_ROOT}") + singularity_msg(VERBOSE "located user-provided install, ${dep_PKG}_ROOT = ${${dep_PKG}_ROOT}") endif() endif() if(SINGULARITY_${dep_CAP}_IMPORT_DIR) @@ -191,5 +215,5 @@ macro(singularity_import_submodule) add_subdirectory(${dep_SUBDIR} "${CMAKE_CURRENT_BINARY_DIR}/extern/${dep_PKG}") - singularity_msg(STATUS "${dep_PKG} added from: ${dep_SUBDIR}") + singularity_msg(VERBOSE "${dep_PKG} added from: ${dep_SUBDIR}") endmacro() diff --git a/cmake/install.cmake b/cmake/install.cmake index 3eb245d3b4..c99871dbe1 100644 --- a/cmake/install.cmake +++ b/cmake/install.cmake @@ -39,19 +39,19 @@ endforeach() # package install path foreach(_depName ${SINGULARITY_DEP_PKGS}) set(_components "") - set(_target "") + list(APPEND _targets "") if(SINGULARITY_DEP_PKGS_${_depName}) set(_components "COMPONENTS ${SINGULARITY_DEP_PKGS_${_depName}}") endif() - if(SINGULARITY_DEP_TARGET_${_depName}) - set(_target "${SINGULARITY_DEP_TARGET_${_depName}}") + if(SINGULARITY_DEP_TARGETS_${_depName}) + set(_targets "${SINGULARITY_DEP_TARGETS_${_depName}}") endif() set(SINGULARITY_CONFIG_DEPENDENCIES "${SINGULARITY_CONFIG_DEPENDENCIES}\nif(NOT ${_depName}_FOUND") - if(NOT "${_target}" STREQUAL "") + foreach(_tar ${_targets}) set(SINGULARITY_CONFIG_DEPENDENCIES - "${SINGULARITY_CONFIG_DEPENDENCIES} OR NOT TARGET ${_target}") - endif() + "${SINGULARITY_CONFIG_DEPENDENCIES} OR NOT TARGET ${_tar}") + endforeach() set(SINGULARITY_CONFIG_DEPENDENCIES "${SINGULARITY_CONFIG_DEPENDENCIES})\n\tfind_package(${_depName} ${_components} REQUIRED)\nendif()") endforeach() diff --git a/cmake/submodule_configs.cmake b/cmake/submodule_configs.cmake index 2bf234e638..0805440009 100644 --- a/cmake/submodule_configs.cmake +++ b/cmake/submodule_configs.cmake @@ -61,11 +61,11 @@ macro(singularity_cmake_config pkg) set(_PKG_DEFAULT_CONFIGURED ON) endif() if(_PKG_DEFAULT_CONFIGURED) - singularity_msg(STATUS "[SUBMOD_CONFIG] \"${pkg}\" does not have a defined config, using defaults.") + singularity_msg(VERBOSE "[SUBMOD_CONFIG] \"${pkg}\" does not have a defined config, using defaults.") unset(_PKG_DEFAULT_CONFIGURED) else() #TODO: optional print of options - singularity_msg(STATUS "[SUBMOD_CONFIG] \"${pkg}\" configured with defined config.") + singularity_msg(VERBOSE "[SUBMOD_CONFIG] \"${pkg}\" configured with defined config.") endif() set(BUILD_TESTING ${_storBT} CACHE BOOL "" FORCE) unset(_storBT)