Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
1d5d2ad
Support using minitrace from conan
ericriff Sep 26, 2025
48ac8d7
Support using tinyxml2 from conan
ericriff Sep 26, 2025
0604135
Add support for using minicoro from conan
ericriff Sep 26, 2025
910c05f
Add support for using flatbuffers from conan
ericriff Sep 26, 2025
d2cffb9
Create separate targets for each 3rdparty lib not yet supported by co…
ericriff Sep 26, 2025
d1a030b
Fix builds
ericriff Sep 26, 2025
f19b357
Do not include the whole 3rdparty folder, only link in what we need
ericriff Sep 26, 2025
4d88af4
Use the regular lexy target
ericriff Sep 26, 2025
5118048
Do not expose the whole 3rdparty folder as a include_directory
ericriff Sep 26, 2025
7eda756
Add options to opt-out of vendored libraries
ericriff Sep 28, 2025
50c24ad
This was shared across both code paths, conan_build.cmake and ament_b…
ericriff Sep 28, 2025
48d81ed
Keep all the find_package calls on the toplevel CMakeLists
ericriff Sep 28, 2025
d145e46
SQLite3 is actually a dependency of cpp-sqlite
ericriff Sep 28, 2025
b063794
Fix include dirs of the vendored minicoro and flatbuffers
ericriff Sep 28, 2025
76b22a6
Define libzmq cmake target on FindZeroMQ to match the conan package
ericriff Sep 28, 2025
d317e69
Improve message. This code path doesn't really mean we're using conan…
ericriff Sep 28, 2025
833570e
Use the python version of conanfile.py so we can set the CMake option…
ericriff Sep 28, 2025
97f2776
Address pre-commit complains
ericriff Sep 28, 2025
0bafb1b
Use conanfile.py across the board
ericriff Sep 28, 2025
38e4d2d
Do not look for ZeroMQ directly as it is a dependency of cppzmq
ericriff Sep 28, 2025
af954f8
Keep a single copy of zmq.hpp
ericriff Sep 28, 2025
995890d
Leave a FIXME for posterity
ericriff Sep 28, 2025
824c807
Leave comment for posterity
ericriff Sep 28, 2025
45afb6c
Remove empty line
ericriff Sep 28, 2025
021d80a
Remove unneeded line
ericriff Sep 28, 2025
c4f1680
Remove uneeded line
ericriff Sep 28, 2025
8a47185
Remove empty line
ericriff Sep 28, 2025
c869c77
Revert unintentional changes
ericriff Sep 29, 2025
0f5d249
Use cmake_layout to support multiconfig
ericriff Sep 29, 2025
37e9134
Update toolchain path on cicd
ericriff Sep 29, 2025
5297135
Emtpy commit to re-trigger CI
ericriff Sep 29, 2025
ad3b950
Use cppzmq from conan
ericriff Sep 30, 2025
083bbf3
Use cmake presets on conan builds
ericriff Sep 30, 2025
7a3cd99
It looks like in windows the preset is called conan-default
ericriff Sep 30, 2025
13fdbde
It looks like the preset is only called default for config?
ericriff Sep 30, 2025
7402040
Fix tests path in windows
ericriff Sep 30, 2025
f858b08
Use lexy from conan
ericriff Sep 30, 2025
f88b727
Force cppstd to 17, conan profile detect uses 14
ericriff Sep 30, 2025
314bdd7
Try to fix windows builds
ericriff Sep 30, 2025
7d40d96
Merge remote-tracking branch 'origin/master' into unvendor-dependencies
ericriff Sep 30, 2025
5230419
Remove wildcards cmake options, it has been removed on master
ericriff Sep 30, 2025
81bc7e4
Merge remote-tracking branch 'origin/master' into unvendor-dependencies
ericriff Sep 30, 2025
b21cb25
Update changes after cpp-sqlite removal
ericriff Sep 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 10 additions & 13 deletions .github/workflows/cmake_ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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.txt -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=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
20 changes: 9 additions & 11 deletions .github/workflows/cmake_windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,22 @@ 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.txt -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
# 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=conan_toolchain.cmake
run: cmake --preset conan-default

- 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
Expand Down
19 changes: 19 additions & 0 deletions 3rdparty/cppzmq/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
find_package(ZeroMQ REQUIRED)

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}
)

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()
8 changes: 8 additions & 0 deletions 3rdparty/flatbuffers/CMakeLists.txt
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you create these CMake files only to provide an alias? Have you checked if the upstream really provides that target alias? Still, you can use Conan CMakeDeps.set_property to avoid any extra cmake file here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created these CMakeLists.txt to make each vendored library be a CMake target. Then I matched the target name that conan exposes.

Then you can use this pattern to select where someLibrary is coming from

if(USE_VENDORED_someLibrary)
  add_subdirectory(3rdparty/someLibrary)
else()
  find_package(someLibrary REQUIRED)
endif()

But regardless of the origin of the package (vendored, package manager) you link it the same way

target_link_library(btcpp PRIVATE someLibraryTargetName)

This also allowed me to remove an ugly line that was exposing the whole 3rdparty folder as a include dir. it was something like this

target_include_directory(btcpp PUBLIC 3rdparty)

This line was problematic because all the vendored headers where visible to btcpp, regardless of the value of USE_VENDORED_someLibrary. So if you opted out of some vendored lib and replaced it with a package, it was still not clear which version of the header was going to end up being included. The one from the package or the one vendored? It was a recipe for disaster.

Besides, CMake best practices is to always use targets.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
add_library(flatbuffers INTERFACE)

add_library(flatbuffers::flatbuffers ALIAS flatbuffers)

