Skip to content

use ament export targets #778

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
58 changes: 58 additions & 0 deletions .github/workflows/colcon_ament.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: colcon ament Ubuntu

on: [push, pull_request]

env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release

jobs:
build:
container: osrf/ros:${{matrix.ros_distro}}-desktop
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-22.04]
ros_distro: [humble, rolling]
steps:
- uses: actions/checkout@v2

- name: Install binary dependencies with rosdep
id: rosdep
run: |
apt update
rosdep update
source /opt/ros/${{matrix.ros_distro}}/setup.bash
rosdep install --from-paths src --ignore-src -y
shell: bash

- name: Build with colcon
id: colcon-build
run: |
source /opt/ros/${{matrix.ros_distro}}/setup.bash
colcon build
shell: bash

- name: Test with colcon
id: colcon-test
run: |
source /opt/ros/${{matrix.ros_distro}}/setup.bash
colcon test
colcon test-result --all --verbose
shell: bash

- name: Test consuming with ament_target_dependencies
run: |
source /opt/ros/${{matrix.ros_distro}}/setup.bash
# This sets the variable AMENT_PREFIX_PATH
source install/setup.bash
cd tests/export/ament_target_deps
colcon build

- name: Test consuming with target_link_libraries
run: |
source /opt/ros/${{matrix.ros_distro}}/setup.bash
# This sets the variable AMENT_PREFIX_PATH
source install/setup.bash
cd tests/export/target_link_libs
colcon build
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ endif()

find_package(ament_cmake QUIET)

# This is a private variable to control the exported namespace name for installation
# macros that support namespace targets.
set(_BTCPP_EXPORTED_NAMESPACE BT::)
if ( ament_cmake_FOUND )

add_definitions( -DUSING_ROS2 )
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ If you are looking for a more fancy graphical user interface (and I know you do)

**BT.CPP** requires a compile that supports c++17.

Three build systems are supported:
Four build systems are supported:

- **catkin**, if you use ROS
- **colcon (ament)**, if you use ROS2
Expand Down
10 changes: 6 additions & 4 deletions cmake/ament_build.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ set( BTCPP_EXTRA_LIBRARIES
$<BUILD_INTERFACE:${SQLite3_LIBRARIES}>
)

ament_export_dependencies(ament_index_cpp)

set( BTCPP_LIB_DESTINATION lib )
set( BTCPP_INCLUDE_DESTINATION include )
set( BTCPP_BIN_DESTINATION bin )
Expand All @@ -31,7 +29,11 @@ mark_as_advanced(
BTCPP_BIN_DESTINATION )

macro(export_btcpp_package)
ament_export_include_directories(include)
ament_export_libraries(${BTCPP_LIBRARY})
ament_export_targets(
${PROJECT_NAME}Targets
NAMESPACE "{_BTCPP_EXPORTED_NAMESPACE}"
HAS_LIBRARY_TARGET
)
ament_export_dependencies(ament_index_cpp)
ament_package()
endmacro()
2 changes: 1 addition & 1 deletion cmake/conan_build.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ macro(export_btcpp_package)
install(EXPORT ${PROJECT_NAME}Targets
FILE "${PROJECT_NAME}Targets.cmake"
DESTINATION "${BTCPP_LIB_DESTINATION}/cmake/${PROJECT_NAME}"
NAMESPACE BT::
NAMESPACE "{_BTCPP_EXPORTED_NAMESPACE}"
)
export(PACKAGE ${PROJECT_NAME})

Expand Down
5 changes: 5 additions & 0 deletions tests/export/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Export tests

The purpose of the tests below is to ensure that BTCPP exports itself correctly for use with find_package.

Without testing this, it is easy to accidentally break consumer applications when working on CMake installation code.
15 changes: 15 additions & 0 deletions tests/export/ament_target_deps/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 3.22.1) # version on Ubuntu Jammy
project(btcpp_ament_tgt_dep LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(ament_cmake 1 CONFIG REQUIRED)
find_package(behaviortree_cpp 4 REQUIRED)

add_executable(btcpp_sample main.cpp)

# This function doesn't yet support PRIVATE as an argument.
# See https://github.com/ament/ament_cmake/issues/158#issuecomment-475384147
# Instead, test preserving legacy usage with no linkage specifier.
ament_target_dependencies(btcpp_sample behaviortree_cpp)
78 changes: 78 additions & 0 deletions tests/export/ament_target_deps/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copy of https://github.com/BehaviorTree/btcpp_sample/blob/main/main.cpp

#include "behaviortree_cpp/bt_factory.h"

using namespace BT;

// clang-format off
static const char* xml_text = R"(

<root BTCPP_format="4" >

<BehaviorTree ID="MainTree">
<Sequence name="root">
<AlwaysSuccess/>
<SaySomething message="this works too" />
<ThinkWhatToSay text="{the_answer}"/>
<SaySomething message="{the_answer}" />
</Sequence>
</BehaviorTree>

</root>
)";
// clang-format on

