Skip to content

Commit 03ec870

Browse files
Add USE_VENDORED_JSON option to use the system nlohmann_json (fixes #959) (#1235)
* Add USE_VENDORED_JSON option to use the system nlohmann_json (fixes #959) BT.CPP bundles nlohmann/json 3.11.3 and its public headers include it unconditionally. A user that also includes a system nlohmann/json gets two versions behind the same include guard: whichever comes first wins, and the result is mismatched types or link errors (#959). With -DUSE_VENDORED_JSON=OFF the library uses find_package(nlohmann_json 3.10): - the public headers include <nlohmann/json.hpp> when BTCPP_SYSTEM_JSON is defined. The library exports that definition together with the nlohmann_json target (CMake config and ament), so its users see the same version it was built with; - the bundled header is not installed: a user that bypasses the CMake target (plain include dirs, Makefiles, Bazel) fails to compile, instead of silently mixing two versions; - the tests get nlohmann::json from the BT.CPP headers, like any user, instead of including the bundled copy directly. The default (ON) is unchanged: it needs no new definition and the headers preprocess to the same code, so the API and ABI are the same. nlohmann::json is part of the public API, so an OFF build has a different ABI than the default one: everything linking it must use the same nlohmann_json. A new CI job builds and tests OFF on Ubuntu 22.04 with apt's nlohmann_json 3.10.5, the oldest supported version. Supersedes #1080. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * CI: limit the system-json build to nproc jobs 'cmake --build --parallel' without a number runs an unbounded 'make -j' with the default generator: the runner ran out of memory and was shut down. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 62c4bb4 commit 03ec870

11 files changed

Lines changed: 70 additions & 5 deletions

File tree

‎.github/workflows/cmake_ubuntu.yml‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,27 @@ jobs:
5050
- name: run test (Linux)
5151
run: ctest --test-dir build/${{env.BUILD_TYPE}}
5252

53+
# USE_VENDORED_JSON=OFF, with the oldest supported nlohmann_json (3.10.5 on 22.04)
54+
system-json:
55+
runs-on: ubuntu-22.04
56+
57+
steps:
58+
- uses: actions/checkout@v7
59+
60+
- name: Install dependencies
61+
run: |
62+
sudo apt-get update
63+
sudo apt-get install -y nlohmann-json3-dev libzmq3-dev libsqlite3-dev libgtest-dev
64+
65+
- name: Configure CMake
66+
run: cmake -B build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DUSE_VENDORED_JSON=OFF
67+
68+
- name: Build
69+
run: cmake --build build --parallel $(nproc)
70+
71+
- name: run test
72+
run: ctest --test-dir build --output-on-failure
73+
5374
coverage:
5475
runs-on: ubuntu-24.04
5576

‎CMakeLists.txt‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ option(FORCE_STATIC_LINKING "Force static linking of all dependencies" OFF)
2525

2626
option(USE_VENDORED_CPPZMQ "Use the bundled version of cppzmq" ON)
2727
option(USE_VENDORED_FLATBUFFERS "Use the bundled version of flatbuffers" ON)
28+
option(USE_VENDORED_JSON "Use the bundled version of nlohmann/json" ON)
2829
option(USE_VENDORED_MINICORO "Use the bundled version of minicoro" ON)
2930
option(USE_VENDORED_MINITRACE "Use the bundled version of minitrace" ON)
3031

@@ -133,6 +134,10 @@ else()
133134
find_package(flatbuffers REQUIRED)
134135
endif()
135136

137+
if(NOT USE_VENDORED_JSON)
138+
find_package(nlohmann_json 3.10 REQUIRED)
139+
endif()
140+
136141
if(USE_VENDORED_MINICORO)
137142
add_subdirectory(3rdparty/minicoro)
138143
else()
@@ -259,6 +264,12 @@ target_include_directories(${BTCPP_LIBRARY}
259264

260265
target_compile_definitions(${BTCPP_LIBRARY} PUBLIC BTCPP_LIBRARY_VERSION="${PROJECT_VERSION}")
261266

267+
if(NOT USE_VENDORED_JSON)
268+
# The public headers include <nlohmann/json.hpp> instead of the bundled copy
269+
target_compile_definitions(${BTCPP_LIBRARY} PUBLIC BTCPP_SYSTEM_JSON)
270+
target_link_libraries(${BTCPP_LIBRARY} PUBLIC nlohmann_json::nlohmann_json)
271+
endif()
272+
262273
target_compile_features(${BTCPP_LIBRARY} PUBLIC cxx_std_17)
263274

264275
if(MSVC)
@@ -327,8 +338,14 @@ INSTALL(TARGETS ${BTCPP_LIBRARY}
327338
INCLUDES DESTINATION ${BTCPP_INCLUDE_DESTINATION}
328339
)
329340

341+
if(NOT USE_VENDORED_JSON)
342+
# Don't install the bundled copy: a user that doesn't get BTCPP_SYSTEM_JSON
343+
# must fail to compile, rather than mix two versions of nlohmann::json
344+
set(BTCPP_INSTALL_EXCLUDE REGEX "contrib/json\\.hpp$" EXCLUDE)
345+
endif()
346+
330347
INSTALL( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/
331348
DESTINATION ${BTCPP_INCLUDE_DESTINATION}
332-
FILES_MATCHING PATTERN "*.h*")
349+
FILES_MATCHING PATTERN "*.h*" ${BTCPP_INSTALL_EXCLUDE})
333350

334351
export_btcpp_package()

‎README.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ cmake -S . -B build_release
7979
cmake --build build_release --parallel
8080
```
8181

82+
BT.CPP includes its own copy of [nlohmann/json](https://github.com/nlohmann/json).
83+
To use the one installed in your system instead (version 3.10 or newer), add `-DUSE_VENDORED_JSON=OFF`.
84+
Since `nlohmann::json` is part of the public API, everything that links BT.CPP must then be
85+
compiled with that same version.
86+
8287
If you want to build in a [pixi](https://pixi.sh/) project (conda virtual environment).
8388
```
8489
pixi run build

‎cmake/Config.cmake.in‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
@PACKAGE_INIT@
22

3+
if(NOT "@USE_VENDORED_JSON@")
4+
include(CMakeFindDependencyMacro)
5+
find_dependency(nlohmann_json 3.10)
6+
endif()
7+
38
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
49

510
set(@PROJECT_NAME@_TARGETS "BT::@PROJECT_NAME@")

‎cmake/ament_build.cmake‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ set( BTCPP_EXTRA_LIBRARIES
1414
)
1515

1616
ament_export_dependencies(ament_index_cpp)
17+
if(NOT USE_VENDORED_JSON)
18+
ament_export_dependencies(nlohmann_json)
19+
endif()
1720

1821
# The ROS build farm (bloom/debhelper) configures with
1922
# -DCMAKE_INSTALL_LIBDIR=lib/<multiarch-triplet>, but ament tooling

‎include/behaviortree_cpp/blackboard.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
#pragma once
22

33
#include "behaviortree_cpp/basic_types.h"
4+
#ifdef BTCPP_SYSTEM_JSON
5+
#include <nlohmann/json.hpp>
6+
#else
47
#include "behaviortree_cpp/contrib/json.hpp"
8+
#endif
59
#include "behaviortree_cpp/exceptions.h"
610
#include "behaviortree_cpp/utils/locked_reference.hpp"
711
#include "behaviortree_cpp/utils/polymorphic_cast_registry.hpp"

‎include/behaviortree_cpp/bt_factory.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@
1515
#define BT_FACTORY_H
1616

1717
#include "behaviortree_cpp/behavior_tree.h"
18+
#ifdef BTCPP_SYSTEM_JSON
19+
#include <nlohmann/json.hpp>
20+
#else
1821
#include "behaviortree_cpp/contrib/json.hpp"
22+
#endif
1923
#include "behaviortree_cpp/contrib/magic_enum.hpp"
2024
#include "behaviortree_cpp/utils/polymorphic_cast_registry.hpp"
2125

‎include/behaviortree_cpp/json_export.h‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@
33
#include "behaviortree_cpp/basic_types.h"
44
#include "behaviortree_cpp/utils/safe_any.hpp"
55

6-
// Use the version nlohmann::json embedded in BT.CPP
6+
// Use the version of nlohmann::json embedded in BT.CPP,
7+
// or the system one if BT.CPP was built with USE_VENDORED_JSON=OFF
8+
#ifdef BTCPP_SYSTEM_JSON
9+
#include <nlohmann/json.hpp>
10+
#else
711
#include "behaviortree_cpp/contrib/json.hpp"
12+
#endif
813

914
namespace BT
1015
{

‎include/behaviortree_cpp/loggers/groot2_protocol.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
#pragma once
22

33
#include "behaviortree_cpp/basic_types.h"
4+
#ifdef BTCPP_SYSTEM_JSON
5+
#include <nlohmann/json.hpp>
6+
#else
47
#include "behaviortree_cpp/contrib/json.hpp"
8+
#endif
59

610
#include <array>
711
#include <condition_variable>

‎tests/groot2_test_utils.hpp‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include <behaviortree_cpp/loggers/groot2_protocol.h>
1111
#include <behaviortree_cpp/loggers/groot2_publisher.h>
1212

13-
#include <behaviortree_cpp/contrib/json.hpp>
1413
#include <zmq_addon.hpp>
1514

1615
namespace Groot2Test

0 commit comments

Comments
 (0)