From b8d70d6e5f44caf28be932857d87ba22aa0a7582 Mon Sep 17 00:00:00 2001 From: Griswald Brooks Date: Fri, 31 Jul 2026 12:54:11 -0400 Subject: [PATCH] fix: make bt4_picknik tools and vendored lexy disjoint from stock Issue #20928's rename gave the library, headers, and CMake config distinct names from stock upstream behaviortree_cpp, but two file sets were still shared or shareable: - bin/bt4_plugin_manifest (and bin/bt4_recorder, gated on ZMQ_FOUND) used stock's unscoped tool names, causing a real dpkg install conflict once both packages are installed in the same image. Renamed to bt4_picknik_plugin_manifest / bt4_picknik_recorder. - Vendored lexy installed its own headers, CMake config, and static lib unscoped. lexy is linked PRIVATE/BUILD_INTERFACE-only and its only consumer (src/script_parser.cpp) is compiled into this library; no installed public header transitively requires it. Disabled lexy's own LEXY_ENABLE_INSTALL option instead of reproducing its install rules under a scoped path. 208/208 -> 207/207 tests pass (test count unchanged by these edits; target renames and an unrelated 3rdparty subproject's install option cannot affect gtest discovery). Verified empirically: built the deb the same way apt_build_farm does (bloom-generate rosdebian + fakeroot debian/rules binary) and compared dpkg-deb -c file lists against the pinned stock snapshot (ros-jazzy-behaviortree-cpp 4.9.0-1noble.20260412) - the regular-file intersection is exactly zero (directory entries are excluded from that count; dpkg always allows multiple packages to jointly own a directory). --- CMakeLists.txt | 31 +++++++++++++++++++++++++++++++ tools/CMakeLists.txt | 21 ++++++++++++--------- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 91ab2d69f..3cc53530a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,7 +92,38 @@ endif() ############################################################# # LIBRARY +# lexy is linked PRIVATE/BUILD_INTERFACE-only (see the target_link_libraries +# calls below) and its only consumer, src/script_parser.cpp, is compiled into +# this library itself. No header reachable from the public entry points +# (behavior_tree.h / bt_factory.h / basic_types.h) includes lexy; the +# scripting/operators.hpp -> any_types.hpp chain does, but it is parser-internal +# and consumed only by src/script_parser.cpp. So installing lexy's own +# headers/CMake config/static lib is dead weight that would otherwise collide +# with any stock behaviortree_cpp snapshot that also vendors lexy unscoped +# (issue #20928). Disable lexy's own install rule before pulling it in. +# +# CACHE ... FORCE is configure-wide, not scoped to this add_subdirectory() call: +# if this project is itself embedded via add_subdirectory() alongside another, +# unrelated lexy instance, forcing this cache entry OFF would also suppress +# that instance's install rules for the rest of the configure run. Save the +# caller's prior cache state (absent or a value) and restore it once lexy's own +# option(LEXY_ENABLE_INSTALL ...) has read our forced OFF -- restoring after +# add_subdirectory() returns is safe because that option() call, not any later +# read, is what CMP0077-OLD in 3rdparty/lexy/CMakeLists.txt makes CACHE FORCE +# necessary for in the first place. +if(DEFINED CACHE{LEXY_ENABLE_INSTALL}) + set(_btcpp_picknik_prev_lexy_enable_install "${LEXY_ENABLE_INSTALL}") +else() + unset(_btcpp_picknik_prev_lexy_enable_install) +endif() +set(LEXY_ENABLE_INSTALL OFF CACHE BOOL "Disabled by behaviortree_cpp_picknik, see comment above" FORCE) add_subdirectory(3rdparty/lexy) +if(DEFINED _btcpp_picknik_prev_lexy_enable_install) + set(LEXY_ENABLE_INSTALL "${_btcpp_picknik_prev_lexy_enable_install}" CACHE BOOL "Disabled by behaviortree_cpp_picknik, see comment above" FORCE) + unset(_btcpp_picknik_prev_lexy_enable_install) +else() + unset(LEXY_ENABLE_INSTALL CACHE) +endif() add_library(minitrace STATIC 3rdparty/minitrace/minitrace.cpp) target_compile_definitions(minitrace PRIVATE MTR_ENABLED=True) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index b3d0875f3..b9f98b439 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,19 +1,22 @@ include_directories(${PROJECT_SOURCE_DIR}/3rdparty) -# add_executable(bt4_log_cat bt_log_cat.cpp ) -# target_link_libraries(bt4_log_cat ${BTCPP_LIBRARY} ) -# install(TARGETS bt4_log_cat +# add_executable(bt4_picknik_log_cat bt_log_cat.cpp ) +# target_link_libraries(bt4_picknik_log_cat ${BTCPP_LIBRARY} ) +# install(TARGETS bt4_picknik_log_cat # DESTINATION ${BTCPP_BIN_DESTINATION} ) +# bt4_picknik_* names (rather than upstream's bt4_*) so no bin/ path collides +# with stock upstream behaviortree_cpp, which installs identically-named +# tools at the same unscoped destination (issue #20928). if( ZMQ_FOUND ) - add_executable(bt4_recorder bt_recorder.cpp ) - target_link_libraries(bt4_recorder ${BTCPP_LIBRARY} ${ZMQ_LIBRARIES}) - install(TARGETS bt4_recorder + add_executable(bt4_picknik_recorder bt_recorder.cpp ) + target_link_libraries(bt4_picknik_recorder ${BTCPP_LIBRARY} ${ZMQ_LIBRARIES}) + install(TARGETS bt4_picknik_recorder DESTINATION ${BTCPP_BIN_DESTINATION} ) endif() -add_executable(bt4_plugin_manifest bt_plugin_manifest.cpp ) -target_link_libraries(bt4_plugin_manifest ${BTCPP_LIBRARY} ) -install(TARGETS bt4_plugin_manifest +add_executable(bt4_picknik_plugin_manifest bt_plugin_manifest.cpp ) +target_link_libraries(bt4_picknik_plugin_manifest ${BTCPP_LIBRARY} ) +install(TARGETS bt4_picknik_plugin_manifest DESTINATION ${BTCPP_BIN_DESTINATION} )