Compare commits

..
Author SHA1 Message Date
Niels LohmannandDylan Baker ad307af626 Install CMake package config files with Meson, and add Meson options
Squashed onto develop from:
- Install CMake package config files with Meson
- meson: Indent code inside an if block
- meson: set a minimum Meson version
- meson: use `override_dependency()` to set dependencies
- meson: use `install_subdir` for headers
- meson: set the C++ standard to C++11
- meson: handle single header and multiheader the same way CMake does
- meson: add support for the GlobalUDLs option
- meson: add support for the ImplictConversions option
- Add meson information to FILES.md
- Complete the Meson options and match CMake's compile definitions
- Add the JSON_* definitions to the CMake pkg-config file
- Document the Meson options and check them in CI
- Fix the Meson CMake target for includedir or datadir outside the prefix
- Avoid //include in Meson-generated CMake target for prefix /
- Add DisableTupleReferenceConversion to Meson and the CMake pkg-config file
- Check in CI that Meson and pkg-config offer the CMake options
- Remove accidentally committed Python bytecode

Co-authored-by: Dylan Baker <dylan@pnwbakers.com>
Signed-off-by: Dylan Baker <dylan@pnwbakers.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-06 07:26:56 +02:00
21 changed files with 533 additions and 137 deletions
-35
View File
@@ -71,38 +71,3 @@ jobs:
run: cmake --build build --parallel 10 run: cmake --build build --parallel 10
- name: Test - name: Test
run: cd build ; ctest -j 10 --output-on-failure run: cd build ; ctest -j 10 --output-on-failure
swiftpm:
runs-on: macos-15
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Check that Package.swift resolves without a deprecation warning
run: swift package dump-package
- name: Build the SwiftPM documentation example against this checkout
run: |
mkdir -p /tmp/json-swiftpm-consumer/Sources/MyLibrary
cp docs/mkdocs/docs/integration/swift/example.cpp /tmp/json-swiftpm-consumer/Sources/MyLibrary/example.cpp
cat > /tmp/json-swiftpm-consumer/Package.swift << EOF
// swift-tools-version: 5.9
import PackageDescription
let package = Package(
name: "MyPackage",
dependencies: [
.package(path: "${{ github.workspace }}")
],
targets: [
.target(
name: "MyLibrary",
dependencies: [
.product(name: "json", package: "json")
],
publicHeadersPath: "."
)
]
)
EOF
cd /tmp/json-swiftpm-consumer
swift build
+42
View File
@@ -31,6 +31,48 @@ jobs:
- name: Build - name: Build
run: cmake --build build --target ci_test_gcc 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: Check that Meson and pkg-config offer the CMake options
run: make check_build_options
- 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
- name: Install with Meson and non-default options
run: |
meson setup build-meson-options --prefix=${{ github.workspace }}/install-options -DMultipleHeaders=true -DDiagnostics=true -DGlobalUDLs=false -DDisableTupleReferenceConversion=true
meson install -C build-meson-options
- name: Check that the options reach the installed files
run: |
test -d install-options/include/nlohmann/detail
cflags=$(PKG_CONFIG_PATH=${{ github.workspace }}/install-options/share/pkgconfig pkg-config --cflags nlohmann_json)
echo "$cflags"
echo "$cflags" | grep -q -- '-DJSON_DIAGNOSTICS=1'
echo "$cflags" | grep -q -- '-DJSON_USE_GLOBAL_UDLS=0'
echo "$cflags" | grep -q -- '-DJSON_DISABLE_TUPLE_REFERENCE_CONVERSION=1'
grep -q 'JSON_USE_GLOBAL_UDLS=0;JSON_DISABLE_TUPLE_REFERENCE_CONVERSION=1;JSON_DIAGNOSTICS=1' install-options/share/cmake/nlohmann_json/nlohmann_jsonTargets.cmake
cmake -S tests/cmake_import/project -B build-import-options -DCMAKE_PREFIX_PATH=${{ github.workspace }}/install-options
cmake --build build-import-options
- name: Install with Meson and the include directory outside the prefix
run: |
meson setup build-meson-split --prefix=${{ github.workspace }}/install-split --includedir=${{ github.workspace }}/install-split-dev/include
meson install -C build-meson-split
cmake -S tests/cmake_import/project -B build-import-split -DCMAKE_PREFIX_PATH=${{ github.workspace }}/install-split
cmake --build build-import-split
ci_infer: ci_infer:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
+36
View File
@@ -0,0 +1,36 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: json
Upstream-Contact: Niels Lohmann <mail@nlohmann.me>
Source: https://github.com/nlohmann/json
Files: *
Copyright: 2013-2026 Niels Lohmann <https://nlohmann.me>
License: MIT
Files: include/nlohmann/thirdparty/hedley.hpp
Copyright: 2016-2021 Evan Nemerson <evan@nemerson.com>
License: CC0
Files: include/nlohmann/detail/meta/cpp_future.hpp
Copyright: 2013-2026 Niels Lohmann <https://nlohmann.me> and 2018 The Abseil Authors
License: MIT AND Apache-2.0
Files: tests/thirdparty/doctest/*
Copyright: 2016-2023 Viktor Kirilov
License: MIT
Files: tests/thirdparty/fifo_map/*
Copyright: 2015-2017 Niels Lohmann
License: MIT
Files: tests/thirdparty/imapdl/*
Copyright: 2017 Georg Sauthoff <mail@gms.tf>
License: GPL-3.0-only
Files: tools/amalgamate/*
Copyright: 2012 Erik Edlund <erik.edlund@32767.se>
License: BSD-3-Clause
Files: tools/gdb_pretty_printer/*
Copyright: 2020 Hannes Domani <https://github.com/ssbssa>
License: MIT
-1
View File
@@ -80,7 +80,6 @@ cc_library(
name = "singleheader-json", name = "singleheader-json",
hdrs = [ hdrs = [
"single_include/nlohmann/json.hpp", "single_include/nlohmann/json.hpp",
"single_include/nlohmann/json_fwd.hpp",
], ],
includes = ["single_include"], includes = ["single_include"],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
+1 -1
View File
@@ -10,5 +10,5 @@ title: "JSON for Modern C++"
version: 3.12.0 version: 3.12.0
date-released: 2025-04-07 date-released: 2025-04-07
license: MIT license: MIT
repository-code: "https://github.com/nlohmann/json" repository-code: "https://github.com/nlohmann"
url: https://json.nlohmann.me url: https://json.nlohmann.me
+28 -5
View File
@@ -42,11 +42,8 @@ endif()
## OPTIONS ## OPTIONS
## ##
# Build the tests by default only for the main project and only if the tests
# directory exists (the release archive json.tar.xz does not contain it).
# VERSION_GREATER_EQUAL is not available in older CMake (< 3.7) # VERSION_GREATER_EQUAL is not available in older CMake (< 3.7)
if(${MAIN_PROJECT} AND (${CMAKE_VERSION} VERSION_EQUAL 3.13 OR ${CMAKE_VERSION} VERSION_GREATER 3.13) if(${MAIN_PROJECT} AND (${CMAKE_VERSION} VERSION_EQUAL 3.13 OR ${CMAKE_VERSION} VERSION_GREATER 3.13))
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/CMakeLists.txt")
set(JSON_BuildTests_INIT ON) set(JSON_BuildTests_INIT ON)
else() else()
set(JSON_BuildTests_INIT OFF) set(JSON_BuildTests_INIT OFF)
@@ -189,7 +186,33 @@ if (MSVC)
) )
endif() endif()
# Install a pkg-config file, so other tools can find this. # Install a pkg-config file, so other tools can find this. It carries the same
# compile definitions as the target above.
set(NLOHMANN_JSON_PKGCONFIG_CFLAGS "")
if (NOT JSON_GlobalUDLs)
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_USE_GLOBAL_UDLS=0")
endif()
if (NOT JSON_ImplicitConversions)
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_USE_IMPLICIT_CONVERSIONS=0")
endif()
if (JSON_DisableEnumSerialization)
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_DISABLE_ENUM_SERIALIZATION=1")
endif()
if (JSON_DisableTupleReferenceConversion)
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_DISABLE_TUPLE_REFERENCE_CONVERSION=1")
endif()
if (JSON_Diagnostics)
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_DIAGNOSTICS=1")
endif()
if (JSON_Diagnostic_Positions)
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_DIAGNOSTIC_POSITIONS=1")
endif()
if (JSON_LegacyDiscardedValueComparison)
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON=1")
endif()
if (JSON_StrictNulHandling)
string(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -DJSON_STRICT_NUL_HANDLING=1")
endif()
configure_file( configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/pkg-config.pc.in" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/pkg-config.pc.in"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
+27 -5
View File
@@ -196,19 +196,19 @@ Further documentation:
## REUSE ## REUSE
### `REUSE.toml` ### `.reuse/dep5`
The file defines the licenses of certain third-party components in the repository. The root `Makefile` contains a target `reuse` that checks for compliance. The file defines the licenses of certain third-party components in the repository. The root `Makefile` contains a target `reuse` that checks for compliance.
Further documentation: Further documentation:
- [REUSE.toml](https://reuse.software/spec-3.3/#reusetoml) - [DEP5](https://reuse.software/spec-3.2/#dep5-deprecated)
- [reuse command-line tool](https://pypi.org/project/reuse/) - [reuse command-line tool](https://pypi.org/project/reuse/)
- [documentation of linting](https://reuse.readthedocs.io/en/stable/man/reuse-lint.html) - [documentation of linting](https://reuse.readthedocs.io/en/stable/man/reuse-lint.html)
- [REUSE](http://reuse.software) - [REUSE](http://reuse.software)
> [!IMPORTANT] > [!IMPORTANT]
> The filename `REUSE.toml` is predetermined by REUSE. Alternatively, a `.reuse/dep5` file (deprecated) can be used. > The filename `.reuse/dep5` is predetermined by REUSE. Alternatively, a `REUSE.toml` file can be used.
### `.reuse/templates` ### `.reuse/templates`
@@ -249,9 +249,31 @@ make BUILD.bazel
The "Check amalgamation" workflow fails if the file is out of date. The "Check amalgamation" workflow fails if the file is out of date.
### `meson.build` ### `meson.build` and `meson_options.txt`
The build definition for the [Meson](https://mesonbuild.com) build system. Meson build definitions suitable for use as a subproject ("wrap" in Meson terminology).
Projects wishing to use the wrap can execute:
```sh
meson wrap install nlohmann_json
```
Which allows Meson to build from source when a system provided dependency isn't available.
To build directly:
```sh
meson setup builddir
ninja -C builddir
```
`meson_options.txt` defines the options, which mirror the CMake options that change the library's target (for example,
`-DDiagnostics=true`). Meson requires this file next to `meson.build`, so it is also part of `include.zip`. `make check_build_options`
([`tools/check_build_options`](tools/check_build_options/README.md)) checks in CI that both files and the pkg-config files
stay in sync with the CMake options.
When installing, `meson.build` installs the headers, a pkg-config file, and 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` ### `Package.swift`
+8 -7
View File
@@ -1,4 +1,4 @@
.PHONY: pretty clean ChangeLog.md release update_hedley update_hedley_undef BUILD.bazel natvis macro_builder_check .PHONY: pretty clean ChangeLog.md release update_hedley update_hedley_undef BUILD.bazel natvis macro_builder_check check_build_options
########################################################################## ##########################################################################
# configuration # configuration
@@ -7,9 +7,6 @@
# find GNU sed to use `-i` parameter # find GNU sed to use `-i` parameter
SED:=$(shell command -v gsed || which sed) SED:=$(shell command -v gsed || which sed)
# find GNU tar to use `--sort` and `--pax-option` parameters
TAR:=$(shell command -v gtar || which tar)
########################################################################## ##########################################################################
# source files # source files
@@ -127,6 +124,10 @@ macro_builder_check:
diff "$$TMPDIR/paste.hpp" "$$TMPDIR/paste_actual.hpp" || (echo "===================================================================\n $(MACRO_SCOPE_HPP) (NLOHMANN_JSON_EXPAND..NLOHMANN_JSON_DOUBLE_PASTE63) is out of date!\n Regenerate it, see tools/macro_builder/README.md.\n===================================================================" ; exit 1); \ diff "$$TMPDIR/paste.hpp" "$$TMPDIR/paste_actual.hpp" || (echo "===================================================================\n $(MACRO_SCOPE_HPP) (NLOHMANN_JSON_EXPAND..NLOHMANN_JSON_DOUBLE_PASTE63) is out of date!\n Regenerate it, see tools/macro_builder/README.md.\n===================================================================" ; exit 1); \
diff "$$TMPDIR/type_body.hpp" "$$TMPDIR/type_body_actual.hpp" || (echo "===================================================================\n $(MACRO_SCOPE_HPP) (NLOHMANN_JSON_TYPE_BODY) is out of date!\n Regenerate it, see tools/macro_builder/README.md.\n===================================================================" ; exit 1) diff "$$TMPDIR/type_body.hpp" "$$TMPDIR/type_body_actual.hpp" || (echo "===================================================================\n $(MACRO_SCOPE_HPP) (NLOHMANN_JSON_TYPE_BODY) is out of date!\n Regenerate it, see tools/macro_builder/README.md.\n===================================================================" ; exit 1)
# check that the Meson build and the pkg-config files offer the options of the CMake target
check_build_options:
python3 tools/check_build_options/check_build_options.py .
# check if file single_include/nlohmann/json.hpp has been amalgamated from the nlohmann sources # check if file single_include/nlohmann/json.hpp has been amalgamated from the nlohmann sources
check-amalgamation: check-amalgamation:
@mv $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~ @mv $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~
@@ -177,14 +178,14 @@ ChangeLog.md:
# archive is created according to the advices of <https://reproducible-builds.org/docs/archives/>. # archive is created according to the advices of <https://reproducible-builds.org/docs/archives/>.
json.tar.xz: json.tar.xz:
mkdir json mkdir json
rsync -R $(shell find LICENSE.MIT nlohmann_json.natvis CMakeLists.txt cmake/*.in include single_include src/modules -type f) json rsync -R $(shell find LICENSE.MIT nlohmann_json.natvis CMakeLists.txt cmake/*.in include single_include -type f) json
$(TAR) --sort=name --mtime="@$(shell git log -1 --pretty=%ct)" --owner=0 --group=0 --numeric-owner --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime --create --file - json | xz --compress -9e --threads=2 - > json.tar.xz gtar --sort=name --mtime="@$(shell git log -1 --pretty=%ct)" --owner=0 --group=0 --numeric-owner --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime --create --file - json | xz --compress -9e --threads=2 - > json.tar.xz
rm -fr json rm -fr json
# We use `-X` to make the resulting ZIP file reproducible, see # We use `-X` to make the resulting ZIP file reproducible, see
# <https://content.pivotal.io/blog/barriers-to-deterministic-reproducible-zip-files>. # <https://content.pivotal.io/blog/barriers-to-deterministic-reproducible-zip-files>.
include.zip: BUILD.bazel include.zip: BUILD.bazel
zip -9 --recurse-paths -X include.zip $(SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) BUILD.bazel MODULE.bazel meson.build LICENSE.MIT zip -9 --recurse-paths -X include.zip $(SRCS) $(AMALGAMATED_FILE) $(AMALGAMATED_FWD_FILE) $(AMALGAMATED_LITERALS_FILE) BUILD.bazel MODULE.bazel meson.build meson_options.txt LICENSE.MIT
# Create the files for a release and add signatures and hashes. # Create the files for a release and add signatures and hashes.
release: include.zip json.tar.xz release: include.zip json.tar.xz
+1 -1
View File
@@ -6,7 +6,7 @@ import PackageDescription
let package = Package( let package = Package(
name: "nlohmann-json", name: "nlohmann-json",
platforms: [ platforms: [
.iOS(.v12), .macOS(.v10_13), .tvOS(.v12), .watchOS(.v9), .visionOS(.v1) .iOS(.v12), .macOS(.v10_13), .tvOS(.v12), .watchOS(.v4), .visionOS(.v1)
], ],
products: [ products: [
.library(name: "json", targets: ["json"]) .library(name: "json", targets: ["json"])
+10 -13
View File
@@ -1202,18 +1202,15 @@ language bindings, format converters, and the like. See the curated [Ecosystem](
Though it's 2026 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work: Though it's 2026 already, the support for C++11 is still a bit sparse. Currently, the following compilers are known to work:
- GCC 4.8 - 16.2 (and possibly later) - GCC 4.8 - 14.2 (and possibly later)
- Clang 3.4 - 22.1 (and possibly later) - Clang 3.4 - 21.0 (and possibly later)
- Apple Clang 15.0 - 21.0 (and possibly later) - Apple Clang 9.1 - 16.0 (and possibly later)
- Intel C++ Compiler Classic (icpc) 2021.10 - Intel C++ Compiler 17.0.2 (and possibly later)
- Intel oneAPI DPC++/C++ Compiler (icpx) 2025.3 (and possibly later) - Nvidia CUDA Compiler 11.0.221 (and possibly later)
- NVIDIA CUDA Compiler (nvcc) 11.8 - 12.6 (and possibly later) - Microsoft Visual C++ 2015 / Build Tools 14.0.25123.0 (and possibly later)
- NVIDIA HPC SDK C++ Compiler (nvc++) 25.5 (and possibly later) - Microsoft Visual C++ 2017 / Build Tools 15.5.180.51428 (and possibly later)
- Microsoft Visual C++ 2015 / MSVC 19.0 (and possibly later) - Microsoft Visual C++ 2019 / Build Tools 16.3.1+1def00d3d (and possibly later)
- Microsoft Visual C++ 2017 / MSVC 19.16 (and possibly later) - Microsoft Visual C++ 2022 / Build Tools 19.30.30709.0 (and possibly later)
- Microsoft Visual C++ 2019 / MSVC 19.29 (and possibly later)
- Microsoft Visual C++ 2022 / MSVC 19.44 (and possibly later)
- Microsoft Visual C++ 2026 / MSVC 19.51 (and possibly later)
I would be happy to learn about other compilers/versions. I would be happy to learn about other compilers/versions.
@@ -1404,7 +1401,7 @@ The library is compliant to version 3.3 of the [**REUSE specification**](https:/
- Every source file contains an SPDX copyright header. - Every source file contains an SPDX copyright header.
- The full text of all licenses used in the repository can be found in the `LICENSES` folder. - The full text of all licenses used in the repository can be found in the `LICENSES` folder.
- File `REUSE.toml` contains an overview of all files' copyrights and licenses. - File `.reuse/dep5` contains an overview of all files' copyrights and licenses.
- Run `pipx run reuse lint` to verify the project's REUSE compliance and `pipx run reuse spdx` to generate a SPDX SBOM. - Run `pipx run reuse lint` to verify the project's REUSE compliance and `pipx run reuse spdx` to generate a SPDX SBOM.
## Contact ## Contact
-52
View File
@@ -1,52 +0,0 @@
version = 1
SPDX-PackageName = "json"
SPDX-PackageSupplier = "Niels Lohmann <mail@nlohmann.me>"
SPDX-PackageDownloadLocation = "https://github.com/nlohmann/json"
[[annotations]]
path = "**"
precedence = "aggregate"
SPDX-FileCopyrightText = "2013-2026 Niels Lohmann <https://nlohmann.me>"
SPDX-License-Identifier = "MIT"
[[annotations]]
path = "include/nlohmann/thirdparty/hedley.hpp"
precedence = "aggregate"
SPDX-FileCopyrightText = "2016-2021 Evan Nemerson <evan@nemerson.com>"
SPDX-License-Identifier = "CC0"
[[annotations]]
path = "include/nlohmann/detail/meta/cpp_future.hpp"
precedence = "aggregate"
SPDX-FileCopyrightText = "2013-2026 Niels Lohmann <https://nlohmann.me> and 2018 The Abseil Authors"
SPDX-License-Identifier = "MIT AND Apache-2.0"
[[annotations]]
path = "tests/thirdparty/doctest/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "2016-2023 Viktor Kirilov"
SPDX-License-Identifier = "MIT"
[[annotations]]
path = "tests/thirdparty/fifo_map/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "2015-2017 Niels Lohmann"
SPDX-License-Identifier = "MIT"
[[annotations]]
path = "tests/thirdparty/imapdl/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "2017 Georg Sauthoff <mail@gms.tf>"
SPDX-License-Identifier = "GPL-3.0-only"
[[annotations]]
path = "tools/amalgamate/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "2012 Erik Edlund <erik.edlund@32767.se>"
SPDX-License-Identifier = "BSD-3-Clause"
[[annotations]]
path = "tools/gdb_pretty_printer/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "2020 Hannes Domani <https://github.com/ssbssa>"
SPDX-License-Identifier = "MIT"
+42
View File
@@ -0,0 +1,42 @@
# 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, the C++ standard, and the compile definitions of the options that
# differ from their defaults. Paths are computed relative to this file so that
# the installation can be relocated (e.g., into a sysroot), unless includedir or
# datadir is outside the prefix.
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)
# As in CMake's generated file: avoid "//include" for an installation to "/".
if(_IMPORT_PREFIX STREQUAL "/")
set(_IMPORT_PREFIX "")
endif()
add_library(@PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@ INTERFACE IMPORTED)
set_target_properties(@PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@ PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "@NLOHMANN_JSON_INCLUDE_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()
set(_NLOHMANN_JSON_COMPILE_DEFINITIONS "@NLOHMANN_JSON_COMPILE_DEFINITIONS@")
if(_NLOHMANN_JSON_COMPILE_DEFINITIONS)
set_target_properties(@PROJECT_NAME@::@NLOHMANN_JSON_TARGET_NAME@ PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "${_NLOHMANN_JSON_COMPILE_DEFINITIONS}"
)
endif()
unset(_NLOHMANN_JSON_COMPILE_DEFINITIONS)
unset(_IMPORT_PREFIX)
+1 -1
View File
@@ -4,4 +4,4 @@ includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
Name: @PROJECT_NAME@ Name: @PROJECT_NAME@
Description: JSON for Modern C++ Description: JSON for Modern C++
Version: @PROJECT_VERSION@ Version: @PROJECT_VERSION@
Cflags: -I${includedir} Cflags: -I${includedir}@NLOHMANN_JSON_PKGCONFIG_CFLAGS@
-1
View File
@@ -48,7 +48,6 @@ cc_library(
name = "singleheader-json", name = "singleheader-json",
hdrs = [ hdrs = [
"single_include/nlohmann/json.hpp", "single_include/nlohmann/json.hpp",
"single_include/nlohmann/json_fwd.hpp",
], ],
includes = ["single_include"], includes = ["single_include"],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
+1 -1
View File
@@ -64,7 +64,7 @@ if(MODE STREQUAL "undef")
# recipe is self-contained and its output is byte-stable across reruns. # recipe is self-contained and its output is byte-stable across reruns.
# The embedded SPDX tags below are part of the *generated* file's # The embedded SPDX tags below are part of the *generated* file's
# content, not a REUSE header for this .cmake script itself (which is # content, not a REUSE header for this .cmake script itself (which is
# already covered by the blanket path = "**" rule in REUSE.toml) -- keep # already covered by the blanket "Files: *" rule in .reuse/dep5) -- keep
# them wrapped in REUSE-IgnoreStart/End so `reuse lint` does not try to # them wrapped in REUSE-IgnoreStart/End so `reuse lint` does not try to
# parse "MIT\n")" as this file's own SPDX-License-Identifier value. # parse "MIT\n")" as this file's own SPDX-License-Identifier value.
# REUSE-IgnoreStart # REUSE-IgnoreStart
+1 -1
View File
@@ -126,7 +126,7 @@ automatically download a release as a dependency at configure time.
### `JSON_BuildTests` ### `JSON_BuildTests`
Build the unit tests when [`BUILD_TESTING`](https://cmake.org/cmake/help/latest/command/enable_testing.html) is enabled. This option is `ON` by default if the library's CMake project is the top project and the `tests` directory exists (the release archive `json.tar.xz` does not contain it). That is, when integrating the library as described above, the test suite is not built unless explicitly switched on with this option. Build the unit tests when [`BUILD_TESTING`](https://cmake.org/cmake/help/latest/command/enable_testing.html) is enabled. This option is `ON` by default if the library's CMake project is the top project. That is, when integrating the library as described above, the test suite is not built unless explicitly switched on with this option.
### `JSON_CI` ### `JSON_CI`
@@ -125,10 +125,23 @@ meson wrap install nlohmann_json
Please see the Meson project for any issues regarding the packaging. 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 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](pkg-config.md) file is installed. To use it, have your build system require the which case a [pkg-config](pkg-config.md) file and the CMake package config files are installed. To use it, have your build system require
`nlohmann_json` pkg-config dependency. In Meson, it is preferred to use the the `nlohmann_json` pkg-config dependency, or use [`find_package(nlohmann_json)`](cmake.md#external) in CMake. In Meson,
[`dependency()`](https://mesonbuild.com/Reference-manual.html#dependency) object with a subproject fallback, rather than it is preferred to use the [`dependency()`](https://mesonbuild.com/Reference-manual.html#dependency) object with a
using the subproject directly. subproject fallback, rather than using the subproject directly.
The options that change the library's configuration are available in Meson as well, named like the
[CMake options](cmake.md#cmake-options) without the `JSON_` prefix: `MultipleHeaders`, `GlobalUDLs`,
`ImplicitConversions`, `DisableEnumSerialization`, `DisableTupleReferenceConversion`, `Diagnostics`,
`Diagnostic_Positions`, `LegacyDiscardedValueComparison`, and `StrictNulHandling`. They have the same defaults as in CMake, except that
`MultipleHeaders` is `false`. Set them with `-D` when setting up the build, or with the subproject name as prefix when
the library is used as a subproject:
```shell
meson setup build -Dnlohmann_json:Diagnostics=true
```
The resulting compile definitions are part of the Meson dependency, the pkg-config file, and the CMake target.
??? example "Example: Wrap" ??? example "Example: Wrap"
+99 -9
View File
@@ -2,24 +2,114 @@ project('nlohmann_json',
'cpp', 'cpp',
version : '3.12.0', version : '3.12.0',
license : 'MIT', license : 'MIT',
meson_version : '>= 0.64',
default_options: ['cpp_std=c++11'],
) )
if get_option('MultipleHeaders')
incdir = 'include'
else
incdir = 'single_include'
endif
# The same compile definitions as the CMake target (see target_compile_definitions
# in CMakeLists.txt): only an option that differs from its default adds one.
json_defines = []
if not get_option('GlobalUDLs')
json_defines += 'JSON_USE_GLOBAL_UDLS=0'
endif
if not get_option('ImplicitConversions')
json_defines += 'JSON_USE_IMPLICIT_CONVERSIONS=0'
endif
if get_option('DisableEnumSerialization')
json_defines += 'JSON_DISABLE_ENUM_SERIALIZATION=1'
endif
if get_option('DisableTupleReferenceConversion')
json_defines += 'JSON_DISABLE_TUPLE_REFERENCE_CONVERSION=1'
endif
if get_option('Diagnostics')
json_defines += 'JSON_DIAGNOSTICS=1'
endif
if get_option('Diagnostic_Positions')
json_defines += 'JSON_DIAGNOSTIC_POSITIONS=1'
endif
if get_option('LegacyDiscardedValueComparison')
json_defines += 'JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON=1'
endif
if get_option('StrictNulHandling')
json_defines += 'JSON_STRICT_NUL_HANDLING=1'
endif
cpp_args = []
foreach define : json_defines
cpp_args += '-D' + define
endforeach
nlohmann_json_dep = declare_dependency( nlohmann_json_dep = declare_dependency(
include_directories: include_directories('single_include') compile_args: cpp_args,
include_directories: include_directories(incdir)
) )
meson.override_dependency('nlohmann_json', nlohmann_json_dep)
# The multi-header version under the name earlier versions of this file used
nlohmann_json_multiple_headers = declare_dependency( nlohmann_json_multiple_headers = declare_dependency(
compile_args: cpp_args,
include_directories: include_directories('include') include_directories: include_directories('include')
) )
if not meson.is_subproject() if not meson.is_subproject()
install_headers('single_include/nlohmann/json.hpp', subdir: 'nlohmann') install_subdir(
install_headers('single_include/nlohmann/json_fwd.hpp', subdir: 'nlohmann') incdir / 'nlohmann',
install_headers('single_include/nlohmann/json_literals.hpp', subdir: 'nlohmann') install_dir: get_option('includedir'),
install_tag: 'devel',
)
pkgc = import('pkgconfig') pkgc = import('pkgconfig')
pkgc.generate(name: 'nlohmann_json', pkgc.generate(name: 'nlohmann_json',
version: meson.project_version(), version: meson.project_version(),
description: 'JSON for Modern C++' description: 'JSON for Modern C++',
) extra_cflags: cpp_args,
install_dir: get_option('datadir') / 'pkgconfig',
)
# CMake package config files, so that find_package(nlohmann_json) works. The
# include directory is given relative to the config files, so that the
# installation can be relocated. This is not possible if includedir or datadir
# is an absolute path outside the prefix (e.g., with the separate outputs of
# Nix); then the absolute include directory is used, as CMake does.
fs = import('fs')
cmake_install_dir = get_option('datadir') / 'cmake' / meson.project_name()
cmake_to_prefix = []
if fs.is_absolute(get_option('includedir')) or fs.is_absolute(cmake_install_dir)
cmake_include_dir = (get_option('prefix') / get_option('includedir')).replace('\\', '/')
else
foreach component : cmake_install_dir.split('/')
cmake_to_prefix += '..'
endforeach
cmake_include_dir = '${_IMPORT_PREFIX}/' + get_option('includedir')
endif
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_DIR', cmake_include_dir)
cmake_conf.set('NLOHMANN_JSON_CONFIG_TO_PREFIX', '/'.join(cmake_to_prefix))
cmake_conf.set('NLOHMANN_JSON_COMPILE_DEFINITIONS', ';'.join(json_defines))
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 endif
+54
View File
@@ -0,0 +1,54 @@
option(
'MultipleHeaders',
type: 'boolean',
value: false,
description: 'Use non-amalgamated version of the library',
)
option(
'GlobalUDLs',
type: 'boolean',
value: true,
description: 'Place user-defined string literals in the global namespace',
)
option(
'ImplicitConversions',
type: 'boolean',
value: true,
description: 'Enable implicit conversions',
)
option(
'DisableEnumSerialization',
type: 'boolean',
value: false,
description: 'Disable default integer enum serialization',
)
option(
'DisableTupleReferenceConversion',
type: 'boolean',
value: false,
description: 'Disable conversion from a one-element tuple of a JSON reference',
)
option(
'Diagnostics',
type: 'boolean',
value: false,
description: 'Use extended diagnostic messages',
)
option(
'Diagnostic_Positions',
type: 'boolean',
value: false,
description: 'Enable diagnostic positions',
)
option(
'LegacyDiscardedValueComparison',
type: 'boolean',
value: false,
description: 'Enable legacy discarded value comparison',
)
option(
'StrictNulHandling',
type: 'boolean',
value: false,
description: 'Enable strict NUL-byte handling',
)
+21
View File
@@ -0,0 +1,21 @@
# check_build_options
Checks that the Meson build and the pkg-config files offer the same options as the CMake target, so that a new CMake
option is not forgotten in one of them.
The compile definitions of the CMake target (`target_compile_definitions` in [`CMakeLists.txt`](../../CMakeLists.txt))
are the reference. When you add an option there, also add it to
- the pkg-config block in `CMakeLists.txt` (`NLOHMANN_JSON_PKGCONFIG_CFLAGS`),
- [`meson_options.txt`](../../meson_options.txt), named without the `JSON_` prefix and with the same default,
- [`meson.build`](../../meson.build) (`json_defines`), and
- the list of Meson options in
[`docs/mkdocs/docs/integration/package_managers.md`](../../docs/mkdocs/docs/integration/package_managers.md).
Run the check with
```shell
make check_build_options
```
It needs only Python 3 and runs in the `ci_meson_install` CI job.
+144
View File
@@ -0,0 +1,144 @@
#!/usr/bin/env python3
"""Check that the Meson build and the pkg-config files offer the CMake options.
The compile definitions of the CMake target (target_compile_definitions in
CMakeLists.txt) are the reference. For every option used there, the script
checks that
- the CMake pkg-config file adds the same definition under the same condition,
- meson_options.txt has a boolean option of the same name without the "JSON_"
prefix and with the same default,
- meson.build adds the same definition under the same condition, and
- the Meson section of the package manager documentation lists the option.
Meson's MultipleHeaders option selects the include directory and adds no
definition; it is the only Meson option without a definition.
"""
import argparse
import os
import re
import sys
REPO_ROOT = os.path.normpath(os.path.join(sys.path[0], '..', '..'))
DOCS = os.path.join('docs', 'mkdocs', 'docs', 'integration', 'package_managers.md')
# Meson options that add no compile definition, with their default
MESON_ONLY = {'MultipleHeaders': 'false'}
def read(root, path):
with open(os.path.join(root, path), encoding='utf-8') as f:
return f.read()
def cmake_target_definitions(cmake):
"""Return {option: (definition, add_if_on)} from target_compile_definitions."""
block = re.search(r'target_compile_definitions\(\s*\$\{NLOHMANN_JSON_TARGET_NAME\}\s*INTERFACE(.*?)\n\)', cmake, re.S)
if not block:
sys.exit('CMakeLists.txt: target_compile_definitions of the target not found')
result = {}
for line in block.group(1).split('\n'):
line = line.strip()
if not line:
continue
m = re.fullmatch(r'\$<\$<NOT:\$<BOOL:\$\{JSON_(\w+)\}>>:(\w+=\w+)>', line)
if m:
result[m.group(1)] = (m.group(2), False)
continue
m = re.fullmatch(r'\$<\$<BOOL:\$\{JSON_(\w+)\}>:(\w+=\w+)>', line)
if m:
result[m.group(1)] = (m.group(2), True)
continue
sys.exit(f'CMakeLists.txt: unexpected line in target_compile_definitions: {line}')
return result
def cmake_defaults(cmake):
"""Return {option: 'true'/'false'} for the option() calls of the form JSON_<name>."""
return {m.group(1): 'true' if m.group(2) == 'ON' else 'false'
for m in re.finditer(r'^option\(JSON_(\w+)\s+"[^"]*"\s+(ON|OFF)\)', cmake, re.M)}
def cmake_pkgconfig_definitions(cmake):
"""Return {option: (definition, add_if_on)} from the pkg-config block."""
return {m.group(2): (m.group(3), m.group(1) is None)
for m in re.finditer(r'if \((NOT )?JSON_(\w+)\)\s*\n\s*string\(APPEND NLOHMANN_JSON_PKGCONFIG_CFLAGS " -D(\w+=\w+)"\)', cmake)}
def meson_options(options):
"""Return {option: default} for the boolean options in meson_options.txt."""
result = {}
for block in re.findall(r'option\((.*?)\)', options, re.S):
name = re.search(r"'(\w+)'", block).group(1)
kind = re.search(r"type\s*:\s*'(\w+)'", block)
value = re.search(r'value\s*:\s*(\w+)', block)
result[name] = value.group(1) if kind and kind.group(1) == 'boolean' and value else None
return result
def meson_definitions(meson):
"""Return {option: (definition, add_if_on)} from meson.build."""
return {m.group(2): (m.group(3), m.group(1) is None)
for m in re.finditer(r"if (not )?get_option\('(\w+)'\)\s*\n\s*json_defines \+= '(\w+=\w+)'", meson)}
def describe(definition):
name, add_if_on = definition
return f'{name} if {"enabled" if add_if_on else "disabled"}'
def compare(errors, where, expected, actual):
for option, definition in expected.items():
if option not in actual:
errors.append(f'{where}: no definition for option {option} (expected {describe(definition)})')
elif actual[option] != definition:
errors.append(f'{where}: option {option} adds {describe(actual[option])}, expected {describe(definition)}')
for option in actual.keys() - expected.keys():
errors.append(f'{where}: definition for option {option}, which the CMake target does not have')
def main():
parser = argparse.ArgumentParser(description=__doc__.split('\n')[0])
parser.add_argument('root', nargs='?', default=REPO_ROOT, help='repository root (default: %(default)s)')
root = parser.parse_args().root
cmake = read(root, 'CMakeLists.txt')
reference = cmake_target_definitions(cmake)
defaults = cmake_defaults(cmake)
errors = []
compare(errors, 'CMakeLists.txt (pkg-config)', reference, cmake_pkgconfig_definitions(cmake))
compare(errors, 'meson.build', reference, meson_definitions(read(root, 'meson.build')))
options = meson_options(read(root, 'meson_options.txt'))
for option in reference:
if option not in defaults:
errors.append(f'CMakeLists.txt: no option(JSON_{option} ... ON|OFF)')
elif option not in options:
errors.append(f'meson_options.txt: option {option} missing')
elif options[option] != defaults[option]:
errors.append(f'meson_options.txt: option {option} must be boolean with value {defaults[option]} as in CMake')
for option, default in MESON_ONLY.items():
if options.get(option) != default:
errors.append(f'meson_options.txt: option {option} must be boolean with value {default}')
for option in options.keys() - reference.keys() - MESON_ONLY.keys():
errors.append(f'meson_options.txt: option {option} has no counterpart in the CMake target')
docs = read(root, DOCS)
for option in sorted(set(options) & (reference.keys() | MESON_ONLY.keys())):
if f'`{option}`' not in docs:
errors.append(f'{DOCS}: Meson option {option} not listed')
for error in errors:
print(error, file=sys.stderr)
if errors:
print('The Meson build and the pkg-config files must offer the options of the CMake target; see '
'tools/check_build_options/README.md.', file=sys.stderr)
return 1
print(f'OK: {len(reference)} options with compile definitions agree between CMake, pkg-config, and Meson.')
return 0
if __name__ == '__main__':
sys.exit(main())