Skip to content

Commit

Permalink
Merge pull request #218 from eseiler/infra/optional_tdl
Browse files Browse the repository at this point in the history
[INFRA] Optional tdl
  • Loading branch information
eseiler authored Jan 31, 2024
2 parents 60abdbe + 82a96f7 commit 518c1bb
Show file tree
Hide file tree
Showing 16 changed files with 189 additions and 67 deletions.
16 changes: 14 additions & 2 deletions .github/workflows/ci_linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,22 @@ jobs:
build_type: Release
cxx_flags: "-stdlib=libc++"

- name: "clang17 no TDL"
compiler: "clang-17"
build: unit
build_type: Release
cxx_flags: "-stdlib=libc++"

- name: "gcc13"
compiler: "gcc-13"
build: unit
build_type: Release

- name: "gcc13 no TDL"
compiler: "gcc-13"
build: unit
build_type: Release

- name: "gcc12"
compiler: "gcc-12"
build: unit
Expand Down Expand Up @@ -89,8 +100,9 @@ jobs:
cd sharg-build
cmake ../sharg/test/${{ matrix.build }} -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \
-DCMAKE_CXX_FLAGS="${{ matrix.cxx_flags }}" \
-DSHARG_VERBOSE_TESTS=OFF
make -j2 gtest_build yaml-cpp
-DSHARG_VERBOSE_TESTS=OFF \
${{ contains(matrix.name, 'no TDL') && '-DSHARG_NO_TDL=ON' || '' }}
make -j2 gtest_build ${{ contains(matrix.name, 'no TDL') == false && 'yaml-cpp' || '' }}
- name: Build tests
run: |
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ If possible, provide tooling that performs the changes, e.g. a shell-script.

# Release 1.1.2

## API changes