class SaySomething : public BT::SyncActionNode
{
public:
SaySomething(const std::string& name, const BT::NodeConfig& config) :
BT::SyncActionNode(name, config)
{}

BT::NodeStatus tick() override
{
std::string msg;
getInput("message", msg);
std::cout << msg << std::endl;
return BT::NodeStatus::SUCCESS;
}

static BT::PortsList providedPorts()
{
return {BT::InputPort<std::string>("message")};
}
};

class ThinkWhatToSay : public BT::SyncActionNode
{
public:
ThinkWhatToSay(const std::string& name, const BT::NodeConfig& config) :
BT::SyncActionNode(name, config)
{}

BT::NodeStatus tick() override
{
setOutput("text", "The answer is 42");
return BT::NodeStatus::SUCCESS;
}

static BT::PortsList providedPorts()
{
return {BT::OutputPort<std::string>("text")};
}
};

int main()
{

BehaviorTreeFactory factory;

factory.registerNodeType<SaySomething>("SaySomething");
factory.registerNodeType<ThinkWhatToSay>("ThinkWhatToSay");

auto tree = factory.createTreeFromText(xml_text);

tree.tickWhileRunning();

return 0;
}
16 changes: 16 additions & 0 deletions tests/export/target_link_libs/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 3.22.1) # version on Ubuntu Jammy
project(btcpp_tgt_link_libs LANGUAGES CXX)


set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(ament_cmake 1 CONFIG REQUIRED)
set(CMAKE_FIND_DEBUG_MODE TRUE)
find_package(behaviortree_cpp 4 CONFIG REQUIRED)
set(CMAKE_FIND_DEBUG_MODE FALSE)

add_executable(btcpp_sample main.cpp)

# Check it works with the same target that conan users use
target_link_libraries(btcpp_sample PRIVATE BT::behaviortree_cpp)
78 changes: 78 additions & 0 deletions tests/export/target_link_libs/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copy of https://github.com/BehaviorTree/btcpp_sample/blob/main/main.cpp

#include "behaviortree_cpp/bt_factory.h"

using namespace BT;

// clang-format off
static const char* xml_text = R"(

<root BTCPP_format="4" >

<BehaviorTree ID="MainTree">
<Sequence name="root">
<AlwaysSuccess/>
<SaySomething message="this works too" />
<ThinkWhatToSay text="{the_answer}"/>
<SaySomething message="{the_answer}" />
</Sequence>
</BehaviorTree>

</root>
)";
// clang-format on

class SaySomething : public BT::SyncActionNode
{
public:
SaySomething(const std::string& name, const BT::NodeConfig& config) :
BT::SyncActionNode(name, config)
{}

BT::NodeStatus tick() override
{
std::string msg;
getInput("message", msg);
std::cout << msg << std::endl;
return BT::NodeStatus::SUCCESS;
}

static BT::PortsList providedPorts()
{
return {BT::InputPort<std::string>("message")};
}
};

class ThinkWhatToSay : public BT::SyncActionNode
{
public:
ThinkWhatToSay(const std::string& name, const BT::NodeConfig& config) :
BT::SyncActionNode(name, config)
{}

BT::NodeStatus tick() override
{
setOutput("text", "The answer is 42");
return BT::NodeStatus::SUCCESS;
}

static BT::PortsList providedPorts()
{
return {BT::OutputPort<std::string>("text")};
}
};

int main()
{

BehaviorTreeFactory factory;

factory.registerNodeType<SaySomething>("SaySomething");
factory.registerNodeType<ThinkWhatToSay>("ThinkWhatToSay");

auto tree = factory.createTreeFromText(xml_text);

tree.tickWhileRunning();

return 0;
}