diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 647c7982b..c2cbb7a55 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -100,7 +100,8 @@ jobs: displayName: generate test directories - script: ln -s "$(pwd)" tests/mesonTest/subprojects/CLI11 displayName: generate CLI11 symlink - - script: meson build + # Ensure that Meson doesn't use cmake or pkgconfig to find CLI11 + - script: meson setup build --force-fallback-for=CLI11 displayName: Run meson to generate build workingDirectory: tests/mesonTest - script: ninja -C tests/mesonTest/build diff --git a/book/chapters/installation.md b/book/chapters/installation.md index e1678a523..467638a03 100644 --- a/book/chapters/installation.md +++ b/book/chapters/installation.md @@ -51,7 +51,7 @@ If the CMake option `CLI11_PRECOMPILED` is set then the library is compiled into a static library. This can be used to improve compile times if CLI11 is included in many different parts of a project. -### Global Headers +#### Global Headers Use `CLI/*.hpp` files stored in a shared folder. You could check out the git repository to a system-wide folder, for example `/opt/`. With CMake, you could @@ -194,6 +194,32 @@ default to off if CLI11 is used as a subdirectory in another project. nothing special about this container. Alpine is being used because it is small, modern, and fast. Commands are similar on any other platform. +## Meson support + +### Global Headers from pkg-config + +If CLI11 is installed globally, then nothing more than `dependency('CLI11')` is +required. If it installed in a non-default search path, then setting the +`PKG_CONFIG_PATH` environment variable of the `--pkg-config-path` option to +`meson setup` is all that's required. + +### Using Meson's subprojects + +Meson has a system called +[wraps](https://mesonbuild.com/Wrap-dependency-system-manual.html), which allow +Meson to fetch sources, configure, and build dependencies as part of a main +project. This is the mechanism that Meson recommends for projects to use, as it +allows updating the dependency transparently, and allows packagers to have fine +grained control on the use of subprojects vs system provided dependencies. +Simply run `meson wrap install cli11` to install the `cli11.wrap` file, and +commit it, if desired. + +It is also possible to use git submodules. This is generally discouraged by +Meson upstream, but may be appropriate if a project needs to build with multiple +build systems and wishes to share subprojects between them. As long as the +submodule is in the parent project's subproject directory nothing additional is +needed. + ## Installing cli11 using vcpkg You can download and install cli11 using the diff --git a/meson.build b/meson.build index 1b6d98e9b..004bd615c 100644 --- a/meson.build +++ b/meson.build @@ -7,9 +7,78 @@ project('CLI11', ['cpp'], cxx = meson.get_compiler('cpp') +use_single_header = get_option('single-file-header') +use_precompiled = get_option('precompiled') + +if use_precompiled and use_single_header + error('Options "single-file"header" and "precompiled" are mutually exclusive') +endif + +cli11_headers = files( + 'include/CLI/App.hpp', + 'include/CLI/Argv.hpp', + 'include/CLI/CLI.hpp', + 'include/CLI/Config.hpp', + 'include/CLI/ConfigFwd.hpp', + 'include/CLI/Encoding.hpp', + 'include/CLI/Error.hpp', + 'include/CLI/Formatter.hpp', + 'include/CLI/FormatterFwd.hpp', + 'include/CLI/Macros.hpp', + 'include/CLI/Option.hpp', + 'include/CLI/Split.hpp', + 'include/CLI/StringTools.hpp', + 'include/CLI/TypeTools.hpp', + 'include/CLI/Validators.hpp', + 'include/CLI/Version.hpp', +) + +cli11_impl_headers = files( + 'include/CLI/impl/App_inl.hpp', + 'include/CLI/impl/Argv_inl.hpp', + 'include/CLI/impl/Config_inl.hpp', + 'include/CLI/impl/Encoding_inl.hpp', + 'include/CLI/impl/Formatter_inl.hpp', + 'include/CLI/impl/Option_inl.hpp', + 'include/CLI/impl/Split_inl.hpp', + 'include/CLI/impl/StringTools_inl.hpp', + 'include/CLI/impl/Validators_inl.hpp', +) + +subdir('single-include') + CLI11_inc = include_directories(['include']) +warnings = ['-Wshadow', '-Wsign-conversion', '-Wswitch-enum'] +if cxx.get_id() == 'gcc' and cxx.version().version_compare('>=4.9') + warnings += '-Weffc++' +endif +if cxx.get_id() == 'clang' + warnings += [ + '-Wcast-align', + '-Wimplicit-atomic-properties', + '-Wmissing-declarations', + '-Woverlength-strings', + '-Wstrict-selector-match', + '-Wundeclared-selector', + ] +endif +add_project_arguments(cxx.get_supported_arguments(warnings), language: 'cpp') + +if use_precompiled + libcli11 = static_library( + 'CLI11', + 'src/Precompile.cpp', + include_directories : CLI11_inc, + cpp_args : ['-DCLI11_COMPILE'], + ) +else + libcli11 = [] +endif + CLI11_dep = declare_dependency( + sources : single_header, + link_with : libcli11, include_directories : CLI11_inc, version : meson.project_version(), ) @@ -17,11 +86,5 @@ CLI11_dep = declare_dependency( meson.override_dependency('CLI11', CLI11_dep) if get_option('tests') - warnings = ['-Wshadow', '-Wsign-conversion', '-Wswitch-enum'] - if cxx.get_id() == 'gcc' and cxx.version().version_compare('>=4.9') - warnings += '-Weffc++' - endif - add_project_arguments(cxx.get_supported_arguments(warnings), language: 'cpp') - - subdir('tests') + subdir('tests') endif diff --git a/meson_options.txt b/meson_options.txt index dd4654d48..f32583d87 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1 +1,3 @@ option('tests', type: 'boolean', value: false, description: 'Build CLI11 tests') +option('single-file-header', type: 'boolean', value: false, description : 'Generate a single header file.') +option('precompiled', type: 'boolean', value: false, description : 'Generate a precompiled static library instead of a header-only') diff --git a/single-include/meson.build b/single-include/meson.build new file mode 100644 index 000000000..ee58adf6f --- /dev/null +++ b/single-include/meson.build @@ -0,0 +1,23 @@ +# Because Meson does not allow outputs to be placed in subfolders, we must have +# meson.build here when generating the single file header so that it is placced +# in the correct location. + +prog_python = find_program('python') + +single_main_file = files('CLI11.hpp.in') + +if use_single_header + single_header = custom_target( + 'CLI11.hpp', + input: [files('../scripts/MakeSingleHeader.py'), cli11_headers, cli11_impl_headers], + output: 'CLI11.hpp', + command : [prog_python, '@INPUT@', '--main', single_main_file, '--output', '@OUTPUT@'], + depend_files: [single_main_file], + ) +else + # the `declare_dependency` needs to have the single_header source as a source + # dependency, to ensure that the generator runs before any attempts to include + # the header happen. Adding an empty list is an idiomatic way to ensure the + # variable exists but does nothing + single_header = [] +endif diff --git a/tests/meson.build b/tests/meson.build index 7fd05a4ba..510bfced4 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -58,6 +58,7 @@ testnames = [ ['ComplexTypeTest', {}], ['TrueFalseTest', {}], ['OptionGroupTest', {}], + ['EncodingTest', {}], # multi-only ['TimerTest', {}], # link_test diff --git a/tests/mesonTest/meson.build b/tests/mesonTest/meson.build index 56ebadb65..9fa9d385a 100644 --- a/tests/mesonTest/meson.build +++ b/tests/mesonTest/meson.build @@ -1,5 +1,5 @@ -project('mesonTest', ['c', 'cpp'], default_options: ['cpp_std=c++11']) +project('mesonTest', ['cpp'], default_options: ['cpp_std=c++11']) -cli11_dep = subproject('CLI11').get_variable('CLI11_dep') +cli11_dep = dependency('CLI11') mainExe = executable('main', ['main.cpp'], dependencies: [cli11_dep])