From 1d5d2ad21c15a8ec37a646d7bed914760b704b63 Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Fri, 26 Sep 2025 19:19:28 +0000 Subject: [PATCH 01/41] Support using minitrace from conan --- 3rdparty/minitrace/CMakeLists.txt | 20 ++++++++++++++++++++ CMakeLists.txt | 8 ++++---- README.md | 4 ++-- cmake/conan_build.cmake | 4 ++++ conanfile.txt | 1 + src/loggers/bt_minitrace_logger.cpp | 2 +- 6 files changed, 32 insertions(+), 7 deletions(-) create mode 100644 3rdparty/minitrace/CMakeLists.txt diff --git a/3rdparty/minitrace/CMakeLists.txt b/3rdparty/minitrace/CMakeLists.txt new file mode 100644 index 000000000..7728087e4 --- /dev/null +++ b/3rdparty/minitrace/CMakeLists.txt @@ -0,0 +1,20 @@ +add_library(minitrace STATIC + minitrace.cpp +) + +add_library(minitrace::minitrace ALIAS minitrace) + +target_include_directories(minitrace + PUBLIC + "." +) + +target_compile_definitions(minitrace + PRIVATE + MTR_ENABLED=True +) + +set_property(TARGET minitrace + PROPERTY + POSITION_INDEPENDENT_CODE ON +) diff --git a/CMakeLists.txt b/CMakeLists.txt index e69c9e96c..06b64372a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,9 +94,9 @@ endif() add_subdirectory(3rdparty/lexy) -add_library(minitrace STATIC 3rdparty/minitrace/minitrace.cpp) -target_compile_definitions(minitrace PRIVATE MTR_ENABLED=True) -set_property(TARGET minitrace PROPERTY POSITION_INDEPENDENT_CODE ON) +if(NOT BUILDING_WITH_CONAN) + add_subdirectory(3rdparty/minitrace) +endif() list(APPEND BT_SOURCE src/action_node.cpp @@ -180,7 +180,7 @@ target_link_libraries(${BTCPP_LIBRARY} Threads::Threads ${CMAKE_DL_LIBS} $ - $ + minitrace::minitrace PUBLIC ${BTCPP_EXTRA_LIBRARIES} ) diff --git a/README.md b/README.md index f1ddc4082..5b071f114 100644 --- a/README.md +++ b/README.md @@ -61,11 +61,11 @@ Three build systems are supported: Compiling with [conan](https://conan.io/): -Assuming that you are in the **parent** directory of `BehaviorTree.CPP`: +Assuming that you are in the **root** directory of `BehaviorTree.CPP`: ``` mkdir build_release -conan install . -of build_release -s build_type=Release +conan install . -of build_release -s build_type=Release --build=missing cmake -S . -B build_release -DCMAKE_TOOLCHAIN_FILE="build_release/conan_toolchain.cmake" cmake --build build_release --parallel ``` diff --git a/cmake/conan_build.cmake b/cmake/conan_build.cmake index 83876cc61..ec01728e8 100644 --- a/cmake/conan_build.cmake +++ b/cmake/conan_build.cmake @@ -1,5 +1,7 @@ list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}") +set(BUILDING_WITH_CONAN ON) + if(BTCPP_GROOT_INTERFACE) find_package(ZeroMQ REQUIRED) list(APPEND BTCPP_EXTRA_LIBRARIES ${ZeroMQ_LIBRARIES}) @@ -19,6 +21,8 @@ set( BTCPP_LIB_DESTINATION lib ) set( BTCPP_INCLUDE_DESTINATION include ) set( BTCPP_BIN_DESTINATION bin ) +find_package(minitrace REQUIRED) + mark_as_advanced( BTCPP_EXTRA_LIBRARIES BTCPP_LIB_DESTINATION diff --git a/conanfile.txt b/conanfile.txt index 7b81d1d6d..5cfd798b0 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -2,6 +2,7 @@ gtest/1.14.0 zeromq/4.3.4 sqlite3/3.40.1 +minitrace/cci.20230905 [generators] CMakeDeps diff --git a/src/loggers/bt_minitrace_logger.cpp b/src/loggers/bt_minitrace_logger.cpp index 69d6d0b16..ad2c9ec86 100644 --- a/src/loggers/bt_minitrace_logger.cpp +++ b/src/loggers/bt_minitrace_logger.cpp @@ -2,7 +2,7 @@ #include "behaviortree_cpp/loggers/bt_minitrace_logger.h" #define MTR_ENABLED true -#include "minitrace/minitrace.h" +#include "minitrace.h" namespace BT { From 48ac8d7ff5f3f64bd880c45f5f431e4e71fc1dc9 Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Fri, 26 Sep 2025 19:33:56 +0000 Subject: [PATCH 02/41] Support using tinyxml2 from conan --- 3rdparty/tinyxml2/CMakeLists.txt | 15 +++++++++++++++ CMakeLists.txt | 4 ++-- cmake/conan_build.cmake | 1 + conanfile.txt | 1 + src/xml_parsing.cpp | 2 +- 5 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 3rdparty/tinyxml2/CMakeLists.txt diff --git a/3rdparty/tinyxml2/CMakeLists.txt b/3rdparty/tinyxml2/CMakeLists.txt new file mode 100644 index 000000000..14e522f3a --- /dev/null +++ b/3rdparty/tinyxml2/CMakeLists.txt @@ -0,0 +1,15 @@ +add_library(tinyxml2 STATIC + tinyxml2.cpp +) + +add_library(tinyxml2::tinyxml2 ALIAS tinyxml2) + +target_include_directories(tinyxml2 + PUBLIC + "." +) + +set_property(TARGET tinyxml2 + PROPERTY + POSITION_INDEPENDENT_CODE ON +) diff --git a/CMakeLists.txt b/CMakeLists.txt index 06b64372a..b2622a450 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,6 +96,7 @@ add_subdirectory(3rdparty/lexy) if(NOT BUILDING_WITH_CONAN) add_subdirectory(3rdparty/minitrace) + add_subdirectory(3rdparty/tinyxml2) endif() list(APPEND BT_SOURCE @@ -140,8 +141,6 @@ list(APPEND BT_SOURCE src/loggers/bt_file_logger_v2.cpp src/loggers/bt_minitrace_logger.cpp src/loggers/bt_observer.cpp - - 3rdparty/tinyxml2/tinyxml2.cpp ) @@ -181,6 +180,7 @@ target_link_libraries(${BTCPP_LIBRARY} ${CMAKE_DL_LIBS} $ minitrace::minitrace + tinyxml2::tinyxml2 PUBLIC ${BTCPP_EXTRA_LIBRARIES} ) diff --git a/cmake/conan_build.cmake b/cmake/conan_build.cmake index ec01728e8..250d7b330 100644 --- a/cmake/conan_build.cmake +++ b/cmake/conan_build.cmake @@ -22,6 +22,7 @@ set( BTCPP_INCLUDE_DESTINATION include ) set( BTCPP_BIN_DESTINATION bin ) find_package(minitrace REQUIRED) +find_package(tinyxml2 REQUIRED) mark_as_advanced( BTCPP_EXTRA_LIBRARIES diff --git a/conanfile.txt b/conanfile.txt index 5cfd798b0..18b4db20e 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -3,6 +3,7 @@ gtest/1.14.0 zeromq/4.3.4 sqlite3/3.40.1 minitrace/cci.20230905 +tinyxml2/10.0.0 [generators] CMakeDeps diff --git a/src/xml_parsing.cpp b/src/xml_parsing.cpp index 3f895e04b..179ccd777 100644 --- a/src/xml_parsing.cpp +++ b/src/xml_parsing.cpp @@ -33,7 +33,7 @@ #include #include "behaviortree_cpp/xml_parsing.h" -#include "tinyxml2/tinyxml2.h" +#include "tinyxml2.h" #include #ifdef USING_ROS2 From 0604135a17c8bd1e3b594c529945341b5a551faa Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Fri, 26 Sep 2025 16:46:31 -0300 Subject: [PATCH 03/41] Add support for using minicoro from conan --- 3rdparty/minicoro/CMakeLists.txt | 8 ++++++++ CMakeLists.txt | 3 +++ cmake/conan_build.cmake | 1 + conanfile.txt | 1 + src/action_node.cpp | 2 +- 5 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 3rdparty/minicoro/CMakeLists.txt diff --git a/3rdparty/minicoro/CMakeLists.txt b/3rdparty/minicoro/CMakeLists.txt new file mode 100644 index 000000000..1d87c2065 --- /dev/null +++ b/3rdparty/minicoro/CMakeLists.txt @@ -0,0 +1,8 @@ +add_library(minicoro INTERFACE) + +add_library(minicoro::minicoro ALIAS minicoro) + +target_include_directories(minicoro + PUBLIC + "." +) diff --git a/CMakeLists.txt b/CMakeLists.txt index b2622a450..611034d97 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,6 +95,7 @@ endif() add_subdirectory(3rdparty/lexy) if(NOT BUILDING_WITH_CONAN) + add_subdirectory(3rdparty/minicoro) add_subdirectory(3rdparty/minitrace) add_subdirectory(3rdparty/tinyxml2) endif() @@ -181,6 +182,8 @@ target_link_libraries(${BTCPP_LIBRARY} $ minitrace::minitrace tinyxml2::tinyxml2 + minicoro::minicoro + flatbuffers::flatbuffers PUBLIC ${BTCPP_EXTRA_LIBRARIES} ) diff --git a/cmake/conan_build.cmake b/cmake/conan_build.cmake index 250d7b330..e529b543b 100644 --- a/cmake/conan_build.cmake +++ b/cmake/conan_build.cmake @@ -21,6 +21,7 @@ set( BTCPP_LIB_DESTINATION lib ) set( BTCPP_INCLUDE_DESTINATION include ) set( BTCPP_BIN_DESTINATION bin ) +find_package(minicoro REQUIRED) find_package(minitrace REQUIRED) find_package(tinyxml2 REQUIRED) diff --git a/conanfile.txt b/conanfile.txt index 18b4db20e..b17d4a630 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -4,6 +4,7 @@ zeromq/4.3.4 sqlite3/3.40.1 minitrace/cci.20230905 tinyxml2/10.0.0 +minicoro/0.1.3 [generators] CMakeDeps diff --git a/src/action_node.cpp b/src/action_node.cpp index 61dff35ef..2bf78f964 100644 --- a/src/action_node.cpp +++ b/src/action_node.cpp @@ -12,7 +12,7 @@ */ #define MINICORO_IMPL -#include "minicoro/minicoro.h" +#include "minicoro.h" #include "behaviortree_cpp/action_node.h" using namespace BT; From 910c05f525b19be5412f38e048a65cb06532281e Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Fri, 26 Sep 2025 16:46:50 -0300 Subject: [PATCH 04/41] Add support for using flatbuffers from conan --- 3rdparty/flatbuffers/CMakeLists.txt | 8 ++++++++ 3rdparty/flatbuffers/{ => flatbuffers}/base.h | 0 cmake/conan_build.cmake | 1 + conanfile.txt | 4 ++++ 4 files changed, 13 insertions(+) create mode 100644 3rdparty/flatbuffers/CMakeLists.txt rename 3rdparty/flatbuffers/{ => flatbuffers}/base.h (100%) diff --git a/3rdparty/flatbuffers/CMakeLists.txt b/3rdparty/flatbuffers/CMakeLists.txt new file mode 100644 index 000000000..a3997a070 --- /dev/null +++ b/3rdparty/flatbuffers/CMakeLists.txt @@ -0,0 +1,8 @@ +add_library(flatbuffers INTERFACE) + +add_library(flatbuffers::flatbuffers ALIAS flatbuffers) + +target_include_directories(flatbuffers + PUBLIC + "." +) diff --git a/3rdparty/flatbuffers/base.h b/3rdparty/flatbuffers/flatbuffers/base.h similarity index 100% rename from 3rdparty/flatbuffers/base.h rename to 3rdparty/flatbuffers/flatbuffers/base.h diff --git a/cmake/conan_build.cmake b/cmake/conan_build.cmake index e529b543b..04a1c6583 100644 --- a/cmake/conan_build.cmake +++ b/cmake/conan_build.cmake @@ -24,6 +24,7 @@ set( BTCPP_BIN_DESTINATION bin ) find_package(minicoro REQUIRED) find_package(minitrace REQUIRED) find_package(tinyxml2 REQUIRED) +find_package(flatbuffers REQUIRED) mark_as_advanced( BTCPP_EXTRA_LIBRARIES diff --git a/conanfile.txt b/conanfile.txt index b17d4a630..ea3bf9731 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -5,6 +5,10 @@ sqlite3/3.40.1 minitrace/cci.20230905 tinyxml2/10.0.0 minicoro/0.1.3 +flatbuffers/24.12.23 + +[options] +flatbuffers/*:header_only=True [generators] CMakeDeps From d2cffb93b45bb40d8eb7145b077e767db20aa1ce Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Fri, 26 Sep 2025 17:17:54 -0300 Subject: [PATCH 05/41] Create separate targets for each 3rdparty lib not yet supported by conan so we can avoid exposing the whole 3rdparty folder on target_include_directories Since this can create some confusion around which headers are actually being included -- the ones from that folder or the ones from conan? Also fixes the include dirs by using ${CMAKE_CURRENT_SOURCE_DIR} instead of "." --- 3rdparty/cpp-sqlite/CMakeLists.txt | 8 ++++++++ 3rdparty/cppzmq/CMakeLists.txt | 9 +++++++++ 3rdparty/flatbuffers/CMakeLists.txt | 2 +- 3rdparty/minicoro/CMakeLists.txt | 2 +- 3rdparty/minitrace/CMakeLists.txt | 2 +- 3rdparty/tinyxml2/CMakeLists.txt | 2 +- 3rdparty/wildcards/CMakeLists.txt | 8 ++++++++ CMakeLists.txt | 12 +++++++++--- src/bt_factory.cpp | 2 +- src/loggers/bt_sqlite_logger.cpp | 2 +- src/loggers/groot2_publisher.cpp | 4 ++-- tests/gtest_match.cpp | 2 +- 12 files changed, 43 insertions(+), 12 deletions(-) create mode 100644 3rdparty/cpp-sqlite/CMakeLists.txt create mode 100644 3rdparty/cppzmq/CMakeLists.txt create mode 100644 3rdparty/wildcards/CMakeLists.txt diff --git a/3rdparty/cpp-sqlite/CMakeLists.txt b/3rdparty/cpp-sqlite/CMakeLists.txt new file mode 100644 index 000000000..7257b8295 --- /dev/null +++ b/3rdparty/cpp-sqlite/CMakeLists.txt @@ -0,0 +1,8 @@ +add_library(cpp-sqlite INTERFACE) + +add_library(cpp-sqlite::cpp-sqlite ALIAS cpp-sqlite) + +target_include_directories(cpp-sqlite + INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR} +) diff --git a/3rdparty/cppzmq/CMakeLists.txt b/3rdparty/cppzmq/CMakeLists.txt new file mode 100644 index 000000000..78e52ab7c --- /dev/null +++ b/3rdparty/cppzmq/CMakeLists.txt @@ -0,0 +1,9 @@ +add_library(cppzmq INTERFACE) + +# This library doesn't use modern targets unfortunately. +#add_library(cppzmq::cppzmq ALIAS cppzmq) + +target_include_directories(cppzmq + INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR} +) diff --git a/3rdparty/flatbuffers/CMakeLists.txt b/3rdparty/flatbuffers/CMakeLists.txt index a3997a070..8cb1c1f15 100644 --- a/3rdparty/flatbuffers/CMakeLists.txt +++ b/3rdparty/flatbuffers/CMakeLists.txt @@ -4,5 +4,5 @@ add_library(flatbuffers::flatbuffers ALIAS flatbuffers) target_include_directories(flatbuffers PUBLIC - "." + ${CMAKE_CURRENT_SOURCE_DIR} ) diff --git a/3rdparty/minicoro/CMakeLists.txt b/3rdparty/minicoro/CMakeLists.txt index 1d87c2065..ab884a253 100644 --- a/3rdparty/minicoro/CMakeLists.txt +++ b/3rdparty/minicoro/CMakeLists.txt @@ -4,5 +4,5 @@ add_library(minicoro::minicoro ALIAS minicoro) target_include_directories(minicoro PUBLIC - "." + ${CMAKE_CURRENT_SOURCE_DIR} ) diff --git a/3rdparty/minitrace/CMakeLists.txt b/3rdparty/minitrace/CMakeLists.txt index 7728087e4..a228df116 100644 --- a/3rdparty/minitrace/CMakeLists.txt +++ b/3rdparty/minitrace/CMakeLists.txt @@ -6,7 +6,7 @@ add_library(minitrace::minitrace ALIAS minitrace) target_include_directories(minitrace PUBLIC - "." + ${CMAKE_CURRENT_SOURCE_DIR} ) target_compile_definitions(minitrace diff --git a/3rdparty/tinyxml2/CMakeLists.txt b/3rdparty/tinyxml2/CMakeLists.txt index 14e522f3a..9d5dc9fb9 100644 --- a/3rdparty/tinyxml2/CMakeLists.txt +++ b/3rdparty/tinyxml2/CMakeLists.txt @@ -6,7 +6,7 @@ add_library(tinyxml2::tinyxml2 ALIAS tinyxml2) target_include_directories(tinyxml2 PUBLIC - "." + ${CMAKE_CURRENT_SOURCE_DIR} ) set_property(TARGET tinyxml2 diff --git a/3rdparty/wildcards/CMakeLists.txt b/3rdparty/wildcards/CMakeLists.txt new file mode 100644 index 000000000..d8571d82d --- /dev/null +++ b/3rdparty/wildcards/CMakeLists.txt @@ -0,0 +1,8 @@ +add_library(wildcards INTERFACE) + +add_library(wildcards::wildcards ALIAS wildcards) + +target_include_directories(wildcards + INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR} +) diff --git a/CMakeLists.txt b/CMakeLists.txt index 611034d97..f79113a12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,14 +92,18 @@ endif() ############################################################# # LIBRARY -add_subdirectory(3rdparty/lexy) - if(NOT BUILDING_WITH_CONAN) add_subdirectory(3rdparty/minicoro) add_subdirectory(3rdparty/minitrace) add_subdirectory(3rdparty/tinyxml2) endif() +# Libraries not yet supported by conan +add_subdirectory(3rdparty/lexy) +add_subdirectory(3rdparty/cpp-sqlite) # https://github.com/conan-io/conan-center-index/pull/28407 +add_subdirectory(3rdparty/cppzmq) +add_subdirectory(3rdparty/wildcards) # The version supported by conan is newer and not compatible with behaviortree.cpp + list(APPEND BT_SOURCE src/action_node.cpp src/basic_types.cpp @@ -184,6 +188,9 @@ target_link_libraries(${BTCPP_LIBRARY} tinyxml2::tinyxml2 minicoro::minicoro flatbuffers::flatbuffers + cpp-sqlite::cpp-sqlite + cppzmq + wildcards::wildcards PUBLIC ${BTCPP_EXTRA_LIBRARIES} ) @@ -193,7 +200,6 @@ target_include_directories(${BTCPP_LIBRARY} $ $ PRIVATE - $ $ ${BTCPP_EXTRA_INCLUDE_DIRS} ) diff --git a/src/bt_factory.cpp b/src/bt_factory.cpp index 63f6652ef..79900a7da 100644 --- a/src/bt_factory.cpp +++ b/src/bt_factory.cpp @@ -14,7 +14,7 @@ #include "behaviortree_cpp/bt_factory.h" #include "behaviortree_cpp/utils/shared_library.h" #include "behaviortree_cpp/xml_parsing.h" -#include "wildcards/wildcards.hpp" +#include "wildcards.hpp" namespace BT { diff --git a/src/loggers/bt_sqlite_logger.cpp b/src/loggers/bt_sqlite_logger.cpp index 7dd736b31..59a960d9c 100644 --- a/src/loggers/bt_sqlite_logger.cpp +++ b/src/loggers/bt_sqlite_logger.cpp @@ -1,6 +1,6 @@ #include "behaviortree_cpp/loggers/bt_sqlite_logger.h" #include "behaviortree_cpp/xml_parsing.h" -#include "cpp-sqlite/sqlite.hpp" +#include "sqlite.hpp" namespace BT { diff --git a/src/loggers/groot2_publisher.cpp b/src/loggers/groot2_publisher.cpp index 6146507e8..83bbe748b 100644 --- a/src/loggers/groot2_publisher.cpp +++ b/src/loggers/groot2_publisher.cpp @@ -1,8 +1,8 @@ #include "behaviortree_cpp/loggers/groot2_publisher.h" #include "behaviortree_cpp/loggers/groot2_protocol.h" #include "behaviortree_cpp/xml_parsing.h" -#include "cppzmq/zmq.hpp" -#include "cppzmq/zmq_addon.hpp" +#include "zmq.hpp" +#include "zmq_addon.hpp" namespace BT { diff --git a/tests/gtest_match.cpp b/tests/gtest_match.cpp index 9078e08e3..234d8921e 100644 --- a/tests/gtest_match.cpp +++ b/tests/gtest_match.cpp @@ -1,5 +1,5 @@ #include -#include "wildcards/wildcards.hpp" +#include "wildcards.hpp" TEST(Match, Match) { From d1a030b2c956f10f98640937e5ecbb2e23a8e6b5 Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Fri, 26 Sep 2025 17:28:25 -0300 Subject: [PATCH 06/41] Fix builds For whatever reason including zmq.hpp before zmq_addon.hpp (which does include zmq.hpp internally) breaks builds --- src/loggers/groot2_publisher.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/loggers/groot2_publisher.cpp b/src/loggers/groot2_publisher.cpp index 83bbe748b..f6f0afd0d 100644 --- a/src/loggers/groot2_publisher.cpp +++ b/src/loggers/groot2_publisher.cpp @@ -1,7 +1,6 @@ #include "behaviortree_cpp/loggers/groot2_publisher.h" #include "behaviortree_cpp/loggers/groot2_protocol.h" #include "behaviortree_cpp/xml_parsing.h" -#include "zmq.hpp" #include "zmq_addon.hpp" namespace BT From f19b357ffe4a40a4559bc54d11474548b244a37d Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Fri, 26 Sep 2025 17:28:54 -0300 Subject: [PATCH 07/41] Do not include the whole 3rdparty folder, only link in what we need --- tests/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c4b982576..ea3bb52d5 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -55,6 +55,6 @@ else() endif() -target_link_libraries(behaviortree_cpp_test ${BTCPP_LIBRARY} bt_sample_nodes foonathan::lexy) -target_include_directories(behaviortree_cpp_test PRIVATE include ${PROJECT_SOURCE_DIR}/3rdparty) +target_include_directories(behaviortree_cpp_test PRIVATE include) +target_link_libraries(behaviortree_cpp_test ${BTCPP_LIBRARY} bt_sample_nodes foonathan::lexy wildcards::wildcards) target_compile_definitions(behaviortree_cpp_test PRIVATE BT_TEST_FOLDER="${CMAKE_CURRENT_SOURCE_DIR}") From 4d88af40459fcb3e4271de962101d72c3a3bb45f Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Fri, 26 Sep 2025 17:29:08 -0300 Subject: [PATCH 08/41] Use the regular lexy target --- CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f79113a12..27ae3fee2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -183,7 +183,7 @@ target_link_libraries(${BTCPP_LIBRARY} PRIVATE Threads::Threads ${CMAKE_DL_LIBS} - $ + foonathan::lexy minitrace::minitrace tinyxml2::tinyxml2 minicoro::minicoro @@ -200,7 +200,6 @@ target_include_directories(${BTCPP_LIBRARY} $ $ PRIVATE - $ ${BTCPP_EXTRA_INCLUDE_DIRS} ) From 511804812386e1fba0b60a187d652e9911e6ce9b Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Fri, 26 Sep 2025 17:43:27 -0300 Subject: [PATCH 09/41] Do not expose the whole 3rdparty folder as a include_directory --- 3rdparty/cppzmq/CMakeLists.txt | 9 +++++++++ tools/CMakeLists.txt | 2 -- tools/bt_recorder.cpp | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/3rdparty/cppzmq/CMakeLists.txt b/3rdparty/cppzmq/CMakeLists.txt index 78e52ab7c..420e9a875 100644 --- a/3rdparty/cppzmq/CMakeLists.txt +++ b/3rdparty/cppzmq/CMakeLists.txt @@ -1,4 +1,13 @@ +find_package(ZeroMQ REQUIRED) + add_library(cppzmq INTERFACE) +if(TARGET libzmq-static) + target_link_libraries(cppzmq INTERFACE libzmq-static) +elseif(TARGET libzmq) + target_link_libraries(cppzmq INTERFACE libzmq) +else() + message(FATAL_ERROR "Failed to find libzmq") +endif() # This library doesn't use modern targets unfortunately. #add_library(cppzmq::cppzmq ALIAS cppzmq) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index b3d0875f3..14a2e8231 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,6 +1,4 @@ -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 diff --git a/tools/bt_recorder.cpp b/tools/bt_recorder.cpp index c652f9a7f..a1266def2 100644 --- a/tools/bt_recorder.cpp +++ b/tools/bt_recorder.cpp @@ -3,7 +3,7 @@ #include #include #include -#include "cppzmq/zmq.hpp" +#include "zmq.hpp" #include "behaviortree_cpp/flatbuffers/BT_logger_generated.h" // http://zguide.zeromq.org/cpp:interrupt From 7eda75615e65cb00d86dfd8ae4dced6e5672350c Mon Sep 17 00:00:00 2001 From: "Riff, Eric" Date: Sun, 28 Sep 2025 00:41:57 +0000 Subject: [PATCH 10/41] Add options to opt-out of vendored libraries --- CMakeLists.txt | 71 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 27ae3fee2..517a765a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,15 @@ option(USE_AFLPLUSPLUS "Use AFL++ instead of libFuzzer" OFF) option(ENABLE_DEBUG "Enable debug build with full symbols" OFF) option(FORCE_STATIC_LINKING "Force static linking of all dependencies" OFF) +option(USE_VENDORED_CPPSQLITE "Use the bundled version of cpp-sqlite" ON) +option(USE_VENDORED_CPPZMQ "Use the bundled version of cppzmq" ON) +option(USE_VENDORED_FLATBUFFERS "Use the bundled version of flatbuffers" ON) +option(USE_VENDORED_LEXY "Use the bundled version of lexy" ON) +option(USE_VENDORED_MINICORO "Use the bundled version of minicoro" ON) +option(USE_VENDORED_MINITRACE "Use the bundled version of minitrace" ON) +option(USE_VENDORED_TINYXML2 "Use the bundled version of tinyxml2" ON) +option(USE_VENDORED_WILDCARDS "Use the bundled version of wildcards" ON) + set(BASE_FLAGS "") if(ENABLE_DEBUG) @@ -61,10 +70,6 @@ if(USE_V3_COMPATIBLE_NAMES) add_definitions(-DUSE_BTCPP3_OLD_NAMES) endif() -#---- Find other packages ---- -find_package(Threads REQUIRED) - - set(BEHAVIOR_TREE_LIBRARY ${PROJECT_NAME}) # Update the policy setting to avoid an error when loading the ament_cmake package @@ -90,19 +95,63 @@ else() endif() ############################################################# -# LIBRARY +# Handle dependencies + +find_package(Threads REQUIRED) + +if(BTCPP_GROOT_INTERFACE) + find_package(ZeroMQ REQUIRED) +endif() + +if(BTCPP_SQLITE_LOGGING) + if(USE_VENDORED_CPPSQLITE) + add_subdirectory(3rdparty/cpp-sqlite) + else() + find_package(cpp-sqlite REQUIRED) + endif() +endif() + +if(USE_VENDORED_CPPZMQ) + add_subdirectory(3rdparty/cppzmq) +else() + find_package(cppzmq REQUIRED) +endif() + +if(USE_VENDORED_FLATBUFFERS) + add_subdirectory(3rdparty/flatbuffers) +else() + find_package(flatbuffers REQUIRED) +endif() -if(NOT BUILDING_WITH_CONAN) +if(USE_VENDORED_LEXY) + add_subdirectory(3rdparty/lexy) +else() + find_package(lexy REQUIRED) +endif() + +if(USE_VENDORED_MINICORO) add_subdirectory(3rdparty/minicoro) +else() + find_package(minicoro REQUIRED) +endif() + +if(USE_VENDORED_MINITRACE) add_subdirectory(3rdparty/minitrace) +else() + find_package(minitrace REQUIRED) +endif() + +if(USE_VENDORED_TINYXML2) add_subdirectory(3rdparty/tinyxml2) +else() + find_package(tinyxml2 REQUIRED) endif() -# Libraries not yet supported by conan -add_subdirectory(3rdparty/lexy) -add_subdirectory(3rdparty/cpp-sqlite) # https://github.com/conan-io/conan-center-index/pull/28407 -add_subdirectory(3rdparty/cppzmq) -add_subdirectory(3rdparty/wildcards) # The version supported by conan is newer and not compatible with behaviortree.cpp +if(USE_VENDORED_WILDCARDS) + add_subdirectory(3rdparty/wildcards) +else() + find_package(wildcards REQUIRED) +endif() list(APPEND BT_SOURCE src/action_node.cpp From 50c24ada1017d662f75126cbc0dc1d095b1f0743 Mon Sep 17 00:00:00 2001 From: "Riff, Eric" Date: Sun, 28 Sep 2025 00:41:59 +0000 Subject: [PATCH 11/41] This was shared across both code paths, conan_build.cmake and ament_build.cmake So it is better to keep this on a single place --- CMakeLists.txt | 4 ++++ cmake/ament_build.cmake | 4 ---- cmake/conan_build.cmake | 4 ---- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 517a765a9..c6e1d5b9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,10 @@ option(USE_VENDORED_MINITRACE "Use the bundled version of minitrace" ON) option(USE_VENDORED_TINYXML2 "Use the bundled version of tinyxml2" ON) option(USE_VENDORED_WILDCARDS "Use the bundled version of wildcards" ON) +set(BTCPP_LIB_DESTINATION lib) +set(BTCPP_INCLUDE_DESTINATION include) +set(BTCPP_BIN_DESTINATION bin) + set(BASE_FLAGS "") if(ENABLE_DEBUG) diff --git a/cmake/ament_build.cmake b/cmake/ament_build.cmake index ec1e0a66b..b82c8207d 100644 --- a/cmake/ament_build.cmake +++ b/cmake/ament_build.cmake @@ -23,10 +23,6 @@ set( BTCPP_EXTRA_LIBRARIES ament_export_dependencies(ament_index_cpp) -set( BTCPP_LIB_DESTINATION lib ) -set( BTCPP_INCLUDE_DESTINATION include ) -set( BTCPP_BIN_DESTINATION bin ) - mark_as_advanced( BTCPP_EXTRA_LIBRARIES BTCPP_EXTRA_INCLUDE_DIRS diff --git a/cmake/conan_build.cmake b/cmake/conan_build.cmake index 04a1c6583..583e91248 100644 --- a/cmake/conan_build.cmake +++ b/cmake/conan_build.cmake @@ -17,10 +17,6 @@ if(BTCPP_SQLITE_LOGGING) endif() -set( BTCPP_LIB_DESTINATION lib ) -set( BTCPP_INCLUDE_DESTINATION include ) -set( BTCPP_BIN_DESTINATION bin ) - find_package(minicoro REQUIRED) find_package(minitrace REQUIRED) find_package(tinyxml2 REQUIRED) From 48d81ed37592d3b7f0c68691b4459b017a25b6ac Mon Sep 17 00:00:00 2001 From: "Riff, Eric" Date: Sun, 28 Sep 2025 00:41:59 +0000 Subject: [PATCH 12/41] Keep all the find_package calls on the toplevel CMakeLists --- cmake/ament_build.cmake | 8 -------- cmake/conan_build.cmake | 12 ++---------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/cmake/ament_build.cmake b/cmake/ament_build.cmake index b82c8207d..0bcfa64eb 100644 --- a/cmake/ament_build.cmake +++ b/cmake/ament_build.cmake @@ -2,14 +2,6 @@ set(CMAKE_CONFIG_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CONFIG_PATH}") -if(BTCPP_GROOT_INTERFACE) - find_package(ZeroMQ REQUIRED) -endif() - -if(BTCPP_SQLITE_LOGGING) - find_package(SQLite3 REQUIRED) -endif() - find_package(ament_index_cpp REQUIRED) set(BTCPP_EXTRA_INCLUDE_DIRS ${ZeroMQ_INCLUDE_DIRS} diff --git a/cmake/conan_build.cmake b/cmake/conan_build.cmake index 583e91248..d110fcceb 100644 --- a/cmake/conan_build.cmake +++ b/cmake/conan_build.cmake @@ -1,27 +1,19 @@ list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}") -set(BUILDING_WITH_CONAN ON) - if(BTCPP_GROOT_INTERFACE) - find_package(ZeroMQ REQUIRED) +# find_package(ZeroMQ REQUIRED) list(APPEND BTCPP_EXTRA_LIBRARIES ${ZeroMQ_LIBRARIES}) list(APPEND BTCPP_EXTRA_INCLUDE_DIRS ${ZeroMQ_INCLUDE_DIRS}) message(STATUS "ZeroMQ_LIBRARIES: ${ZeroMQ_LIBRARIES}") endif() if(BTCPP_SQLITE_LOGGING) - find_package(SQLite3 REQUIRED) +# find_package(SQLite3 REQUIRED) list(APPEND BTCPP_EXTRA_LIBRARIES ${SQLite3_LIBRARIES}) list(APPEND BTCPP_EXTRA_INCLUDE_DIRS ${SQLite3_INCLUDE_DIRS}) message(STATUS "SQLite3_LIBRARIES: ${SQLite3_LIBRARIES}") endif() - -find_package(minicoro REQUIRED) -find_package(minitrace REQUIRED) -find_package(tinyxml2 REQUIRED) -find_package(flatbuffers REQUIRED) - mark_as_advanced( BTCPP_EXTRA_LIBRARIES BTCPP_LIB_DESTINATION From d145e4616b8902f4c3adb910b69a35aad47c68d8 Mon Sep 17 00:00:00 2001 From: "Riff, Eric" Date: Sun, 28 Sep 2025 00:42:00 +0000 Subject: [PATCH 13/41] SQLite3 is actually a dependency of cpp-sqlite --- 3rdparty/cpp-sqlite/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/3rdparty/cpp-sqlite/CMakeLists.txt b/3rdparty/cpp-sqlite/CMakeLists.txt index 7257b8295..3cb7e9849 100644 --- a/3rdparty/cpp-sqlite/CMakeLists.txt +++ b/3rdparty/cpp-sqlite/CMakeLists.txt @@ -1,3 +1,5 @@ +find_package(SQLite3 REQUIRED) + add_library(cpp-sqlite INTERFACE) add_library(cpp-sqlite::cpp-sqlite ALIAS cpp-sqlite) @@ -6,3 +8,8 @@ target_include_directories(cpp-sqlite INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} ) + +target_link_libraries(cpp-sqlite + INTERFACE + SQLite::SQLite3 +) From b063794f65cf4a5a541672ddb74180c5745e2ee9 Mon Sep 17 00:00:00 2001 From: "Riff, Eric" Date: Sun, 28 Sep 2025 00:42:01 +0000 Subject: [PATCH 14/41] Fix include dirs of the vendored minicoro and flatbuffers --- 3rdparty/flatbuffers/CMakeLists.txt | 2 +- 3rdparty/minicoro/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/3rdparty/flatbuffers/CMakeLists.txt b/3rdparty/flatbuffers/CMakeLists.txt index 8cb1c1f15..bc91f8e27 100644 --- a/3rdparty/flatbuffers/CMakeLists.txt +++ b/3rdparty/flatbuffers/CMakeLists.txt @@ -3,6 +3,6 @@ add_library(flatbuffers INTERFACE) add_library(flatbuffers::flatbuffers ALIAS flatbuffers) target_include_directories(flatbuffers - PUBLIC + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} ) diff --git a/3rdparty/minicoro/CMakeLists.txt b/3rdparty/minicoro/CMakeLists.txt index ab884a253..9508d8445 100644 --- a/3rdparty/minicoro/CMakeLists.txt +++ b/3rdparty/minicoro/CMakeLists.txt @@ -3,6 +3,6 @@ add_library(minicoro INTERFACE) add_library(minicoro::minicoro ALIAS minicoro) target_include_directories(minicoro - PUBLIC + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} ) From 76b22a694f3bbd9391ea4fb3d9cb8c85728cf9f9 Mon Sep 17 00:00:00 2001 From: "Riff, Eric" Date: Sun, 28 Sep 2025 00:42:01 +0000 Subject: [PATCH 15/41] Define libzmq cmake target on FindZeroMQ to match the conan package --- cmake/FindZeroMQ.cmake | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cmake/FindZeroMQ.cmake b/cmake/FindZeroMQ.cmake index b11258812..1549d9948 100644 --- a/cmake/FindZeroMQ.cmake +++ b/cmake/FindZeroMQ.cmake @@ -63,5 +63,13 @@ else (ZeroMQ_LIBRARIES AND ZeroMQ_INCLUDE_DIRS) # show the ZeroMQ_INCLUDE_DIRS and ZeroMQ_LIBRARIES variables only in the advanced view mark_as_advanced(ZeroMQ_INCLUDE_DIRS ZeroMQ_LIBRARIES) + if(ZeroMQ_FOUND AND NOT TARGET libzmq) + add_library(libzmq UNKNOWN IMPORTED) + set_target_properties(libzmq PROPERTIES + IMPORTED_LOCATION "${ZeroMQ_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${ZeroMQ_INCLUDE_DIRS}" + ) + endif() + endif (ZeroMQ_LIBRARIES AND ZeroMQ_INCLUDE_DIRS) endif(ZeroMQ_FOUND) From d317e697cd41aaaf8860fcc461a70d1cce462547 Mon Sep 17 00:00:00 2001 From: "Riff, Eric" Date: Sun, 28 Sep 2025 00:42:02 +0000 Subject: [PATCH 16/41] Improve message. This code path doesn't really mean we're using conan, it just means we're not using ament. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c6e1d5b9b..2ff5ab75b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,7 +93,7 @@ if ( ament_cmake_FOUND ) include(cmake/ament_build.cmake) else() message(STATUS "------------------------------------------") - message(STATUS "BehaviorTree is being built with conan.") + message(STATUS "BehaviorTree is being built without AMENT.") message(STATUS "------------------------------------------") include(cmake/conan_build.cmake) endif() From 833570eb305855025ccef9f616837c9b3be9c50e Mon Sep 17 00:00:00 2001 From: "Riff, Eric" Date: Sun, 28 Sep 2025 00:42:02 +0000 Subject: [PATCH 17/41] Use the python version of conanfile.py so we can set the CMake options needed to opt out of vendored dependencies --- conanfile.py | 37 +++++++++++++++++++++++++++++++++++++ conanfile.txt | 15 --------------- 2 files changed, 37 insertions(+), 15 deletions(-) create mode 100644 conanfile.py delete mode 100644 conanfile.txt diff --git a/conanfile.py b/conanfile.py new file mode 100644 index 000000000..769eb0588 --- /dev/null +++ b/conanfile.py @@ -0,0 +1,37 @@ +from conan import ConanFile +from conan.tools.cmake import CMakeToolchain, CMakeDeps + +class BehaviortreeCppConan(ConanFile): + name = "behaviortree.cpp" + settings = "os", "arch", "compiler", "build_type" + + default_options = { + "flatbuffers/*:header_only": True, + } + + def build_requirements(self): + self.test_requires("gtest/1.14.0") + + def requirements(self): + self.requires("flatbuffers/24.12.23") + self.requires("minicoro/0.1.3") + self.requires("minitrace/cci.20230905") + self.requires("sqlite3/3.40.1") # This should be a transitive dependency of cpp-sqlite + self.requires("tinyxml2/10.0.0") + self.requires("zeromq/4.3.4") + + def generate(self): + tc = CMakeToolchain(self) + + #tc.variables["USE_VENDORED_CPPSQLITE"] = False + #tc.variables["USE_VENDORED_CPPZMQ"] = False + tc.variables["USE_VENDORED_FLATBUFFERS"] = False + #tc.variables["USE_VENDORED_LEXY"] = False + tc.variables["USE_VENDORED_MINICORO"] = False + tc.variables["USE_VENDORED_MINITRACE"] = False + tc.variables["USE_VENDORED_TINYXML2"] = False + #tc.variables["USE_VENDORED_WILDCARDS"] = False + tc.generate() + + deps = CMakeDeps(self) + deps.generate() diff --git a/conanfile.txt b/conanfile.txt deleted file mode 100644 index ea3bf9731..000000000 --- a/conanfile.txt +++ /dev/null @@ -1,15 +0,0 @@ -[requires] -gtest/1.14.0 -zeromq/4.3.4 -sqlite3/3.40.1 -minitrace/cci.20230905 -tinyxml2/10.0.0 -minicoro/0.1.3 -flatbuffers/24.12.23 - -[options] -flatbuffers/*:header_only=True - -[generators] -CMakeDeps -CMakeToolchain From 97f277625da50fb0cec21dfaa82c02d3ad3b08f6 Mon Sep 17 00:00:00 2001 From: "Riff, Eric" Date: Sun, 28 Sep 2025 00:45:00 +0000 Subject: [PATCH 18/41] Address pre-commit complains --- conanfile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conanfile.py b/conanfile.py index 769eb0588..2ae1cf59c 100644 --- a/conanfile.py +++ b/conanfile.py @@ -22,7 +22,7 @@ def requirements(self): def generate(self): tc = CMakeToolchain(self) - + #tc.variables["USE_VENDORED_CPPSQLITE"] = False #tc.variables["USE_VENDORED_CPPZMQ"] = False tc.variables["USE_VENDORED_FLATBUFFERS"] = False @@ -32,6 +32,6 @@ def generate(self): tc.variables["USE_VENDORED_TINYXML2"] = False #tc.variables["USE_VENDORED_WILDCARDS"] = False tc.generate() - + deps = CMakeDeps(self) deps.generate() From 0bafb1b731d7d5f2f579c549ff0e16b12e02587a Mon Sep 17 00:00:00 2001 From: "Riff, Eric" Date: Sun, 28 Sep 2025 00:46:46 +0000 Subject: [PATCH 19/41] Use conanfile.py across the board --- .github/workflows/cmake_ubuntu.yml | 2 +- .github/workflows/cmake_windows.yml | 2 +- cmake/conan.cmake | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cmake_ubuntu.yml b/.github/workflows/cmake_ubuntu.yml index 41ed9a196..8b9e33870 100644 --- a/.github/workflows/cmake_ubuntu.yml +++ b/.github/workflows/cmake_ubuntu.yml @@ -39,7 +39,7 @@ jobs: - name: Install conan dependencies working-directory: ${{github.workspace}}/build - run: conan install ${{github.workspace}}/conanfile.txt -s build_type=${{env.BUILD_TYPE}} --build=missing + run: conan install ${{github.workspace}}/conanfile.py -s build_type=${{env.BUILD_TYPE}} --build=missing - name: Configure CMake shell: bash diff --git a/.github/workflows/cmake_windows.yml b/.github/workflows/cmake_windows.yml index 34f4f97ce..1125e18ab 100644 --- a/.github/workflows/cmake_windows.yml +++ b/.github/workflows/cmake_windows.yml @@ -39,7 +39,7 @@ jobs: - name: Install conan dependencies working-directory: ${{github.workspace}}/build - run: conan install ${{github.workspace}}/conanfile.txt -s build_type=${{env.BUILD_TYPE}} --build=missing + run: conan install ${{github.workspace}}/conanfile.py -s build_type=${{env.BUILD_TYPE}} --build=missing - name: Configure CMake shell: bash diff --git a/cmake/conan.cmake b/cmake/conan.cmake index d36c5ed44..5de17afa0 100644 --- a/cmake/conan.cmake +++ b/cmake/conan.cmake @@ -808,14 +808,14 @@ function(conan_cmake_configure) conan_cmake_generate_conanfile(OFF ${ARGV}) endfunction() -# Generate, writing in disk a conanfile.txt with the requires, options, and imports +# Generate, writing in disk a conanfile.py with the requires, options, and imports # specified as arguments # This will be considered as temporary file, generated in CMAKE_CURRENT_BINARY_DIR) function(conan_cmake_generate_conanfile DEFAULT_GENERATOR) conan_parse_arguments(${ARGV}) - set(_FN "${CMAKE_CURRENT_BINARY_DIR}/conanfile.txt") + set(_FN "${CMAKE_CURRENT_BINARY_DIR}/conanfile.py") file(WRITE ${_FN} "") if(DEFINED ARGUMENTS_REQUIRES) From 38e4d2d8a6d250b224819dd3c27145114a3e5957 Mon Sep 17 00:00:00 2001 From: "Riff, Eric" Date: Sun, 28 Sep 2025 02:41:41 +0000 Subject: [PATCH 20/41] Do not look for ZeroMQ directly as it is a dependency of cppzmq Also only look for cppzmq if BTCPP_GROOT_INTERFACE --- 3rdparty/cppzmq/CMakeLists.txt | 15 ++++++++------- CMakeLists.txt | 12 ++++++------ 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/3rdparty/cppzmq/CMakeLists.txt b/3rdparty/cppzmq/CMakeLists.txt index 420e9a875..9a0bb86b0 100644 --- a/3rdparty/cppzmq/CMakeLists.txt +++ b/3rdparty/cppzmq/CMakeLists.txt @@ -1,13 +1,6 @@ find_package(ZeroMQ REQUIRED) add_library(cppzmq INTERFACE) -if(TARGET libzmq-static) - target_link_libraries(cppzmq INTERFACE libzmq-static) -elseif(TARGET libzmq) - target_link_libraries(cppzmq INTERFACE libzmq) -else() - message(FATAL_ERROR "Failed to find libzmq") -endif() # This library doesn't use modern targets unfortunately. #add_library(cppzmq::cppzmq ALIAS cppzmq) @@ -16,3 +9,11 @@ target_include_directories(cppzmq INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} ) + +if(TARGET libzmq-static) + target_link_libraries(cppzmq INTERFACE libzmq-static) +elseif(TARGET libzmq) + target_link_libraries(cppzmq INTERFACE libzmq) +else() + message(FATAL_ERROR "Unknown zeromq target name") +endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ff5ab75b..508ee535c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,7 +104,11 @@ endif() find_package(Threads REQUIRED) if(BTCPP_GROOT_INTERFACE) - find_package(ZeroMQ REQUIRED) + if(USE_VENDORED_CPPZMQ) + add_subdirectory(3rdparty/cppzmq) + else() + find_package(cppzmq REQUIRED) + endif() endif() if(BTCPP_SQLITE_LOGGING) @@ -115,11 +119,7 @@ if(BTCPP_SQLITE_LOGGING) endif() endif() -if(USE_VENDORED_CPPZMQ) - add_subdirectory(3rdparty/cppzmq) -else() - find_package(cppzmq REQUIRED) -endif() + if(USE_VENDORED_FLATBUFFERS) add_subdirectory(3rdparty/flatbuffers) From af954f83e5ad48aa1d90faf3215a2f18f6d41ac1 Mon Sep 17 00:00:00 2001 From: "Riff, Eric" Date: Sun, 28 Sep 2025 02:45:03 +0000 Subject: [PATCH 21/41] Keep a single copy of zmq.hpp This header is part of the cppzmq library so it lives on 3rdparty/cppzmq. But for whatever reason there was another version of this header here. Furthermore it was a differnt version of the library. --- src/loggers/zmq.hpp | 2815 ------------------------------------------- 1 file changed, 2815 deletions(-) delete mode 100644 src/loggers/zmq.hpp diff --git a/src/loggers/zmq.hpp b/src/loggers/zmq.hpp deleted file mode 100644 index 26c2c6f42..000000000 --- a/src/loggers/zmq.hpp +++ /dev/null @@ -1,2815 +0,0 @@ -/* - Copyright (c) 2016-2017 ZeroMQ community - Copyright (c) 2009-2011 250bpm s.r.o. - Copyright (c) 2011 Botond Ballo - Copyright (c) 2007-2009 iMatix Corporation - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. -*/ - -#ifndef __ZMQ_HPP_INCLUDED__ -#define __ZMQ_HPP_INCLUDED__ - -#ifdef _WIN32 -#ifndef NOMINMAX -#define NOMINMAX -#endif -#endif - -// included here for _HAS_CXX* macros -#include - -#if defined(_MSVC_LANG) -#define CPPZMQ_LANG _MSVC_LANG -#else -#define CPPZMQ_LANG __cplusplus -#endif -// overwrite if specific language macros indicate higher version -#if defined(_HAS_CXX14) && _HAS_CXX14 && CPPZMQ_LANG < 201402L -#undef CPPZMQ_LANG -#define CPPZMQ_LANG 201402L -#endif -#if defined(_HAS_CXX17) && _HAS_CXX17 && CPPZMQ_LANG < 201703L -#undef CPPZMQ_LANG -#define CPPZMQ_LANG 201703L -#endif - -// macros defined if has a specific standard or greater -#if CPPZMQ_LANG >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900) -#define ZMQ_CPP11 -#endif -#if CPPZMQ_LANG >= 201402L -#define ZMQ_CPP14 -#endif -#if CPPZMQ_LANG >= 201703L -#define ZMQ_CPP17 -#endif - -#if defined(ZMQ_CPP14) && !defined(_MSC_VER) -#define ZMQ_DEPRECATED(msg) [[deprecated(msg)]] -#elif defined(_MSC_VER) -#define ZMQ_DEPRECATED(msg) __declspec(deprecated(msg)) -#elif defined(__GNUC__) -#define ZMQ_DEPRECATED(msg) __attribute__((deprecated(msg))) -#endif - -#if defined(ZMQ_CPP17) -#define ZMQ_NODISCARD [[nodiscard]] -#else -#define ZMQ_NODISCARD -#endif - -#if defined(ZMQ_CPP11) -#define ZMQ_NOTHROW noexcept -#define ZMQ_EXPLICIT explicit -#define ZMQ_OVERRIDE override -#define ZMQ_NULLPTR nullptr -#define ZMQ_CONSTEXPR_FN constexpr -#define ZMQ_CONSTEXPR_VAR constexpr -#define ZMQ_CPP11_DEPRECATED(msg) ZMQ_DEPRECATED(msg) -#else -#define ZMQ_NOTHROW throw() -#define ZMQ_EXPLICIT -#define ZMQ_OVERRIDE -#define ZMQ_NULLPTR 0 -#define ZMQ_CONSTEXPR_FN -#define ZMQ_CONSTEXPR_VAR const -#define ZMQ_CPP11_DEPRECATED(msg) -#endif -#if defined(ZMQ_CPP14) && (!defined(_MSC_VER) || _MSC_VER > 1900) -#define ZMQ_EXTENDED_CONSTEXPR -#endif -#if defined(ZMQ_CPP17) -#define ZMQ_INLINE_VAR inline -#else -#define ZMQ_INLINE_VAR -#endif - -#include -#include - -#include -#include -#include -#include -#include -#include -#ifdef ZMQ_CPP11 -#include -#include -#include -#include -#endif - -#if defined(__has_include) && defined(ZMQ_CPP17) -#define CPPZMQ_HAS_INCLUDE_CPP17(X) __has_include(X) -#else -#define CPPZMQ_HAS_INCLUDE_CPP17(X) 0 -#endif - -#if CPPZMQ_HAS_INCLUDE_CPP17() && !defined(CPPZMQ_HAS_OPTIONAL) -#define CPPZMQ_HAS_OPTIONAL 1 -#endif -#ifndef CPPZMQ_HAS_OPTIONAL -#define CPPZMQ_HAS_OPTIONAL 0 -#elif CPPZMQ_HAS_OPTIONAL -#include -#endif - -#if CPPZMQ_HAS_INCLUDE_CPP17() && !defined(CPPZMQ_HAS_STRING_VIEW) -#define CPPZMQ_HAS_STRING_VIEW 1 -#endif -#ifndef CPPZMQ_HAS_STRING_VIEW -#define CPPZMQ_HAS_STRING_VIEW 0 -#elif CPPZMQ_HAS_STRING_VIEW -#include -#endif - -/* Version macros for compile-time API version detection */ -#define CPPZMQ_VERSION_MAJOR 4 -#define CPPZMQ_VERSION_MINOR 7 -#define CPPZMQ_VERSION_PATCH 1 - -#define CPPZMQ_VERSION \ - ZMQ_MAKE_VERSION(CPPZMQ_VERSION_MAJOR, CPPZMQ_VERSION_MINOR, CPPZMQ_VERSION_PATCH) - -// Detect whether the compiler supports C++11 rvalue references. -#if(defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)) && \ - defined(__GXX_EXPERIMENTAL_CXX0X__)) -#define ZMQ_HAS_RVALUE_REFS -#define ZMQ_DELETED_FUNCTION = delete -#elif defined(__clang__) -#if __has_feature(cxx_rvalue_references) -#define ZMQ_HAS_RVALUE_REFS -#endif - -#if __has_feature(cxx_deleted_functions) -#define ZMQ_DELETED_FUNCTION = delete -#else -#define ZMQ_DELETED_FUNCTION -#endif -#elif defined(_MSC_VER) && (_MSC_VER >= 1900) -#define ZMQ_HAS_RVALUE_REFS -#define ZMQ_DELETED_FUNCTION = delete -#elif defined(_MSC_VER) && (_MSC_VER >= 1600) -#define ZMQ_HAS_RVALUE_REFS -#define ZMQ_DELETED_FUNCTION -#else -#define ZMQ_DELETED_FUNCTION -#endif - -#if defined(ZMQ_CPP11) && !defined(__llvm__) && !defined(__INTEL_COMPILER) && \ - defined(__GNUC__) && __GNUC__ < 5 -#define ZMQ_CPP11_PARTIAL -#elif defined(__GLIBCXX__) && __GLIBCXX__ < 20160805 -//the date here is the last date of gcc 4.9.4, which -// effectively means libstdc++ from gcc 5.5 and higher won't trigger this branch -#define ZMQ_CPP11_PARTIAL -#endif - -#ifdef ZMQ_CPP11 -#ifdef ZMQ_CPP11_PARTIAL -#define ZMQ_IS_TRIVIALLY_COPYABLE(T) __has_trivial_copy(T) -#else -#include -#define ZMQ_IS_TRIVIALLY_COPYABLE(T) std::is_trivially_copyable::value -#endif -#endif - -#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3, 3, 0) -#define ZMQ_NEW_MONITOR_EVENT_LAYOUT -#endif - -#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 1, 0) -#define ZMQ_HAS_PROXY_STEERABLE -/* Socket event data */ -typedef struct -{ - uint16_t event; // id of the event as bitfield - int32_t value; // value is either error code, fd or reconnect interval -} zmq_event_t; -#endif - -// Avoid using deprecated message receive function when possible -#if ZMQ_VERSION < ZMQ_MAKE_VERSION(3, 2, 0) -#define zmq_msg_recv(msg, socket, flags) zmq_recvmsg(socket, msg, flags) -#endif - -// In order to prevent unused variable warnings when building in non-debug -// mode use this macro to make assertions. -#ifndef NDEBUG -#define ZMQ_ASSERT(expression) assert(expression) -#else -#define ZMQ_ASSERT(expression) (void)(expression) -#endif - -namespace zmq -{ -#ifdef ZMQ_CPP11 -namespace detail -{ -namespace ranges -{ -using std::begin; -using std::end; -template -auto begin(T&& r) -> decltype(begin(std::forward(r))) -{ - return begin(std::forward(r)); -} -template -auto end(T&& r) -> decltype(end(std::forward(r))) -{ - return end(std::forward(r)); -} -} // namespace ranges - -template -using void_t = void; - -template -using iter_value_t = typename std::iterator_traits::value_type; - -template -using range_iter_t = - decltype(ranges::begin(std::declval::type&>())); - -template -using range_value_t = iter_value_t>; - -template -struct is_range : std::false_type -{ -}; - -template -struct is_range< - T, void_t::type&>()) == - ranges::end( - std::declval::type&>()))>> - : std::true_type -{ -}; - -} // namespace detail -#endif - -typedef zmq_free_fn free_fn; -typedef zmq_pollitem_t pollitem_t; - -class error_t : public std::exception -{ -public: - error_t() ZMQ_NOTHROW : errnum(zmq_errno()) - {} - explicit error_t(int err) ZMQ_NOTHROW : errnum(err) - {} - virtual const char* what() const ZMQ_NOTHROW ZMQ_OVERRIDE - { - return zmq_strerror(errnum); - } - int num() const ZMQ_NOTHROW - { - return errnum; - } - -private: - int errnum; -}; - -inline int poll(zmq_pollitem_t* items_, size_t nitems_, long timeout_ = -1) -{ - int rc = zmq_poll(items_, static_cast(nitems_), timeout_); - if(rc < 0) - throw error_t(); - return rc; -} - -ZMQ_DEPRECATED("from 4.3.1, use poll taking non-const items") -inline int poll(zmq_pollitem_t const* items_, size_t nitems_, long timeout_ = -1) -{ - return poll(const_cast(items_), nitems_, timeout_); -} - -#ifdef ZMQ_CPP11 -ZMQ_DEPRECATED("from 4.3.1, use poll taking non-const items") -inline int poll(zmq_pollitem_t const* items, size_t nitems, - std::chrono::milliseconds timeout) -{ - return poll(const_cast(items), nitems, - static_cast(timeout.count())); -} - -ZMQ_DEPRECATED("from 4.3.1, use poll taking non-const items") -inline int poll(std::vector const& items, - std::chrono::milliseconds timeout) -{ - return poll(const_cast(items.data()), items.size(), - static_cast(timeout.count())); -} - -ZMQ_DEPRECATED("from 4.3.1, use poll taking non-const items") -inline int poll(std::vector const& items, long timeout_ = -1) -{ - return poll(const_cast(items.data()), items.size(), timeout_); -} - -inline int poll(zmq_pollitem_t* items, size_t nitems, std::chrono::milliseconds timeout) -{ - return poll(items, nitems, static_cast(timeout.count())); -} - -inline int poll(std::vector& items, std::chrono::milliseconds timeout) -{ - return poll(items.data(), items.size(), static_cast(timeout.count())); -} - -ZMQ_DEPRECATED("from 4.3.1, use poll taking std::chrono instead of long") -inline int poll(std::vector& items, long timeout_ = -1) -{ - return poll(items.data(), items.size(), timeout_); -} - -template -inline int poll(std::array& items, - std::chrono::milliseconds timeout) -{ - return poll(items.data(), items.size(), static_cast(timeout.count())); -} -#endif - -inline void version(int* major_, int* minor_, int* patch_) -{ - zmq_version(major_, minor_, patch_); -} - -#ifdef ZMQ_CPP11 -inline std::tuple version() -{ - std::tuple v; - zmq_version(&std::get<0>(v), &std::get<1>(v), &std::get<2>(v)); - return v; -} - -#if !defined(ZMQ_CPP11_PARTIAL) -namespace detail -{ -template -struct is_char_type -{ - // true if character type for string literals in C++11 - static constexpr bool value = - std::is_same::value || std::is_same::value || - std::is_same::value || std::is_same::value; -}; -} // namespace detail -#endif - -#endif - -class message_t -{ -public: - message_t() ZMQ_NOTHROW - { - int rc = zmq_msg_init(&msg); - ZMQ_ASSERT(rc == 0); - } - - explicit message_t(size_t size_) - { - int rc = zmq_msg_init_size(&msg, size_); - if(rc != 0) - throw error_t(); - } - - template - message_t(ForwardIter first, ForwardIter last) - { - typedef typename std::iterator_traits::value_type value_t; - - assert(std::distance(first, last) >= 0); - size_t const size_ = - static_cast(std::distance(first, last)) * sizeof(value_t); - int const rc = zmq_msg_init_size(&msg, size_); - if(rc != 0) - throw error_t(); - std::copy(first, last, data()); - } - - message_t(const void* data_, size_t size_) - { - int rc = zmq_msg_init_size(&msg, size_); - if(rc != 0) - throw error_t(); - if(size_) - { - // this constructor allows (nullptr, 0), - // memcpy with a null pointer is UB - memcpy(data(), data_, size_); - } - } - - message_t(void* data_, size_t size_, free_fn* ffn_, void* hint_ = ZMQ_NULLPTR) - { - int rc = zmq_msg_init_data(&msg, data_, size_, ffn_, hint_); - if(rc != 0) - throw error_t(); - } - - // overload set of string-like types and generic containers -#if defined(ZMQ_CPP11) && !defined(ZMQ_CPP11_PARTIAL) - // NOTE this constructor will include the null terminator - // when called with a string literal. - // An overload taking const char* can not be added because - // it would be preferred over this function and break compatibility. - template ::value>::type> - ZMQ_DEPRECATED("from 4.7.0, use constructors taking iterators, (pointer, size) " - "or strings instead") - explicit message_t(const Char (&data)[N]) - : message_t(detail::ranges::begin(data), detail::ranges::end(data)) - {} - - template ::value && - ZMQ_IS_TRIVIALLY_COPYABLE(detail::range_value_t) && - !detail::is_char_type>::value && - !std::is_same::value>::type> - explicit message_t(const Range& rng) - : message_t(detail::ranges::begin(rng), detail::ranges::end(rng)) - {} - - explicit message_t(const std::string& str) : message_t(str.data(), str.size()) - {} - -#if CPPZMQ_HAS_STRING_VIEW - explicit message_t(std::string_view str) : message_t(str.data(), str.size()) - {} -#endif - -#endif - -#ifdef ZMQ_HAS_RVALUE_REFS - message_t(message_t&& rhs) ZMQ_NOTHROW : msg(rhs.msg) - { - int rc = zmq_msg_init(&rhs.msg); - ZMQ_ASSERT(rc == 0); - } - - message_t& operator=(message_t&& rhs) ZMQ_NOTHROW - { - std::swap(msg, rhs.msg); - return *this; - } -#endif - - ~message_t() ZMQ_NOTHROW - { - int rc = zmq_msg_close(&msg); - ZMQ_ASSERT(rc == 0); - } - - void rebuild() - { - int rc = zmq_msg_close(&msg); - if(rc != 0) - throw error_t(); - rc = zmq_msg_init(&msg); - ZMQ_ASSERT(rc == 0); - } - - void rebuild(size_t size_) - { - int rc = zmq_msg_close(&msg); - if(rc != 0) - throw error_t(); - rc = zmq_msg_init_size(&msg, size_); - if(rc != 0) - throw error_t(); - } - - void rebuild(const void* data_, size_t size_) - { - int rc = zmq_msg_close(&msg); - if(rc != 0) - throw error_t(); - rc = zmq_msg_init_size(&msg, size_); - if(rc != 0) - throw error_t(); - memcpy(data(), data_, size_); - } - - void rebuild(void* data_, size_t size_, free_fn* ffn_, void* hint_ = ZMQ_NULLPTR) - { - int rc = zmq_msg_close(&msg); - if(rc != 0) - throw error_t(); - rc = zmq_msg_init_data(&msg, data_, size_, ffn_, hint_); - if(rc != 0) - throw error_t(); - } - - ZMQ_DEPRECATED("from 4.3.1, use move taking non-const reference instead") - void move(message_t const* msg_) - { - int rc = zmq_msg_move(&msg, const_cast(msg_->handle())); - if(rc != 0) - throw error_t(); - } - - void move(message_t& msg_) - { - int rc = zmq_msg_move(&msg, msg_.handle()); - if(rc != 0) - throw error_t(); - } - - ZMQ_DEPRECATED("from 4.3.1, use copy taking non-const reference instead") - void copy(message_t const* msg_) - { - int rc = zmq_msg_copy(&msg, const_cast(msg_->handle())); - if(rc != 0) - throw error_t(); - } - - void copy(message_t& msg_) - { - int rc = zmq_msg_copy(&msg, msg_.handle()); - if(rc != 0) - throw error_t(); - } - - bool more() const ZMQ_NOTHROW - { - int rc = zmq_msg_more(const_cast(&msg)); - return rc != 0; - } - - void* data() ZMQ_NOTHROW - { - return zmq_msg_data(&msg); - } - - const void* data() const ZMQ_NOTHROW - { - return zmq_msg_data(const_cast(&msg)); - } - - size_t size() const ZMQ_NOTHROW - { - return zmq_msg_size(const_cast(&msg)); - } - - ZMQ_NODISCARD bool empty() const ZMQ_NOTHROW - { - return size() == 0u; - } - - template - T* data() ZMQ_NOTHROW - { - return static_cast(data()); - } - - template - T const* data() const ZMQ_NOTHROW - { - return static_cast(data()); - } - - ZMQ_DEPRECATED("from 4.3.0, use operator== instead") - bool equal(const message_t* other) const ZMQ_NOTHROW - { - return *this == *other; - } - - bool operator==(const message_t& other) const ZMQ_NOTHROW - { - const size_t my_size = size(); - return my_size == other.size() && 0 == memcmp(data(), other.data(), my_size); - } - - bool operator!=(const message_t& other) const ZMQ_NOTHROW - { - return !(*this == other); - } - -#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3, 2, 0) - int get(int property_) - { - int value = zmq_msg_get(&msg, property_); - if(value == -1) - throw error_t(); - return value; - } -#endif - -#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 1, 0) - const char* gets(const char* property_) - { - const char* value = zmq_msg_gets(&msg, property_); - if(value == ZMQ_NULLPTR) - throw error_t(); - return value; - } -#endif - -#if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 0) - uint32_t routing_id() const - { - return zmq_msg_routing_id(const_cast(&msg)); - } - - void set_routing_id(uint32_t routing_id) - { - int rc = zmq_msg_set_routing_id(&msg, routing_id); - if(rc != 0) - throw error_t(); - } - - const char* group() const - { - return zmq_msg_group(const_cast(&msg)); - } - - void set_group(const char* group) - { - int rc = zmq_msg_set_group(&msg, group); - if(rc != 0) - throw error_t(); - } -#endif - - // interpret message content as a string - std::string to_string() const - { - return std::string(static_cast(data()), size()); - } -#if CPPZMQ_HAS_STRING_VIEW - // interpret message content as a string - std::string_view to_string_view() const noexcept - { - return std::string_view(static_cast(data()), size()); - } -#endif - - /** Dump content to string for debugging. - * Ascii chars are readable, the rest is printed as hex. - * Probably ridiculously slow. - * Use to_string() or to_string_view() for - * interpreting the message as a string. - */ - std::string str() const - { - // Partly mutuated from the same method in zmq::multipart_t - std::stringstream os; - - const unsigned char* msg_data = this->data(); - unsigned char byte; - size_t size = this->size(); - int is_ascii[2] = { 0, 0 }; - - os << "zmq::message_t [size " << std::dec << std::setw(3) << std::setfill('0') << size - << "] ("; - // Totally arbitrary - if(size >= 1000) - { - os << "... too big to print)"; - } - else - { - while(size--) - { - byte = *msg_data++; - - is_ascii[1] = (byte >= 32 && byte < 127); - if(is_ascii[1] != is_ascii[0]) - os << " "; // Separate text/non text - - if(is_ascii[1]) - { - os << byte; - } - else - { - os << std::hex << std::uppercase << std::setw(2) << std::setfill('0') - << static_cast(byte); - } - is_ascii[0] = is_ascii[1]; - } - os << ")"; - } - return os.str(); - } - - void swap(message_t& other) ZMQ_NOTHROW - { - // this assumes zmq::msg_t from libzmq is trivially relocatable - std::swap(msg, other.msg); - } - - ZMQ_NODISCARD zmq_msg_t* handle() ZMQ_NOTHROW - { - return &msg; - } - ZMQ_NODISCARD const zmq_msg_t* handle() const ZMQ_NOTHROW - { - return &msg; - } - -private: - // The underlying message - zmq_msg_t msg; - - // Disable implicit message copying, so that users won't use shared - // messages (less efficient) without being aware of the fact. - message_t(const message_t&) ZMQ_DELETED_FUNCTION; - void operator=(const message_t&) ZMQ_DELETED_FUNCTION; -}; - -inline void swap(message_t& a, message_t& b) ZMQ_NOTHROW -{ - a.swap(b); -} - -#ifdef ZMQ_CPP11 -enum class ctxopt -{ -#ifdef ZMQ_BLOCKY - blocky = ZMQ_BLOCKY, -#endif -#ifdef ZMQ_IO_THREADS - io_threads = ZMQ_IO_THREADS, -#endif -#ifdef ZMQ_THREAD_SCHED_POLICY - thread_sched_policy = ZMQ_THREAD_SCHED_POLICY, -#endif -#ifdef ZMQ_THREAD_PRIORITY - thread_priority = ZMQ_THREAD_PRIORITY, -#endif -#ifdef ZMQ_THREAD_AFFINITY_CPU_ADD - thread_affinity_cpu_add = ZMQ_THREAD_AFFINITY_CPU_ADD, -#endif -#ifdef ZMQ_THREAD_AFFINITY_CPU_REMOVE - thread_affinity_cpu_remove = ZMQ_THREAD_AFFINITY_CPU_REMOVE, -#endif -#ifdef ZMQ_THREAD_NAME_PREFIX - thread_name_prefix = ZMQ_THREAD_NAME_PREFIX, -#endif -#ifdef ZMQ_MAX_MSGSZ - max_msgsz = ZMQ_MAX_MSGSZ, -#endif -#ifdef ZMQ_ZERO_COPY_RECV - zero_copy_recv = ZMQ_ZERO_COPY_RECV, -#endif -#ifdef ZMQ_MAX_SOCKETS - max_sockets = ZMQ_MAX_SOCKETS, -#endif -#ifdef ZMQ_SOCKET_LIMIT - socket_limit = ZMQ_SOCKET_LIMIT, -#endif -#ifdef ZMQ_IPV6 - ipv6 = ZMQ_IPV6, -#endif -#ifdef ZMQ_MSG_T_SIZE - msg_t_size = ZMQ_MSG_T_SIZE -#endif -}; -#endif - -class context_t -{ -public: - context_t() - { - ptr = zmq_ctx_new(); - if(ptr == ZMQ_NULLPTR) - throw error_t(); - } - - explicit context_t(int io_threads_, int max_sockets_ = ZMQ_MAX_SOCKETS_DFLT) - { - ptr = zmq_ctx_new(); - if(ptr == ZMQ_NULLPTR) - throw error_t(); - - int rc = zmq_ctx_set(ptr, ZMQ_IO_THREADS, io_threads_); - ZMQ_ASSERT(rc == 0); - - rc = zmq_ctx_set(ptr, ZMQ_MAX_SOCKETS, max_sockets_); - ZMQ_ASSERT(rc == 0); - } - -#ifdef ZMQ_HAS_RVALUE_REFS - context_t(context_t&& rhs) ZMQ_NOTHROW : ptr(rhs.ptr) - { - rhs.ptr = ZMQ_NULLPTR; - } - context_t& operator=(context_t&& rhs) ZMQ_NOTHROW - { - close(); - std::swap(ptr, rhs.ptr); - return *this; - } -#endif - - ~context_t() ZMQ_NOTHROW - { - close(); - } - - ZMQ_CPP11_DEPRECATED("from 4.7.0, use set taking zmq::ctxopt instead") - int setctxopt(int option_, int optval_) - { - int rc = zmq_ctx_set(ptr, option_, optval_); - ZMQ_ASSERT(rc == 0); - return rc; - } - - ZMQ_CPP11_DEPRECATED("from 4.7.0, use get taking zmq::ctxopt instead") - int getctxopt(int option_) - { - return zmq_ctx_get(ptr, option_); - } - -#ifdef ZMQ_CPP11 - void set(ctxopt option, int optval) - { - int rc = zmq_ctx_set(ptr, static_cast(option), optval); - if(rc == -1) - throw error_t(); - } - - ZMQ_NODISCARD int get(ctxopt option) - { - int rc = zmq_ctx_get(ptr, static_cast(option)); - // some options have a default value of -1 - // which is unfortunate, and may result in errors - // that don't make sense - if(rc == -1) - throw error_t(); - return rc; - } -#endif - - // Terminates context (see also shutdown()). - void close() ZMQ_NOTHROW - { - if(ptr == ZMQ_NULLPTR) - return; - - int rc; - do - { - rc = zmq_ctx_destroy(ptr); - } while(rc == -1 && errno == EINTR); - - ZMQ_ASSERT(rc == 0); - ptr = ZMQ_NULLPTR; - } - - // Shutdown context in preparation for termination (close()). - // Causes all blocking socket operations and any further - // socket operations to return with ETERM. - void shutdown() ZMQ_NOTHROW - { - if(ptr == ZMQ_NULLPTR) - return; - int rc = zmq_ctx_shutdown(ptr); - ZMQ_ASSERT(rc == 0); - } - - // Be careful with this, it's probably only useful for - // using the C api together with an existing C++ api. - // Normally you should never need to use this. - ZMQ_EXPLICIT operator void*() ZMQ_NOTHROW - { - return ptr; - } - - ZMQ_EXPLICIT operator void const*() const ZMQ_NOTHROW - { - return ptr; - } - - ZMQ_NODISCARD void* handle() ZMQ_NOTHROW - { - return ptr; - } - - ZMQ_DEPRECATED("from 4.7.0, use handle() != nullptr instead") - operator bool() const ZMQ_NOTHROW - { - return ptr != ZMQ_NULLPTR; - } - - void swap(context_t& other) ZMQ_NOTHROW - { - std::swap(ptr, other.ptr); - } - -private: - void* ptr; - - context_t(const context_t&) ZMQ_DELETED_FUNCTION; - void operator=(const context_t&) ZMQ_DELETED_FUNCTION; -}; - -inline void swap(context_t& a, context_t& b) ZMQ_NOTHROW -{ - a.swap(b); -} - -#ifdef ZMQ_CPP11 - -struct recv_buffer_size -{ - size_t size; // number of bytes written to buffer - size_t untruncated_size; // untruncated message size in bytes - - ZMQ_NODISCARD bool truncated() const noexcept - { - return size != untruncated_size; - } -}; - -#if CPPZMQ_HAS_OPTIONAL - -using send_result_t = std::optional; -using recv_result_t = std::optional; -using recv_buffer_result_t = std::optional; - -#else - -namespace detail -{ -// A C++11 type emulating the most basic -// operations of std::optional for trivial types -template -class trivial_optional -{ -public: - static_assert(std::is_trivial::value, "T must be trivial"); - using value_type = T; - - trivial_optional() = default; - trivial_optional(T value) noexcept : _value(value), _has_value(true) - {} - - const T* operator->() const noexcept - { - assert(_has_value); - return &_value; - } - T* operator->() noexcept - { - assert(_has_value); - return &_value; - } - - const T& operator*() const noexcept - { - assert(_has_value); - return _value; - } - T& operator*() noexcept - { - assert(_has_value); - return _value; - } - - T& value() - { - if(!_has_value) - throw std::exception(); - return _value; - } - const T& value() const - { - if(!_has_value) - throw std::exception(); - return _value; - } - - explicit operator bool() const noexcept - { - return _has_value; - } - bool has_value() const noexcept - { - return _has_value; - } - -private: - T _value{}; - bool _has_value{ false }; -}; -} // namespace detail - -using send_result_t = detail::trivial_optional; -using recv_result_t = detail::trivial_optional; -using recv_buffer_result_t = detail::trivial_optional; - -#endif - -namespace detail -{ -template -constexpr T enum_bit_or(T a, T b) noexcept -{ - static_assert(std::is_enum::value, "must be enum"); - using U = typename std::underlying_type::type; - return static_cast(static_cast(a) | static_cast(b)); -} -template -constexpr T enum_bit_and(T a, T b) noexcept -{ - static_assert(std::is_enum::value, "must be enum"); - using U = typename std::underlying_type::type; - return static_cast(static_cast(a) & static_cast(b)); -} -template -constexpr T enum_bit_xor(T a, T b) noexcept -{ - static_assert(std::is_enum::value, "must be enum"); - using U = typename std::underlying_type::type; - return static_cast(static_cast(a) ^ static_cast(b)); -} -template -constexpr T enum_bit_not(T a) noexcept -{ - static_assert(std::is_enum::value, "must be enum"); - using U = typename std::underlying_type::type; - return static_cast(~static_cast(a)); -} -} // namespace detail - -// partially satisfies named requirement BitmaskType -enum class send_flags : int -{ - none = 0, - dontwait = ZMQ_DONTWAIT, - sndmore = ZMQ_SNDMORE -}; - -constexpr send_flags operator|(send_flags a, send_flags b) noexcept -{ - return detail::enum_bit_or(a, b); -} -constexpr send_flags operator&(send_flags a, send_flags b) noexcept -{ - return detail::enum_bit_and(a, b); -} -constexpr send_flags operator^(send_flags a, send_flags b) noexcept -{ - return detail::enum_bit_xor(a, b); -} -constexpr send_flags operator~(send_flags a) noexcept -{ - return detail::enum_bit_not(a); -} - -// partially satisfies named requirement BitmaskType -enum class recv_flags : int -{ - none = 0, - dontwait = ZMQ_DONTWAIT -}; - -constexpr recv_flags operator|(recv_flags a, recv_flags b) noexcept -{ - return detail::enum_bit_or(a, b); -} -constexpr recv_flags operator&(recv_flags a, recv_flags b) noexcept -{ - return detail::enum_bit_and(a, b); -} -constexpr recv_flags operator^(recv_flags a, recv_flags b) noexcept -{ - return detail::enum_bit_xor(a, b); -} -constexpr recv_flags operator~(recv_flags a) noexcept -{ - return detail::enum_bit_not(a); -} - -// mutable_buffer, const_buffer and buffer are based on -// the Networking TS specification, draft: -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4771.pdf - -class mutable_buffer -{ -public: - constexpr mutable_buffer() noexcept : _data(nullptr), _size(0) - {} - constexpr mutable_buffer(void* p, size_t n) noexcept : _data(p), _size(n) - { -#ifdef ZMQ_EXTENDED_CONSTEXPR - assert(p != nullptr || n == 0); -#endif - } - - constexpr void* data() const noexcept - { - return _data; - } - constexpr size_t size() const noexcept - { - return _size; - } - mutable_buffer& operator+=(size_t n) noexcept - { - // (std::min) is a workaround for when a min macro is defined - const auto shift = (std::min)(n, _size); - _data = static_cast(_data) + shift; - _size -= shift; - return *this; - } - -private: - void* _data; - size_t _size; -}; - -inline mutable_buffer operator+(const mutable_buffer& mb, size_t n) noexcept -{ - return mutable_buffer(static_cast(mb.data()) + (std::min)(n, mb.size()), - mb.size() - (std::min)(n, mb.size())); -} -inline mutable_buffer operator+(size_t n, const mutable_buffer& mb) noexcept -{ - return mb + n; -} - -class const_buffer -{ -public: - constexpr const_buffer() noexcept : _data(nullptr), _size(0) - {} - constexpr const_buffer(const void* p, size_t n) noexcept : _data(p), _size(n) - { -#ifdef ZMQ_EXTENDED_CONSTEXPR - assert(p != nullptr || n == 0); -#endif - } - constexpr const_buffer(const mutable_buffer& mb) noexcept - : _data(mb.data()), _size(mb.size()) - {} - - constexpr const void* data() const noexcept - { - return _data; - } - constexpr size_t size() const noexcept - { - return _size; - } - const_buffer& operator+=(size_t n) noexcept - { - const auto shift = (std::min)(n, _size); - _data = static_cast(_data) + shift; - _size -= shift; - return *this; - } - -private: - const void* _data; - size_t _size; -}; - -inline const_buffer operator+(const const_buffer& cb, size_t n) noexcept -{ - return const_buffer(static_cast(cb.data()) + (std::min)(n, cb.size()), - cb.size() - (std::min)(n, cb.size())); -} -inline const_buffer operator+(size_t n, const const_buffer& cb) noexcept -{ - return cb + n; -} - -// buffer creation - -constexpr mutable_buffer buffer(void* p, size_t n) noexcept -{ - return mutable_buffer(p, n); -} -constexpr const_buffer buffer(const void* p, size_t n) noexcept -{ - return const_buffer(p, n); -} -constexpr mutable_buffer buffer(const mutable_buffer& mb) noexcept -{ - return mb; -} -inline mutable_buffer buffer(const mutable_buffer& mb, size_t n) noexcept -{ - return mutable_buffer(mb.data(), (std::min)(mb.size(), n)); -} -constexpr const_buffer buffer(const const_buffer& cb) noexcept -{ - return cb; -} -inline const_buffer buffer(const const_buffer& cb, size_t n) noexcept -{ - return const_buffer(cb.data(), (std::min)(cb.size(), n)); -} - -namespace detail -{ -template -struct is_buffer -{ - static constexpr bool value = - std::is_same::value || std::is_same::value; -}; - -template -struct is_pod_like -{ - // NOTE: The networking draft N4771 section 16.11 requires - // T in the buffer functions below to be - // trivially copyable OR standard layout. - // Here we decide to be conservative and require both. - static constexpr bool value = - ZMQ_IS_TRIVIALLY_COPYABLE(T) && std::is_standard_layout::value; -}; - -template -constexpr auto seq_size(const C& c) noexcept -> decltype(c.size()) -{ - return c.size(); -} -template -constexpr size_t seq_size(const T (& /*array*/)[N]) noexcept -{ - return N; -} - -template -auto buffer_contiguous_sequence(Seq&& seq) noexcept - -> decltype(buffer(std::addressof(*std::begin(seq)), size_t{})) -{ - using T = typename std::remove_cv< - typename std::remove_reference::type>::type; - static_assert(detail::is_pod_like::value, "T must be POD"); - - const auto size = seq_size(seq); - return buffer(size != 0u ? std::addressof(*std::begin(seq)) : nullptr, - size * sizeof(T)); -} -template -auto buffer_contiguous_sequence(Seq&& seq, size_t n_bytes) noexcept - -> decltype(buffer_contiguous_sequence(seq)) -{ - using T = typename std::remove_cv< - typename std::remove_reference::type>::type; - static_assert(detail::is_pod_like::value, "T must be POD"); - - const auto size = seq_size(seq); - return buffer(size != 0u ? std::addressof(*std::begin(seq)) : nullptr, - (std::min)(size * sizeof(T), n_bytes)); -} - -} // namespace detail - -// C array -template -mutable_buffer buffer(T (&data)[N]) noexcept -{ - return detail::buffer_contiguous_sequence(data); -} -template -mutable_buffer buffer(T (&data)[N], size_t n_bytes) noexcept -{ - return detail::buffer_contiguous_sequence(data, n_bytes); -} -template -const_buffer buffer(const T (&data)[N]) noexcept -{ - return detail::buffer_contiguous_sequence(data); -} -template -const_buffer buffer(const T (&data)[N], size_t n_bytes) noexcept -{ - return detail::buffer_contiguous_sequence(data, n_bytes); -} -// std::array -template -mutable_buffer buffer(std::array& data) noexcept -{ - return detail::buffer_contiguous_sequence(data); -} -template -mutable_buffer buffer(std::array& data, size_t n_bytes) noexcept -{ - return detail::buffer_contiguous_sequence(data, n_bytes); -} -template -const_buffer buffer(std::array& data) noexcept -{ - return detail::buffer_contiguous_sequence(data); -} -template -const_buffer buffer(std::array& data, size_t n_bytes) noexcept -{ - return detail::buffer_contiguous_sequence(data, n_bytes); -} -template -const_buffer buffer(const std::array& data) noexcept -{ - return detail::buffer_contiguous_sequence(data); -} -template -const_buffer buffer(const std::array& data, size_t n_bytes) noexcept -{ - return detail::buffer_contiguous_sequence(data, n_bytes); -} -// std::vector -template -mutable_buffer buffer(std::vector& data) noexcept -{ - return detail::buffer_contiguous_sequence(data); -} -template -mutable_buffer buffer(std::vector& data, size_t n_bytes) noexcept -{ - return detail::buffer_contiguous_sequence(data, n_bytes); -} -template -const_buffer buffer(const std::vector& data) noexcept -{ - return detail::buffer_contiguous_sequence(data); -} -template -const_buffer buffer(const std::vector& data, size_t n_bytes) noexcept -{ - return detail::buffer_contiguous_sequence(data, n_bytes); -} -// std::basic_string -template -mutable_buffer buffer(std::basic_string& data) noexcept -{ - return detail::buffer_contiguous_sequence(data); -} -template -mutable_buffer buffer(std::basic_string& data, - size_t n_bytes) noexcept -{ - return detail::buffer_contiguous_sequence(data, n_bytes); -} -template -const_buffer buffer(const std::basic_string& data) noexcept -{ - return detail::buffer_contiguous_sequence(data); -} -template -const_buffer buffer(const std::basic_string& data, - size_t n_bytes) noexcept -{ - return detail::buffer_contiguous_sequence(data, n_bytes); -} - -#if CPPZMQ_HAS_STRING_VIEW -// std::basic_string_view -template -const_buffer buffer(std::basic_string_view data) noexcept -{ - return detail::buffer_contiguous_sequence(data); -} -template -const_buffer buffer(std::basic_string_view data, size_t n_bytes) noexcept -{ - return detail::buffer_contiguous_sequence(data, n_bytes); -} -#endif - -// Buffer for a string literal (null terminated) -// where the buffer size excludes the terminating character. -// Equivalent to zmq::buffer(std::string_view("...")). -template -constexpr const_buffer str_buffer(const Char (&data)[N]) noexcept -{ - static_assert(detail::is_pod_like::value, "Char must be POD"); -#ifdef ZMQ_EXTENDED_CONSTEXPR - assert(data[N - 1] == Char{ 0 }); -#endif - return const_buffer(static_cast(data), (N - 1) * sizeof(Char)); -} - -namespace literals -{ -constexpr const_buffer operator"" _zbuf(const char* str, size_t len) noexcept -{ - return const_buffer(str, len * sizeof(char)); -} -constexpr const_buffer operator"" _zbuf(const wchar_t* str, size_t len) noexcept -{ - return const_buffer(str, len * sizeof(wchar_t)); -} -constexpr const_buffer operator"" _zbuf(const char16_t* str, size_t len) noexcept -{ - return const_buffer(str, len * sizeof(char16_t)); -} -constexpr const_buffer operator"" _zbuf(const char32_t* str, size_t len) noexcept -{ - return const_buffer(str, len * sizeof(char32_t)); -} -} // namespace literals - -#endif // ZMQ_CPP11 - -#ifdef ZMQ_CPP11 -namespace sockopt -{ -// There are two types of options, -// integral type with known compiler time size (int, bool, int64_t, uint64_t) -// and arrays with dynamic size (strings, binary data). - -// BoolUnit: if true accepts values of type bool (but passed as T into libzmq) -template -struct integral_option -{ -}; - -// NullTerm: -// 0: binary data -// 1: null-terminated string (`getsockopt` size includes null) -// 2: binary (size 32) or Z85 encoder string of size 41 (null included) -template -struct array_option -{ -}; - -#define ZMQ_DEFINE_INTEGRAL_OPT(OPT, NAME, TYPE) \ - using NAME##_t = integral_option; \ - ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME \ - {} -#define ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(OPT, NAME, TYPE) \ - using NAME##_t = integral_option; \ - ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME \ - {} -#define ZMQ_DEFINE_ARRAY_OPT(OPT, NAME) \ - using NAME##_t = array_option; \ - ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME \ - {} -#define ZMQ_DEFINE_ARRAY_OPT_BINARY(OPT, NAME) \ - using NAME##_t = array_option; \ - ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME \ - {} -#define ZMQ_DEFINE_ARRAY_OPT_BIN_OR_Z85(OPT, NAME) \ - using NAME##_t = array_option; \ - ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME \ - {} - -// duplicate definition from libzmq 4.3.3 -#if defined _WIN32 -#if defined _WIN64 -typedef unsigned __int64 cppzmq_fd_t; -#else -typedef unsigned int cppzmq_fd_t; -#endif -#else -typedef int cppzmq_fd_t; -#endif - -#ifdef ZMQ_AFFINITY -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_AFFINITY, affinity, uint64_t); -#endif -#ifdef ZMQ_BACKLOG -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_BACKLOG, backlog, int); -#endif -#ifdef ZMQ_BINDTODEVICE -ZMQ_DEFINE_ARRAY_OPT_BINARY(ZMQ_BINDTODEVICE, bindtodevice); -#endif -#ifdef ZMQ_CONFLATE -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_CONFLATE, conflate, int); -#endif -#ifdef ZMQ_CONNECT_ROUTING_ID -ZMQ_DEFINE_ARRAY_OPT(ZMQ_CONNECT_ROUTING_ID, connect_routing_id); -#endif -#ifdef ZMQ_CONNECT_TIMEOUT -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_CONNECT_TIMEOUT, connect_timeout, int); -#endif -#ifdef ZMQ_CURVE_PUBLICKEY -ZMQ_DEFINE_ARRAY_OPT_BIN_OR_Z85(ZMQ_CURVE_PUBLICKEY, curve_publickey); -#endif -#ifdef ZMQ_CURVE_SECRETKEY -ZMQ_DEFINE_ARRAY_OPT_BIN_OR_Z85(ZMQ_CURVE_SECRETKEY, curve_secretkey); -#endif -#ifdef ZMQ_CURVE_SERVER -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_CURVE_SERVER, curve_server, int); -#endif -#ifdef ZMQ_CURVE_SERVERKEY -ZMQ_DEFINE_ARRAY_OPT_BIN_OR_Z85(ZMQ_CURVE_SERVERKEY, curve_serverkey); -#endif -#ifdef ZMQ_EVENTS -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_EVENTS, events, int); -#endif -#ifdef ZMQ_FD -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_FD, fd, cppzmq_fd_t); -#endif -#ifdef ZMQ_GSSAPI_PLAINTEXT -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_GSSAPI_PLAINTEXT, gssapi_plaintext, int); -#endif -#ifdef ZMQ_GSSAPI_SERVER -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_GSSAPI_SERVER, gssapi_server, int); -#endif -#ifdef ZMQ_GSSAPI_SERVICE_PRINCIPAL -ZMQ_DEFINE_ARRAY_OPT(ZMQ_GSSAPI_SERVICE_PRINCIPAL, gssapi_service_principal); -#endif -#ifdef ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE, - gssapi_service_principal_nametype, int); -#endif -#ifdef ZMQ_GSSAPI_PRINCIPAL -ZMQ_DEFINE_ARRAY_OPT(ZMQ_GSSAPI_PRINCIPAL, gssapi_principal); -#endif -#ifdef ZMQ_GSSAPI_PRINCIPAL_NAMETYPE -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_GSSAPI_PRINCIPAL_NAMETYPE, gssapi_principal_nametype, int); -#endif -#ifdef ZMQ_HANDSHAKE_IVL -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_HANDSHAKE_IVL, handshake_ivl, int); -#endif -#ifdef ZMQ_HEARTBEAT_IVL -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_HEARTBEAT_IVL, heartbeat_ivl, int); -#endif -#ifdef ZMQ_HEARTBEAT_TIMEOUT -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_HEARTBEAT_TIMEOUT, heartbeat_timeout, int); -#endif -#ifdef ZMQ_HEARTBEAT_TTL -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_HEARTBEAT_TTL, heartbeat_ttl, int); -#endif -#ifdef ZMQ_IMMEDIATE -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_IMMEDIATE, immediate, int); -#endif -#ifdef ZMQ_INVERT_MATCHING -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_INVERT_MATCHING, invert_matching, int); -#endif -#ifdef ZMQ_IPV6 -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_IPV6, ipv6, int); -#endif -#ifdef ZMQ_LAST_ENDPOINT -ZMQ_DEFINE_ARRAY_OPT(ZMQ_LAST_ENDPOINT, last_endpoint); -#endif -#ifdef ZMQ_LINGER -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_LINGER, linger, int); -#endif -#ifdef ZMQ_MAXMSGSIZE -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_MAXMSGSIZE, maxmsgsize, int64_t); -#endif -#ifdef ZMQ_MECHANISM -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_MECHANISM, mechanism, int); -#endif -#ifdef ZMQ_METADATA -ZMQ_DEFINE_ARRAY_OPT(ZMQ_METADATA, metadata); -#endif -#ifdef ZMQ_MULTICAST_HOPS -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_MULTICAST_HOPS, multicast_hops, int); -#endif -#ifdef ZMQ_MULTICAST_LOOP -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_MULTICAST_LOOP, multicast_loop, int); -#endif -#ifdef ZMQ_MULTICAST_MAXTPDU -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_MULTICAST_MAXTPDU, multicast_maxtpdu, int); -#endif -#ifdef ZMQ_PLAIN_SERVER -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_PLAIN_SERVER, plain_server, int); -#endif -#ifdef ZMQ_PLAIN_PASSWORD -ZMQ_DEFINE_ARRAY_OPT(ZMQ_PLAIN_PASSWORD, plain_password); -#endif -#ifdef ZMQ_PLAIN_USERNAME -ZMQ_DEFINE_ARRAY_OPT(ZMQ_PLAIN_USERNAME, plain_username); -#endif -#ifdef ZMQ_USE_FD -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_USE_FD, use_fd, int); -#endif -#ifdef ZMQ_PROBE_ROUTER -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_PROBE_ROUTER, probe_router, int); -#endif -#ifdef ZMQ_RATE -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RATE, rate, int); -#endif -#ifdef ZMQ_RCVBUF -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RCVBUF, rcvbuf, int); -#endif -#ifdef ZMQ_RCVHWM -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RCVHWM, rcvhwm, int); -#endif -#ifdef ZMQ_RCVMORE -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_RCVMORE, rcvmore, int); -#endif -#ifdef ZMQ_RCVTIMEO -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RCVTIMEO, rcvtimeo, int); -#endif -#ifdef ZMQ_RECONNECT_IVL -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RECONNECT_IVL, reconnect_ivl, int); -#endif -#ifdef ZMQ_RECONNECT_IVL_MAX -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RECONNECT_IVL_MAX, reconnect_ivl_max, int); -#endif -#ifdef ZMQ_RECOVERY_IVL -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RECOVERY_IVL, recovery_ivl, int); -#endif -#ifdef ZMQ_REQ_CORRELATE -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_REQ_CORRELATE, req_correlate, int); -#endif -#ifdef ZMQ_REQ_RELAXED -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_REQ_RELAXED, req_relaxed, int); -#endif -#ifdef ZMQ_ROUTER_HANDOVER -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_ROUTER_HANDOVER, router_handover, int); -#endif -#ifdef ZMQ_ROUTER_MANDATORY -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_ROUTER_MANDATORY, router_mandatory, int); -#endif -#ifdef ZMQ_ROUTER_NOTIFY -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_ROUTER_NOTIFY, router_notify, int); -#endif -#ifdef ZMQ_ROUTING_ID -ZMQ_DEFINE_ARRAY_OPT_BINARY(ZMQ_ROUTING_ID, routing_id); -#endif -#ifdef ZMQ_SNDBUF -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_SNDBUF, sndbuf, int); -#endif -#ifdef ZMQ_SNDHWM -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_SNDHWM, sndhwm, int); -#endif -#ifdef ZMQ_SNDTIMEO -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_SNDTIMEO, sndtimeo, int); -#endif -#ifdef ZMQ_SOCKS_PROXY -ZMQ_DEFINE_ARRAY_OPT(ZMQ_SOCKS_PROXY, socks_proxy); -#endif -#ifdef ZMQ_STREAM_NOTIFY -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_STREAM_NOTIFY, stream_notify, int); -#endif -#ifdef ZMQ_SUBSCRIBE -ZMQ_DEFINE_ARRAY_OPT(ZMQ_SUBSCRIBE, subscribe); -#endif -#ifdef ZMQ_TCP_KEEPALIVE -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_KEEPALIVE, tcp_keepalive, int); -#endif -#ifdef ZMQ_TCP_KEEPALIVE_CNT -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_KEEPALIVE_CNT, tcp_keepalive_cnt, int); -#endif -#ifdef ZMQ_TCP_KEEPALIVE_IDLE -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_KEEPALIVE_IDLE, tcp_keepalive_idle, int); -#endif -#ifdef ZMQ_TCP_KEEPALIVE_INTVL -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_KEEPALIVE_INTVL, tcp_keepalive_intvl, int); -#endif -#ifdef ZMQ_TCP_MAXRT -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_MAXRT, tcp_maxrt, int); -#endif -#ifdef ZMQ_THREAD_SAFE -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_THREAD_SAFE, thread_safe, int); -#endif -#ifdef ZMQ_TOS -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TOS, tos, int); -#endif -#ifdef ZMQ_TYPE -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TYPE, type, int); -#endif -#ifdef ZMQ_UNSUBSCRIBE -ZMQ_DEFINE_ARRAY_OPT(ZMQ_UNSUBSCRIBE, unsubscribe); -#endif -#ifdef ZMQ_VMCI_BUFFER_SIZE -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_VMCI_BUFFER_SIZE, vmci_buffer_size, uint64_t); -#endif -#ifdef ZMQ_VMCI_BUFFER_MIN_SIZE -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_VMCI_BUFFER_MIN_SIZE, vmci_buffer_min_size, uint64_t); -#endif -#ifdef ZMQ_VMCI_BUFFER_MAX_SIZE -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_VMCI_BUFFER_MAX_SIZE, vmci_buffer_max_size, uint64_t); -#endif -#ifdef ZMQ_VMCI_CONNECT_TIMEOUT -ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_VMCI_CONNECT_TIMEOUT, vmci_connect_timeout, int); -#endif -#ifdef ZMQ_XPUB_VERBOSE -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_XPUB_VERBOSE, xpub_verbose, int); -#endif -#ifdef ZMQ_XPUB_VERBOSER -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_XPUB_VERBOSER, xpub_verboser, int); -#endif -#ifdef ZMQ_XPUB_MANUAL -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_XPUB_MANUAL, xpub_manual, int); -#endif -#ifdef ZMQ_XPUB_NODROP -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_XPUB_NODROP, xpub_nodrop, int); -#endif -#ifdef ZMQ_XPUB_WELCOME_MSG -ZMQ_DEFINE_ARRAY_OPT(ZMQ_XPUB_WELCOME_MSG, xpub_welcome_msg); -#endif -#ifdef ZMQ_ZAP_ENFORCE_DOMAIN -ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_ZAP_ENFORCE_DOMAIN, zap_enforce_domain, int); -#endif -#ifdef ZMQ_ZAP_DOMAIN -ZMQ_DEFINE_ARRAY_OPT(ZMQ_ZAP_DOMAIN, zap_domain); -#endif - -} // namespace sockopt -#endif // ZMQ_CPP11 - -namespace detail -{ -class socket_base -{ -public: - socket_base() ZMQ_NOTHROW : _handle(ZMQ_NULLPTR) - {} - ZMQ_EXPLICIT socket_base(void* handle) ZMQ_NOTHROW : _handle(handle) - {} - - template - ZMQ_CPP11_DEPRECATED("from 4.7.0, use `set` taking option from zmq::sockopt") - void setsockopt(int option_, T const& optval) - { - setsockopt(option_, &optval, sizeof(T)); - } - - ZMQ_CPP11_DEPRECATED("from 4.7.0, use `set` taking option from zmq::sockopt") - void setsockopt(int option_, const void* optval_, size_t optvallen_) - { - int rc = zmq_setsockopt(_handle, option_, optval_, optvallen_); - if(rc != 0) - throw error_t(); - } - - ZMQ_CPP11_DEPRECATED("from 4.7.0, use `get` taking option from zmq::sockopt") - void getsockopt(int option_, void* optval_, size_t* optvallen_) const - { - int rc = zmq_getsockopt(_handle, option_, optval_, optvallen_); - if(rc != 0) - throw error_t(); - } - - template - ZMQ_CPP11_DEPRECATED("from 4.7.0, use `get` taking option from zmq::sockopt") - T getsockopt(int option_) const - { - T optval; - size_t optlen = sizeof(T); - getsockopt(option_, &optval, &optlen); - return optval; - } - -#ifdef ZMQ_CPP11 - // Set integral socket option, e.g. - // `socket.set(zmq::sockopt::linger, 0)` - template - void set(sockopt::integral_option, const T& val) - { - static_assert(std::is_integral::value, "T must be integral"); - set_option(Opt, &val, sizeof val); - } - - // Set integral socket option from boolean, e.g. - // `socket.set(zmq::sockopt::immediate, false)` - template - void set(sockopt::integral_option, bool val) - { - static_assert(std::is_integral::value, "T must be integral"); - T rep_val = val; - set_option(Opt, &rep_val, sizeof rep_val); - } - - // Set array socket option, e.g. - // `socket.set(zmq::sockopt::plain_username, "foo123")` - template - void set(sockopt::array_option, const char* buf) - { - set_option(Opt, buf, std::strlen(buf)); - } - - // Set array socket option, e.g. - // `socket.set(zmq::sockopt::routing_id, zmq::buffer(id))` - template - void set(sockopt::array_option, const_buffer buf) - { - set_option(Opt, buf.data(), buf.size()); - } - - // Set array socket option, e.g. - // `socket.set(zmq::sockopt::routing_id, id_str)` - template - void set(sockopt::array_option, const std::string& buf) - { - set_option(Opt, buf.data(), buf.size()); - } - -#if CPPZMQ_HAS_STRING_VIEW - // Set array socket option, e.g. - // `socket.set(zmq::sockopt::routing_id, id_str)` - template - void set(sockopt::array_option, std::string_view buf) - { - set_option(Opt, buf.data(), buf.size()); - } -#endif - - // Get scalar socket option, e.g. - // `auto opt = socket.get(zmq::sockopt::linger)` - template - ZMQ_NODISCARD T get(sockopt::integral_option) const - { - static_assert(std::is_integral::value, "T must be integral"); - T val; - size_t size = sizeof val; - get_option(Opt, &val, &size); - assert(size == sizeof val); - return val; - } - - // Get array socket option, writes to buf, returns option size in bytes, e.g. - // `size_t optsize = socket.get(zmq::sockopt::routing_id, zmq::buffer(id))` - template - ZMQ_NODISCARD size_t get(sockopt::array_option, mutable_buffer buf) const - { - size_t size = buf.size(); - get_option(Opt, buf.data(), &size); - return size; - } - - // Get array socket option as string (initializes the string buffer size to init_size) e.g. - // `auto s = socket.get(zmq::sockopt::routing_id)` - // Note: removes the null character from null-terminated string options, - // i.e. the string size excludes the null character. - template - ZMQ_NODISCARD std::string get(sockopt::array_option, - size_t init_size = 1024) const - { - if(NullTerm == 2 && init_size == 1024) - { - init_size = 41; // get as Z85 string - } - std::string str(init_size, '\0'); - size_t size = get(sockopt::array_option{}, buffer(str)); - if(NullTerm == 1) - { - if(size > 0) - { - assert(str[size - 1] == '\0'); - --size; - } - } - else if(NullTerm == 2) - { - assert(size == 32 || size == 41); - if(size == 41) - { - assert(str[size - 1] == '\0'); - --size; - } - } - str.resize(size); - return str; - } -#endif - - void bind(std::string const& addr) - { - bind(addr.c_str()); - } - - void bind(const char* addr_) - { - int rc = zmq_bind(_handle, addr_); - if(rc != 0) - throw error_t(); - } - - void unbind(std::string const& addr) - { - unbind(addr.c_str()); - } - - void unbind(const char* addr_) - { - int rc = zmq_unbind(_handle, addr_); - if(rc != 0) - throw error_t(); - } - - void connect(std::string const& addr) - { - connect(addr.c_str()); - } - - void connect(const char* addr_) - { - int rc = zmq_connect(_handle, addr_); - if(rc != 0) - throw error_t(); - } - - void disconnect(std::string const& addr) - { - disconnect(addr.c_str()); - } - - void disconnect(const char* addr_) - { - int rc = zmq_disconnect(_handle, addr_); - if(rc != 0) - throw error_t(); - } - - bool connected() const ZMQ_NOTHROW - { - return (_handle != ZMQ_NULLPTR); - } - - ZMQ_CPP11_DEPRECATED("from 4.3.1, use send taking a const_buffer and send_flags") - size_t send(const void* buf_, size_t len_, int flags_ = 0) - { - int nbytes = zmq_send(_handle, buf_, len_, flags_); - if(nbytes >= 0) - return static_cast(nbytes); - if(zmq_errno() == EAGAIN) - return 0; - throw error_t(); - } - - ZMQ_CPP11_DEPRECATED("from 4.3.1, use send taking message_t and send_flags") - bool send(message_t& msg_, - int flags_ = 0) // default until removed - { - int nbytes = zmq_msg_send(msg_.handle(), _handle, flags_); - if(nbytes >= 0) - return true; - if(zmq_errno() == EAGAIN) - return false; - throw error_t(); - } - - template - ZMQ_CPP11_DEPRECATED("from 4.4.1, use send taking message_t or buffer (for contiguous " - "ranges), and send_flags") - bool send(T first, T last, int flags_ = 0) - { - zmq::message_t msg(first, last); - int nbytes = zmq_msg_send(msg.handle(), _handle, flags_); - if(nbytes >= 0) - return true; - if(zmq_errno() == EAGAIN) - return false; - throw error_t(); - } - -#ifdef ZMQ_HAS_RVALUE_REFS - ZMQ_CPP11_DEPRECATED("from 4.3.1, use send taking message_t and send_flags") - bool send(message_t&& msg_, - int flags_ = 0) // default until removed - { -#ifdef ZMQ_CPP11 - return send(msg_, static_cast(flags_)).has_value(); -#else - return send(msg_, flags_); -#endif - } -#endif - -#ifdef ZMQ_CPP11 - send_result_t send(const_buffer buf, send_flags flags = send_flags::none) - { - const int nbytes = zmq_send(_handle, buf.data(), buf.size(), static_cast(flags)); - if(nbytes >= 0) - return static_cast(nbytes); - if(zmq_errno() == EAGAIN) - return {}; - throw error_t(); - } - - send_result_t send(message_t& msg, send_flags flags) - { - int nbytes = zmq_msg_send(msg.handle(), _handle, static_cast(flags)); - if(nbytes >= 0) - return static_cast(nbytes); - if(zmq_errno() == EAGAIN) - return {}; - throw error_t(); - } - - send_result_t send(message_t&& msg, send_flags flags) - { - return send(msg, flags); - } -#endif - - ZMQ_CPP11_DEPRECATED("from 4.3.1, use recv taking a mutable_buffer and recv_flags") - size_t recv(void* buf_, size_t len_, int flags_ = 0) - { - int nbytes = zmq_recv(_handle, buf_, len_, flags_); - if(nbytes >= 0) - return static_cast(nbytes); - if(zmq_errno() == EAGAIN) - return 0; - throw error_t(); - } - - ZMQ_CPP11_DEPRECATED("from 4.3.1, use recv taking a reference to message_t and " - "recv_flags") - bool recv(message_t* msg_, int flags_ = 0) - { - int nbytes = zmq_msg_recv(msg_->handle(), _handle, flags_); - if(nbytes >= 0) - return true; - if(zmq_errno() == EAGAIN) - return false; - throw error_t(); - } - -#ifdef ZMQ_CPP11 - ZMQ_NODISCARD - recv_buffer_result_t recv(mutable_buffer buf, recv_flags flags = recv_flags::none) - { - const int nbytes = zmq_recv(_handle, buf.data(), buf.size(), static_cast(flags)); - if(nbytes >= 0) - { - return recv_buffer_size{ (std::min)(static_cast(nbytes), buf.size()), - static_cast(nbytes) }; - } - if(zmq_errno() == EAGAIN) - return {}; - throw error_t(); - } - - ZMQ_NODISCARD - recv_result_t recv(message_t& msg, recv_flags flags = recv_flags::none) - { - const int nbytes = zmq_msg_recv(msg.handle(), _handle, static_cast(flags)); - if(nbytes >= 0) - { - assert(msg.size() == static_cast(nbytes)); - return static_cast(nbytes); - } - if(zmq_errno() == EAGAIN) - return {}; - throw error_t(); - } -#endif - -#if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 0) - void join(const char* group) - { - int rc = zmq_join(_handle, group); - if(rc != 0) - throw error_t(); - } - - void leave(const char* group) - { - int rc = zmq_leave(_handle, group); - if(rc != 0) - throw error_t(); - } -#endif - - ZMQ_NODISCARD void* handle() ZMQ_NOTHROW - { - return _handle; - } - ZMQ_NODISCARD const void* handle() const ZMQ_NOTHROW - { - return _handle; - } - - ZMQ_EXPLICIT operator bool() const ZMQ_NOTHROW - { - return _handle != ZMQ_NULLPTR; - } - // note: non-const operator bool can be removed once - // operator void* is removed from socket_t - ZMQ_EXPLICIT operator bool() ZMQ_NOTHROW - { - return _handle != ZMQ_NULLPTR; - } - -protected: - void* _handle; - -private: - void set_option(int option_, const void* optval_, size_t optvallen_) - { - int rc = zmq_setsockopt(_handle, option_, optval_, optvallen_); - if(rc != 0) - throw error_t(); - } - - void get_option(int option_, void* optval_, size_t* optvallen_) const - { - int rc = zmq_getsockopt(_handle, option_, optval_, optvallen_); - if(rc != 0) - throw error_t(); - } -}; -} // namespace detail - -#ifdef ZMQ_CPP11 -enum class socket_type : int -{ - req = ZMQ_REQ, - rep = ZMQ_REP, - dealer = ZMQ_DEALER, - router = ZMQ_ROUTER, - pub = ZMQ_PUB, - sub = ZMQ_SUB, - xpub = ZMQ_XPUB, - xsub = ZMQ_XSUB, - push = ZMQ_PUSH, - pull = ZMQ_PULL, -#if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 0) - server = ZMQ_SERVER, - client = ZMQ_CLIENT, - radio = ZMQ_RADIO, - dish = ZMQ_DISH, -#endif -#if ZMQ_VERSION_MAJOR >= 4 - stream = ZMQ_STREAM, -#endif - pair = ZMQ_PAIR -}; -#endif - -struct from_handle_t -{ - struct _private - { - }; // disabling use other than with from_handle - ZMQ_CONSTEXPR_FN ZMQ_EXPLICIT from_handle_t(_private /*p*/) ZMQ_NOTHROW - {} -}; - -ZMQ_CONSTEXPR_VAR from_handle_t from_handle = from_handle_t(from_handle_t::_private()); - -// A non-owning nullable reference to a socket. -// The reference is invalidated on socket close or destruction. -class socket_ref : public detail::socket_base -{ -public: - socket_ref() ZMQ_NOTHROW : detail::socket_base() - {} -#ifdef ZMQ_CPP11 - socket_ref(std::nullptr_t) ZMQ_NOTHROW : detail::socket_base() - {} -#endif - socket_ref(from_handle_t /*fh*/, void* handle) ZMQ_NOTHROW : detail::socket_base(handle) - {} -}; - -#ifdef ZMQ_CPP11 -inline bool operator==(socket_ref sr, std::nullptr_t /*p*/) ZMQ_NOTHROW -{ - return sr.handle() == nullptr; -} -inline bool operator==(std::nullptr_t /*p*/, socket_ref sr) ZMQ_NOTHROW -{ - return sr.handle() == nullptr; -} -inline bool operator!=(socket_ref sr, std::nullptr_t /*p*/) ZMQ_NOTHROW -{ - return !(sr == nullptr); -} -inline bool operator!=(std::nullptr_t /*p*/, socket_ref sr) ZMQ_NOTHROW -{ - return !(sr == nullptr); -} -#endif - -inline bool operator==(socket_ref a, socket_ref b) ZMQ_NOTHROW -{ - return std::equal_to()(a.handle(), b.handle()); -} -inline bool operator!=(socket_ref a, socket_ref b) ZMQ_NOTHROW -{ - return !(a == b); -} -inline bool operator<(socket_ref a, socket_ref b) ZMQ_NOTHROW -{ - return std::less()(a.handle(), b.handle()); -} -inline bool operator>(socket_ref a, socket_ref b) ZMQ_NOTHROW -{ - return b < a; -} -inline bool operator<=(socket_ref a, socket_ref b) ZMQ_NOTHROW -{ - return !(a > b); -} -inline bool operator>=(socket_ref a, socket_ref b) ZMQ_NOTHROW -{ - return !(a < b); -} - -} // namespace zmq - -#ifdef ZMQ_CPP11 -namespace std -{ -template <> -struct hash -{ - size_t operator()(zmq::socket_ref sr) const ZMQ_NOTHROW - { - return hash()(sr.handle()); - } -}; -} // namespace std -#endif - -namespace zmq -{ -class socket_t : public detail::socket_base -{ - friend class monitor_t; - -public: - socket_t() ZMQ_NOTHROW : detail::socket_base(ZMQ_NULLPTR), ctxptr(ZMQ_NULLPTR) - {} - - socket_t(context_t& context_, int type_) - : detail::socket_base(zmq_socket(context_.handle(), type_)), ctxptr(context_.handle()) - { - if(_handle == ZMQ_NULLPTR) - throw error_t(); - } - -#ifdef ZMQ_CPP11 - socket_t(context_t& context_, socket_type type_) - : socket_t(context_, static_cast(type_)) - {} -#endif - -#ifdef ZMQ_HAS_RVALUE_REFS - socket_t(socket_t&& rhs) ZMQ_NOTHROW : detail::socket_base(rhs._handle), - ctxptr(rhs.ctxptr) - { - rhs._handle = ZMQ_NULLPTR; - rhs.ctxptr = ZMQ_NULLPTR; - } - socket_t& operator=(socket_t&& rhs) ZMQ_NOTHROW - { - close(); - std::swap(_handle, rhs._handle); - std::swap(ctxptr, rhs.ctxptr); - return *this; - } -#endif - - ~socket_t() ZMQ_NOTHROW - { - close(); - } - - operator void*() ZMQ_NOTHROW - { - return _handle; - } - - operator void const*() const ZMQ_NOTHROW - { - return _handle; - } - - void close() ZMQ_NOTHROW - { - if(_handle == ZMQ_NULLPTR) - // already closed - return; - int rc = zmq_close(_handle); - ZMQ_ASSERT(rc == 0); - _handle = ZMQ_NULLPTR; - ctxptr = ZMQ_NULLPTR; - } - - void swap(socket_t& other) ZMQ_NOTHROW - { - std::swap(_handle, other._handle); - std::swap(ctxptr, other.ctxptr); - } - - operator socket_ref() ZMQ_NOTHROW - { - return socket_ref(from_handle, _handle); - } - -private: - void* ctxptr; - - socket_t(const socket_t&) ZMQ_DELETED_FUNCTION; - void operator=(const socket_t&) ZMQ_DELETED_FUNCTION; - - // used by monitor_t - socket_t(void* context_, int type_) - : detail::socket_base(zmq_socket(context_, type_)), ctxptr(context_) - { - if(_handle == ZMQ_NULLPTR) - throw error_t(); - if(ctxptr == ZMQ_NULLPTR) - throw error_t(); - } -}; - -inline void swap(socket_t& a, socket_t& b) ZMQ_NOTHROW -{ - a.swap(b); -} - -ZMQ_DEPRECATED("from 4.3.1, use proxy taking socket_t objects") -inline void proxy(void* frontend, void* backend, void* capture) -{ - int rc = zmq_proxy(frontend, backend, capture); - if(rc != 0) - throw error_t(); -} - -inline void proxy(socket_ref frontend, socket_ref backend, - socket_ref capture = socket_ref()) -{ - int rc = zmq_proxy(frontend.handle(), backend.handle(), capture.handle()); - if(rc != 0) - throw error_t(); -} - -#ifdef ZMQ_HAS_PROXY_STEERABLE -ZMQ_DEPRECATED("from 4.3.1, use proxy_steerable taking socket_t objects") -inline void proxy_steerable(void* frontend, void* backend, void* capture, void* control) -{ - int rc = zmq_proxy_steerable(frontend, backend, capture, control); - if(rc != 0) - throw error_t(); -} - -inline void proxy_steerable(socket_ref frontend, socket_ref backend, socket_ref capture, - socket_ref control) -{ - int rc = zmq_proxy_steerable(frontend.handle(), backend.handle(), capture.handle(), - control.handle()); - if(rc != 0) - throw error_t(); -} -#endif - -class monitor_t -{ -public: - monitor_t() : _socket(), _monitor_socket() - {} - - virtual ~monitor_t() - { - close(); - } - -#ifdef ZMQ_HAS_RVALUE_REFS - monitor_t(monitor_t&& rhs) ZMQ_NOTHROW : _socket(), _monitor_socket() - { - std::swap(_socket, rhs._socket); - std::swap(_monitor_socket, rhs._monitor_socket); - } - - monitor_t& operator=(monitor_t&& rhs) ZMQ_NOTHROW - { - close(); - _socket = socket_ref(); - std::swap(_socket, rhs._socket); - std::swap(_monitor_socket, rhs._monitor_socket); - return *this; - } -#endif - - void monitor(socket_t& socket, std::string const& addr, int events = ZMQ_EVENT_ALL) - { - monitor(socket, addr.c_str(), events); - } - - void monitor(socket_t& socket, const char* addr_, int events = ZMQ_EVENT_ALL) - { - init(socket, addr_, events); - while(true) - { - check_event(-1); - } - } - - void init(socket_t& socket, std::string const& addr, int events = ZMQ_EVENT_ALL) - { - init(socket, addr.c_str(), events); - } - - void init(socket_t& socket, const char* addr_, int events = ZMQ_EVENT_ALL) - { - int rc = zmq_socket_monitor(socket.handle(), addr_, events); - if(rc != 0) - throw error_t(); - - _socket = socket; - _monitor_socket = socket_t(socket.ctxptr, ZMQ_PAIR); - _monitor_socket.connect(addr_); - - on_monitor_started(); - } - - bool check_event(int timeout = 0) - { - assert(_monitor_socket); - - zmq_msg_t eventMsg; - zmq_msg_init(&eventMsg); - - zmq::pollitem_t items[] = { - { _monitor_socket.handle(), 0, ZMQ_POLLIN, 0 }, - }; - - zmq::poll(&items[0], 1, timeout); - - if(items[0].revents & ZMQ_POLLIN) - { - int rc = zmq_msg_recv(&eventMsg, _monitor_socket.handle(), 0); - if(rc == -1 && zmq_errno() == ETERM) - return false; - assert(rc != -1); - } - else - { - zmq_msg_close(&eventMsg); - return false; - } - -#if ZMQ_VERSION_MAJOR >= 4 - const char* data = static_cast(zmq_msg_data(&eventMsg)); - zmq_event_t msgEvent; - memcpy(&msgEvent.event, data, sizeof(uint16_t)); - data += sizeof(uint16_t); - memcpy(&msgEvent.value, data, sizeof(int32_t)); - zmq_event_t* event = &msgEvent; -#else - zmq_event_t* event = static_cast(zmq_msg_data(&eventMsg)); -#endif - -#ifdef ZMQ_NEW_MONITOR_EVENT_LAYOUT - zmq_msg_t addrMsg; - zmq_msg_init(&addrMsg); - int rc = zmq_msg_recv(&addrMsg, _monitor_socket.handle(), 0); - if(rc == -1 && zmq_errno() == ETERM) - { - zmq_msg_close(&eventMsg); - return false; - } - - assert(rc != -1); - const char* str = static_cast(zmq_msg_data(&addrMsg)); - std::string address(str, str + zmq_msg_size(&addrMsg)); - zmq_msg_close(&addrMsg); -#else - // Bit of a hack, but all events in the zmq_event_t union have the same layout so this will work for all event types. - std::string address = event->data.connected.addr; -#endif - -#ifdef ZMQ_EVENT_MONITOR_STOPPED - if(event->event == ZMQ_EVENT_MONITOR_STOPPED) - { - zmq_msg_close(&eventMsg); - return false; - } - -#endif - - switch(event->event) - { - case ZMQ_EVENT_CONNECTED: - on_event_connected(*event, address.c_str()); - break; - case ZMQ_EVENT_CONNECT_DELAYED: - on_event_connect_delayed(*event, address.c_str()); - break; - case ZMQ_EVENT_CONNECT_RETRIED: - on_event_connect_retried(*event, address.c_str()); - break; - case ZMQ_EVENT_LISTENING: - on_event_listening(*event, address.c_str()); - break; - case ZMQ_EVENT_BIND_FAILED: - on_event_bind_failed(*event, address.c_str()); - break; - case ZMQ_EVENT_ACCEPTED: - on_event_accepted(*event, address.c_str()); - break; - case ZMQ_EVENT_ACCEPT_FAILED: - on_event_accept_failed(*event, address.c_str()); - break; - case ZMQ_EVENT_CLOSED: - on_event_closed(*event, address.c_str()); - break; - case ZMQ_EVENT_CLOSE_FAILED: - on_event_close_failed(*event, address.c_str()); - break; - case ZMQ_EVENT_DISCONNECTED: - on_event_disconnected(*event, address.c_str()); - break; -#ifdef ZMQ_BUILD_DRAFT_API -#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 3) - case ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL: - on_event_handshake_failed_no_detail(*event, address.c_str()); - break; - case ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL: - on_event_handshake_failed_protocol(*event, address.c_str()); - break; - case ZMQ_EVENT_HANDSHAKE_FAILED_AUTH: - on_event_handshake_failed_auth(*event, address.c_str()); - break; - case ZMQ_EVENT_HANDSHAKE_SUCCEEDED: - on_event_handshake_succeeded(*event, address.c_str()); - break; -#elif ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 1) - case ZMQ_EVENT_HANDSHAKE_FAILED: - on_event_handshake_failed(*event, address.c_str()); - break; - case ZMQ_EVENT_HANDSHAKE_SUCCEED: - on_event_handshake_succeed(*event, address.c_str()); - break; -#endif -#endif - default: - on_event_unknown(*event, address.c_str()); - break; - } - zmq_msg_close(&eventMsg); - - return true; - } - -#ifdef ZMQ_EVENT_MONITOR_STOPPED - void abort() - { - if(_socket) - zmq_socket_monitor(_socket.handle(), ZMQ_NULLPTR, 0); - - _socket = socket_ref(); - } -#endif - virtual void on_monitor_started() - {} - virtual void on_event_connected(const zmq_event_t& event_, const char* addr_) - { - (void)event_; - (void)addr_; - } - virtual void on_event_connect_delayed(const zmq_event_t& event_, const char* addr_) - { - (void)event_; - (void)addr_; - } - virtual void on_event_connect_retried(const zmq_event_t& event_, const char* addr_) - { - (void)event_; - (void)addr_; - } - virtual void on_event_listening(const zmq_event_t& event_, const char* addr_) - { - (void)event_; - (void)addr_; - } - virtual void on_event_bind_failed(const zmq_event_t& event_, const char* addr_) - { - (void)event_; - (void)addr_; - } - virtual void on_event_accepted(const zmq_event_t& event_, const char* addr_) - { - (void)event_; - (void)addr_; - } - virtual void on_event_accept_failed(const zmq_event_t& event_, const char* addr_) - { - (void)event_; - (void)addr_; - } - virtual void on_event_closed(const zmq_event_t& event_, const char* addr_) - { - (void)event_; - (void)addr_; - } - virtual void on_event_close_failed(const zmq_event_t& event_, const char* addr_) - { - (void)event_; - (void)addr_; - } - virtual void on_event_disconnected(const zmq_event_t& event_, const char* addr_) - { - (void)event_; - (void)addr_; - } -#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 3) - virtual void on_event_handshake_failed_no_detail(const zmq_event_t& event_, - const char* addr_) - { - (void)event_; - (void)addr_; - } - virtual void on_event_handshake_failed_protocol(const zmq_event_t& event_, - const char* addr_) - { - (void)event_; - (void)addr_; - } - virtual void on_event_handshake_failed_auth(const zmq_event_t& event_, - const char* addr_) - { - (void)event_; - (void)addr_; - } - virtual void on_event_handshake_succeeded(const zmq_event_t& event_, const char* addr_) - { - (void)event_; - (void)addr_; - } -#elif ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 1) - virtual void on_event_handshake_failed(const zmq_event_t& event_, const char* addr_) - { - (void)event_; - (void)addr_; - } - virtual void on_event_handshake_succeed(const zmq_event_t& event_, const char* addr_) - { - (void)event_; - (void)addr_; - } -#endif - virtual void on_event_unknown(const zmq_event_t& event_, const char* addr_) - { - (void)event_; - (void)addr_; - } - -private: - monitor_t(const monitor_t&) ZMQ_DELETED_FUNCTION; - void operator=(const monitor_t&) ZMQ_DELETED_FUNCTION; - - socket_ref _socket; - socket_t _monitor_socket; - - void close() ZMQ_NOTHROW - { - if(_socket) - zmq_socket_monitor(_socket.handle(), ZMQ_NULLPTR, 0); - _monitor_socket.close(); - } -}; - -#if defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER) - -// polling events -enum class event_flags : short -{ - none = 0, - pollin = ZMQ_POLLIN, - pollout = ZMQ_POLLOUT, - pollerr = ZMQ_POLLERR, - pollpri = ZMQ_POLLPRI -}; - -constexpr event_flags operator|(event_flags a, event_flags b) noexcept -{ - return detail::enum_bit_or(a, b); -} -constexpr event_flags operator&(event_flags a, event_flags b) noexcept -{ - return detail::enum_bit_and(a, b); -} -constexpr event_flags operator^(event_flags a, event_flags b) noexcept -{ - return detail::enum_bit_xor(a, b); -} -constexpr event_flags operator~(event_flags a) noexcept -{ - return detail::enum_bit_not(a); -} - -struct no_user_data; - -// layout compatible with zmq_poller_event_t -template -struct poller_event -{ - socket_ref socket; -#ifdef _WIN32 - SOCKET fd; -#else - int fd; -#endif - T* user_data; - event_flags events; -}; - -template -class poller_t -{ -public: - using event_type = poller_event; - - poller_t() : poller_ptr(zmq_poller_new()) - { - if(!poller_ptr) - throw error_t(); - } - - template ::value, - Dummy>::type> - void add(zmq::socket_ref socket, event_flags events, T* user_data) - { - add_impl(socket, events, user_data); - } - - void add(zmq::socket_ref socket, event_flags events) - { - add_impl(socket, events, nullptr); - } - - void remove(zmq::socket_ref socket) - { - if(0 != zmq_poller_remove(poller_ptr.get(), socket.handle())) - { - throw error_t(); - } - } - - void modify(zmq::socket_ref socket, event_flags events) - { - if(0 != - zmq_poller_modify(poller_ptr.get(), socket.handle(), static_cast(events))) - { - throw error_t(); - } - } - - size_t wait_all(std::vector& poller_events, - const std::chrono::milliseconds timeout) - { - int rc = zmq_poller_wait_all( - poller_ptr.get(), reinterpret_cast(poller_events.data()), - static_cast(poller_events.size()), static_cast(timeout.count())); - if(rc > 0) - return static_cast(rc); - -#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 3) - if(zmq_errno() == EAGAIN) -#else - if(zmq_errno() == ETIMEDOUT) -#endif - return 0; - - throw error_t(); - } - -private: - struct destroy_poller_t - { - void operator()(void* ptr) noexcept - { - int rc = zmq_poller_destroy(&ptr); - ZMQ_ASSERT(rc == 0); - } - }; - - std::unique_ptr poller_ptr; - - void add_impl(zmq::socket_ref socket, event_flags events, T* user_data) - { - if(0 != zmq_poller_add(poller_ptr.get(), socket.handle(), user_data, - static_cast(events))) - { - throw error_t(); - } - } -}; -#endif // defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER) - -inline std::ostream& operator<<(std::ostream& os, const message_t& msg) -{ - return os << msg.str(); -} - -} // namespace zmq - -#endif // __ZMQ_HPP_INCLUDED__ From 995890d08087d654480da89a0a1c03bc3d1dbc9b Mon Sep 17 00:00:00 2001 From: "Riff, Eric" Date: Sun, 28 Sep 2025 03:11:12 +0000 Subject: [PATCH 22/41] Leave a FIXME for posterity This target was silently being skiped, not it is explicit --- tools/CMakeLists.txt | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 14a2e8231..b88db7561 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -4,12 +4,21 @@ # install(TARGETS bt4_log_cat # DESTINATION ${BTCPP_BIN_DESTINATION} ) -if( ZMQ_FOUND ) - add_executable(bt4_recorder bt_recorder.cpp ) - target_link_libraries(bt4_recorder ${BTCPP_LIBRARY} ${ZMQ_LIBRARIES}) - install(TARGETS bt4_recorder - DESTINATION ${BTCPP_BIN_DESTINATION} ) -endif() +# FIXME! This target doesn't build because behaviortree_cpp/flatbuffers/BT_logger_generated.h +# doesn't get generated. +# It was being silently ignored because it was included only if ZMQ_FOUND was set, but that check +# was wrong for two reasons: +# 1) The actual variable name set on FindZeroMQ.cmake is ZeroMQ_FOUND not ZMQ_FOUND +# 2) This target does not depend on ZeroMQ, but actually on its C++ wrapper cppzmq. +# Ideally we should check for cppzmq_FOUND, but because that would be only set in non-vendored mode +# and furthermore it would not be set on this scope, I chose to use BTCPP_GROOT_INTERFACE as the check +# for now. +#if( BTCPP_GROOT_INTERFACE ) +# add_executable(bt4_recorder bt_recorder.cpp ) +# target_link_libraries(bt4_recorder ${BTCPP_LIBRARY} cppzmq) +# install(TARGETS bt4_recorder +# DESTINATION ${BTCPP_BIN_DESTINATION} ) +#endif() add_executable(bt4_plugin_manifest bt_plugin_manifest.cpp ) target_link_libraries(bt4_plugin_manifest ${BTCPP_LIBRARY} ) From 824c807e5fa3bb1044d8c195c9675ee7ec9324ed Mon Sep 17 00:00:00 2001 From: "Riff, Eric" Date: Sun, 28 Sep 2025 03:11:52 +0000 Subject: [PATCH 23/41] Leave comment for posterity --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 2ae1cf59c..899909c54 100644 --- a/conanfile.py +++ b/conanfile.py @@ -18,7 +18,7 @@ def requirements(self): self.requires("minitrace/cci.20230905") self.requires("sqlite3/3.40.1") # This should be a transitive dependency of cpp-sqlite self.requires("tinyxml2/10.0.0") - self.requires("zeromq/4.3.4") + self.requires("zeromq/4.3.4") # This should be a transitive dependency of cppzmq def generate(self): tc = CMakeToolchain(self) From 45afb6c1ee33538e89ba7fc15e5aa2a9bf775807 Mon Sep 17 00:00:00 2001 From: "Riff, Eric" Date: Sun, 28 Sep 2025 03:12:13 +0000 Subject: [PATCH 24/41] Remove empty line --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 508ee535c..083376538 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -120,7 +120,6 @@ if(BTCPP_SQLITE_LOGGING) endif() - if(USE_VENDORED_FLATBUFFERS) add_subdirectory(3rdparty/flatbuffers) else() From 021d80a1f295b21151890726d62bc07445bf1931 Mon Sep 17 00:00:00 2001 From: "Riff, Eric" Date: Sun, 28 Sep 2025 03:16:04 +0000 Subject: [PATCH 25/41] Remove unneeded line --- sample_nodes/CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/sample_nodes/CMakeLists.txt b/sample_nodes/CMakeLists.txt index 217fec77d..d6a78f7a7 100644 --- a/sample_nodes/CMakeLists.txt +++ b/sample_nodes/CMakeLists.txt @@ -1,7 +1,4 @@ -include_directories( ../include ) - # compile as static libraries - set(CMAKE_DEBUG_POSTFIX "") add_library(bt_sample_nodes STATIC From c4f168058c1741e991c7bc2e970c799a68799ae9 Mon Sep 17 00:00:00 2001 From: "Riff, Eric" Date: Sun, 28 Sep 2025 03:18:31 +0000 Subject: [PATCH 26/41] Remove uneeded line --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 083376538..d84046cdb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,8 +74,6 @@ if(USE_V3_COMPATIBLE_NAMES) add_definitions(-DUSE_BTCPP3_OLD_NAMES) endif() -set(BEHAVIOR_TREE_LIBRARY ${PROJECT_NAME}) - # Update the policy setting to avoid an error when loading the ament_cmake package # at the current cmake version level if(POLICY CMP0057) From 8a47185081c1413694b6e4928e34f91d2c876b1f Mon Sep 17 00:00:00 2001 From: "Riff, Eric" Date: Sun, 28 Sep 2025 03:21:55 +0000 Subject: [PATCH 27/41] Remove empty line --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d84046cdb..8f4679c33 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,7 +117,6 @@ if(BTCPP_SQLITE_LOGGING) endif() endif() - if(USE_VENDORED_FLATBUFFERS) add_subdirectory(3rdparty/flatbuffers) else() From c869c77531a8ca9a450a548f45768d7ac48dcd62 Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Mon, 29 Sep 2025 18:01:49 +0000 Subject: [PATCH 28/41] Revert unintentional changes --- cmake/conan.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/conan.cmake b/cmake/conan.cmake index 5de17afa0..d36c5ed44 100644 --- a/cmake/conan.cmake +++ b/cmake/conan.cmake @@ -808,14 +808,14 @@ function(conan_cmake_configure) conan_cmake_generate_conanfile(OFF ${ARGV}) endfunction() -# Generate, writing in disk a conanfile.py with the requires, options, and imports +# Generate, writing in disk a conanfile.txt with the requires, options, and imports # specified as arguments # This will be considered as temporary file, generated in CMAKE_CURRENT_BINARY_DIR) function(conan_cmake_generate_conanfile DEFAULT_GENERATOR) conan_parse_arguments(${ARGV}) - set(_FN "${CMAKE_CURRENT_BINARY_DIR}/conanfile.py") + set(_FN "${CMAKE_CURRENT_BINARY_DIR}/conanfile.txt") file(WRITE ${_FN} "") if(DEFINED ARGUMENTS_REQUIRES) From 0f5d249336ef12ac561c6caebc7e4f98cb3fc62d Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Mon, 29 Sep 2025 15:11:49 -0300 Subject: [PATCH 29/41] Use cmake_layout to support multiconfig --- README.md | 2 +- conanfile.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5b071f114..72f11fae7 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ Assuming that you are in the **root** directory of `BehaviorTree.CPP`: ``` mkdir build_release conan install . -of build_release -s build_type=Release --build=missing -cmake -S . -B build_release -DCMAKE_TOOLCHAIN_FILE="build_release/conan_toolchain.cmake" +cmake -S . -B build_release -DCMAKE_TOOLCHAIN_FILE="build_release/build/Release/generators/conan_toolchain.cmake" cmake --build build_release --parallel ``` diff --git a/conanfile.py b/conanfile.py index 899909c54..9673cb693 100644 --- a/conanfile.py +++ b/conanfile.py @@ -1,5 +1,5 @@ from conan import ConanFile -from conan.tools.cmake import CMakeToolchain, CMakeDeps +from conan.tools.cmake import CMakeToolchain, CMakeDeps, cmake_layout class BehaviortreeCppConan(ConanFile): name = "behaviortree.cpp" @@ -9,6 +9,9 @@ class BehaviortreeCppConan(ConanFile): "flatbuffers/*:header_only": True, } + def layout(self): + cmake_layout(self) + def build_requirements(self): self.test_requires("gtest/1.14.0") From 37e9134a4e8f2d1be13a0963f67743d025392bff Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Mon, 29 Sep 2025 18:26:21 +0000 Subject: [PATCH 30/41] Update toolchain path on cicd --- .github/workflows/cmake_ubuntu.yml | 2 +- .github/workflows/cmake_windows.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cmake_ubuntu.yml b/.github/workflows/cmake_ubuntu.yml index 8b9e33870..1a379d97d 100644 --- a/.github/workflows/cmake_ubuntu.yml +++ b/.github/workflows/cmake_ubuntu.yml @@ -44,7 +44,7 @@ jobs: - name: Configure CMake shell: bash working-directory: ${{github.workspace}}/build - run: cmake ${{github.workspace}} -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake + run: cmake ${{github.workspace}} -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=${{env.BUILD_TYPE}}/generators/conan_toolchain.cmake - name: Build shell: bash diff --git a/.github/workflows/cmake_windows.yml b/.github/workflows/cmake_windows.yml index 1125e18ab..96f268438 100644 --- a/.github/workflows/cmake_windows.yml +++ b/.github/workflows/cmake_windows.yml @@ -44,7 +44,7 @@ jobs: - name: Configure CMake shell: bash working-directory: ${{github.workspace}}/build - run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake + run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=generators/conan_toolchain.cmake - name: Build working-directory: ${{github.workspace}}/build From 5297135cd1b1f9ce50edbf843e14a768dc4883d4 Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Mon, 29 Sep 2025 19:16:04 +0000 Subject: [PATCH 31/41] Emtpy commit to re-trigger CI From ad3b950ffcb982cbd1141b8a136272c8fd795a51 Mon Sep 17 00:00:00 2001 From: "Riff, Eric" Date: Tue, 30 Sep 2025 02:34:48 +0000 Subject: [PATCH 32/41] Use cppzmq from conan --- conanfile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conanfile.py b/conanfile.py index 9673cb693..3b93d492a 100644 --- a/conanfile.py +++ b/conanfile.py @@ -21,13 +21,13 @@ def requirements(self): self.requires("minitrace/cci.20230905") self.requires("sqlite3/3.40.1") # This should be a transitive dependency of cpp-sqlite self.requires("tinyxml2/10.0.0") - self.requires("zeromq/4.3.4") # This should be a transitive dependency of cppzmq + self.requires("cppzmq/4.11.0") def generate(self): tc = CMakeToolchain(self) #tc.variables["USE_VENDORED_CPPSQLITE"] = False - #tc.variables["USE_VENDORED_CPPZMQ"] = False + tc.variables["USE_VENDORED_CPPZMQ"] = False tc.variables["USE_VENDORED_FLATBUFFERS"] = False #tc.variables["USE_VENDORED_LEXY"] = False tc.variables["USE_VENDORED_MINICORO"] = False From 083bbf34097c81286246129594703438d727b509 Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Tue, 30 Sep 2025 18:59:50 +0000 Subject: [PATCH 33/41] Use cmake presets on conan builds --- .github/workflows/cmake_ubuntu.yml | 23 ++++++++++------------- .github/workflows/cmake_windows.yml | 22 ++++++++++------------ README.md | 10 ++++++---- conanfile.py | 16 ++++++++-------- 4 files changed, 34 insertions(+), 37 deletions(-) diff --git a/.github/workflows/cmake_ubuntu.yml b/.github/workflows/cmake_ubuntu.yml index 1a379d97d..1d4ba93f1 100644 --- a/.github/workflows/cmake_ubuntu.yml +++ b/.github/workflows/cmake_ubuntu.yml @@ -32,28 +32,25 @@ jobs: - name: Create default profile run: conan profile detect - - name: Create Build Environment - # Some projects don't allow in-source building, so create a separate build directory - # We'll use this as our working directory for all subsequent commands - run: cmake -E make_directory ${{github.workspace}}/build - - name: Install conan dependencies - working-directory: ${{github.workspace}}/build - run: conan install ${{github.workspace}}/conanfile.py -s build_type=${{env.BUILD_TYPE}} --build=missing + run: conan install conanfile.py -s build_type=${{env.BUILD_TYPE}} --build=missing + + - name: Normalize build type + shell: bash + # The build type is Capitalized, e.g. Release, but the preset is all lowercase, e.g. release. + # There is no built in way to do string manipulations on GHA as far as I know.` + run: echo "BUILD_TYPE_LOWERCASE=$(echo "${BUILD_TYPE}" | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV - name: Configure CMake shell: bash - working-directory: ${{github.workspace}}/build - run: cmake ${{github.workspace}} -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=${{env.BUILD_TYPE}}/generators/conan_toolchain.cmake + run: cmake --preset conan-${{ env.BUILD_TYPE_LOWERCASE }} - name: Build shell: bash - working-directory: ${{github.workspace}}/build - run: cmake --build . --config ${{env.BUILD_TYPE}} + run: cmake --build --preset conan-${{ env.BUILD_TYPE_LOWERCASE }} - name: run test (Linux) - working-directory: ${{github.workspace}}/build/tests - run: ctest + run: ctest --test-dir build/${{env.BUILD_TYPE}} - name: Upload coverage reports to Codecov uses: codecov/codecov-action@v3 diff --git a/.github/workflows/cmake_windows.yml b/.github/workflows/cmake_windows.yml index 96f268438..a6eb1c3f1 100644 --- a/.github/workflows/cmake_windows.yml +++ b/.github/workflows/cmake_windows.yml @@ -32,25 +32,23 @@ jobs: - name: Create default profile run: conan profile detect - - name: Create Build Environment - # Some projects don't allow in-source building, so create a separate build directory - # We'll use this as our working directory for all subsequent commands - run: cmake -E make_directory ${{github.workspace}}/build - - name: Install conan dependencies - working-directory: ${{github.workspace}}/build - run: conan install ${{github.workspace}}/conanfile.py -s build_type=${{env.BUILD_TYPE}} --build=missing + run: conan install conanfile.py -s build_type=${{env.BUILD_TYPE}} --build=missing + + - name: Normalize build type + shell: bash + # The build type is Capitalized, e.g. Release, but the preset is all lowercase, e.g. release. + # There is no built in way to do string manipulations on GHA as far as I know.` + run: echo "BUILD_TYPE_LOWERCASE=$(echo "${BUILD_TYPE}" | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV - name: Configure CMake shell: bash - working-directory: ${{github.workspace}}/build - run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=generators/conan_toolchain.cmake + run: cmake --preset conan-${{ env.BUILD_TYPE_LOWERCASE }} - name: Build - working-directory: ${{github.workspace}}/build shell: bash - run: cmake --build . --config ${{env.BUILD_TYPE}} + run: cmake --build --preset conan-${{ env.BUILD_TYPE_LOWERCASE }} - name: run test (Windows) - working-directory: ${{github.workspace}}/build + working-directory: ${{github.workspace}}/build/${{env.BUILD_TYPE}} run: $env:PATH+=";${{env.BUILD_TYPE}}"; tests/${{env.BUILD_TYPE}}/behaviortree_cpp_test.exe diff --git a/README.md b/README.md index 72f11fae7..b30335ffc 100644 --- a/README.md +++ b/README.md @@ -61,13 +61,15 @@ Three build systems are supported: Compiling with [conan](https://conan.io/): +> [!NOTE] +> Conan builds require CMake 3.23 or newer. + Assuming that you are in the **root** directory of `BehaviorTree.CPP`: ``` -mkdir build_release -conan install . -of build_release -s build_type=Release --build=missing -cmake -S . -B build_release -DCMAKE_TOOLCHAIN_FILE="build_release/build/Release/generators/conan_toolchain.cmake" -cmake --build build_release --parallel +conan install . -s build_type=Release --build=missing +cmake --preset conan-release +cmake --build --preset conan-release ``` If you have dependencies such as ZeroMQ and SQlite already installed and you don't want to diff --git a/conanfile.py b/conanfile.py index 3b93d492a..cb31ef94a 100644 --- a/conanfile.py +++ b/conanfile.py @@ -26,14 +26,14 @@ def requirements(self): def generate(self): tc = CMakeToolchain(self) - #tc.variables["USE_VENDORED_CPPSQLITE"] = False - tc.variables["USE_VENDORED_CPPZMQ"] = False - tc.variables["USE_VENDORED_FLATBUFFERS"] = False - #tc.variables["USE_VENDORED_LEXY"] = False - tc.variables["USE_VENDORED_MINICORO"] = False - tc.variables["USE_VENDORED_MINITRACE"] = False - tc.variables["USE_VENDORED_TINYXML2"] = False - #tc.variables["USE_VENDORED_WILDCARDS"] = False + #tc.cache_variables["USE_VENDORED_CPPSQLITE"] = False + tc.cache_variables["USE_VENDORED_CPPZMQ"] = False + tc.cache_variables["USE_VENDORED_FLATBUFFERS"] = False + #tc.cache_variables["USE_VENDORED_LEXY"] = False + tc.cache_variables["USE_VENDORED_MINICORO"] = False + tc.cache_variables["USE_VENDORED_MINITRACE"] = False + tc.cache_variables["USE_VENDORED_TINYXML2"] = False + #tc.cache_variables["USE_VENDORED_WILDCARDS"] = False tc.generate() deps = CMakeDeps(self) From 7a3cd995f30d2167efe1a14c1b5c9ba86447fbb4 Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Tue, 30 Sep 2025 20:13:01 +0000 Subject: [PATCH 34/41] It looks like in windows the preset is called conan-default --- .github/workflows/cmake_windows.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/cmake_windows.yml b/.github/workflows/cmake_windows.yml index a6eb1c3f1..60e1d48dc 100644 --- a/.github/workflows/cmake_windows.yml +++ b/.github/workflows/cmake_windows.yml @@ -35,19 +35,13 @@ jobs: - name: Install conan dependencies run: conan install conanfile.py -s build_type=${{env.BUILD_TYPE}} --build=missing - - name: Normalize build type - shell: bash - # The build type is Capitalized, e.g. Release, but the preset is all lowercase, e.g. release. - # There is no built in way to do string manipulations on GHA as far as I know.` - run: echo "BUILD_TYPE_LOWERCASE=$(echo "${BUILD_TYPE}" | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV - - name: Configure CMake shell: bash - run: cmake --preset conan-${{ env.BUILD_TYPE_LOWERCASE }} + run: cmake --preset conan-default - name: Build shell: bash - run: cmake --build --preset conan-${{ env.BUILD_TYPE_LOWERCASE }} + run: cmake --build --preset conan-default - name: run test (Windows) working-directory: ${{github.workspace}}/build/${{env.BUILD_TYPE}} From 13fdbde0f7e87463cc94d0671b884fd126548609 Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Tue, 30 Sep 2025 20:15:20 +0000 Subject: [PATCH 35/41] It looks like the preset is only called default for config? --- .github/workflows/cmake_windows.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cmake_windows.yml b/.github/workflows/cmake_windows.yml index 60e1d48dc..ce8ec4452 100644 --- a/.github/workflows/cmake_windows.yml +++ b/.github/workflows/cmake_windows.yml @@ -35,13 +35,19 @@ jobs: - name: Install conan dependencies run: conan install conanfile.py -s build_type=${{env.BUILD_TYPE}} --build=missing + - name: Normalize build type + shell: bash + # The build type is Capitalized, e.g. Release, but the preset is all lowercase, e.g. release. + # There is no built in way to do string manipulations on GHA as far as I know.` + run: echo "BUILD_TYPE_LOWERCASE=$(echo "${BUILD_TYPE}" | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV + - name: Configure CMake shell: bash run: cmake --preset conan-default - name: Build shell: bash - run: cmake --build --preset conan-default + run: cmake --build --preset conan-${{ env.BUILD_TYPE_LOWERCASE }} - name: run test (Windows) working-directory: ${{github.workspace}}/build/${{env.BUILD_TYPE}} From 740204069a917c5b36106962361d67589e352665 Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Tue, 30 Sep 2025 20:26:32 +0000 Subject: [PATCH 36/41] Fix tests path in windows --- .github/workflows/cmake_windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cmake_windows.yml b/.github/workflows/cmake_windows.yml index ce8ec4452..78fb92c9e 100644 --- a/.github/workflows/cmake_windows.yml +++ b/.github/workflows/cmake_windows.yml @@ -50,5 +50,5 @@ jobs: run: cmake --build --preset conan-${{ env.BUILD_TYPE_LOWERCASE }} - name: run test (Windows) - working-directory: ${{github.workspace}}/build/${{env.BUILD_TYPE}} + working-directory: ${{github.workspace}}/build run: $env:PATH+=";${{env.BUILD_TYPE}}"; tests/${{env.BUILD_TYPE}}/behaviortree_cpp_test.exe From f858b0828abdf38e771f0ac4df2ffe4adb782c63 Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Tue, 30 Sep 2025 20:49:45 +0000 Subject: [PATCH 37/41] Use lexy from conan --- conanfile.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index cb31ef94a..459b85341 100644 --- a/conanfile.py +++ b/conanfile.py @@ -22,6 +22,7 @@ def requirements(self): self.requires("sqlite3/3.40.1") # This should be a transitive dependency of cpp-sqlite self.requires("tinyxml2/10.0.0") self.requires("cppzmq/4.11.0") + self.requires("foonathan-lexy/2022.12.1") def generate(self): tc = CMakeToolchain(self) @@ -29,7 +30,7 @@ def generate(self): #tc.cache_variables["USE_VENDORED_CPPSQLITE"] = False tc.cache_variables["USE_VENDORED_CPPZMQ"] = False tc.cache_variables["USE_VENDORED_FLATBUFFERS"] = False - #tc.cache_variables["USE_VENDORED_LEXY"] = False + tc.cache_variables["USE_VENDORED_LEXY"] = False tc.cache_variables["USE_VENDORED_MINICORO"] = False tc.cache_variables["USE_VENDORED_MINITRACE"] = False tc.cache_variables["USE_VENDORED_TINYXML2"] = False From f88b72709d394511dbd68d5006bbd4ad2f9538ad Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Tue, 30 Sep 2025 20:59:34 +0000 Subject: [PATCH 38/41] Force cppstd to 17, conan profile detect uses 14 --- .github/workflows/cmake_windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cmake_windows.yml b/.github/workflows/cmake_windows.yml index 78fb92c9e..5082acdc7 100644 --- a/.github/workflows/cmake_windows.yml +++ b/.github/workflows/cmake_windows.yml @@ -33,7 +33,7 @@ jobs: run: conan profile detect - name: Install conan dependencies - run: conan install conanfile.py -s build_type=${{env.BUILD_TYPE}} --build=missing + run: conan install conanfile.py -s build_type=${{env.BUILD_TYPE}} --build=missing --settings:host compiler.cppstd=17 - name: Normalize build type shell: bash From 314bdd7f010b7a4c8659c3e0ed7a351aadd953ab Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Tue, 30 Sep 2025 21:28:56 +0000 Subject: [PATCH 39/41] Try to fix windows builds --- src/xml_parsing.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/xml_parsing.cpp b/src/xml_parsing.cpp index 179ccd777..da68be99a 100644 --- a/src/xml_parsing.cpp +++ b/src/xml_parsing.cpp @@ -53,7 +53,7 @@ std::string xsdAttributeType(const BT::PortInfo& port_info) return "blackboardType"; } const auto& type_info = port_info.type(); - if((type_info == typeid(int)) or (type_info == typeid(unsigned int))) + if((type_info == typeid(int)) || (type_info == typeid(unsigned int))) { return "integerOrBlackboardType"; } @@ -1444,7 +1444,7 @@ std::string writeTreeXSD(const BehaviorTreeFactory& factory) { XMLElement* type = doc.NewElement("xs:complexType"); type->SetAttribute("name", (model->registration_ID + "Type").c_str()); - if((model->type == NodeType::ACTION) or (model->type == NodeType::CONDITION) or + if((model->type == NodeType::ACTION) || (model->type == NodeType::CONDITION) || (model->type == NodeType::SUBTREE)) { /* No children, nothing to add. */ @@ -1478,11 +1478,11 @@ std::string writeTreeXSD(const BehaviorTreeFactory& factory) XMLElement* attr = doc.NewElement("xs:attribute"); attr->SetAttribute("name", port_name.c_str()); const auto xsd_attribute_type = xsdAttributeType(port_info); - if(not xsd_attribute_type.empty()) + if(!xsd_attribute_type.empty()) { attr->SetAttribute("type", xsd_attribute_type.c_str()); } - if(not port_info.defaultValue().empty()) + if(!port_info.defaultValue().empty()) { attr->SetAttribute("default", port_info.defaultValueString().c_str()); } From 52304190eb26a6a2e9c1a82ced7c5d7c5571f442 Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Tue, 30 Sep 2025 21:56:20 +0000 Subject: [PATCH 40/41] Remove wildcards cmake options, it has been removed on master --- 3rdparty/wildcards/CMakeLists.txt | 8 -------- CMakeLists.txt | 8 -------- conanfile.py | 1 - tests/CMakeLists.txt | 2 +- 4 files changed, 1 insertion(+), 18 deletions(-) delete mode 100644 3rdparty/wildcards/CMakeLists.txt diff --git a/3rdparty/wildcards/CMakeLists.txt b/3rdparty/wildcards/CMakeLists.txt deleted file mode 100644 index d8571d82d..000000000 --- a/3rdparty/wildcards/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -add_library(wildcards INTERFACE) - -add_library(wildcards::wildcards ALIAS wildcards) - -target_include_directories(wildcards - INTERFACE - ${CMAKE_CURRENT_SOURCE_DIR} -) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f4679c33..364c1f8cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,6 @@ option(USE_VENDORED_LEXY "Use the bundled version of lexy" ON) option(USE_VENDORED_MINICORO "Use the bundled version of minicoro" ON) option(USE_VENDORED_MINITRACE "Use the bundled version of minitrace" ON) option(USE_VENDORED_TINYXML2 "Use the bundled version of tinyxml2" ON) -option(USE_VENDORED_WILDCARDS "Use the bundled version of wildcards" ON) set(BTCPP_LIB_DESTINATION lib) set(BTCPP_INCLUDE_DESTINATION include) @@ -147,12 +146,6 @@ else() find_package(tinyxml2 REQUIRED) endif() -if(USE_VENDORED_WILDCARDS) - add_subdirectory(3rdparty/wildcards) -else() - find_package(wildcards REQUIRED) -endif() - list(APPEND BT_SOURCE src/action_node.cpp src/basic_types.cpp @@ -239,7 +232,6 @@ target_link_libraries(${BTCPP_LIBRARY} flatbuffers::flatbuffers cpp-sqlite::cpp-sqlite cppzmq - wildcards::wildcards PUBLIC ${BTCPP_EXTRA_LIBRARIES} ) diff --git a/conanfile.py b/conanfile.py index 459b85341..0f05a3912 100644 --- a/conanfile.py +++ b/conanfile.py @@ -34,7 +34,6 @@ def generate(self): tc.cache_variables["USE_VENDORED_MINICORO"] = False tc.cache_variables["USE_VENDORED_MINITRACE"] = False tc.cache_variables["USE_VENDORED_TINYXML2"] = False - #tc.cache_variables["USE_VENDORED_WILDCARDS"] = False tc.generate() deps = CMakeDeps(self) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ea3bb52d5..9c62b335e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -56,5 +56,5 @@ else() endif() target_include_directories(behaviortree_cpp_test PRIVATE include) -target_link_libraries(behaviortree_cpp_test ${BTCPP_LIBRARY} bt_sample_nodes foonathan::lexy wildcards::wildcards) +target_link_libraries(behaviortree_cpp_test ${BTCPP_LIBRARY} bt_sample_nodes foonathan::lexy) target_compile_definitions(behaviortree_cpp_test PRIVATE BT_TEST_FOLDER="${CMAKE_CURRENT_SOURCE_DIR}") From b21cb25a721f9115532fd94adf7cc27f3e5d9927 Mon Sep 17 00:00:00 2001 From: Eric Riff Date: Tue, 30 Sep 2025 22:22:47 +0000 Subject: [PATCH 41/41] Update changes after cpp-sqlite removal --- 3rdparty/cpp-sqlite/CMakeLists.txt | 15 --------------- CMakeLists.txt | 11 +++-------- conanfile.py | 3 +-- 3 files changed, 4 insertions(+), 25 deletions(-) delete mode 100644 3rdparty/cpp-sqlite/CMakeLists.txt diff --git a/3rdparty/cpp-sqlite/CMakeLists.txt b/3rdparty/cpp-sqlite/CMakeLists.txt deleted file mode 100644 index 3cb7e9849..000000000 --- a/3rdparty/cpp-sqlite/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -find_package(SQLite3 REQUIRED) - -add_library(cpp-sqlite INTERFACE) - -add_library(cpp-sqlite::cpp-sqlite ALIAS cpp-sqlite) - -target_include_directories(cpp-sqlite - INTERFACE - ${CMAKE_CURRENT_SOURCE_DIR} -) - -target_link_libraries(cpp-sqlite - INTERFACE - SQLite::SQLite3 -) diff --git a/CMakeLists.txt b/CMakeLists.txt index 364c1f8cf..ddb06ab2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,6 @@ option(USE_AFLPLUSPLUS "Use AFL++ instead of libFuzzer" OFF) option(ENABLE_DEBUG "Enable debug build with full symbols" OFF) option(FORCE_STATIC_LINKING "Force static linking of all dependencies" OFF) -option(USE_VENDORED_CPPSQLITE "Use the bundled version of cpp-sqlite" ON) option(USE_VENDORED_CPPZMQ "Use the bundled version of cppzmq" ON) option(USE_VENDORED_FLATBUFFERS "Use the bundled version of flatbuffers" ON) option(USE_VENDORED_LEXY "Use the bundled version of lexy" ON) @@ -109,11 +108,7 @@ if(BTCPP_GROOT_INTERFACE) endif() if(BTCPP_SQLITE_LOGGING) - if(USE_VENDORED_CPPSQLITE) - add_subdirectory(3rdparty/cpp-sqlite) - else() - find_package(cpp-sqlite REQUIRED) - endif() + find_package(SQLite3 REQUIRED) endif() if(USE_VENDORED_FLATBUFFERS) @@ -230,8 +225,8 @@ target_link_libraries(${BTCPP_LIBRARY} tinyxml2::tinyxml2 minicoro::minicoro flatbuffers::flatbuffers - cpp-sqlite::cpp-sqlite - cppzmq + $<$:cppzmq> + $<$:SQLite::SQLite3> PUBLIC ${BTCPP_EXTRA_LIBRARIES} ) diff --git a/conanfile.py b/conanfile.py index 0f05a3912..ff1d57b5e 100644 --- a/conanfile.py +++ b/conanfile.py @@ -19,7 +19,7 @@ def requirements(self): self.requires("flatbuffers/24.12.23") self.requires("minicoro/0.1.3") self.requires("minitrace/cci.20230905") - self.requires("sqlite3/3.40.1") # This should be a transitive dependency of cpp-sqlite + self.requires("sqlite3/3.40.1") self.requires("tinyxml2/10.0.0") self.requires("cppzmq/4.11.0") self.requires("foonathan-lexy/2022.12.1") @@ -27,7 +27,6 @@ def requirements(self): def generate(self): tc = CMakeToolchain(self) - #tc.cache_variables["USE_VENDORED_CPPSQLITE"] = False tc.cache_variables["USE_VENDORED_CPPZMQ"] = False tc.cache_variables["USE_VENDORED_FLATBUFFERS"] = False tc.cache_variables["USE_VENDORED_LEXY"] = False