diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d44225ce41d6f3e2bcdd32886b4ab5a23e601006..68eaca4ed3a2a944e32510b744c9294bf0e4d417 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -160,6 +160,8 @@ gkfwd:integration:
parallel:
matrix:
- SUBTEST: [ forwarding ]
+ rules:
+ - when: never
script:
## run tests
@@ -297,8 +299,9 @@ coverage:baseline:
coverage:
stage: report
image: gekkofs/testing:0.9.2
- needs: [ 'coverage:baseline', 'gkfs:integration', 'gkfwd:integration',
- 'gkfs:unit' ]
+# needs: [ 'coverage:baseline', 'gkfs:integration', 'gkfwd:integration',
+# 'gkfs:unit' ]
+ needs: [ 'coverage:baseline', 'gkfs:integration', 'gkfs:unit' ]
script:
- cd ${CI_PROJECT_DIR}
- cmake
diff --git a/.gitmodules b/.gitmodules
index 71b5722a3a194ed8a774f66c8de440457ec22641..18f937ae7b811d4f78fc6fce7f89600199f28abd 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,9 +1,6 @@
[submodule "external/hermes"]
path = external/hermes
url = https://github.com/bsc-ssrg/hermes.git
-[submodule "external/fmt"]
- path = external/fmt
- url = https://github.com/fmtlib/fmt
[submodule "tests/scripts/bats"]
path = tests/scripts/bats
url = https://github.com/bats-core/bats-core.git
@@ -19,3 +16,9 @@
[submodule "external/spdlog"]
path = external/spdlog
url = https://github.com/gabime/spdlog
+[submodule "external/fmt"]
+ path = external/fmt
+ url = https://github.com/fmtlib/fmt.git
+[submodule "external/CLI11"]
+ path = external/CLI11
+ url = https://github.com/CLIUtils/CLI11.git
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c1f3aeadf8a273db4e67a9b5bec0668f0ca880ad..d1ca56e57e0c18093d5896ca0366cec55c4f8eb3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -21,6 +21,18 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
- FLOCK and fcntl functions for locks, are not supported, but they are available.
- Added support for [CMake presets](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html) to simplify build
configurations ([!163](https://storage.bsc.es/gitlab/hpc/gekkofs/-/merge_requests/163#note_8179)).
+- Several improvements to CMake scripts ([!143](https://storage.bsc.es/gitlab/hpc/gekkofs/-/merge_requests/143))):
+ - Dependency management is now handled more consistently: system
+ dependencies are found using `find_package()`, whereas source-only
+ dependencies are found using `include_from_source()`. This new function
+ integrates a dependency provided its source code is available at
+ `GKFS_DEPENDENCIES_PATH`. If it's not, it will try to
+ automatically download it from its git repository using CMake's
+ `FetchContent()`.
+ - More consistent use of targets (we are closer to 100% modern CMake).
+ - Adds the `gkfs_feature_summary()` to allow printing a summary of all
+ GekkoFS configuration options and their values. This should help users
+ when building to precisely see how a GekkoFS instance has been configured.
### Changed
diff --git a/CMake/FindAGIOS.cmake b/CMake/FindAGIOS.cmake
index 4ef139eb4781808fa792f445c3ab48a728995609..e8c8cb10087eaf35dd0aa36d629f1a909e664fb5 100644
--- a/CMake/FindAGIOS.cmake
+++ b/CMake/FindAGIOS.cmake
@@ -26,21 +26,36 @@
# SPDX-License-Identifier: GPL-3.0-or-later #
################################################################################
-find_path(AGIOS_INCLUDE_DIR
- NAMES agios.h
+find_path(
+ AGIOS_INCLUDE_DIR
+ NAMES agios.h
+ PATH_SUFFIXES include
)
-find_library(AGIOS_LIBRARY
- NAMES agios
-)
+find_library(AGIOS_LIBRARY NAMES agios)
set(AGIOS_INCLUDE_DIRS ${AGIOS_INCLUDE_DIR})
set(AGIOS_LIBRARIES ${AGIOS_LIBRARY})
+mark_as_advanced(AGIOS_LIBRARY AGIOS_INCLUDE_DIR)
+
include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(AGIOS DEFAULT_MSG AGIOS_LIBRARIES AGIOS_INCLUDE_DIRS)
+find_package_handle_standard_args(
+ AGIOS
+ FOUND_VAR AGIOS_FOUND
+ REQUIRED_VARS AGIOS_LIBRARY AGIOS_INCLUDE_DIR
+)
+
+if(AGIOS_FOUND)
+ set(AGIOS_INCLUDE_DIRS ${AGIOS_INCLUDE_DIR})
+ set(AGIOS_LIBRARIES ${AGIOS_LIBRARY})
+ if(NOT TARGET AGIOS::AGIOS)
+ add_library(AGIOS::AGIOS UNKNOWN IMPORTED)
+ set_target_properties(
+ AGIOS::AGIOS
+ PROPERTIES IMPORTED_LOCATION "${AGIOS_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${AGIOS_INCLUDE_DIR}"
+ )
+ endif()
+endif( )
-mark_as_advanced(
- AGIOS_LIBRARY
- AGIOS_INCLUDE_DIR
-)
\ No newline at end of file
diff --git a/CMake/FindLZ4.cmake b/CMake/FindAIO.cmake
similarity index 78%
rename from CMake/FindLZ4.cmake
rename to CMake/FindAIO.cmake
index a82ff81e698254274eb7531f996813cee4700bec..a1546d86f0e13e7b7346e1b11155067e1981af7a 100644
--- a/CMake/FindLZ4.cmake
+++ b/CMake/FindAIO.cmake
@@ -1,3 +1,4 @@
+
################################################################################
# Copyright 2018-2022, Barcelona Supercomputing Center (BSC), Spain #
# Copyright 2015-2022, Johannes Gutenberg Universitaet Mainz, Germany #
@@ -25,29 +26,33 @@
# #
# SPDX-License-Identifier: GPL-3.0-or-later #
################################################################################
+find_path(
+ AIO_INCLUDE_DIR
+ NAMES aio.h
+ PATH_SUFFIXES include
+)
-# - Find Lz4
-# Find the lz4 compression library and includes
-#
-# LZ4_FOUND - True if lz4 found.
-# LZ4_LIBRARIES - List of libraries when using lz4.
-# LZ4_INCLUDE_DIR - where to find lz4.h, etc.
+find_library(AIO_LIBRARY NAMES rt)
-find_path(LZ4_INCLUDE_DIR
- NAMES lz4.h
-)
+mark_as_advanced(AIO_INCLUDE_DIR AIO_LIBRARY)
-find_library(LZ4_LIBRARY
- NAMES lz4
+find_package_handle_standard_args(
+ AIO
+ FOUND_VAR AIO_FOUND
+ REQUIRED_VARS AIO_INCLUDE_DIR AIO_LIBRARY
)
-set(LZ4_LIBRARIES ${LZ4_LIBRARY} )
-set(LZ4_INCLUDE_DIRS ${LZ4_INCLUDE_DIR} )
+if(AIO_FOUND AND NOT TARGET AIO::AIO)
+ add_library(AIO::AIO UNKNOWN IMPORTED)
+ if(AIO_INCLUDE_DIR)
+ set_target_properties(
+ AIO::AIO PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${AIO_INCLUDE_DIR}"
+ )
+ endif()
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(LZ4 DEFAULT_MSG LZ4_LIBRARY LZ4_INCLUDE_DIR)
+ set_target_properties(
+ AIO::AIO PROPERTIES IMPORTED_LOCATION "${AIO_LIBRARY}"
+ IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+ )
+endif()
-mark_as_advanced(
- LZ4_LIBRARY
- LZ4_INCLUDE_DIR
-)
diff --git a/CMake/FindArgobots.cmake b/CMake/FindArgobots.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..3a7db506e021775d461429fbebf1a3a192b751d0
--- /dev/null
+++ b/CMake/FindArgobots.cmake
@@ -0,0 +1,213 @@
+################################################################################
+# Copyright 2018-2022, Barcelona Supercomputing Center (BSC), Spain #
+# Copyright 2015-2022, Johannes Gutenberg Universitaet Mainz, Germany #
+# #
+# This software was partially supported by the #
+# EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). #
+# #
+# This software was partially supported by the #
+# ADA-FS project under the SPPEXA project funded by the DFG. #
+# #
+# This file is part of GekkoFS. #
+# #
+# GekkoFS is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# GekkoFS is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with GekkoFS. If not, see . #
+# #
+# SPDX-License-Identifier: GPL-3.0-or-later #
+################################################################################
+
+#[=======================================================================[.rst:
+FindArgobots
+---------
+
+Find Argobots include dirs and libraries.
+
+Use this module by invoking find_package with the form::
+
+ find_package(Argobots
+ [version] [EXACT] # Minimum or EXACT version e.g. 0.6.2
+ [REQUIRED] # Fail with error if Argobots is not found
+ )
+
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+This module provides the following imported targets, if found:
+
+``Argobots::Argobots``
+ The Argobots library
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This will define the following variables:
+
+``Argobots_FOUND``
+ True if the system has the Argobots library.
+``Argobots_VERSION``
+ The version of the Argobots library which was found.
+``Argobots_INCLUDE_DIRS``
+ Include directories needed to use Argobots.
+``Argobots_LIBRARIES``
+ Libraries needed to link to Argobots.
+
+Cache Variables
+^^^^^^^^^^^^^^^
+
+The following cache variables may also be set:
+
+``ARGOBOTS_INCLUDE_DIR``
+ The directory containing ``abt.h``.
+``ARGOBOTS_LIBRARY``
+ The path to the Argobots library.
+
+#]=======================================================================]
+
+function(_get_pkgconfig_paths target_var)
+ set(_lib_dirs)
+ if(NOT DEFINED CMAKE_SYSTEM_NAME
+ OR (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$"
+ AND NOT CMAKE_CROSSCOMPILING)
+ )
+ if(EXISTS "/etc/debian_version") # is this a debian system ?
+ if(CMAKE_LIBRARY_ARCHITECTURE)
+ list(APPEND _lib_dirs "lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig")
+ endif()
+ else()
+ # not debian, check the FIND_LIBRARY_USE_LIB32_PATHS and FIND_LIBRARY_USE_LIB64_PATHS properties
+ get_property(uselib32 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS)
+ if(uselib32 AND CMAKE_SIZEOF_VOID_P EQUAL 4)
+ list(APPEND _lib_dirs "lib32/pkgconfig")
+ endif()
+ get_property(uselib64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
+ if(uselib64 AND CMAKE_SIZEOF_VOID_P EQUAL 8)
+ list(APPEND _lib_dirs "lib64/pkgconfig")
+ endif()
+ get_property(uselibx32 GLOBAL PROPERTY FIND_LIBRARY_USE_LIBX32_PATHS)
+ if(uselibx32 AND CMAKE_INTERNAL_PLATFORM_ABI STREQUAL "ELF X32")
+ list(APPEND _lib_dirs "libx32/pkgconfig")
+ endif()
+ endif()
+ endif()
+ if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" AND NOT CMAKE_CROSSCOMPILING)
+ list(APPEND _lib_dirs "libdata/pkgconfig")
+ endif()
+ list(APPEND _lib_dirs "lib/pkgconfig")
+ list(APPEND _lib_dirs "share/pkgconfig")
+
+ set(_extra_paths)
+ list(APPEND _extra_paths ${CMAKE_PREFIX_PATH})
+ list(APPEND _extra_paths ${CMAKE_FRAMEWORK_PATH})
+ list(APPEND _extra_paths ${CMAKE_APPBUNDLE_PATH})
+
+ # Check if directories exist and eventually append them to the
+ # pkgconfig path list
+ foreach(_prefix_dir ${_extra_paths})
+ foreach(_lib_dir ${_lib_dirs})
+ if(EXISTS "${_prefix_dir}/${_lib_dir}")
+ list(APPEND _pkgconfig_paths "${_prefix_dir}/${_lib_dir}")
+ list(REMOVE_DUPLICATES _pkgconfig_paths)
+ endif()
+ endforeach()
+ endforeach()
+
+ set("${target_var}"
+ ${_pkgconfig_paths}
+ PARENT_SCOPE
+ )
+endfunction()
+
+# prevent repeating work if the main CMakeLists.txt already called
+# find_package(PkgConfig)
+if(NOT PKG_CONFIG_FOUND)
+ find_package(PkgConfig)
+endif()
+
+if(PKG_CONFIG_FOUND)
+ pkg_check_modules(PC_ARGOBOTS QUIET argobots)
+
+ find_path(
+ ARGOBOTS_INCLUDE_DIR
+ NAMES abt.h
+ PATHS ${PC_ARGOBOTS_INCLUDE_DIRS}
+ PATH_SUFFIXES include
+ )
+
+ find_library(
+ ARGOBOTS_LIBRARY
+ NAMES abt
+ PATHS ${PC_ARGOBOTS_LIBRARY_DIRS}
+ )
+
+ set(Argobots_VERSION ${PC_ARGOBOTS_VERSION})
+else()
+ find_path(
+ ARGOBOTS_INCLUDE_DIR
+ NAMES abt.h
+ PATH_SUFFIXES include
+ )
+
+ find_library(ARGOBOTS_LIBRARY NAMES abt)
+
+ # even if pkg-config is not available, but Argobots still installs a .pc file
+ # that we can use to retrieve library information from. Try to find it at all
+ # possible pkgconfig subfolders (depending on the system).
+ _get_pkgconfig_paths(_pkgconfig_paths)
+
+ find_file(_argobots_pc_file argobots.pc PATHS "${_pkgconfig_paths}")
+
+ if(NOT _argobots_pc_file)
+ message(
+ FATAL_ERROR
+ "ERROR: Could not find 'argobots.pc' file. Unable to determine library version"
+ )
+ endif()
+
+ file(STRINGS "${_argobots_pc_file}" _argobots_pc_file_contents
+ REGEX "Version: "
+ )
+
+ if("${_argobots_pc_file_contents}" MATCHES
+ "Version: ([0-9]+\\.[0-9]+\\.[0-9])"
+ )
+ set(Argobots_VERSION ${CMAKE_MATCH_1})
+ else()
+ message(FATAL_ERROR "ERROR: Failed to determine library version")
+ endif()
+
+ unset(_pkg_config_paths)
+ unset(_argobots_pc_file_contents)
+endif()
+
+mark_as_advanced(ARGOBOTS_INCLUDE_DIR ARGOBOTS_LIBRARY)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+ Argobots
+ FOUND_VAR Argobots_FOUND
+ REQUIRED_VARS ARGOBOTS_LIBRARY ARGOBOTS_INCLUDE_DIR
+ VERSION_VAR Argobots_VERSION
+)
+
+if(Argobots_FOUND)
+ set(Argobots_INCLUDE_DIRS ${ARGOBOTS_INCLUDE_DIR})
+ set(Argobots_LIBRARIES ${ARGOBOTS_LIBRARY})
+ if(NOT TARGET Argobots::Argobots)
+ add_library(Argobots::Argobots UNKNOWN IMPORTED)
+ set_target_properties(
+ Argobots::Argobots
+ PROPERTIES IMPORTED_LOCATION "${ARGOBOTS_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${ARGOBOTS_INCLUDE_DIR}"
+ )
+ endif()
+endif()
diff --git a/CMake/FindMargo.cmake b/CMake/FindMargo.cmake
index ec3f3193c41de41c9656906dcd0d2e2d8b07ff8a..b79b7affa372d28efbd0c7d1a6b93dab6ef309b9 100644
--- a/CMake/FindMargo.cmake
+++ b/CMake/FindMargo.cmake
@@ -26,41 +26,184 @@
# SPDX-License-Identifier: GPL-3.0-or-later #
################################################################################
-# Try to find Margo headers and library.
-#
-# Usage of this module as follows:
-#
-# find_package(Margo)
-#
-# Variables used by this module, they can change the default behaviour and need
-# to be set before calling find_package:
-#
-# MARGO_ROOT_DIR Set this variable to the root installation of
-# Margo if the module has problems finding the
-# proper installation path.
-#
-# Variables defined by this module:
-#
-# MARGO_FOUND System has Margo library/headers.
-# MARGO_LIBRARIES The Margo library.
-# MARGO_INCLUDE_DIRS The location of Margo headers.
-
-
-find_path(MARGO_INCLUDE_DIR
+#[=======================================================================[.rst:
+FindMargo
+---------
+
+Find Margo include dirs and libraries.
+
+Use this module by invoking find_package with the form::
+
+ find_package(Margo
+ [version] [EXACT] # Minimum or EXACT version e.g. 0.6.2
+ [REQUIRED] # Fail with error if Margo is not found
+ )
+
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+This module provides the following imported targets, if found:
+
+``Margo::Margo``
+ The Margo library
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This will define the following variables:
+
+``Margo_FOUND``
+ True if the system has the Margo library.
+``Margo_VERSION``
+ The version of the Margo library which was found.
+``Margo_INCLUDE_DIRS``
+ Include directories needed to use Margo.
+``Margo_LIBRARIES``
+ Libraries needed to link to Margo.
+
+Cache Variables
+^^^^^^^^^^^^^^^
+
+The following cache variables may also be set:
+
+``MARGO_INCLUDE_DIR``
+ The directory containing ``margo.h``.
+``MARGO_LIBRARY``
+ The path to the Margo library.
+
+#]=======================================================================]
+
+function(_get_pkgconfig_paths target_var)
+ set(_lib_dirs)
+ if(NOT DEFINED CMAKE_SYSTEM_NAME
+ OR (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$"
+ AND NOT CMAKE_CROSSCOMPILING)
+ )
+ if(EXISTS "/etc/debian_version") # is this a debian system ?
+ if(CMAKE_LIBRARY_ARCHITECTURE)
+ list(APPEND _lib_dirs "lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig")
+ endif()
+ else()
+ # not debian, check the FIND_LIBRARY_USE_LIB32_PATHS and FIND_LIBRARY_USE_LIB64_PATHS properties
+ get_property(uselib32 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS)
+ if(uselib32 AND CMAKE_SIZEOF_VOID_P EQUAL 4)
+ list(APPEND _lib_dirs "lib32/pkgconfig")
+ endif()
+ get_property(uselib64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
+ if(uselib64 AND CMAKE_SIZEOF_VOID_P EQUAL 8)
+ list(APPEND _lib_dirs "lib64/pkgconfig")
+ endif()
+ get_property(uselibx32 GLOBAL PROPERTY FIND_LIBRARY_USE_LIBX32_PATHS)
+ if(uselibx32 AND CMAKE_INTERNAL_PLATFORM_ABI STREQUAL "ELF X32")
+ list(APPEND _lib_dirs "libx32/pkgconfig")
+ endif()
+ endif()
+ endif()
+ if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" AND NOT CMAKE_CROSSCOMPILING)
+ list(APPEND _lib_dirs "libdata/pkgconfig")
+ endif()
+ list(APPEND _lib_dirs "lib/pkgconfig")
+ list(APPEND _lib_dirs "share/pkgconfig")
+
+ set(_extra_paths)
+ list(APPEND _extra_paths ${CMAKE_PREFIX_PATH})
+ list(APPEND _extra_paths ${CMAKE_FRAMEWORK_PATH})
+ list(APPEND _extra_paths ${CMAKE_APPBUNDLE_PATH})
+
+ # Check if directories exist and eventually append them to the
+ # pkgconfig path list
+ foreach(_prefix_dir ${_extra_paths})
+ foreach(_lib_dir ${_lib_dirs})
+ if(EXISTS "${_prefix_dir}/${_lib_dir}")
+ list(APPEND _pkgconfig_paths "${_prefix_dir}/${_lib_dir}")
+ list(REMOVE_DUPLICATES _pkgconfig_paths)
+ endif()
+ endforeach()
+ endforeach()
+
+ set("${target_var}"
+ ${_pkgconfig_paths}
+ PARENT_SCOPE
+ )
+endfunction()
+
+# prevent repeating work if the main CMakeLists.txt already called
+# find_package(PkgConfig)
+if(NOT PKG_CONFIG_FOUND)
+ find_package(PkgConfig)
+endif()
+
+if(PKG_CONFIG_FOUND)
+ pkg_check_modules(PC_MARGO QUIET margo)
+
+ find_path(
+ MARGO_INCLUDE_DIR
NAMES margo.h
-)
+ PATHS ${PC_MARGO_INCLUDE_DIRS}
+ PATH_SUFFIXES include
+ )
-find_library(MARGO_LIBRARY
+ find_library(
+ MARGO_LIBRARY
NAMES margo
-)
+ PATHS ${PC_MARGO_LIBRARY_DIRS}
+ )
+
+ set(Margo_VERSION ${PC_MARGO_VERSION})
+else()
+ find_path(
+ MARGO_INCLUDE_DIR
+ NAMES margo.h
+ PATH_SUFFIXES include
+ )
-set(MARGO_INCLUDE_DIRS ${MARGO_INCLUDE_DIR})
-set(MARGO_LIBRARIES ${MARGO_LIBRARY})
+ find_library(MARGO_LIBRARY NAMES margo)
+
+ # even if pkg-config is not available, but Margo still installs a .pc file
+ # that we can use to retrieve library information from. Try to find it at all
+ # possible pkgconfig subfolders (depending on the system).
+ _get_pkgconfig_paths(_pkgconfig_paths)
+
+ find_file(_margo_pc_file margo.pc PATHS "${_pkgconfig_paths}")
+
+ if(NOT _margo_pc_file)
+ message(
+ FATAL_ERROR
+ "ERROR: Could not find 'margo.pc' file. Unable to determine library version"
+ )
+ endif()
+
+ file(STRINGS "${_margo_pc_file}" _margo_pc_file_contents REGEX "Version: ")
+
+ if("${_margo_pc_file_contents}" MATCHES "Version: ([0-9]+\\.[0-9]+\\.[0-9])")
+ set(Margo_VERSION ${CMAKE_MATCH_1})
+ else()
+ message(FATAL_ERROR "ERROR: Failed to determine library version")
+ endif()
+
+ unset(_pkg_config_paths)
+ unset(_margo_pc_file_contents)
+endif()
+
+mark_as_advanced(MARGO_INCLUDE_DIR MARGO_LIBRARY)
include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(Margo DEFAULT_MSG MARGO_LIBRARY MARGO_INCLUDE_DIR)
+find_package_handle_standard_args(
+ Margo
+ FOUND_VAR Margo_FOUND
+ REQUIRED_VARS MARGO_LIBRARY MARGO_INCLUDE_DIR
+ VERSION_VAR Margo_VERSION
+)
-mark_as_advanced(
- MARGO_LIBRARY
- MARGO_INCLUDE_DIR
-)
\ No newline at end of file
+if(Margo_FOUND)
+ set(Margo_INCLUDE_DIRS ${MARGO_INCLUDE_DIR})
+ set(Margo_LIBRARIES ${MARGO_LIBRARY})
+ if(NOT TARGET Margo::Margo)
+ add_library(Margo::Margo UNKNOWN IMPORTED)
+ set_target_properties(
+ Margo::Margo
+ PROPERTIES IMPORTED_LOCATION "${MARGO_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${MARGO_INCLUDE_DIR}"
+ )
+ endif()
+endif()
diff --git a/CMake/FindMercury.cmake b/CMake/FindMercury.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..fd83231c1095dda367a3220de15324c1b7bcff54
--- /dev/null
+++ b/CMake/FindMercury.cmake
@@ -0,0 +1,280 @@
+################################################################################
+# Copyright 2018-2022, Barcelona Supercomputing Center (BSC), Spain #
+# Copyright 2015-2022, Johannes Gutenberg Universitaet Mainz, Germany #
+# #
+# This software was partially supported by the #
+# EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). #
+# #
+# This software was partially supported by the #
+# ADA-FS project under the SPPEXA project funded by the DFG. #
+# #
+# This file is part of GekkoFS. #
+# #
+# GekkoFS is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# GekkoFS is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with GekkoFS. If not, see . #
+# #
+# SPDX-License-Identifier: GPL-3.0-or-later #
+################################################################################
+
+#[=======================================================================[.rst:
+FindMercury
+---------
+
+Find Mercury include dirs and libraries.
+
+Use this module by invoking find_package with the form::
+
+ find_package(Mercury
+ [version] [EXACT] # Minimum or EXACT version e.g. 0.6.2
+ [REQUIRED] # Fail with error if Mercury is not found
+ )
+
+Some variables one may set to control this module are::
+
+ Mercury_DEBUG - Set to ON to enable debug output from FindMercury.
+
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+This module provides the following imported targets, if found:
+
+``Mercury::Mercury``
+ The Mercury library
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This will define the following variables:
+
+``Mercury_FOUND``
+ True if the system has the Mercury library.
+``Mercury_VERSION``
+ The version of the Mercury library which was found.
+``Mercury_INCLUDE_DIRS``
+ Include directories needed to use Mercury.
+``Mercury_LIBRARIES``
+ Libraries needed to link to Mercury.
+
+Cache Variables
+^^^^^^^^^^^^^^^
+
+The following cache variables may also be set:
+
+``MERCURY_INCLUDE_DIR``
+ The directory containing ``mercury.h``.
+``MERCURY_LIBRARY``
+ The path to the Mercury library.
+
+#]=======================================================================]
+
+#
+# Print debug text if Mercury_DEBUG is set.
+# Call example:
+# _mercury_DEBUG_PRINT("debug message")
+#
+function(_mercury_DEBUG_PRINT text)
+ if(Mercury_DEBUG)
+ message(
+ STATUS
+ "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_FUNCTION_LIST_LINE} ] ${text}"
+ )
+ endif()
+endfunction()
+
+macro(_mercury_find_component _component_name)
+
+ _mercury_debug_print("Searching for Mercury component: ${_component}")
+
+ string(TOUPPER ${_component} _upper_component)
+
+ # find component header
+ find_path(
+ ${_upper_component}_INCLUDE_DIR ${_component}
+ NAMES ${_component}.h
+ PATH_SUFFIXES include
+ PATHS ${PC_MERCURY_INCLUDE_DIRS}
+ )
+
+ # find component library (release version)
+ find_library(
+ ${_upper_component}_LIBRARY_RELEASE
+ NAMES ${_component}
+ PATHS ${PC_MERCURY_LIBRARY_DIRS}
+ )
+
+ # find component library (debug version)
+ find_library(
+ ${_upper_component}_LIBRARY_DEBUG
+ NAMES ${_component}_debug
+ PATHS ${PC_MERCURY_LIBRARY_DIRS}
+ )
+
+ # initialize ${_upper_component}_LIBRARY (e.g. NA_LIBRARY)
+ # with the appropriate library for this build configuration
+ select_library_configurations(${_upper_component})
+
+ _mercury_debug_print(
+ "${_upper_component}_INCLUDE_DIR: ${${_upper_component}_INCLUDE_DIR}"
+ )
+ _mercury_debug_print(
+ "${_upper_component}_LIBRARY: ${${_upper_component}_LIBRARY}"
+ )
+
+ # define an imported target for the component
+ if (NOT TARGET Mercury::${_component})
+ add_library(Mercury::${_component} UNKNOWN IMPORTED)
+ endif ()
+
+ if(${_upper_component}_LIBRARY_RELEASE)
+ set_property(TARGET Mercury::${_component} APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS RELEASE)
+ set_target_properties(Mercury::${_component} PROPERTIES
+ IMPORTED_LOCATION_RELEASE "${${_upper_component}_LIBRARY_RELEASE}"
+ )
+ endif()
+
+ if(${_upper_component}_LIBRARY_DEBUG)
+ set_property(TARGET Mercury::${_component} APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS DEBUG)
+ set_target_properties(Mercury::${_component} PROPERTIES
+ IMPORTED_LOCATION_DEBUG "${${_upper_component}_LIBRARY_DEBUG}"
+ IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C"
+ )
+ endif()
+
+ set_target_properties(
+ Mercury::${_component}
+ PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${MERCURY_INCLUDE_DIR}"
+ )
+
+ get_target_property(_configs Mercury::${_component} IMPORTED_CONFIGURATIONS)
+ foreach(_config ${_configs})
+ _mercury_DEBUG_PRINT("---> ${_config}")
+
+ endforeach()
+
+ set_property(TARGET Mercury::${_component} APPEND PROPERTY
+ INTERFACE_LINK_LIBRARIES )
+
+
+ mark_as_advanced(${_upper_component}_INCLUDE_DIR ${_upper_component}_LIBRARY)
+
+endmacro()
+
+###############################################################################
+# Find Mercury headers and library
+###############################################################################
+
+include(SelectLibraryConfigurations)
+
+set(_mercury_components na mchecksum mercury_util mercury_hl)
+
+# prevent repeating work if the main CMakeLists.txt already called
+# find_package(PkgConfig)
+if(NOT PKG_CONFIG_FOUND)
+ find_package(PkgConfig REQUIRED)
+endif()
+
+if(PKG_CONFIG_FOUND)
+ pkg_check_modules(PC_MERCURY QUIET mercury)
+
+ # find mercury header
+ find_path(
+ MERCURY_INCLUDE_DIR
+ NAMES mercury.h
+ PATHS ${PC_MERCURY_INCLUDE_DIRS}
+ PATH_SUFFIXES include
+ )
+ # find mercury library (release version)
+ find_library(
+ MERCURY_LIBRARY_RELEASE
+ NAMES mercury
+ PATHS ${PC_MERCURY_LIBRARY_DIRS}
+ )
+
+ # find mercury library (debug version)
+ find_library(
+ MERCURY_LIBRARY_DEBUG
+ NAMES mercury_debug
+ PATHS ${PC_MERCURY_LIBRARY_DIRS}
+ )
+
+ # initialize MERCURY_LIBRARY with the appropriate library for this build
+ # configuration
+ select_library_configurations(MERCURY)
+
+ # Mercury_VERSION needs to be set to the appropriate value for the call
+ # to find_package_handle_standard_args() below to work as expected
+ set(Mercury_VERSION ${PC_MERCURY_VERSION})
+endif()
+
+mark_as_advanced(MERCURY_INCLUDE_DIR MERCURY_LIBRARY)
+
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+ Mercury
+ FOUND_VAR Mercury_FOUND
+ REQUIRED_VARS MERCURY_LIBRARY MERCURY_INCLUDE_DIR
+ VERSION_VAR Mercury_VERSION
+)
+
+if(Mercury_FOUND)
+ set(Mercury_INCLUDE_DIRS ${MERCURY_INCLUDE_DIR})
+ set(Mercury_LIBRARIES ${MERCURY_LIBRARY})
+
+ if(NOT TARGET Mercury::Mercury)
+ add_library(Mercury::Mercury UNKNOWN IMPORTED)
+ endif()
+
+ if(MERCURY_LIBRARY_RELEASE)
+ set_property(
+ TARGET Mercury::Mercury
+ APPEND
+ PROPERTY IMPORTED_CONFIGURATIONS RELEASE
+ )
+ set_target_properties(
+ Mercury::Mercury PROPERTIES IMPORTED_LOCATION_RELEASE
+ "${MERCURY_LIBRARY_RELEASE}"
+ )
+ endif()
+
+ if(MERCURY_LIBRARY_DEBUG)
+ set_property(
+ TARGET Mercury::Mercury
+ APPEND
+ PROPERTY IMPORTED_CONFIGURATIONS DEBUG
+ )
+ set_target_properties(
+ Mercury::Mercury PROPERTIES IMPORTED_LOCATION_DEBUG
+ "${MERCURY_LIBRARY_DEBUG}"
+ )
+ endif()
+
+ set_target_properties(
+ Mercury::Mercury
+ PROPERTIES INTERFACE_COMPILE_OPTIONS "${PC_MERCURY_CFLAGS_OTHER}"
+ INTERFACE_INCLUDE_DIRECTORIES "${MERCURY_INCLUDE_DIR}"
+
+ )
+
+ ###############################################################################
+ # Find headers and libraries for additional Mercury components
+ ###############################################################################
+ foreach(_component ${_mercury_components})
+ _mercury_find_component(${_component})
+
+ set_target_properties(Mercury::Mercury PROPERTIES
+ INTERFACE_LINK_LIBRARIES Mercury::${_component})
+ endforeach()
+endif()
diff --git a/CMake/FindParallax.cmake b/CMake/FindParallax.cmake
index 562ad6b9ce2f9c8e5f9a8469094cb32dc312c7a3..e2b85c646dc1564b9405c0344c5536e42b7afb2e 100644
--- a/CMake/FindParallax.cmake
+++ b/CMake/FindParallax.cmake
@@ -25,27 +25,59 @@
# #
# SPDX-License-Identifier: GPL-3.0-or-later #
################################################################################
-find_path(PARALLAX_INCLUDE_DIR
- NAMES parallax.h
- )
-find_library(PARALLAX_LIBRARY
- NAMES parallax
- )
+list(APPEND _parallax_components "log")
-find_library(PARALLAX_LOG_LIBRARY
- NAMES log
- )
+find_path(
+ PARALLAX_INCLUDE_DIR
+ NAMES parallax.h
+ PATH_SUFFIXES include
+)
-set(PARALLAX_INCLUDE_DIRS ${PARALLAX_INCLUDE_DIR})
-set(PARALLAX_LIBRARIES ${PARALLAX_LIBRARY})
-set(PARALLAX_LIBRARIES ${PARALLAX_LOG_LIBRARY})
+find_library(PARALLAX_LIBRARY NAMES parallax)
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(Parallax DEFAULT_MSG PARALLAX_LIBRARY PARALLAX_LOG_LIBRARY PARALLAX_INCLUDE_DIR)
+find_library(PARALLAX_LOG_LIBRARY NAMES log)
-mark_as_advanced(
- PARALLAX_LIBRARY
- PARALLAX_INCLUDE_DIR
- PARALLAX_LOG_LIBRARY
+mark_as_advanced(PARALLAX_LIBRARY PARALLAX_INCLUDE_DIR PARALLAX_LOG_LIBRARY)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+ Parallax
+ FOUND_VAR Parallax_FOUND
+ REQUIRED_VARS PARALLAX_LIBRARY PARALLAX_LOG_LIBRARY PARALLAX_INCLUDE_DIR
)
+
+if(Parallax_FOUND)
+ set(Parallax_INCLUDE_DIRS ${PARALLAX_INCLUDE_DIR})
+ set(Parallax_LIBRARIES ${PARALLAX_LIBRARY} ${PARALLAX_LOG_LIBRARY})
+
+ if(NOT TARGET Parallax::parallax)
+ add_library(Parallax::parallax UNKNOWN IMPORTED)
+ endif()
+
+ set_target_properties(
+ Parallax::parallax
+ PROPERTIES IMPORTED_LOCATION "${PARALLAX_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${PARALLAX_INCLUDE_DIR}"
+ IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
+ )
+
+ foreach(_component ${_parallax_components})
+ if(NOT TARGET Parallax::${_component})
+ add_library(Parallax::${_component} UNKNOWN IMPORTED)
+
+ if(Parallax_INCLUDE_DIRS)
+ set_target_properties(
+ Parallax::${_component} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
+ "${PARALLAX_INCLUDE_DIR}"
+ )
+
+ set_target_properties(
+ Parallax::${_component}
+ PROPERTIES IMPORTED_LOCATION "${PARALLAX_LOG_LIBRARY}"
+ IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
+ )
+ endif()
+ endif()
+ endforeach()
+endif()
diff --git a/CMake/gkfs-options.cmake b/CMake/gkfs-options.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..598de903ca9a82d9dd4496a2bd96a704792fe2ad
--- /dev/null
+++ b/CMake/gkfs-options.cmake
@@ -0,0 +1,373 @@
+################################################################################
+# Copyright 2018-2022, Barcelona Supercomputing Center (BSC), Spain #
+# Copyright 2015-2022, Johannes Gutenberg Universitaet Mainz, Germany #
+# #
+# This software was partially supported by the #
+# EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). #
+# #
+# This software was partially supported by the #
+# ADA-FS project under the SPPEXA project funded by the DFG. #
+# #
+# This file is part of GekkoFS. #
+# #
+# GekkoFS is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# GekkoFS is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with GekkoFS. If not, see . #
+# #
+# SPDX-License-Identifier: GPL-3.0-or-later #
+################################################################################
+
+function(_get_feature_summary _output _property)
+
+ set(_currentFeatureText "")
+ get_property(_features GLOBAL PROPERTY ${_property})
+
+ if(_features)
+ list(REMOVE_DUPLICATES _features)
+ endif()
+
+ foreach(_f ${_features})
+ string(APPEND _currentFeatureText "\n-- * ${_f}")
+ get_property(_info GLOBAL PROPERTY _CMAKE_${_f}_DESCRIPTION)
+ if(_info)
+ string(APPEND _currentFeatureText ": ${_info}")
+ else()
+ get_property(_info GLOBAL PROPERTY _CMAKE_${_f}_HELP_TEXT)
+ string(APPEND _currentFeatureText ": ${_info}")
+ endif()
+ get_property(_info GLOBAL PROPERTY _CMAKE_${_f}_DEPENDS)
+ if(_info)
+ string(APPEND _currentFeatureText " [${${_info}}]")
+ endif()
+ get_property(_info GLOBAL PROPERTY _CMAKE_${_f}_EXTRA_INFO)
+ if(_info)
+ string(APPEND _currentFeatureText "\n-- ${_info}")
+ endif()
+
+ endforeach()
+
+ set(${_output}
+ "${_currentFeatureText}"
+ PARENT_SCOPE
+ )
+
+endfunction()
+
+function(_add_feature_info _name _depends _help)
+ set(_enabled 1)
+ foreach(_d ${_depends})
+ string(REGEX REPLACE " +" ";" _d "${_d}")
+ if(${_d})
+
+ else()
+ set(_enabled 0)
+ break()
+ endif()
+ endforeach()
+ if(${_enabled})
+ set_property(GLOBAL APPEND PROPERTY GKFS_ENABLED_FEATURES "${_name}")
+ else()
+ set_property(GLOBAL APPEND PROPERTY GKFS_DISABLED_FEATURES "${_name}")
+ endif()
+
+ set_property(GLOBAL PROPERTY _CMAKE_${_name}_DEPENDS ${_depends})
+ set_property(GLOBAL PROPERTY _CMAKE_${_name}_HELP_TEXT "${_help}")
+
+ if(ARGC GREATER_EQUAL 4)
+ set_property(GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION "${ARGV3}")
+ if(ARGC EQUAL 5)
+ set_property(GLOBAL PROPERTY _CMAKE_${_name}_EXTRA_INFO "${ARGV4}")
+ endif()
+ endif()
+endfunction()
+
+function(gkfs_feature_summary)
+
+ set(OPTIONS)
+ set(SINGLE_VALUE DESCRIPTION)
+ set(MULTI_VALUE)
+
+ cmake_parse_arguments(
+ ARGS "${OPTIONS}" "${SINGLE_VALUE}" "${MULTI_VALUE}" ${ARGN}
+ )
+
+ if(ARGS_UNPARSED_ARGUMENTS)
+ message(
+ FATAL_ERROR
+ "Unknown keywords given to gkfs_feature_summary(): \"${ARGS_UNPARSED_ARGUMENTS}\""
+ )
+ endif()
+
+ if(NOT ARGS_DESCRIPTION)
+ message(
+ FATAL_ERROR
+ "Missing mandatory keyword DESCRIPTION for gkfs_feature_summary()"
+ )
+ endif()
+
+ list(APPEND _what GKFS_ENABLED_FEATURES GKFS_DISABLED_FEATURES)
+
+ set(_text "\n-- ")
+ string(APPEND _text "\n-- ====================================")
+ string(APPEND _text "\n-- ${ARGS_DESCRIPTION}")
+ string(APPEND _text "\n-- ====================================")
+ foreach(_w ${_what})
+ set(_tmp)
+ _get_feature_summary(_tmp ${_w})
+
+ if(_tmp)
+ if(_text)
+ string(APPEND _text "\n-- ${_tmp}")
+ endif()
+ endif()
+ endforeach()
+
+ string(APPEND _text "\n-- ")
+
+ message(STATUS "${_text}")
+endfunction()
+
+function(gkfs_define_option varName)
+
+ set(OPTIONS)
+ set(SINGLE_VALUE HELP_TEXT DEFAULT_VALUE FEATURE_NAME DESCRIPTION EXTRA_INFO)
+ set(MULTI_VALUE)
+
+ cmake_parse_arguments(
+ ARGS "${OPTIONS}" "${SINGLE_VALUE}" "${MULTI_VALUE}" ${ARGN}
+ )
+
+ if(ARGS_UNPARSED_ARGUMENTS)
+ message(
+ FATAL_ERROR
+ "Unknown keywords given to gkfs_define_option(): \"${ARGS_UNPARSED_ARGUMENTS}\""
+ )
+ endif()
+
+ if(NOT ARGS_HELP_TEXT)
+ message(
+ FATAL_ERROR "Missing mandatory keyword HELP_TEXT for gkfs_define_option()"
+ )
+ endif()
+
+ if(NOT ARGS_FEATURE_NAME)
+ set(ARGS_FEATURE_NAME ${varName})
+ endif()
+
+ _add_feature_info(
+ ${ARGS_FEATURE_NAME} ${varName} ${ARGS_HELP_TEXT} ${ARGS_DESCRIPTION}
+ ${ARGS_EXTRA_INFO}
+ )
+
+ option(${varName} ${ARGS_HELP_TEXT} ${ARGS_DEFAULT_VALUE})
+
+endfunction()
+
+function(gkfs_define_variable varName value type docstring)
+
+ set(OPTIONS ADVANCED)
+ set(SINGLE_VALUE)
+ set(MULTI_VALUE)
+
+ cmake_parse_arguments(
+ ARGS "${OPTIONS}" "${SINGLE_VALUE}" "${MULTI_VALUE}" ${ARGN}
+ )
+
+ if(ARGS_UNPARSED_ARGUMENTS)
+ message(
+ FATAL_ERROR
+ "Unknown keywords given to gkfs_define_variable(): \"${ARGS_UNPARSED_ARGUMENTS}\""
+ )
+ endif()
+
+ set(${varName} ${value} CACHE ${type} ${docstring})
+ _add_feature_info(${varName} ${varName} ${docstring})
+
+ if(ARGS_ADVANCED)
+ mark_as_advanced(varName)
+ endif()
+
+endfunction()
+
+
+################################################################################
+# Variables and options controlling the build process
+################################################################################
+
+# build documentation
+gkfs_define_option(
+ GKFS_BUILD_DOCUMENTATION
+ HELP_TEXT "Build documentation"
+ DEFAULT_VALUE OFF
+ DESCRIPTION "Generate documentation based on Sphinx+Doxygen"
+ FEATURE_NAME "DOCS"
+)
+
+# build tests
+gkfs_define_option(
+ GKFS_ENABLE_UNUSED_FUNCTIONS
+ HELP_TEXT "Enable unused functions compilation"
+ DEFAULT_VALUE OFF
+)
+
+
+# build tests
+gkfs_define_option(
+ GKFS_BUILD_TESTS
+ HELP_TEXT "Build ${PROJECT_NAME} self tests"
+ DEFAULT_VALUE OFF
+)
+
+cmake_dependent_option(GKFS_INSTALL_TESTS "Install GekkoFS self tests" OFF "GKFS_BUILD_TESTS" OFF)
+
+
+################################################################################
+# Variables and options controlling POSIX semantics
+################################################################################
+
+## check before create
+# FIXME: should be prefixed with GKFS_
+gkfs_define_option(
+ CREATE_CHECK_PARENTS
+ HELP_TEXT "Enable checking parent directory for existence before creating children"
+ DEFAULT_VALUE ON
+ DESCRIPTION "Verify that a parent directory exists before creating new files or directories"
+)
+
+## symbolic link support
+# FIXME: should be prefixed with GKFS_
+gkfs_define_option(
+ GKFS_SYMLINK_SUPPORT
+ HELP_TEXT "Enable support for symlinks"
+ DEFAULT_VALUE ON
+ DESCRIPTION "Enable support for symbolic links in paths"
+)
+
+## rename support
+gkfs_define_option(
+ GKFS_RENAME_SUPPORT
+ HELP_TEXT "Enable support for rename"
+ DEFAULT_VALUE OFF
+ DESCRIPTION "Compile with support for rename ops (experimental)"
+)
+
+
+################################################################################
+# Options and variables that control how GekkoFS behaves internally
+################################################################################
+
+## Maximum number of internal file descriptors reserved for GekkoFS
+# FIXME: should be prefixed with GKFS_
+gkfs_define_variable(MAX_INTERNAL_FDS 256
+ STRING "Number of file descriptors reserved for internal use" ADVANCED
+)
+
+## Maximum number of open file descriptors for GekkoFS
+# FIXME: should be prefixed with GKFS_
+execute_process(COMMAND getconf OPEN_MAX
+ OUTPUT_VARIABLE _GETCONF_MAX_FDS
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET)
+if (NOT _GETCONF_MAX_FDS)
+ set(_GETCONF_MAX_FDS=512)
+endif ()
+
+gkfs_define_variable(
+ MAX_OPEN_FDS
+ ${_GETCONF_MAX_FDS}
+ STRING
+ "Maximum number of open file descriptors supported"
+ ADVANCED)
+
+## RocksDB support
+gkfs_define_option(
+ GKFS_ENABLE_ROCKSDB
+ HELP_TEXT "Enable RocksDB metadata backend"
+ DEFAULT_VALUE ON
+ DESCRIPTION "Use RocksDB key-value store for the metadata backend"
+)
+
+## Parallax support
+gkfs_define_option(
+ GKFS_ENABLE_PARALLAX
+ HELP_TEXT "Enable Parallax support"
+ DEFAULT_VALUE OFF
+ DESCRIPTION "Support using the Parallax key-value store in the metadata backend"
+)
+
+## Guided distribution
+gkfs_define_variable(
+ GKFS_USE_GUIDED_DISTRIBUTION_PATH
+ "/tmp/guided.txt"
+ STRING
+ "File Path for guided distributor"
+)
+
+gkfs_define_option(
+ GKFS_USE_GUIDED_DISTRIBUTION
+ HELP_TEXT "Use guided data distributor"
+ DEFAULT_VALUE OFF
+ DESCRIPTION "Use a guided data distribution instead of GekkoFS' wide striping"
+ EXTRA_INFO "Guided data distributor input file path: ${GKFS_USE_GUIDED_DISTRIBUTION_PATH}"
+)
+
+
+################################################################################
+# Logging and tracing support
+################################################################################
+
+## Client logging support
+# FIXME: should be prefixed with GKFS_
+gkfs_define_option(
+ ENABLE_CLIENT_LOG HELP_TEXT "Enable logging messages in clients"
+ DEFAULT_VALUE ON
+)
+
+# FIXME: should be prefixed with GKFS_
+gkfs_define_variable(
+ CLIENT_LOG_MESSAGE_SIZE
+ 1024
+ STRING
+ "Maximum size of a log message in the client library"
+ ADVANCED
+)
+
+## Prometheus tracing support
+gkfs_define_option(
+ GKFS_ENABLE_PROMETHEUS
+ HELP_TEXT "Enable Prometheus Push"
+ DEFAULT_VALUE OFF
+ DESCRIPTION "Enable the collection of stats using Prometheus"
+)
+
+
+################################################################################
+# I/O forwarding
+################################################################################
+
+## Forwarding support
+gkfs_define_option(
+ GKFS_ENABLE_FORWARDING
+ HELP_TEXT "Enable I/O forwarding mode"
+ DEFAULT_VALUE OFF
+ DESCRIPTION "Use ${PROJECT_NAME} as an I/O forwarding layer"
+)
+
+## Scheduling in I/O forwarding mode
+gkfs_define_option(
+ GKFS_ENABLE_AGIOS
+ HELP_TEXT "Enable AGIOS scheduling library"
+ DEFAULT_VALUE OFF
+ DESCRIPTION "If GKFS_ENABLE_FORWARDING is ON, use AGIOS for scheduling I/Os"
+)
+
+
diff --git a/CMake/gkfs-utils.cmake b/CMake/gkfs-utils.cmake
index e4ea1379d0ba3bb14a57a7eeff05b6e8ce0968bf..cdb7047d4f03c8f15fa444dee250a07ad0c5341b 100644
--- a/CMake/gkfs-utils.cmake
+++ b/CMake/gkfs-utils.cmake
@@ -146,3 +146,105 @@ function(mark_variables_as_advanced)
mark_as_advanced(${_var})
endforeach()
endfunction()
+
+
+#[=======================================================================[.rst:
+
+ include_from_source(contentName ...)
+
+The ``include_from_source()`` function ensures that ``contentName`` is
+populated and potentially added to the build by the time it returns.
+
+**Options:**
+
+ ``SOURCE_DIR ``: Source directory into which downloaded contents reside.
+ This must point to an existing directory where the external project has
+ already been unpacked or cloned/checked out. If ```` doesn't exist,
+ the source code will be retrieved.
+
+ ``GIT_REPOSITORY ``
+ URL of the git repository. Any URL understood by the ``git`` command
+ may be used.
+
+ ``GIT_TAG ``
+ Git branch name, tag or commit hash. Note that branch names and tags should
+ generally be specified as remote names (i.e. origin/myBranch rather than
+ simply myBranch). This ensures that if the remote end has its tag moved or
+ branch rebased or history rewritten, the local clone will still be updated
+ correctly. In general, however, specifying a commit hash should be
+ preferred for a number of reasons:
+
+ If the local clone already has the commit corresponding to the hash, no git
+ fetch needs to be performed to check for changes each time CMake is re-run.
+ This can result in a significant speed up if many external projects are
+ being used.
+
+ Using a specific git hash ensures that the main project's own history is
+ fully traceable to a specific point in the external project's evolution.
+ If a branch or tag name is used instead, then checking out a specific
+ commit of the main project doesn't necessarily pin the whole build to a
+ specific point in the life of the external project. The lack of such
+ deterministic behavior makes the main project lose traceability and
+ repeatability.
+
+ NOTE: If both ``SOURCE_DIR`` and ``GIT_REPOSITORY`` are specified,
+ ``SOURCE_DIR`` will be the preferred location to populate ``contentName``
+ from. If ``SOURCE_DIR`` doesn't exist, the function will fall back to the
+ location defined by ``GIT_REPOSITORY``.
+
+#]=======================================================================]
+function(include_from_source contentName)
+
+ set(OPTIONS)
+ set(SINGLE_VALUE MESSAGE SOURCE_DIR GIT_REPOSITORY GIT_TAG)
+ set(MULTI_VALUE)
+
+ cmake_parse_arguments(ARGS "${OPTIONS}" "${SINGLE_VALUE}" "${MULTI_VALUE}" ${ARGN})
+
+ if(ARGS_MESSAGE)
+ message(STATUS ${ARGS_MESSAGE})
+ endif()
+
+ include(FetchContent)
+
+ if (EXISTS ${ARGS_SOURCE_DIR})
+ file(GLOB_RECURSE SOURCE_FILES "${ARGS_SOURCE_DIR}/*")
+ if(SOURCE_FILES STREQUAL "")
+ message(FATAL_ERROR
+ "The '${ARGS_SOURCE_DIR}' source directory appears "
+ "to be empty. If it corresponds to a git submodule it may not have "
+ "been properly initialized. Running:\n"
+ " 'git submodule update --init --recursive'\n"
+ "may fix the issue. If the directory corresponds to a manually "
+ "downloaded dependency, please download it again.")
+ endif()
+
+ message(STATUS "Found source directory for '${contentName}'. Building.")
+ FetchContent_Declare(
+ ${contentName}
+ SOURCE_DIR ${ARGS_SOURCE_DIR}
+ )
+ else()
+ message(STATUS
+ "Source directory for '${contentName}' not found.\n"
+ "Downloading and building from remote Git repository.")
+
+ if(NOT ARGS_GIT_REPOSITORY)
+ message(FATAL_ERROR "GIT_REPOSITORY for \"${contentName}\" not defined")
+ endif()
+
+ if(NOT ARGS_GIT_TAG)
+ message(FATAL_ERROR "GIT_TAG for \"${contentName}\" not defined")
+ endif()
+
+ FetchContent_Declare(
+ ${contentName}
+ GIT_REPOSITORY ${ARGS_GIT_REPOSITORY}
+ GIT_TAG ${ARGS_GIT_TAG}
+ GIT_SHALLOW ON
+ GIT_PROGRESS ON
+ )
+ endif()
+
+ FetchContent_MakeAvailable(${contentName})
+endfunction()
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 50c839b510ae6cf724471c395086a71e5a62311d..0e701f757d39858edb1c8da2eb476fd9b4ad4d4f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -26,7 +26,8 @@
# SPDX-License-Identifier: GPL-3.0-or-later #
################################################################################
-cmake_minimum_required(VERSION 3.6)
+# 3.13+ so that we have a sensible handling of relative paths
+cmake_minimum_required(VERSION 3.13)
project(
GekkoFS
@@ -51,7 +52,7 @@ if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release
CACHE STRING "Choose the type of build: Debug Release Memcheck" FORCE)
ENDIF (NOT CMAKE_BUILD_TYPE)
-message(STATUS "[gekkofs] Build type: ${CMAKE_BUILD_TYPE}")
+message(STATUS "[${PROJECT_NAME}] Build type: ${CMAKE_BUILD_TYPE}")
# Compiler flags for various cmake build types
set(WARNINGS_FLAGS "-Wall -Wextra --pedantic -Wno-unused-parameter -Wno-missing-field-initializers")
@@ -69,6 +70,7 @@ mark_as_advanced(CMAKE_CXX_FLAGS_MAINTAINER)
include(CheckCXXSourceCompiles)
include(CMakeDependentOption)
include(GNUInstallDirs)
+include(FeatureSummary)
# Project version
set(GIT_VERSION_FOUND FALSE)
@@ -98,7 +100,7 @@ if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
endif ()
endif ()
endif ()
-message(STATUS "[gekkofs] Project version: ${PROJECT_VERSION}")
+message(STATUS "[${PROJECT_NAME}] Project version: ${PROJECT_VERSION}")
set(GKFS_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(GKFS_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(GKFS_VERSION_PATCH ${PROJECT_VERSION_PATCH})
@@ -107,115 +109,187 @@ configure_file(include/version.hpp.in include/version.hpp)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH})
+# Import some convenience functions
+include(gkfs-utils)
+
+################################################################################
+## Configuration option definitions:
+## =================================
+##
+## The `gkfs-options` module imports definitions for all the available GekkoFS
+## features
+################################################################################
+include(gkfs-options)
+
set(CMAKE_EXPORT_COMPILE_COMMANDS 0)
-# margo dependencies
-find_package(Mercury REQUIRED)
-find_package(Abt REQUIRED)
-find_package(Margo REQUIRED)
+# ##############################################################################
+# Check for and/or download dependencies:
+#
+# GekkoFS has two types of dependencies:
+# 1. Dependencies that are installed as system-wide packages and provide
+# a FindXXX.cmake file to find them. These are handled using
+# `find_package()`.
+# 2. Depedencies that are used directly from source code (e.g. header-only
+# libraries). The source code for these can be found locally or
+# remotely in a GIT repository. These are handled using our custom
+# `include_from_source()` function defined in `gkfs-utils.cmake`
+# ##############################################################################
+
+# Search for dependencies that should already be installed in the system
+###############################################################################
+
+### some dependencies don't provide CMake modules, but rely on pkg-config
+### instead, make sure that pkg-config is available
+find_package(PkgConfig REQUIRED)
+
+### Mercury
+message(STATUS "[${PROJECT_NAME}] Checking for Mercury")
+find_package(Mercury 2.0.1 REQUIRED)
+
+### Argobots
+message(STATUS "[${PROJECT_NAME}] Checking for Argobots")
+find_package(Argobots 1.1 REQUIRED)
+
+### Margo
+message(STATUS "[${PROJECT_NAME}] Checking for Margo")
+find_package(Margo 0.9.6 REQUIRED)
+
+### syscall-intercept
+message(STATUS "[${PROJECT_NAME}] Checking for syscall_intercept")
find_package(Syscall_intercept REQUIRED)
+
+### Date (required by the libgkfs_intercept.so)
+message(STATUS "[${PROJECT_NAME}] Checking for Date")
+find_package(Date REQUIRED)
+
+### AGIOS: required for scheduling I/O requests
+if (GKFS_ENABLE_AGIOS)
+ message(STATUS "[${PROJECT_NAME}] Checking for Agios")
+ find_package(AGIOS REQUIRED)
+endif()
+
+### Metadata backends
+if(GKFS_ENABLE_ROCKSDB)
+ message(STATUS "[${PROJECT_NAME}] Checking for RocksDB")
+ add_compile_definitions(GKFS_ENABLE_ROCKSDB)
+ find_package(RocksDB 6.26.1 REQUIRED)
+ message(STATUS "[${PROJECT_NAME}] RocksDB version ${RocksDB_VERSION}")
+ message(STATUS "[${PROJECT_NAME}] RocksDB location ${RocksDB_DIR}")
+endif()
+
+if(GKFS_ENABLE_PARALLAX)
+ add_compile_definitions(GKFS_ENABLE_PARALLAX)
+ # The current version of Parallax has a direct dependency on libyaml and librt.
+ # Make sure that we find them and add them as link dependencies..
+
+ message(STATUS "[${PROJECT_NAME}] Checking for yaml")
+ find_package(yaml REQUIRED)
+
+ message(STATUS "[${PROJECT_NAME}] Checking for libaio")
+ find_package(AIO REQUIRED)
+
+ message(STATUS "[${PROJECT_NAME}] Checking for Parallax")
+ find_package(Parallax REQUIRED)
+ target_link_libraries(Parallax::parallax INTERFACE yaml AIO::AIO)
+endif()
+
+### Prometheus-cpp: required for the collection of GekkoFS stats
+### (these expose the prometheus-cpp::pull, prometheus-cpp::push,
+### prometheus-cpp::core, and curl imported targets
+if(GKFS_ENABLE_PROMETHEUS)
+ find_package(CURL 7.68.0 REQUIRED)
+ find_package(prometheus-cpp REQUIRED) # >= 1.0.0
+endif()
+
+### Other stuff that can be found out using find_package:
+
+# determine the thread library of the system
find_package(Threads REQUIRED)
+
# some compilers need extra flags for std::filesystem, such as -lstdc++fs, this
# produces a std::filesystem imported target that takes care of all these
# details transparently
find_package(Filesystem REQUIRED)
-find_package(Date REQUIRED)
-# Import some convenience functions
-include(gkfs-utils)
+# Search for 'source-only' dependencies
+###############################################################################
+
+# the directory where external dependencies should be searched for
+set(GKFS_DEPENDENCIES_PATH ${CMAKE_SOURCE_DIR}/external)
+
+### {fmt}: required for sensible output formatting
+include_from_source(fmt
+ MESSAGE "[${PROJECT_NAME}] Searching for {fmt}"
+ SOURCE_DIR ${GKFS_DEPENDENCIES_PATH}/fmt
+ GIT_REPOSITORY https://github.com/fmtlib/fmt
+ GIT_TAG f94b7364b9409f05207c3af3fa4666730e11a854 # v6.1.2
+)
+
+# ensure that fmt is linked as PIC
+set_property(TARGET fmt PROPERTY POSITION_INDEPENDENT_CODE ON)
+
+### spdlog: required for logging
+include_from_source(spdlog
+ MESSAGE "[${PROJECT_NAME}] Searching for spdlog"
+ SOURCE_DIR ${GKFS_DEPENDENCIES_PATH}/spdlog
+ GIT_REPOSITORY https://github.com/gabime/spdlog.git
+ GIT_TAG eb3220622e73a4889eee355ffa37972b3cac3df5 # v1.9.2
+ )
+
+### CLI11: used for parsing command-line options
+include_from_source(cli11
+ MESSAGE "[${PROJECT_NAME}] Searching for CLI11"
+ SOURCE_DIR ${GKFS_DEPENDENCIES_PATH}/CLI11
+ GIT_REPOSITORY https://github.com/CLIUtils/CLI11
+ GIT_TAG v2.2.0
+ )
+
################################################################################
-## Build GekkoFS documentation
+## Check configured variables/options and act accordingly
################################################################################
-option(GKFS_BUILD_DOCUMENTATION "Build documentation" OFF)
if(GKFS_BUILD_DOCUMENTATION)
- add_subdirectory(docs)
+ add_subdirectory(docs)
endif()
-option(CREATE_CHECK_PARENTS "Check parent directory existance before creating child node" ON)
-message(STATUS "[gekkofs] Create checks parents: ${CREATE_CHECK_PARENTS}")
-
-option(GKFS_SYMLINK_SUPPORT "Compile with support for symlinks" OFF)
if (GKFS_SYMLINK_SUPPORT)
add_definitions(-DHAS_SYMLINKS)
endif ()
-option(GKFS_RENAME_SUPPORT "Compile with support for rename ops" OFF)
+
if (GKFS_RENAME_SUPPORT)
# Rename depends on symlink support
add_definitions(-DHAS_SYMLINKS)
set(GKFS_SYMLINK_SUPPORT ON)
add_definitions(-DHAS_RENAME)
endif ()
-message(STATUS "[gekkofs] Symlink support: ${GKFS_SYMLINK_SUPPORT}")
-message(STATUS "[gekkofs] Rename support: ${GKFS_RENAME_SUPPORT}")
-
-set(MAX_INTERNAL_FDS 256 CACHE STRING "Number of file descriptors reserved for internal use")
-add_definitions(-DMAX_INTERNAL_FDS=${MAX_INTERNAL_FDS})
-message(STATUS "[gekkofs] File descriptors reserved for internal use: ${MAX_INTERNAL_FDS}")
-
-execute_process(COMMAND getconf OPEN_MAX
- OUTPUT_VARIABLE GETCONF_MAX_FDS
- OUTPUT_STRIP_TRAILING_WHITESPACE
- ERROR_QUIET)
-if (NOT GETCONF_MAX_FDS)
- set(GETCONF_MAX_FDS=512)
-endif ()
-add_definitions(-DMAX_OPEN_FDS=${GETCONF_MAX_FDS})
-option(ENABLE_CLIENT_LOG "Enable logging messages" ON)
-if (ENABLE_CLIENT_LOG)
+if(MAX_INTERNAL_FDS)
+ add_definitions(-DMAX_INTERNAL_FDS=${MAX_INTERNAL_FDS})
+endif()
+
+if(MAX_OPEN_FDS)
+ add_definitions(-DMAX_OPEN_FDS=${MAX_OPEN_FDS})
+endif()
+
+if(ENABLE_CLIENT_LOG)
add_definitions(-DGKFS_ENABLE_LOGGING)
+ add_definitions(-DLIBGKFS_LOG_MESSAGE_SIZE=${CLIENT_LOG_MESSAGE_SIZE})
endif ()
-message(STATUS "[gekkofs] Client logging output: ${ENABLE_CLIENT_LOG}")
-option(GKFS_ENABLE_FORWARDING "Enable forwarding mode" OFF)
-option(GKFS_ENABLE_AGIOS "Enable AGIOS scheduling library" OFF)
-if (GKFS_ENABLE_AGIOS)
- find_package(AGIOS REQUIRED)
+if(GKFS_ENABLE_UNUSED_FUNCTIONS)
+ add_definitions(-DGKFS_ENABLE_UNUSED_FUNCTIONS)
endif ()
-option(GKFS_ENABLE_UNUSED_FUNCTIONS "Enable unused functions compilation" OFF)
-
-option(GKFS_ENABLE_PARALLAX "Enable Parallax db backend" OFF)
-option(GKFS_ENABLE_ROCKSDB "Enable ROCKSDB backend" ON)
-
-set(CLIENT_LOG_MESSAGE_SIZE 1024 CACHE STRING "Maximum size of a log message in the client library")
-add_definitions(-DLIBGKFS_LOG_MESSAGE_SIZE=${CLIENT_LOG_MESSAGE_SIZE})
-message(STATUS "[gekkofs] Maximum log message size in the client library: ${CLIENT_LOG_MESSAGE_SIZE}")
-mark_as_advanced(CLIENT_LOG_MESSAGE_SIZE)
-
-option(GKFS_USE_GUIDED_DISTRIBUTION "Use guided data distributor " OFF)
-message(STATUS "[gekkofs] Guided data distributor: ${GKFS_USE_GUIDED_DISTRIBUTION}")
-
-if(GKFS_USE_GUIDED_DISTRIBUTION)
- set(GKFS_USE_GUIDED_DISTRIBUTION_PATH "/tmp/guided.txt" CACHE STRING "File Path for guided distributor")
- set_property(CACHE GKFS_USE_GUIDED_DISTRIBUTION_PATH PROPERTY STRINGS)
- message(STATUS "[gekkofs] Guided data distributor input file path: ${GKFS_USE_GUIDED_DISTRIBUTION_PATH}")
-endif()
-
-option(GKFS_ENABLE_PROMETHEUS "Enable Prometheus Push " OFF)
if(GKFS_ENABLE_PROMETHEUS)
add_definitions(-DGKFS_ENABLE_PROMETHEUS)
endif ()
-message(STATUS "[gekkofs] Prometheus Output: ${GKFS_ENABLE_PROMETHEUS}")
configure_file(include/common/cmake_configure.hpp.in include/common/cmake_configure.hpp)
-
-
-add_library(CLI11 INTERFACE)
-# we cannot use target_include_directories with CMake < 3.11
-set_target_properties(CLI11
- PROPERTIES
- INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}/external"
- )
-
-add_subdirectory(external/fmt)
-set_property(TARGET fmt PROPERTY POSITION_INDEPENDENT_CODE ON)
-
-if (ENABLE_CLIENT_LOG)
+if(ENABLE_CLIENT_LOG)
option(HERMES_LOGGING "" ON)
option(HERMES_LOGGING_FMT_USE_BUNDLED "" OFF)
option(HERMES_LOGGING_FMT_HEADER_ONLY "" OFF)
@@ -223,7 +297,7 @@ endif ()
option(HERMES_MARGO_COMPATIBLE_RPCS "" ON)
add_subdirectory(external/hermes)
-target_compile_definitions(hermes INTERFACE)
+target_include_directories(hermes INTERFACE external/hermes/include)
set(INCLUDE_DIR "${CMAKE_SOURCE_DIR}/include")
@@ -233,22 +307,14 @@ include_directories(
${CMAKE_BINARY_DIR}/include
)
-# Common components
-add_subdirectory(src/common)
-# Daemon
-add_subdirectory(src/daemon)
-# Client library
-add_subdirectory(src/client)
+add_subdirectory(src)
+add_subdirectory(include)
### Mark any CMake variables imported from {fmt} and spdlog as advanced, so
### that they don't appear in cmake-gui or ccmake. Similarly for FETCHCONTENT
### variables.
mark_variables_as_advanced(REGEX "^(FETCHCONTENT|fmt|FMT|spdlog|SPDLOG)_.*$")
-option(GKFS_BUILD_TESTS "Build GekkoFS self tests" OFF)
-
-cmake_dependent_option(GKFS_INSTALL_TESTS "Install GekkoFS self tests" OFF "GKFS_BUILD_TESTS" OFF)
-
if (GKFS_BUILD_TESTS)
# Boost preprocessor header-only is supplied by the Mercury installation
find_package(Boost_preprocessor REQUIRED)
@@ -292,3 +358,7 @@ else()
unset(GKFS_TESTS_INTERFACE CACHE)
endif()
+################################################################################
+## Print GekkoFS configuration summary
+################################################################################
+gkfs_feature_summary(DESCRIPTION "${PROJECT_NAME} configuration summary:")
diff --git a/external/CLI11 b/external/CLI11
new file mode 160000
index 0000000000000000000000000000000000000000..b9be5b9444772324459989177108a6a65b8b2769
--- /dev/null
+++ b/external/CLI11
@@ -0,0 +1 @@
+Subproject commit b9be5b9444772324459989177108a6a65b8b2769
diff --git a/external/CLI11/CLI11.hpp b/external/CLI11/CLI11.hpp
deleted file mode 100644
index dcb57c6c6cafe03f7e5687e78e6cfba4f5a9ff8c..0000000000000000000000000000000000000000
--- a/external/CLI11/CLI11.hpp
+++ /dev/null
@@ -1,9066 +0,0 @@
-// CLI11: Version 2.1.2
-// Originally designed by Henry Schreiner
-// https://github.com/CLIUtils/CLI11
-//
-// This is a standalone header file generated by MakeSingleHeader.py in CLI11/scripts
-// from: v2.1.2
-//
-// CLI11 2.1.2 Copyright (c) 2017-2021 University of Cincinnati, developed by Henry
-// Schreiner under NSF AWARD 1414736. All rights reserved.
-//
-// Redistribution and use in source and binary forms of CLI11, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice, this
-// list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// 3. Neither the name of the copyright holder nor the names of its contributors
-// may be used to endorse or promote products derived from this software without
-// specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#pragma once
-
-// Standard combined includes:
-#include
-#include
-#include
-#include
-#include
-#include