Install CMake package config files with Meson

A Meson installation only provided the headers and a pkg-config file, so
consumers using find_package(nlohmann_json) could not find the library.
Meson now also installs nlohmann_jsonConfig.cmake and
nlohmann_jsonConfigVersion.cmake from the existing templates, plus a
static nlohmann_jsonTargets.cmake that defines the header-only imported
target with a relocatable include path.

A new CI job installs with Meson and builds tests/cmake_import/project
against the result.

Closes #3885

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann
2026-09-27 14:25:10 +02:00
parent 85f8b21e1c
commit 0d2240ad1e
5 changed files with 89 additions and 5 deletions
+19
View File
@@ -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:
+3 -1
View File
@@ -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`
+28
View File
@@ -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)
@@ -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"
+30
View File
@@ -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