target_include_directories(flatbuffers
INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}
)
Copy link
Contributor Author

@ericriff ericriff Sep 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file was moved into a flatbuffers subfolder so it can be included like this

#include <flatbuffers/base.h>`

Otherwise it would have to be included like this

#include <base.h>`

Which doesn't match the conan package.

File renamed without changes.
8 changes: 8 additions & 0 deletions 3rdparty/minicoro/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
add_library(minicoro INTERFACE)

add_library(minicoro::minicoro ALIAS minicoro)

target_include_directories(minicoro
INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}
)
20 changes: 20 additions & 0 deletions 3rdparty/minitrace/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
add_library(minitrace STATIC
minitrace.cpp
)

add_library(minitrace::minitrace ALIAS minitrace)

target_include_directories(minitrace
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)

target_compile_definitions(minitrace
PRIVATE
MTR_ENABLED=True
)

set_property(TARGET minitrace
PROPERTY
POSITION_INDEPENDENT_CODE ON
)
15 changes: 15 additions & 0 deletions 3rdparty/tinyxml2/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
add_library(tinyxml2 STATIC
tinyxml2.cpp
)

add_library(tinyxml2::tinyxml2 ALIAS tinyxml2)

target_include_directories(tinyxml2
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)

set_property(TARGET tinyxml2
PROPERTY
POSITION_INDEPENDENT_CODE ON
)
80 changes: 62 additions & 18 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ 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_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)

set(BTCPP_LIB_DESTINATION lib)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code was repeated on both conan_build.cmake and ament_build.cmake. I've unified it here.

set(BTCPP_INCLUDE_DESTINATION include)
set(BTCPP_BIN_DESTINATION bin)

set(BASE_FLAGS "")

if(ENABLE_DEBUG)
Expand Down Expand Up @@ -61,12 +72,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
# at the current cmake version level
if(POLICY CMP0057)
Expand All @@ -84,19 +89,57 @@ 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.")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed this message to better reflect what's going on. This code path doesn't necesarily means that conan is being used, it just means that ament is not used. On the docs it says that one can build without conan or ament if ZeroMQ and Sqlite3 are provided somehow (e.g. apt on ubuntu). If you do that, then you fall on this code path and the log wrongly says that conan is being used.

message(STATUS "------------------------------------------")
include(cmake/conan_build.cmake)
endif()

#############################################################
# LIBRARY
# Handle dependencies

find_package(Threads REQUIRED)

if(BTCPP_GROOT_INTERFACE)
if(USE_VENDORED_CPPZMQ)
add_subdirectory(3rdparty/cppzmq)
else()
find_package(cppzmq REQUIRED)
endif()
endif()

if(BTCPP_SQLITE_LOGGING)
find_package(SQLite3 REQUIRED)
endif()

if(USE_VENDORED_FLATBUFFERS)
add_subdirectory(3rdparty/flatbuffers)
else()
find_package(flatbuffers REQUIRED)
endif()

add_subdirectory(3rdparty/lexy)
if(USE_VENDORED_LEXY)
add_subdirectory(3rdparty/lexy)
else()
find_package(lexy REQUIRED)
endif()

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(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()

list(APPEND BT_SOURCE
src/action_node.cpp
Expand Down Expand Up @@ -140,8 +183,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
)


Expand Down Expand Up @@ -179,8 +220,13 @@ target_link_libraries(${BTCPP_LIBRARY}
PRIVATE
Threads::Threads
${CMAKE_DL_LIBS}
$<BUILD_INTERFACE:foonathan::lexy>
$<BUILD_INTERFACE:minitrace>
foonathan::lexy
minitrace::minitrace
tinyxml2::tinyxml2
minicoro::minicoro
flatbuffers::flatbuffers
$<$<BOOL:${BTCPP_GROOT_INTERFACE}>:cppzmq>
$<$<BOOL:${BTCPP_SQLITE_LOGGING}>:SQLite::SQLite3>
PUBLIC
${BTCPP_EXTRA_LIBRARIES}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still need to figure out this line. I think it is always empty now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's for optional libraries like zeromq and sqlite3, but I would not touch it as the project may add new dependencies in the future and will need to rework it in case it changes now.

)
Expand All @@ -190,8 +236,6 @@ target_include_directories(${BTCPP_LIBRARY}
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
PRIVATE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/3rdparty>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/lexy/include>
${BTCPP_EXTRA_INCLUDE_DIRS}
)

Expand Down
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,15 @@ Three build systems are supported:

Compiling with [conan](https://conan.io/):

Assuming that you are in the **parent** directory of `BehaviorTree.CPP`:
> [!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
cmake -S . -B build_release -DCMAKE_TOOLCHAIN_FILE="build_release/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
Expand Down
8 changes: 8 additions & 0 deletions cmake/FindZeroMQ.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using variables like ZeroMQ_INCLUDE_DIRS or ZeroMQ_LIBRARIES is old-school cmake and it is discouraged. All modern codebases should use targets instead.
So I slightly tweaked this Find module to also expose a target, using a name that matches conan's.

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)
12 changes: 0 additions & 12 deletions cmake/ament_build.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand All @@ -23,10 +15,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
Expand Down
9 changes: 2 additions & 7 deletions cmake/conan_build.cmake
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}")

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})
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to clean this up.

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()


set( BTCPP_LIB_DESTINATION lib )
set( BTCPP_INCLUDE_DESTINATION include )
set( BTCPP_BIN_DESTINATION bin )

mark_as_advanced(
BTCPP_EXTRA_LIBRARIES
BTCPP_LIB_DESTINATION
Expand Down
Loading
Loading