From e38ac73c69ac6b09c9260e85e68a01768397c6d5 Mon Sep 17 00:00:00 2001 From: Dirk Thomas Date: Mon, 7 Dec 2015 18:04:19 -0800 Subject: [PATCH] refactor typesupport --- rclcpp/CMakeLists.txt | 60 +++++++------ rclcpp/cmake/get_rclcpp_information.cmake | 88 +++++++++++++++++++ rclcpp/include/rclcpp/type_support_decl.hpp | 16 ++++ rclcpp/include/rclcpp/visibility_control.hpp | 25 ------ rclcpp/package.xml | 5 +- rclcpp/rclcpp-extras.cmake | 2 + rclcpp/src/rclcpp/node.cpp | 37 -------- rclcpp/src/rclcpp/parameter_client.cpp | 51 ----------- .../rclcpp/type_support.cpp} | 7 -- rclcpp/src/rclcpp/windows_helper.cpp | 17 ---- 10 files changed, 142 insertions(+), 166 deletions(-) create mode 100644 rclcpp/cmake/get_rclcpp_information.cmake rename rclcpp/{include/rclcpp/type_support_def.hpp => src/rclcpp/type_support.cpp} (94%) delete mode 100644 rclcpp/src/rclcpp/windows_helper.cpp diff --git a/rclcpp/CMakeLists.txt b/rclcpp/CMakeLists.txt index c342640..e767aba 100644 --- a/rclcpp/CMakeLists.txt +++ b/rclcpp/CMakeLists.txt @@ -5,6 +5,8 @@ project(rclcpp) find_package(ament_cmake REQUIRED) find_package(rcl_interfaces REQUIRED) find_package(rmw REQUIRED) +find_package(rmw_implementation REQUIRED) +find_package(rmw_implementation_cmake REQUIRED) find_package(rosidl_generator_cpp REQUIRED) if(NOT WIN32) @@ -35,31 +37,37 @@ set(${PROJECT_NAME}_SRCS src/rclcpp/service.cpp src/rclcpp/subscription.cpp src/rclcpp/timer.cpp + src/rclcpp/type_support.cpp src/rclcpp/utilities.cpp ) -if(WIN32) - list(APPEND ${PROJECT_NAME}_SRCS src/rclcpp/windows_helper.cpp) -endif() -add_library(${PROJECT_NAME} SHARED ${${PROJECT_NAME}_SRCS}) -ament_target_dependencies( - ${PROJECT_NAME} - "rcl_interfaces" - "rmw" - "rosidl_generator_cpp" -) -# Causes the visibility macros to use dllexport rather than dllimport, -# which is appropriate when building the dll but not consuming it. -# It also avoids using certain parts of the code that the consuming code must -# use, but which the library cannot consume itself. -target_compile_definitions(${PROJECT_NAME} PRIVATE "RCLCPP_BUILDING_LIBRARY") -if(APPLE) - # Since the rmw_* symbols are unresolved at the time of building librclcpp, - # tell the linker on OS X to dynamically look them up at runtime. - set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") -endif() + +macro(target) + add_library(${PROJECT_NAME}${target_suffix} SHARED + ${${PROJECT_NAME}_SRCS}) + ament_target_dependencies(${PROJECT_NAME}${target_suffix} + "rcl_interfaces" + "rmw" + "rosidl_generator_cpp" + "${rmw_implementation}") + + # Causes the visibility macros to use dllexport rather than dllimport, + # which is appropriate when building the dll but not consuming it. + target_compile_definitions(${PROJECT_NAME}${target_suffix} + PRIVATE "RCLCPP_BUILDING_LIBRARY") + + install( + TARGETS ${PROJECT_NAME}${target_suffix} + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin + ) +endmacro() + +call_for_each_rmw_implementation(target GENERATE_DEFAULT) ament_export_dependencies(rcl_interfaces) ament_export_dependencies(rmw) +ament_export_dependencies(rmw_implementation) ament_export_dependencies(rosidl_generator_cpp) ament_export_include_directories(include) @@ -100,6 +108,11 @@ ament_package( CONFIG_EXTRAS rclcpp-extras.cmake ) +install( + DIRECTORY cmake + DESTINATION share/${PROJECT_NAME} +) + install( DIRECTORY include/ DESTINATION include @@ -109,10 +122,3 @@ install( DIRECTORY src/ DESTINATION src/rclcpp ) - -install( - TARGETS ${PROJECT_NAME} - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - RUNTIME DESTINATION bin -) diff --git a/rclcpp/cmake/get_rclcpp_information.cmake b/rclcpp/cmake/get_rclcpp_information.cmake new file mode 100644 index 0000000..a7553f2 --- /dev/null +++ b/rclcpp/cmake/get_rclcpp_information.cmake @@ -0,0 +1,88 @@ +# Copyright 2015 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. + +# +# Get all information abut rclcpp for a specific RMW implementation. +# +# It sets the common variables _DEFINITIONS, _INCLUDE_DIRS and _LIBRARIES +# with the given prefix. +# +# :param rmw_implementation: the RMW implementation name +# :type target: string +# :param var_prefix: the prefix of all output variable names +# :type var_prefix: string +# +macro(get_rclcpp_information rmw_implementation var_prefix) + # pretend to be a "package" + # so that the variables can be used by various functions / macros + set(${var_prefix}_FOUND TRUE) + + # include directories + set(${var_prefix}_INCLUDE_DIRS + "${rclcpp_DIR}/../../../include") + + # libraries + set(_libs) + # search for library relative to this CMake file + set(_library_target "rclcpp") + get_available_rmw_implementations(_rmw_impls) + list(LENGTH _rmw_impls _rmw_impls_length) + if(_rmw_impls_length GREATER 1) + set(_library_target "${_library_target}__${rmw_implementation}") + endif() + set(_lib "NOTFOUND") + find_library( + _lib NAMES "${_library_target}" + PATHS "${rclcpp_DIR}/../../../lib" + NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH + ) + if(NOT _lib) + # warn about not existing library and ignore it + message(FATAL_ERROR "Package 'rclcpp' doesn't contain the library '${_library_target}'") + elseif(NOT IS_ABSOLUTE "${_lib}") + # the found library must be an absolute path + message(FATAL_ERROR "Package 'rclcpp' found the library '${_library_target}' at '${_lib}' which is not an absolute path") + elseif(NOT EXISTS "${_lib}") + # the found library must exist + message(FATAL_ERROR "Package 'rclcpp' found the library '${_lib}' which doesn't exist") + else() + list(APPEND _libs "${_lib}") + endif() + + # dependencies + set(_exported_dependencies + "rcl_interfaces" + "rmw" + "${rmw_implementation}" + "rosidl_generator_cpp") + set(${var_prefix}_DEFINITIONS) + foreach(_dep ${_exported_dependencies}) + if(NOT ${_dep}_FOUND) + find_package("${_dep}" QUIET REQUIRED) + endif() + if(${_dep}_DEFINITIONS) + list_append_unique(${var_prefix}_DEFINITIONS "${${_dep}_DEFINITIONS}") + endif() + if(${_dep}_INCLUDE_DIRS) + list_append_unique(${var_prefix}_INCLUDE_DIRS "${${_dep}_INCLUDE_DIRS}") + endif() + if(${_dep}_LIBRARIES) + list(APPEND _libs "${${_dep}_LIBRARIES}") + endif() + endforeach() + if(_libs) + ament_libraries_deduplicate(_libs "${_libs}") + endif() + set(${var_prefix}_LIBRARIES "${_libs}") +endmacro() diff --git a/rclcpp/include/rclcpp/type_support_decl.hpp b/rclcpp/include/rclcpp/type_support_decl.hpp index e417ff8..b4abc14 100644 --- a/rclcpp/include/rclcpp/type_support_decl.hpp +++ b/rclcpp/include/rclcpp/type_support_decl.hpp @@ -18,41 +18,57 @@ #include "rosidl_generator_cpp/message_type_support_decl.hpp" #include "rosidl_generator_cpp/service_type_support_decl.hpp" +#include "rosidl_generator_cpp/message_type_support.hpp" +#include "rosidl_generator_cpp/service_type_support.hpp" + +#include "rclcpp/visibility_control.hpp" + namespace rclcpp { namespace type_support { +RCLCPP_PUBLIC const rosidl_message_type_support_t * get_intra_process_message_msg_type_support(); +RCLCPP_PUBLIC const rosidl_message_type_support_t * get_parameter_event_msg_type_support(); +RCLCPP_PUBLIC const rosidl_message_type_support_t * get_set_parameters_result_msg_type_support(); +RCLCPP_PUBLIC const rosidl_message_type_support_t * get_parameter_descriptor_msg_type_support(); +RCLCPP_PUBLIC const rosidl_message_type_support_t * get_list_parameters_result_msg_type_support(); +RCLCPP_PUBLIC const rosidl_service_type_support_t * get_get_parameters_srv_type_support(); +RCLCPP_PUBLIC const rosidl_service_type_support_t * get_get_parameter_types_srv_type_support(); +RCLCPP_PUBLIC const rosidl_service_type_support_t * get_set_parameters_srv_type_support(); +RCLCPP_PUBLIC const rosidl_service_type_support_t * get_list_parameters_srv_type_support(); +RCLCPP_PUBLIC const rosidl_service_type_support_t * get_describe_parameters_srv_type_support(); +RCLCPP_PUBLIC const rosidl_service_type_support_t * get_set_parameters_atomically_srv_type_support(); diff --git a/rclcpp/include/rclcpp/visibility_control.hpp b/rclcpp/include/rclcpp/visibility_control.hpp index 747ab10..b257c51 100644 --- a/rclcpp/include/rclcpp/visibility_control.hpp +++ b/rclcpp/include/rclcpp/visibility_control.hpp @@ -24,31 +24,6 @@ #include "rmw/rmw.h" -#if !defined(RCLCPP_BUILDING_LIBRARY) -// The following header is necessary inorder to get the correct rmw -// implementation specific message symbols. -// Any library or executable using librclcpp must include the header. -// However, librclcpp must not include it. -#include "rclcpp/type_support_def.hpp" - -// Anonymous namespace to prevent duplicate symbols across compile units. -namespace -{ - -// This call to an rmw function is used to force the Linux linker to include -// the rmw implementation library in the user's executable. -// If this is not done, then only librclcpp is missing rmw symbols and when -// linking the next library or exectuable the linker will discard the rmw -// implementation shared library as unused. -// On OS X this isn't an issue because linking is done, by default, in a flat -// namespace, so when linking something that uses librclcpp, it will try to -// resolve the rclcpp symbols each time, taking them from the rmw implementation -// when it is available and not discarding it as unused during the link step. -static const char * __rmw_identifier = rmw_get_implementation_identifier(); - -} // namespace -#endif // !defined(RCLCPP_BUILDING_LIBRARY) - // This logic was borrowed (then namespaced) from the examples on the gcc wiki: // https://gcc.gnu.org/wiki/Visibility diff --git a/rclcpp/package.xml b/rclcpp/package.xml index 2ffce3e..87fa1a1 100644 --- a/rclcpp/package.xml +++ b/rclcpp/package.xml @@ -11,12 +11,13 @@ rmw rcl_interfaces - - rmw_implementation + rmw_implementation_cmake rosidl_generator_cpp rcl_interfaces rosidl_generator_cpp + rmw_implementation + ament_cmake_gtest ament_lint_auto ament_lint_common diff --git a/rclcpp/rclcpp-extras.cmake b/rclcpp/rclcpp-extras.cmake index 3c44bec..7ecfec8 100644 --- a/rclcpp/rclcpp-extras.cmake +++ b/rclcpp/rclcpp-extras.cmake @@ -14,6 +14,8 @@ # copied from rclcpp/rclcpp-extras.cmake +include("${rclcpp_DIR}/get_rclcpp_information.cmake") + set(rclcpp_node_main_SRC "${rclcpp_DIR}/../../../src/rclcpp/node_main.cpp") function(rclcpp_create_node_main node_library_target) diff --git a/rclcpp/src/rclcpp/node.cpp b/rclcpp/src/rclcpp/node.cpp index 4858dbd..5d250f7 100644 --- a/rclcpp/src/rclcpp/node.cpp +++ b/rclcpp/src/rclcpp/node.cpp @@ -21,43 +21,6 @@ #include "rclcpp/node.hpp" -// Specializations with references to unresolved symbols to delay evaluation until later. -// On Windows this is not necessary since it will be built against the rmw implementation directly. -#if !defined(WIN32) -namespace rosidl_generator_cpp -{ - -template<> -const rosidl_message_type_support_t * -get_message_type_support_handle() -{ - return rclcpp::type_support::get_parameter_event_msg_type_support(); -} - -template<> -const rosidl_message_type_support_t * -get_message_type_support_handle() -{ - return rclcpp::type_support::get_set_parameters_result_msg_type_support(); -} - -template<> -const rosidl_message_type_support_t * -get_message_type_support_handle() -{ - return rclcpp::type_support::get_parameter_descriptor_msg_type_support(); -} - -template<> -const rosidl_message_type_support_t * -get_message_type_support_handle() -{ - return rclcpp::type_support::get_list_parameters_result_msg_type_support(); -} - -} // namespace rosidl_generator_cpp -#endif - using rclcpp::node::Node; Node::Node(const std::string & node_name, bool use_intra_process_comms) diff --git a/rclcpp/src/rclcpp/parameter_client.cpp b/rclcpp/src/rclcpp/parameter_client.cpp index e098cc4..f3b88f3 100644 --- a/rclcpp/src/rclcpp/parameter_client.cpp +++ b/rclcpp/src/rclcpp/parameter_client.cpp @@ -18,57 +18,6 @@ #include #include -// Specializations with references to unresolved symbols to delay evaluation until later. -// On Windows this is not necessary since it will be built against the rmw implementation directly. -#if !defined(WIN32) -namespace rosidl_generator_cpp -{ - -template<> -const rosidl_service_type_support_t * -get_service_type_support_handle() -{ - return rclcpp::type_support::get_get_parameters_srv_type_support(); -} - -template<> -const rosidl_service_type_support_t * -get_service_type_support_handle() -{ - return rclcpp::type_support::get_get_parameter_types_srv_type_support(); -} - -template<> -const rosidl_service_type_support_t * -get_service_type_support_handle() -{ - return rclcpp::type_support::get_set_parameters_srv_type_support(); -} - -template<> -const rosidl_service_type_support_t * -get_service_type_support_handle() -{ - return rclcpp::type_support::get_list_parameters_srv_type_support(); -} - -template<> -const rosidl_service_type_support_t * -get_service_type_support_handle() -{ - return rclcpp::type_support::get_describe_parameters_srv_type_support(); -} - -template<> -const rosidl_service_type_support_t * -get_service_type_support_handle() -{ - return rclcpp::type_support::get_set_parameters_atomically_srv_type_support(); -} - -} // namespace rosidl_generator_cpp -#endif - using rclcpp::parameter_client::AsyncParametersClient; using rclcpp::parameter_client::SyncParametersClient; diff --git a/rclcpp/include/rclcpp/type_support_def.hpp b/rclcpp/src/rclcpp/type_support.cpp similarity index 94% rename from rclcpp/include/rclcpp/type_support_def.hpp rename to rclcpp/src/rclcpp/type_support.cpp index 899ab3c..feaab48 100644 --- a/rclcpp/include/rclcpp/type_support_def.hpp +++ b/rclcpp/src/rclcpp/type_support.cpp @@ -12,9 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef RCLCPP__TYPE_SUPPORT_DEF_HPP_ -#define RCLCPP__TYPE_SUPPORT_DEF_HPP_ - #include "rclcpp/type_support_decl.hpp" #include "rclcpp/visibility_control.hpp" @@ -29,8 +26,6 @@ #include "rcl_interfaces/srv/list_parameters.hpp" #include "rcl_interfaces/srv/set_parameters.hpp" #include "rcl_interfaces/srv/set_parameters_atomically.hpp" -#include "rosidl_generator_cpp/message_type_support.hpp" -#include "rosidl_generator_cpp/service_type_support.hpp" const rosidl_message_type_support_t * rclcpp::type_support::get_intra_process_message_msg_type_support() @@ -119,5 +114,3 @@ rclcpp::type_support::get_set_parameters_atomically_srv_type_support() rcl_interfaces::srv::SetParametersAtomically >(); } - -#endif // RCLCPP__TYPE_SUPPORT_DEF_HPP_ diff --git a/rclcpp/src/rclcpp/windows_helper.cpp b/rclcpp/src/rclcpp/windows_helper.cpp deleted file mode 100644 index 5c72951..0000000 --- a/rclcpp/src/rclcpp/windows_helper.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2015 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. - -#if defined(WIN32) -#include "rclcpp/type_support_def.hpp" -#endif