diff --git a/CMakeLists.txt b/CMakeLists.txt index 1474d0ac5f..80811d4cb2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -215,8 +215,6 @@ endfunction() # Dependencies ################################################################ # -include(FetchContent) - message(STATUS "openPMD-api superbuild: ${openPMD_SUPERBUILD}") # external library: MPI (optional) @@ -255,80 +253,17 @@ endif() # external library: nlohmann-json (required) -if(TARGET nlohmann_json::nlohmann_json) - # nothing to do, target already exists in the superbuild - message(STATUS "nlohmann_json::nlohmann_json target already imported") -elseif(openPMD_USE_INTERNAL_JSON) - set(JSON_BuildTests OFF CACHE INTERNAL "NLohmann JSON option defiend internally by openPMD") - set(JSON_Install OFF CACHE INTERNAL "NLohmann JSON option defiend internally by openPMD") # only used PRIVATE - - # Git fetcher - set(openPMD_json_repo "https://github.com/nlohmann/json.git" - CACHE STRING - "Repository URI to pull and build nlohmann-json from if(openPMD_USE_INTERNAL_JSON)") - set(openPMD_json_branch "v3.11.3" - CACHE STRING - "Repository branch for openPMD_json_repo if(openPMD_USE_INTERNAL_JSON)") - - message(STATUS "Downloading nlohmann-json ...") - message(STATUS "nlohmann-json repository: ${openPMD_json_repo} (${openPMD_json_branch})") - - FetchContent_Declare(nlohmann_json - GIT_REPOSITORY ${openPMD_json_repo} - GIT_TAG ${openPMD_json_branch} - BUILD_IN_SOURCE 0 - ) - FetchContent_MakeAvailable(nlohmann_json) -else() - find_package(nlohmann_json 3.9.1 CONFIG REQUIRED) - message(STATUS "nlohmann-json: Found version '${nlohmann_json_VERSION}'") -endif() +include(${openPMD_SOURCE_DIR}/cmake/dependencies/json.cmake) add_library(openPMD::thirdparty::nlohmann_json INTERFACE IMPORTED) target_link_libraries(openPMD::thirdparty::nlohmann_json INTERFACE nlohmann_json::nlohmann_json) -# external library: toml11 -if(TARGET toml11::toml11) - # nothing to do, target already exists in the superbuild - message(STATUS "toml11::toml11 target already imported") -elseif(openPMD_USE_INTERNAL_TOML11) - set(toml11_INSTALL OFF CACHE INTERNAL "toml11 option defined internally by openPMD") - - # Git fetcher - set(openPMD_toml11_repo "https://github.com/ToruNiina/toml11.git" - CACHE STRING - "Repository URI to pull and build toml11 from if(openPMD_USE_INTERNAL_TOML11)") - set(openPMD_toml11_branch "v3.7.1" - CACHE STRING - "Repository branch for openPMD_toml11_branch if(openPMD_USE_INTERNAL_TOML11)") - - message(STATUS "Downloading toml11 ...") - message(STATUS "toml11 repository: ${openPMD_toml11_repo} (${openPMD_toml11_branch})") - - FetchContent_Declare( - toml11 - GIT_REPOSITORY ${openPMD_toml11_repo} - GIT_TAG ${openPMD_toml11_branch} - BUILD_IN_SOURCE 0 - ) - FetchContent_MakeAvailable(toml11) -else() - # toml11 4.0 was a breaking change. This is reflected in the library's CMake - # logic: version 4.0 is not accepted by a call to find_package(toml11 3.7). - # Since we support both incompatible versions, we use two find_package() - # calls. Search for version 4 first in order to prefer that - # in (the unlikely) case that both versions are installed. - find_package(toml11 4.0 CONFIG QUIET) - if(NOT toml11_FOUND) - find_package(toml11 3.7.1 CONFIG REQUIRED) - endif() - message(STATUS "toml11: Found version '${toml11_VERSION}'") -endif() +# external library: toml11 (required) +include(${openPMD_SOURCE_DIR}/cmake/dependencies/toml11.cmake) add_library(openPMD::thirdparty::toml11 INTERFACE IMPORTED) target_link_libraries(openPMD::thirdparty::toml11 INTERFACE toml11::toml11) - # external: CUDA (optional) if(openPMD_BUILD_EXAMPLES) # currently only used in examples if(openPMD_USE_CUDA_EXAMPLES STREQUAL AUTO) @@ -434,54 +369,11 @@ elseif(openPMD_USE_ADIOS2) else() set(openPMD_HAVE_ADIOS2 FALSE) endif() - # TODO: Check if ADIOS2 is parallel when openPMD_HAVE_MPI is ON # external library: pybind11 (optional) -if(openPMD_USE_PYTHON STREQUAL AUTO) - find_package(Python 3.8.0 COMPONENTS Interpreter Development.Module) -elseif(openPMD_USE_PYTHON) - find_package(Python COMPONENTS Interpreter Development.Module REQUIRED) -else() - set(openPMD_HAVE_PYTHON FALSE) -endif() -if(Python_FOUND) - if(TARGET pybind11::module) - # nothing to do, target already exists in the superbuild - message(STATUS "pybind11::module target already imported") - elseif(openPMD_USE_INTERNAL_PYBIND11) - # Git fetcher - set(openPMD_pybind11_repo "https://github.com/pybind/pybind11.git" - CACHE STRING - "Repository URI to pull and build pybind11 from if(openPMD_USE_INTERNAL_PYBIND11)") - set(openPMD_pybind11_branch "v2.12.0" - CACHE STRING - "Repository branch for openPMD_pybind11_repo if(openPMD_USE_INTERNAL_PYBIND11)") - - message(STATUS "Downloading pybind11 ...") - message(STATUS "pybind11 repository: ${openPMD_pybind11_repo} (${openPMD_pybind11_branch})") - - FetchContent_Declare( - pybind11 - GIT_REPOSITORY ${openPMD_pybind11_repo} - GIT_TAG ${openPMD_pybind11_branch} - BUILD_IN_SOURCE 0 - ) - FetchContent_MakeAvailable(pybind11) - else() - find_package(pybind11 2.12.0 CONFIG) - if(pybind11_FOUND) - set(openPMD_HAVE_PYTHON TRUE) - message(STATUS "pybind11: Found version '${pybind11_VERSION}'") - else() - set(openPMD_HAVE_PYTHON FALSE) - endif() +include(${openPMD_SOURCE_DIR}/cmake/dependencies/pybind11.cmake) - endif() - set(openPMD_HAVE_PYTHON TRUE) -else() - set(openPMD_HAVE_PYTHON FALSE) -endif() # Targets ##################################################################### # @@ -598,34 +490,7 @@ target_include_directories(openPMD PUBLIC # Catch2 for unit tests if(openPMD_BUILD_TESTING) - if(TARGET Catch2::Catch2) - # nothing to do, target already exists in the superbuild - message(STATUS "Catch2::Catch2 target already imported") - elseif(openPMD_USE_INTERNAL_CATCH) - # Git fetcher - set(openPMD_catch_repo "https://github.com/catchorg/Catch2.git" - CACHE STRING - "Repository URI to pull and build catch2 from if(openPMD_USE_INTERNAL_CATCH)") - set(openPMD_catch_branch "v2.13.10" # ToDo Migrate to v3 and latest release - CACHE STRING - "Repository branch for openPMD_catch_branch if(openPMD_USE_INTERNAL_CATCH)") - - message(STATUS "Downloading Catch2 ...") - message(STATUS "Catch2 repository: ${openPMD_catch_repo} (${openPMD_catch_branch})") - - FetchContent_Declare( - Catch2 - GIT_REPOSITORY ${openPMD_catch_repo} - GIT_TAG ${openPMD_catch_branch} - BUILD_IN_SOURCE 0 - ) - FetchContent_MakeAvailable(Catch2) - else() - find_package(Catch2 2.13.10 REQUIRED CONFIG) - target_link_libraries(openPMD::thirdparty::Catch2 - INTERFACE Catch2::Catch2) - message(STATUS "Catch2: Found version '${Catch2_VERSION}'") - endif() + include(${openPMD_SOURCE_DIR}/cmake/dependencies/catch.cmake) add_library(openPMD::thirdparty::Catch2 INTERFACE IMPORTED) target_link_libraries(openPMD::thirdparty::Catch2 INTERFACE Catch2::Catch2) diff --git a/cmake/dependencies/catch.cmake b/cmake/dependencies/catch.cmake new file mode 100644 index 0000000000..5c600ba5bc --- /dev/null +++ b/cmake/dependencies/catch.cmake @@ -0,0 +1,55 @@ +function(find_catch2) + if(TARGET Catch2::Catch2) + message(STATUS "Catch2::Catch2 target already imported") + elseif(openPMD_catch_src) + message(STATUS "Compiling local Catch2 ...") + message(STATUS "Catch2 source path: ${openPMD_catch_src}") + if(NOT IS_DIRECTORY ${openPMD_catch_src}) + message(FATAL_ERROR "Specified directory openPMD_catch_src='${openPMD_catch_src}' does not exist!") + endif() + elseif(openPMD_USE_INTERNAL_CATCH) + message(STATUS "Downloading Catch2 ...") + message(STATUS "Catch2 repository: ${openPMD_catch_repo} (${openPMD_catch_branch})") + include(FetchContent) + endif() + if(TARGET Catch2::Catch2) + # nothing to do, target already exists in the superbuild + elseif(openPMD_USE_INTERNAL_CATCH OR openPMD_catch_src) + if(openPMD_catch_src) + add_subdirectory(${openPMD_catch_src} _deps/localCatch2-build/) + else() + FetchContent_Declare(fetchedCatch2 + GIT_REPOSITORY ${openPMD_catch_repo} + GIT_TAG ${openPMD_catch_branch} + BUILD_IN_SOURCE 0 + ) + FetchContent_MakeAvailable(fetchedCatch2) + + # advanced fetch options + mark_as_advanced(FETCHCONTENT_BASE_DIR) + mark_as_advanced(FETCHCONTENT_FULLY_DISCONNECTED) + mark_as_advanced(FETCHCONTENT_QUIET) + #mark_as_advanced(FETCHCONTENT_SOURCE_DIR_FETCHEDCatch2) + mark_as_advanced(FETCHCONTENT_UPDATES_DISCONNECTED) + #mark_as_advanced(FETCHCONTENT_UPDATES_DISCONNECTED_FETCHEDCatch2) + endif() + elseif(NOT openPMD_USE_INTERNAL_CATCH) + find_package(Catch2 2.13.10 CONFIG REQUIRED) + message(STATUS "Catch2: Found version '${Catch2_VERSION}'") + endif() +endfunction() + +# local source-tree +set(openPMD_catch_src "" + CACHE PATH + "Local path to Catch2 source directory (preferred if set)") + +# Git fetcher +set(openPMD_catch_repo "https://github.com/catchorg/Catch2.git" + CACHE STRING + "Repository URI to pull and build Catch2 from if(openPMD_USE_INTERNAL_CATCH)") +set(openPMD_catch_branch "v2.13.10" + CACHE STRING + "Repository branch for openPMD_catch_repo if(openPMD_USE_INTERNAL_CATCH)") + +find_catch2() diff --git a/cmake/dependencies/json.cmake b/cmake/dependencies/json.cmake new file mode 100644 index 0000000000..2e144caadd --- /dev/null +++ b/cmake/dependencies/json.cmake @@ -0,0 +1,55 @@ +function(find_json) + if(TARGET nlohmann_json::nlohmann_json) + message(STATUS "nlohmann_json::nlohmann_json target already imported") + elseif(openPMD_json_src) + message(STATUS "Compiling local nlohmann_json ...") + message(STATUS "nlohmann_json source path: ${openPMD_json_src}") + if(NOT IS_DIRECTORY ${openPMD_json_src}) + message(FATAL_ERROR "Specified directory openPMD_json_src='${openPMD_json_src}' does not exist!") + endif() + elseif(openPMD_USE_INTERNAL_JSON) + message(STATUS "Downloading nlohmann_json ...") + message(STATUS "nlohmann_json repository: ${openPMD_json_repo} (${openPMD_json_branch})") + include(FetchContent) + endif() + if(TARGET nlohmann_json::nlohmann_json) + # nothing to do, target already exists in the superbuild + elseif(openPMD_USE_INTERNAL_JSON OR openPMD_json_src) + if(openPMD_json_src) + add_subdirectory(${openPMD_json_src} _deps/localnlohmann_json-build/) + else() + FetchContent_Declare(fetchednlohmann_json + GIT_REPOSITORY ${openPMD_json_repo} + GIT_TAG ${openPMD_json_branch} + BUILD_IN_SOURCE 0 + ) + FetchContent_MakeAvailable(fetchednlohmann_json) + + # advanced fetch options + mark_as_advanced(FETCHCONTENT_BASE_DIR) + mark_as_advanced(FETCHCONTENT_FULLY_DISCONNECTED) + mark_as_advanced(FETCHCONTENT_QUIET) + #mark_as_advanced(FETCHCONTENT_SOURCE_DIR_FETCHEDnlohmann_json) + mark_as_advanced(FETCHCONTENT_UPDATES_DISCONNECTED) + #mark_as_advanced(FETCHCONTENT_UPDATES_DISCONNECTED_FETCHEDnlohmann_json) + endif() + elseif(NOT openPMD_USE_INTERNAL_JSON) + find_package(nlohmann_json 3.9.1 CONFIG REQUIRED) + message(STATUS "nlohmann_json: Found version '${nlohmann_json_VERSION}'") + endif() +endfunction() + +# local source-tree +set(openPMD_json_src "" + CACHE PATH + "Local path to nlohmann_json source directory (preferred if set)") + +# Git fetcher +set(openPMD_json_repo "https://github.com/nlohmann/json.git" + CACHE STRING + "Repository URI to pull and build nlohmann_json from if(openPMD_USE_INTERNAL_JSON)") +set(openPMD_json_branch "v3.11.3" + CACHE STRING + "Repository branch for openPMD_json_repo if(openPMD_USE_INTERNAL_JSON)") + +find_json() diff --git a/cmake/dependencies/pybind11.cmake b/cmake/dependencies/pybind11.cmake new file mode 100644 index 0000000000..82b97f8c97 --- /dev/null +++ b/cmake/dependencies/pybind11.cmake @@ -0,0 +1,77 @@ +function(find_pybind11) + if(TARGET pybind11::module) + message(STATUS "pybind11::module target already imported") + elseif(openPMD_pybind11_src) + message(STATUS "Compiling local pybind11 ...") + message(STATUS "pybind11 source path: ${openPMD_pybind11_src}") + if(NOT IS_DIRECTORY ${openPMD_pybind11_src}) + message(FATAL_ERROR "Specified directory openPMD_pybind11_src='${openPMD_pybind11_src}' does not exist!") + endif() + elseif(openPMD_USE_INTERNAL_PYBIND11) + message(STATUS "Downloading pybind11 ...") + message(STATUS "pybind11 repository: ${openPMD_pybind11_repo} (${openPMD_pybind11_branch})") + include(FetchContent) + endif() + if(TARGET pybind11::module) + # nothing to do, target already exists in the superbuild + elseif(openPMD_USE_INTERNAL_PYBIND11 OR openPMD_pybind11_src) + if(openPMD_pybind11_src) + add_subdirectory(${openPMD_pybind11_src} _deps/localpybind11-build/) + else() + FetchContent_Declare(fetchedpybind11 + GIT_REPOSITORY ${openPMD_pybind11_repo} + GIT_TAG ${openPMD_pybind11_branch} + BUILD_IN_SOURCE 0 + ) + FetchContent_MakeAvailable(fetchedpybind11) + + # advanced fetch options + mark_as_advanced(FETCHCONTENT_BASE_DIR) + mark_as_advanced(FETCHCONTENT_FULLY_DISCONNECTED) + mark_as_advanced(FETCHCONTENT_QUIET) + mark_as_advanced(FETCHCONTENT_SOURCE_DIR_FETCHEDpybind11) + mark_as_advanced(FETCHCONTENT_UPDATES_DISCONNECTED) + mark_as_advanced(FETCHCONTENT_UPDATES_DISCONNECTED_FETCHEDpybind11) + endif() + elseif(NOT openPMD_USE_INTERNAL_PYBIND11) + if(openPMD_USE_PYTHON STREQUAL AUTO) + find_package(pybind11 2.12.0 CONFIG) + elseif(openPMD_USE_PYTHON) + find_package(pybind11 2.12.0 CONFIG REQUIRED) + endif() + if(TARGET pybind11::module) + message(STATUS "pybind11: Found version '${pybind11_VERSION}'") + endif() + endif() +endfunction() + +# local source-tree +set(openPMD_pybind11_src "" + CACHE PATH + "Local path to pybind11 source directory (preferred if set)") + +# Git fetcher +set(openPMD_pybind11_repo "https://github.com/pybind/pybind11.git" + CACHE STRING + "Repository URI to pull and build pybind11 from if(openPMD_USE_INTERNAL_PYBIND11)") +set(openPMD_pybind11_branch "v2.12.0" + CACHE STRING + "Repository branch for openPMD_pybind11_repo if(openPMD_USE_INTERNAL_PYBIND11)") + +if(openPMD_USE_PYTHON STREQUAL AUTO) + find_package(Python 3.7.0 COMPONENTS Interpreter Development.Module) +elseif(openPMD_USE_PYTHON) + find_package(Python 3.7.0 COMPONENTS Interpreter Development.Module REQUIRED) +else() + set(openPMD_HAVE_PYTHON FALSE) +endif() + +if(Python_FOUND) + find_pybind11() +endif() + +if(TARGET pybind11::module) + set(openPMD_HAVE_PYTHON TRUE) +else() + set(openPMD_HAVE_PYTHON FALSE) +endif() diff --git a/cmake/dependencies/toml11.cmake b/cmake/dependencies/toml11.cmake new file mode 100644 index 0000000000..5f5bc7a684 --- /dev/null +++ b/cmake/dependencies/toml11.cmake @@ -0,0 +1,63 @@ +function(find_toml11) + if(TARGET toml11::toml11) + message(STATUS "toml11::toml11 target already imported") + elseif(openPMD_toml11_src) + message(STATUS "Compiling local toml11 ...") + message(STATUS "toml11 source path: ${openPMD_toml11_src}") + if(NOT IS_DIRECTORY ${openPMD_toml11_src}) + message(FATAL_ERROR "Specified directory openPMD_toml11_src='${openPMD_toml11_src}' does not exist!") + endif() + elseif(openPMD_USE_INTERNAL_TOML11) + message(STATUS "Downloading toml11 ...") + message(STATUS "toml11 repository: ${openPMD_toml11_repo} (${openPMD_toml11_branch})") + include(FetchContent) + endif() + if(TARGET toml11::toml11) + # nothing to do, target already exists in the superbuild + elseif(openPMD_USE_INTERNAL_TOML11 OR openPMD_toml11_src) + if(openPMD_toml11_src) + add_subdirectory(${openPMD_toml11_src} _deps/localtoml11-build/) + else() + FetchContent_Declare(fetchedtoml11 + GIT_REPOSITORY ${openPMD_toml11_repo} + GIT_TAG ${openPMD_toml11_branch} + BUILD_IN_SOURCE 0 + ) + FetchContent_MakeAvailable(fetchedtoml11) + + # advanced fetch options + mark_as_advanced(FETCHCONTENT_BASE_DIR) + mark_as_advanced(FETCHCONTENT_FULLY_DISCONNECTED) + mark_as_advanced(FETCHCONTENT_QUIET) + #mark_as_advanced(FETCHCONTENT_SOURCE_DIR_FETCHEDtoml11) + mark_as_advanced(FETCHCONTENT_UPDATES_DISCONNECTED) + #mark_as_advanced(FETCHCONTENT_UPDATES_DISCONNECTED_FETCHEDtoml11) + endif() + elseif(NOT openPMD_USE_INTERNAL_TOML11) + # toml11 4.0 was a breaking change. This is reflected in the library's CMake + # logic: version 4.0 is not accepted by a call to find_package(toml11 3.7). + # Since we support both incompatible versions, we use two find_package() + # calls. Search for version 4 first in order to prefer that + # in (the unlikely) case that both versions are installed. + find_package(toml11 4.0 CONFIG QUIET) + if(NOT toml11_FOUND) + find_package(toml11 3.7.1 CONFIG REQUIRED) + endif() + message(STATUS "toml11: Found version '${toml11_VERSION}'") + endif() +endfunction() + +# local source-tree +set(openPMD_toml11_src "" + CACHE PATH + "Local path to toml11 source directory (preferred if set)") + +# Git fetcher +set(openPMD_toml11_repo "https://github.com/ToruNiina/toml11.git" + CACHE STRING + "Repository URI to pull and build toml11 from if(openPMD_USE_INTERNAL_TOML11)") +set(openPMD_toml11_branch "v3.7.1" + CACHE STRING + "Repository branch for openPMD_toml11_repo if(openPMD_USE_INTERNAL_TOML11)") + +find_toml11() diff --git a/docs/source/dev/buildoptions.rst b/docs/source/dev/buildoptions.rst index 530eeb01a1..21a8ed0ec6 100644 --- a/docs/source/dev/buildoptions.rst +++ b/docs/source/dev/buildoptions.rst @@ -74,6 +74,25 @@ CMake Option Values Installs Library Version ``openPMD_USE_INTERNAL_TOML11`` ON/OFF No toml11 3.7.1+ ================================= =========== ======== ============= ======== +Developers can also use a local copy of the source directories or control the exact version to download: + +============================= ============================================== =========================================================== +CMake Option Default & Values Description +============================= ============================================== =========================================================== +``openPMD_catch_src`` *None* Path to Catch2 source directory (preferred if set) +``openPMD_catch_repo`` ``https://github.com/catchorg/Catch2.git`` Repository URI to pull and build Catch2 from +``openPMD_catch_branch`` *we set and maintain a compatible commit* Repository branch for ``openPMD_catch_repo`` +``openPMD_pybind11_src`` *None* Path to pybind11 source directory (preferred if set) +``openPMD_pybind11_repo`` ``https://github.com/pybind/pybind11.git`` Repository URI to pull and build pybind11 from +``openPMD_pybind11_branch`` *we set and maintain a compatible commit* Repository branch for ``openPMD_pybind11_repo`` +``openPMD_json_src`` *None* Path to NLohmann JSON source directory (preferred if set) +``openPMD_json_repo`` ``https://github.com/nlohmann/json.git`` Repository URI to pull and build NLohmann JSON from +``openPMD_json_branch`` *we set and maintain a compatible commit* Repository branch for ``openPMD_json_repo`` +``openPMD_toml11_src`` *None* Path to TOML11 source directory (preferred if set) +``openPMD_toml11_repo`` ``https://github.com/ToruNiina/toml11.git`` Repository URI to pull and build TOML11 from +``openPMD_toml11_branch`` *we set and maintain a compatible commit* Repository branch for ``openPMD_toml11_repo`` +============================= ============================================== =========================================================== + Tests, Examples and Command Line Tools --------------------------------------