#### Dependencies
* TDL is now an optional dependency and can be force deactivated via CMake (`-DSHARG_NO_TDL=ON`)
([#218](https://github.com/seqan/sharg-parser/pull/218)).

# Release 1.1.1

## Bug fixes
Expand Down Expand Up @@ -53,6 +59,8 @@ If possible, provide tooling that performs the changes, e.g. a shell-script.
* Segmentation fault when using `sharg::value_list_validator` in conjuction with a `std::filesystem::path` option
([\#179](https://github.com/seqan/sharg-parser/pull/179)).

## API changes

#### Dependencies
* We now use Doxygen version 1.9.5 to build our documentation ([\#145](https://github.com/seqan/sharg-parser/pull/145)).
* We require at least CMake 3.16 for our test suite. Note that the minimum requirement for using Sharg is unchanged
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ VERSION
|**compiler** | [GCC](https://gcc.gnu.org) | ≥ 11 | |
|**compiler** | [Clang](https://clang.llvm.org/) | ≥ 17 | |
|**build system** | [CMake](https://cmake.org) | ≥ 3.16 | optional, but recommended |
|**required libs** | [TDL](https://github.com/deNBI-cibi/tool_description_lib) | ≥ 1.0.0 | required for CWL export |
|**optional libs** | [TDL](https://github.com/deNBI-cibi/tool_description_lib) | ≥ 1.0.0 | required for CWL and CTD export |


## Sponsorships
Expand Down
85 changes: 46 additions & 39 deletions build_system/sharg-config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -136,31 +136,28 @@ if (SHARG_CLONE_DIR)
sharg_config_print ("Detected as running from a repository checkout…")
endif ()

# Currently unused.
# if (SHARG_SUBMODULES_DIR)
# file (GLOB submodules ${SHARG_SUBMODULES_DIR}/lib/*/include)
# foreach (submodule ${submodules})
# if (IS_DIRECTORY ${submodule})
# sharg_config_print (" …adding submodule include: ${submodule}")
# set (SHARG_DEPENDENCY_INCLUDE_DIRS ${submodule} ${SHARG_DEPENDENCY_INCLUDE_DIRS})
# endif ()
# endforeach ()
# endif ()

# ----------------------------------------------------------------------------
# Options for CheckCXXSourceCompiles
# ----------------------------------------------------------------------------

# deactivate messages in check_*
set (CMAKE_REQUIRED_QUIET 1)
# use global variables in Check* calls
set (CMAKE_REQUIRED_INCLUDES ${CMAKE_INCLUDE_PATH} ${SHARG_INCLUDE_DIR} ${SHARG_DEPENDENCY_INCLUDE_DIRS})
set (CMAKE_REQUIRED_INCLUDES ${CMAKE_INCLUDE_PATH} ${SHARG_INCLUDE_DIR})
set (CMAKE_REQUIRED_FLAGS ${CMAKE_CXX_FLAGS})

# ----------------------------------------------------------------------------
# Force-deactivate optional dependencies
# ----------------------------------------------------------------------------

option (SHARG_NO_TDL "Do not use TDL, even if present." OFF)

# ----------------------------------------------------------------------------
# Require C++20
# ----------------------------------------------------------------------------

set (SHARG_CXX_FLAGS "")

set (CMAKE_REQUIRED_FLAGS_SAVE ${CMAKE_REQUIRED_FLAGS})

set (CXXSTD_TEST_SOURCE
Expand All @@ -184,18 +181,19 @@ else ()
sharg_config_error ("SHARG requires C++20, but your compiler does not support it.")
endif ()

set (SHARG_CXX_FLAGS "${SHARG_CXX_FLAGS} -std=c++20")
list (APPEND SHARG_CXX_FLAGS "-std=c++20")
endif ()

# ----------------------------------------------------------------------------
# thread support (pthread, windows threads)
# ----------------------------------------------------------------------------
set (SHARG_LIBRARIES "")

set (THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package (Threads QUIET)

if (Threads_FOUND)
set (SHARG_LIBRARIES ${SHARG_LIBRARIES} Threads::Threads)
list (APPEND SHARG_LIBRARIES Threads::Threads)
if ("${CMAKE_THREAD_LIBS_INIT}" STREQUAL "")
sharg_config_print ("Thread support: builtin.")
else ()
Expand All @@ -208,12 +206,26 @@ endif ()
# ----------------------------------------------------------------------------
# tool description lib (tdl) dependency
# ----------------------------------------------------------------------------
find_package (TDL QUIET HINTS ${SHARG_SUBMODULES_DIR}/submodules/tool_description_lib ${SHARG_HINT_TDL})
set (SHARG_USE_TDL FALSE)

if (NOT SHARG_NO_TDL)
find_package (TDL QUIET HINTS ${SHARG_SUBMODULES_DIR}/submodules/tool_description_lib ${SHARG_HINT_TDL})

if (TDL_FOUND)
sharg_config_print ("Dependency: TDL found.")
if (TDL_FOUND)
sharg_config_print ("Optional dependency: TDL found.")
set (SHARG_USE_TDL TRUE)
list (APPEND SHARG_LIBRARIES tdl::tdl)
else ()
sharg_config_print ("Optional dependency: TDL not found.")
endif ()
else ()
sharg_config_error ("Dependency: TDL not found.")
sharg_config_print ("Optional dependency: TDL deactivated.")
endif ()

if (SHARG_USE_TDL)
set (SHARG_DEFINITIONS ${SHARG_DEFINITIONS} "-DSHARG_HAS_TDL=1")
else ()
set (SHARG_DEFINITIONS ${SHARG_DEFINITIONS} "-DSHARG_HAS_TDL=0")
endif ()

# ----------------------------------------------------------------------------
Expand All @@ -224,7 +236,7 @@ endif ()
if ((${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
OR (${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD")
OR (${CMAKE_SYSTEM_NAME} STREQUAL "GNU"))
set (SHARG_LIBRARIES ${SHARG_LIBRARIES} rt)
list (APPEND SHARG_LIBRARIES rt)
endif ()

# libexecinfo -- implicit
Expand All @@ -233,7 +245,7 @@ mark_as_advanced (_SHARG_HAVE_EXECINFO)
if (_SHARG_HAVE_EXECINFO)
sharg_config_print ("Optional dependency: libexecinfo found.")
if ((${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") OR (${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD"))
set (SHARG_LIBRARIES ${SHARG_LIBRARIES} execinfo elf)
list (APPEND SHARG_LIBRARIES execinfo elf)
endif ()
else ()
sharg_config_print ("Optional dependency: libexecinfo not found.")
Expand All @@ -249,12 +261,15 @@ set (CXXSTD_TEST_SOURCE "#include <sharg/platform.hpp>
# using try_compile instead of check_cxx_source_compiles to capture output in case of failure
file (WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx" "${CXXSTD_TEST_SOURCE}\n")

# Can't find tdl::tdl in try_compile, so we need to remove it from SHARG_LIBRARIES
set (SHARG_TRY_COMPILE_LIBRARIES ${SHARG_LIBRARIES})
list (REMOVE_ITEM SHARG_TRY_COMPILE_LIBRARIES tdl::tdl)
try_compile (SHARG_PLATFORM_TEST ${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx
CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${CMAKE_CXX_FLAGS} ${SHARG_CXX_FLAGS}"
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_INCLUDE_PATH};${SHARG_INCLUDE_DIR};${SHARG_DEPENDENCY_INCLUDE_DIRS}"
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_INCLUDE_PATH};${SHARG_INCLUDE_DIR}"
COMPILE_DEFINITIONS ${SHARG_DEFINITIONS}
LINK_LIBRARIES ${SHARG_LIBRARIES}
LINK_LIBRARIES ${SHARG_TRY_COMPILE_LIBRARIES}
OUTPUT_VARIABLE SHARG_PLATFORM_TEST_OUTPUT)

if (SHARG_PLATFORM_TEST)
Expand Down Expand Up @@ -287,31 +302,23 @@ foreach (package_var
set (SHARG_${package_var} "${${CMAKE_FIND_PACKAGE_NAME}_${package_var}}")
endforeach ()

# propagate SHARG_INCLUDE_DIR into SHARG_INCLUDE_DIRS
set (SHARG_INCLUDE_DIRS ${SHARG_INCLUDE_DIR} ${SHARG_DEPENDENCY_INCLUDE_DIRS})

# ----------------------------------------------------------------------------
# Export targets
# ----------------------------------------------------------------------------

if (SHARG_FOUND AND NOT TARGET sharg::sharg)
separate_arguments (SHARG_CXX_FLAGS_LIST UNIX_COMMAND "${SHARG_CXX_FLAGS}")

add_library (sharg_sharg INTERFACE)
target_compile_definitions (sharg_sharg INTERFACE ${SHARG_DEFINITIONS})
target_compile_options (sharg_sharg INTERFACE ${SHARG_CXX_FLAGS_LIST})

# Include TDL as system header to suppress warnings.
get_target_property (tdl_include_dir tdl::tdl INTERFACE_INCLUDE_DIRECTORIES)
target_include_directories (sharg_sharg SYSTEM INTERFACE ${tdl_include_dir})

target_link_libraries (sharg_sharg INTERFACE "${SHARG_LIBRARIES}" tdl::tdl)
# include sharg/include/ as -I, because sharg should never produce warnings.
target_compile_options (sharg_sharg INTERFACE ${SHARG_CXX_FLAGS})
target_link_libraries (sharg_sharg INTERFACE ${SHARG_LIBRARIES})
target_include_directories (sharg_sharg INTERFACE "${SHARG_INCLUDE_DIR}")
# include everything except sharg/include/ as -isystem, i.e.
# a system header which suppresses warnings of external libraries.
target_include_directories (sharg_sharg SYSTEM INTERFACE "${SHARG_DEPENDENCY_INCLUDE_DIRS}")
add_library (sharg::sharg ALIAS sharg_sharg)

if (SHARG_USE_TDL)
# Include TDL as system header to suppress warnings.
get_target_property (tdl_include_dir tdl::tdl INTERFACE_INCLUDE_DIRECTORIES)
target_include_directories (sharg_sharg SYSTEM INTERFACE ${tdl_include_dir})
endif ()
endif ()

set (CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE})
Expand All @@ -326,7 +333,7 @@ if (SHARG_FIND_DEBUG)
message ("")
message (" ${CMAKE_FIND_PACKAGE_NAME}_FOUND ${${CMAKE_FIND_PACKAGE_NAME}_FOUND}")
message ("")
message (" SHARG_INCLUDE_DIRS ${SHARG_INCLUDE_DIRS}")
message (" SHARG_INCLUDE_DIR ${SHARG_INCLUDE_DIR}")
message (" SHARG_LIBRARIES ${SHARG_LIBRARIES}")
message (" SHARG_DEFINITIONS ${SHARG_DEFINITIONS}")
message (" SHARG_CXX_FLAGS ${SHARG_CXX_FLAGS}")
Expand Down
4 changes: 2 additions & 2 deletions include/sharg/detail/format_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,6 @@ class format_help_base : public format_base
: std::string{" "})
+ validator.get_help_page_message());
});
// clang-format on
}

/*!\brief Initiates the printing of the help page to std::cout.
Expand Down Expand Up @@ -340,7 +339,8 @@ class format_help_base : public format_base
derived_t().print_list_item("\\fB--version\\fP", "Prints the version information.");
derived_t().print_list_item("\\fB--copyright\\fP", "Prints the copyright/license information.");
derived_t().print_list_item("\\fB--export-help\\fP (std::string)",
"Export the help page information. Value must be one of [html, man, ctd, cwl].");
"Export the help page information. Value must be one of "
+ detail::supported_exports + ".");
if (version_check_dev_decision == update_notifications::on)
derived_t().print_list_item("\\fB--version-check\\fP (bool)",
"Whether to check for the newest app version. Default: true.");
Expand Down
53 changes: 48 additions & 5 deletions include/sharg/detail/format_tdl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,54 @@

#pragma once

#include <concepts>
#include <numeric>
#if !SHARG_HAS_TDL

#include <sharg/detail/format_base.hpp>
#include <sharg/validators.hpp>
# include <sharg/detail/format_help.hpp>

#include <tdl/tdl.h>
namespace sharg::detail
{
// A dummy class that is used when TDL is not available.
// This reduces the number of '#if's in the code.
// It will always throw when parse is called.
// For the user, the behavior of the parser will be the same as if `parser::init()` would check for TDL availability.
class format_tdl : public format_help
{
public:
enum class FileFormat
{
CTD,
CWL
};

format_tdl(format_tdl const &) = default;
format_tdl & operator=(format_tdl const &) = default;
format_tdl(format_tdl &&) = default;
format_tdl & operator=(format_tdl &&) = default;
~format_tdl() = default;

format_tdl(FileFormat fileFormat) : fileFormat{fileFormat}
{}

void parse(parser_meta_data &, std::vector<std::string> const &)
{
throw validation_error{"Validation failed for option --export-help: "
"Value must be one of "
+ detail::supported_exports + "."};
}

FileFormat fileFormat;
};

} // namespace sharg::detail

#else
# include <concepts>
# include <numeric>

# include <sharg/detail/format_base.hpp>
# include <sharg/validators.hpp>

# include <tdl/tdl.h>

namespace sharg::detail
{
Expand Down Expand Up @@ -356,3 +397,5 @@ class format_tdl : format_base
};

} // namespace sharg::detail

#endif
8 changes: 8 additions & 0 deletions include/sharg/detail/to_string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@
namespace sharg::detail
{

//!\brief A string containing all supported export formats.
static std::string const supported_exports =
#if SHARG_HAS_TDL
"[html, man, ctd, cwl]";
#else
"[html, man]";
#endif

/*!\brief Streams all parameters via std::ostringstream and returns a concatenated string.
* \ingroup misc
* \tparam value_types Must be sharg::ostreamable (stream << value).
Expand Down
11 changes: 4 additions & 7 deletions include/sharg/parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -437,13 +437,9 @@ class parser
[this]<typename T>(T & f)
{
if constexpr (std::same_as<T, detail::format_tdl>)
{
f.parse(info, executable_name);
}
else
{
f.parse(info);
}
},
format);
parse_was_called = true;
Expand Down Expand Up @@ -718,8 +714,8 @@ class parser
detail::format_html,
detail::format_man,
detail::format_tdl,
detail::format_copyright/*,
detail::format_ctd*/> format{detail::format_help{{}, {}, false}}; // Will be overwritten in any case.
detail::format_copyright>
format{detail::format_help{{}, {}, false}}; // Will be overwritten in any case.

//!\brief List of option/flag identifiers that are already used.
std::set<std::string> used_option_ids{"h", "hh", "help", "advanced-help", "export-help", "version", "copyright"};
Expand Down Expand Up @@ -841,7 +837,8 @@ class parser
format = detail::format_tdl{detail::format_tdl::FileFormat::CWL};
else
throw validation_error{"Validation failed for option --export-help: "
"Value must be one of [html, man, ctd, cwl]."};
"Value must be one of "
+ detail::supported_exports + "."};
special_format_was_set = true;
}
else if (arg == "--copyright")
Expand Down
3 changes: 2 additions & 1 deletion test/documentation/sharg_doxygen_cfg.in
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,8 @@ PREDEFINED = "CEREAL_SERIALIZE_FUNCTION_NAME=serialize" \
"CEREAL_LOAD_MINIMAL_FUNCTION_NAME=load_minimal" \
"CEREAL_SAVE_MINIMAL_FUNCTION_NAME=save_minimal" \
"SHARG_DOXYGEN_ONLY(x)= x" \
"${SHARG_DOXYGEN_PREDEFINED_NDEBUG}"
"${SHARG_DOXYGEN_PREDEFINED_NDEBUG}" \
"SHARG_HAS_TDL=1"
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = NO
#---------------------------------------------------------------------------
Expand Down
Loading

0 comments on commit 518c1bb

Please sign in to comment.