diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index d8c27c621..054118ab7 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -31,6 +31,25 @@ jobs: - name: Build run: cmake --build build --target ci_test_gcc + ci_meson_install: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: Get latest CMake and ninja + uses: lukka/get-cmake@fffaaafeea488556c2c12dad60690008bc1caacb # v4.4.2 + - name: Install Meson + run: pip install meson + - name: Install with Meson + run: | + meson setup build-meson --prefix=${{ github.workspace }}/install + meson install -C build-meson + - name: Use the installed package with find_package + run: | + cmake -S tests/cmake_import/project -B build-import -DCMAKE_PREFIX_PATH=${{ github.workspace }}/install + cmake --build build-import + ci_infer: runs-on: ubuntu-latest steps: diff --git a/FILES.md b/FILES.md index 263647146..2e8bfaecf 100644 --- a/FILES.md +++ b/FILES.md @@ -262,7 +262,9 @@ The "Check amalgamation" workflow fails if the file is out of date. ### `meson.build` -The build definition for the [Meson](https://mesonbuild.com) build system. +The build definition for the [Meson](https://mesonbuild.com) build system. When installing, it also installs the CMake package config +files so that `find_package(nlohmann_json)` works. As Meson cannot generate `nlohmann_jsonTargets.cmake` itself, it is +created from the template `cmake/nlohmann_jsonTargets.cmake.in`, which is only used by Meson. ### `Package.swift` diff --git a/cmake/nlohmann_jsonTargets.cmake.in b/cmake/nlohmann_jsonTargets.cmake.in new file mode 100644 index 000000000..adbefbf82 --- /dev/null +++ b/cmake/nlohmann_jsonTargets.cmake.in @@ -0,0 +1,28 @@ +# Imported target for installations made with Meson (see meson.build). +# +# CMake installations generate this file with install(EXPORT ...). Meson cannot +# do that, but as the library is header-only, the target only needs an include +# directory and the C++ standard. Paths are computed relative to this file so +# that the installation can be relocated (e.g., into a sysroot). + +if(TARGET @PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@) + return() +endif() + +get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_DIR}/@NLOHMANN_JSON_CONFIG_TO_PREFIX@" ABSOLUTE) + +add_library(@PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@ INTERFACE IMPORTED) +set_target_properties(@PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@ PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/@NLOHMANN_JSON_INCLUDE_INSTALL_DIR@" +) +if(CMAKE_VERSION VERSION_LESS 3.8) + set_target_properties(@PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@ PROPERTIES + INTERFACE_COMPILE_FEATURES cxx_range_for + ) +else() + set_target_properties(@PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@ PROPERTIES + INTERFACE_COMPILE_FEATURES cxx_std_11 + ) +endif() + +unset(_IMPORT_PREFIX) diff --git a/docs/mkdocs/docs/integration/package_managers.md b/docs/mkdocs/docs/integration/package_managers.md index 792a0fa5a..1dee51cf1 100644 --- a/docs/mkdocs/docs/integration/package_managers.md +++ b/docs/mkdocs/docs/integration/package_managers.md @@ -121,10 +121,15 @@ meson wrap install nlohmann_json Please see the Meson project for any issues regarding the packaging. The provided `meson.build` can also be used as an alternative to CMake for installing `nlohmann_json` system-wide in -which case a pkg-config file is installed. To use it, have your build system require the `nlohmann_json` -pkg-config dependency. In Meson, it is preferred to use the -[`dependency()`](https://mesonbuild.com/Reference-manual.html#dependency) object with a subproject fallback, rather than -using the subproject directly. +which case a pkg-config file and the CMake package config files are installed. To use it, have your build system require +the `nlohmann_json` pkg-config dependency, or use [`find_package(nlohmann_json)`](cmake.md#external) in CMake. In Meson, +it is preferred to use the [`dependency()`](https://mesonbuild.com/Reference-manual.html#dependency) object with a +subproject fallback, rather than using the subproject directly. + +!!! note + + The `meson.build` does not expose the library's [CMake options](cmake.md#cmake-options), so a Meson installation + always uses the library's default configuration. ??? example "Example: Wrap" diff --git a/meson.build b/meson.build index a2d6e31a2..6be366d6a 100644 --- a/meson.build +++ b/meson.build @@ -21,4 +21,34 @@ pkgc.generate(name: 'nlohmann_json', version: meson.project_version(), description: 'JSON for Modern C++' ) + +# CMake package config files, so that find_package(nlohmann_json) works +cmake_install_dir = get_option('datadir') / 'cmake' / meson.project_name() +cmake_to_prefix = [] +foreach component : cmake_install_dir.split('/') + cmake_to_prefix += '..' +endforeach + +cmake_conf = configuration_data() +cmake_conf.set('PROJECT_NAME', meson.project_name()) +cmake_conf.set('PROJECT_VERSION', meson.project_version()) +cmake_conf.set('PROJECT_VERSION_MAJOR', meson.project_version().split('.')[0]) +cmake_conf.set('NLOHMANN_JSON_TARGET_NAME', meson.project_name()) +cmake_conf.set('NLOHMANN_JSON_TARGETS_EXPORT_NAME', meson.project_name() + 'Targets') +cmake_conf.set('NLOHMANN_JSON_INCLUDE_INSTALL_DIR', get_option('includedir')) +cmake_conf.set('NLOHMANN_JSON_CONFIG_TO_PREFIX', '/'.join(cmake_to_prefix)) + +foreach cmake_file : [ + ['cmake/config.cmake.in', 'nlohmann_jsonConfig.cmake'], + ['cmake/nlohmann_jsonConfigVersion.cmake.in', 'nlohmann_jsonConfigVersion.cmake'], + ['cmake/nlohmann_jsonTargets.cmake.in', 'nlohmann_jsonTargets.cmake'], +] + configure_file( + input: cmake_file[0], + output: cmake_file[1], + configuration: cmake_conf, + format: 'cmake@', + install_dir: cmake_install_dir, + ) +endforeach endif