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