Skip to content

Commit

Permalink
Cmake infrastructure for creating components (#784)
Browse files Browse the repository at this point in the history
*cmake macro to create components for libraries with multiple nodes

Signed-off-by: Siddharth Kucheria <kucheria@usc.edu>
  • Loading branch information
skucheria committed Jul 24, 2019
1 parent cd06357 commit b214324
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 2 deletions.
7 changes: 6 additions & 1 deletion rclcpp_components/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ ament_target_dependencies(component_container
"rclcpp"
)

set(node_main_template_install_dir "share/${PROJECT_NAME}")
install(FILES
src/node_main.cpp.in
DESTINATION ${node_main_template_install_dir})

add_executable(
component_container_mt
src/component_container_mt.cpp
Expand Down Expand Up @@ -119,4 +124,4 @@ install(
ament_export_include_directories(include)
ament_export_dependencies(class_loader)
ament_export_dependencies(rclcpp)
ament_package(CONFIG_EXTRAS rclcpp_components-extras.cmake)
ament_package(CONFIG_EXTRAS rclcpp_components-extras.cmake.in)
52 changes: 52 additions & 0 deletions rclcpp_components/cmake/rclcpp_components_register_node.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Copyright 2019 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# usage: rclcpp_components_register_node(
# <target> PLUGIN <component> EXECUTABLE <node>)
#
# Register an rclcpp component with the ament
# resource index and create an executable.
#
# :param target: the shared library target
# :type target: string
# :param PLUGIN: the plugin name
# :type PLUGIN: string
# :type EXECUTABLE: the node's executable name
# :type EXECUTABLE: string
#
macro(rclcpp_components_register_node target)
cmake_parse_arguments(ARGS "" "PLUGIN;EXECUTABLE" "" ${ARGN})
set(component ${ARGS_PLUGIN})
set(node ${ARGS_EXECUTABLE})
_rclcpp_components_register_package_hook()
set(_path "lib")
set(library_name "$<TARGET_FILE_NAME:${target}>")
if(WIN32)
set(_path "bin")
endif()
set(_RCLCPP_COMPONENTS__NODES
"${_RCLCPP_COMPONENTS__NODES}${component};${_path}/$<TARGET_FILE_NAME:${target}>\n")
configure_file(${rclcpp_components_NODE_TEMPLATE}
${PROJECT_BINARY_DIR}/node_main_configured.cpp.in)
file(GENERATE OUTPUT ${PROJECT_BINARY_DIR}/rclcpp_components/node_main_${node}.cpp
INPUT ${PROJECT_BINARY_DIR}/node_main_configured.cpp.in)
add_executable(${node} ${PROJECT_BINARY_DIR}/rclcpp_components/node_main_${node}.cpp)
ament_target_dependencies(${node}
"rclcpp"
"class_loader"
"rclcpp_components")
install(TARGETS
${node}
DESTINATION lib/${PROJECT_NAME})
endmacro()
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,7 @@ macro(_rclcpp_components_register_package_hook)
endif()
endmacro()

include("${rclcpp_components_DIR}/rclcpp_components_register_nodes.cmake")
set(@PROJECT_NAME@_NODE_TEMPLATE "@CMAKE_INSTALL_PREFIX@/@node_main_template_install_dir@/node_main.cpp.in")

include("${rclcpp_components_DIR}/rclcpp_components_register_nodes.cmake")
include("${rclcpp_components_DIR}/rclcpp_components_register_node.cmake")
66 changes: 66 additions & 0 deletions rclcpp_components/src/node_main.cpp.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2019 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <memory>
#include <string>
#include <vector>

#include "class_loader/class_loader.hpp"
#include "rclcpp/rclcpp.hpp"
#include "rclcpp_components/node_factory.hpp"
#include "rclcpp_components/node_factory_template.hpp"

#define NODE_MAIN_LOGGER_NAME "@node@"

int main(int argc, char * argv[])
{
auto args = rclcpp::init_and_remove_ros_arguments(argc, argv);
rclcpp::Logger logger = rclcpp::get_logger(NODE_MAIN_LOGGER_NAME);
rclcpp::executors::SingleThreadedExecutor exec;
rclcpp::NodeOptions options;
options.arguments(args);
std::vector<class_loader::ClassLoader * > loaders;
std::vector<rclcpp_components::NodeInstanceWrapper> node_wrappers;

std::string library_name = "@library_name@";
std::string class_name = "rclcpp_components::NodeFactoryTemplate<@component@>";

RCLCPP_DEBUG(logger, "Load library %s", library_name.c_str());
auto loader = new class_loader::ClassLoader(library_name);
auto classes = loader->getAvailableClasses<rclcpp_components::NodeFactory>();
for (auto clazz : classes) {
std::string name = clazz.c_str();
if (!(name.compare(class_name))) {
RCLCPP_DEBUG(logger, "Instantiate class %s", clazz.c_str());
auto node_factory = loader->createInstance<rclcpp_components::NodeFactory>(clazz);
auto wrapper = node_factory->create_node_instance(options);
auto node = wrapper.get_node_base_interface();
node_wrappers.push_back(wrapper);
exec.add_node(node);
}
}
loaders.push_back(loader);


exec.spin();

for (auto wrapper : node_wrappers) {
exec.remove_node(wrapper.get_node_base_interface());
}
node_wrappers.clear();

rclcpp::shutdown();

return 0;
}

0 comments on commit b214324

Please sign in to comment.