From 38d0a8dacefbf792f2236c3704bfbcbf1a23bae0 Mon Sep 17 00:00:00 2001 From: Pablo Garrido Date: Fri, 14 May 2021 12:51:13 +0200 Subject: [PATCH 1/3] Static type support initial Signed-off-by: Your Name Default to OFF Signed-off-by: Your Name Linter Signed-off-by: Your Name Fix Signed-off-by: Your Name Refactor Reafactor Signed-off-by: Your Name Lint Signed-off-by: Your Name --- rosidl_typesupport_c/CMakeLists.txt | 20 +++++++++++++++--- ...dl_typesupport_c_generate_interfaces.cmake | 7 +++++-- .../resource/msg__type_support.cpp.em | 21 +++++++++++++++++++ .../resource/srv__type_support.cpp.em | 21 +++++++++++++++++++ .../src/type_support_dispatch.hpp | 12 +++++++++-- 5 files changed, 74 insertions(+), 7 deletions(-) diff --git a/rosidl_typesupport_c/CMakeLists.txt b/rosidl_typesupport_c/CMakeLists.txt index b7cdc0ac..917cc2ec 100644 --- a/rosidl_typesupport_c/CMakeLists.txt +++ b/rosidl_typesupport_c/CMakeLists.txt @@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.5) project(rosidl_typesupport_c) +option(ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT "Enable static typesupport" OFF) + # Default to C11 if(NOT CMAKE_C_STANDARD) set(CMAKE_C_STANDARD 11) @@ -16,13 +18,17 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") endif() find_package(ament_cmake_ros REQUIRED) -find_package(rcpputils REQUIRED) find_package(rcutils REQUIRED) find_package(rosidl_runtime_c REQUIRED) +if(NOT ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT) + find_package(rcpputils REQUIRED) +endif() -ament_export_dependencies(rcpputils) ament_export_dependencies(rosidl_runtime_c) ament_export_dependencies(rosidl_typesupport_interface) +if(NOT ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT) + ament_export_dependencies(rcpputils) +endif() ament_export_include_directories(include) @@ -36,15 +42,23 @@ if(WIN32) target_compile_definitions(${PROJECT_NAME} PRIVATE "ROSIDL_TYPESUPPORT_C_BUILDING_DLL") endif() +target_compile_definitions(${PROJECT_NAME} + PRIVATE + $<$:ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT> +) target_include_directories(${PROJECT_NAME} PUBLIC "$" "$") ament_target_dependencies(${PROJECT_NAME} - "rcpputils" "rcutils" "rosidl_runtime_c" ) +if(NOT ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT) + ament_target_dependencies(${PROJECT_NAME} + "rcpputils" + ) +endif() ament_export_libraries(${PROJECT_NAME}) ament_export_targets(${PROJECT_NAME}) diff --git a/rosidl_typesupport_c/cmake/rosidl_typesupport_c_generate_interfaces.cmake b/rosidl_typesupport_c/cmake/rosidl_typesupport_c_generate_interfaces.cmake index c02ffddd..0c10831e 100644 --- a/rosidl_typesupport_c/cmake/rosidl_typesupport_c_generate_interfaces.cmake +++ b/rosidl_typesupport_c/cmake/rosidl_typesupport_c_generate_interfaces.cmake @@ -126,8 +126,10 @@ if(NOT typesupports MATCHES ";") ${rosidl_generate_interfaces_TARGET}__${typesupports}) else() if("${rosidl_typesupport_c_LIBRARY_TYPE}" STREQUAL "STATIC") - message(FATAL_ERROR "Multiple typesupports [${typesupports}] but static " - "linking was requested") + target_compile_definitions(${rosidl_generate_interfaces_TARGET}${_target_suffix} + PRIVATE + ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT + ) endif() endif() @@ -151,6 +153,7 @@ add_dependencies( add_dependencies( ${rosidl_generate_interfaces_TARGET}${_target_suffix} ${rosidl_generate_interfaces_TARGET}__rosidl_generator_c + ${rosidl_generate_interfaces_TARGET}__rosidl_typesupport_c ) if(NOT rosidl_generate_interfaces_SKIP_INSTALL) diff --git a/rosidl_typesupport_c/resource/msg__type_support.cpp.em b/rosidl_typesupport_c/resource/msg__type_support.cpp.em index d09c4c6d..30b57da3 100644 --- a/rosidl_typesupport_c/resource/msg__type_support.cpp.em +++ b/rosidl_typesupport_c/resource/msg__type_support.cpp.em @@ -76,6 +76,26 @@ typedef struct _@(message.structure.namespaced_type.name)_type_support_data_t void * data[@(len(type_supports))]; } _@(message.structure.namespaced_type.name)_type_support_data_t; +#ifdef ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT +#ifdef __cplusplus +extern "C" +{ +#endif +@[for type_support in sorted(type_supports)]@ +rosidl_message_type_support_t * ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(@(type_support), @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(message.structure.namespaced_type.name))(); +@[end for]@ +#ifdef __cplusplus +} +#endif + +static _@(message.structure.namespaced_type.name)_type_support_data_t _@(message.structure.namespaced_type.name)_message_typesupport_data = { + { +@[for type_support in sorted(type_supports)]@ + (void*) ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(@(type_support), @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(message.structure.namespaced_type.name)), +@[end for]@ + } +}; +#else static _@(message.structure.namespaced_type.name)_type_support_data_t _@(message.structure.namespaced_type.name)_message_typesupport_data = { { @[for type_support in sorted(type_supports)]@ @@ -83,6 +103,7 @@ static _@(message.structure.namespaced_type.name)_type_support_data_t _@(message @[end for]@ } }; +#endif // ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT static const type_support_map_t _@(message.structure.namespaced_type.name)_message_typesupport_map = { @(len(type_supports)), diff --git a/rosidl_typesupport_c/resource/srv__type_support.cpp.em b/rosidl_typesupport_c/resource/srv__type_support.cpp.em index b815f611..3629ac8d 100644 --- a/rosidl_typesupport_c/resource/srv__type_support.cpp.em +++ b/rosidl_typesupport_c/resource/srv__type_support.cpp.em @@ -84,6 +84,26 @@ typedef struct _@(service.namespaced_type.name)_type_support_data_t void * data[@(len(type_supports))]; } _@(service.namespaced_type.name)_type_support_data_t; +#ifdef ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT +#ifdef __cplusplus +extern "C" +{ +#endif +@[for type_support in sorted(type_supports)]@ +rosidl_service_type_support_t * ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(@(type_support), @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(service.namespaced_type.name))(); +@[end for]@ +#ifdef __cplusplus +} +#endif + +static _@(service.namespaced_type.name)_type_support_data_t _@(service.namespaced_type.name)_service_typesupport_data = { + { +@[for type_support in sorted(type_supports)]@ + (void*) ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(@(type_support), @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(service.namespaced_type.name)), +@[end for]@ + } +}; +#else static _@(service.namespaced_type.name)_type_support_data_t _@(service.namespaced_type.name)_service_typesupport_data = { { @[for type_support in sorted(type_supports)]@ @@ -91,6 +111,7 @@ static _@(service.namespaced_type.name)_type_support_data_t _@(service.namespace @[end for]@ } }; +#endif // ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT static const type_support_map_t _@(service.namespaced_type.name)_service_typesupport_map = { @(len(type_supports)), diff --git a/rosidl_typesupport_c/src/type_support_dispatch.hpp b/rosidl_typesupport_c/src/type_support_dispatch.hpp index 4c7ae3e6..eaf821f5 100644 --- a/rosidl_typesupport_c/src/type_support_dispatch.hpp +++ b/rosidl_typesupport_c/src/type_support_dispatch.hpp @@ -15,6 +15,8 @@ #ifndef TYPE_SUPPORT_DISPATCH_HPP_ #define TYPE_SUPPORT_DISPATCH_HPP_ +#ifndef ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT + #include #include #include @@ -24,6 +26,9 @@ #include #include "rcpputils/shared_library.hpp" + +#endif // ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT + #include "rcutils/error_handling.h" #include "rcutils/snprintf.h" #include "rosidl_typesupport_c/identifier.h" @@ -50,6 +55,8 @@ get_typesupport_handle_function( if (strcmp(map->typesupport_identifier[i], identifier) != 0) { continue; } + typedef const TypeSupport * (* funcSignature)(void); +#ifndef ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT rcpputils::SharedLibrary * lib = nullptr; if (!map->data[i]) { @@ -103,9 +110,10 @@ get_typesupport_handle_function( map->symbol_name[i], e.what()); return nullptr; } - - typedef const TypeSupport * (* funcSignature)(void); funcSignature func = reinterpret_cast(sym); +#else + funcSignature func = reinterpret_cast(map->data[i]); +#endif // ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT const TypeSupport * ts = func(); return ts; } From cdbd44dfee5785d7867e5c83c20764cfe987e3df Mon Sep 17 00:00:00 2001 From: Pablo Garrido Date: Mon, 17 May 2021 10:39:36 +0200 Subject: [PATCH 2/3] Separate dynamic handling Signed-off-by: Your Name Inferring flags from build type Signed-off-by: Your Name Remove extra include Signed-off-by: Your Name Update Fix rebase Signed-off-by: Your Name Fixes Add messages Update Fix Fix Messages Update Linter Lint Remove messages Signed-off-by: Your Name --- rosidl_typesupport_c/CMakeLists.txt | 20 ++-- .../src/dynamic_support_dispatch.hpp | 102 ++++++++++++++++++ .../src/type_support_dispatch.hpp | 67 +----------- 3 files changed, 119 insertions(+), 70 deletions(-) create mode 100644 rosidl_typesupport_c/src/dynamic_support_dispatch.hpp diff --git a/rosidl_typesupport_c/CMakeLists.txt b/rosidl_typesupport_c/CMakeLists.txt index 917cc2ec..59a9376c 100644 --- a/rosidl_typesupport_c/CMakeLists.txt +++ b/rosidl_typesupport_c/CMakeLists.txt @@ -2,7 +2,19 @@ cmake_minimum_required(VERSION 3.5) project(rosidl_typesupport_c) -option(ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT "Enable static typesupport" OFF) +if(BUILD_SHARED_LIBS) + set(${PROJECT_NAME}_LIBRARY_TYPE "SHARED") +else() + set(${PROJECT_NAME}_LIBRARY_TYPE "STATIC") +endif() + +if(rosidl_typesupport_c_LIBRARY_TYPE STREQUAL "STATIC" + AND NOT BUILD_TESTING +) + set(ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT ON) +else() + set(ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT OFF) +endif() # Default to C11 if(NOT CMAKE_C_STANDARD) @@ -141,12 +153,6 @@ if(BUILD_TESTING) endif() endif() -if(BUILD_SHARED_LIBS) - set(${PROJECT_NAME}_LIBRARY_TYPE "SHARED") -else() - set(${PROJECT_NAME}_LIBRARY_TYPE "STATIC") -endif() - ament_package( CONFIG_EXTRAS "rosidl_typesupport_c-extras.cmake.in" ) diff --git a/rosidl_typesupport_c/src/dynamic_support_dispatch.hpp b/rosidl_typesupport_c/src/dynamic_support_dispatch.hpp new file mode 100644 index 00000000..d6f1e2cc --- /dev/null +++ b/rosidl_typesupport_c/src/dynamic_support_dispatch.hpp @@ -0,0 +1,102 @@ +// Copyright 2021 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. + +#ifndef DYNAMIC_SUPPORT_DISPATCH_HPP_ +#define DYNAMIC_SUPPORT_DISPATCH_HPP_ + +#include +#include +#include + +#include +#include +#include +#include + +#include "rcpputils/shared_library.hpp" +#include "rcutils/error_handling.h" +#include "rcutils/snprintf.h" +#include "rosidl_typesupport_c/type_support_map.h" + +namespace rosidl_typesupport_c +{ + +static void * +handle_shared_library_from_name( + const type_support_map_t * map, + size_t map_item, + const char * identifier +) +{ + rcpputils::SharedLibrary * lib = nullptr; + + if (!map->data[map_item]) { + char library_basename[1024]; + int ret = rcutils_snprintf( + library_basename, 1023, "%s__%s", + map->package_name, identifier); + if (ret < 0) { + RCUTILS_SET_ERROR_MSG("Failed to format library name"); + return nullptr; + } + + std::string library_name; + try { + library_name = rcpputils::get_platform_library_name(library_basename); + } catch (const std::exception & e) { + RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( + "Failed to compute library name for '%s' due to %s", + library_basename, e.what()); + return nullptr; + } + + try { + lib = new rcpputils::SharedLibrary(library_name); + } catch (const std::runtime_error & e) { + RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( + "Could not load library %s: %s", library_name.c_str(), e.what()); + return nullptr; + } catch (const std::bad_alloc & e) { + RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( + "Could not load library %s: %s", library_name.c_str(), e.what()); + return nullptr; + } + map->data[map_item] = lib; + } + + auto clib = static_cast(map->data[map_item]); + lib = const_cast(clib); + + void * sym = nullptr; + + try { + if (!lib->has_symbol(map->symbol_name[map_item])) { + RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( + "Failed to find symbol '%s' in library", map->symbol_name[map_item]); + return nullptr; + } + sym = lib->get_symbol(map->symbol_name[map_item]); + } catch (const std::exception & e) { + RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( + "Failed to get symbol '%s' in library: %s", + map->symbol_name[map_item], e.what()); + return nullptr; + } + + return sym; +} + +} // namespace rosidl_typesupport_c + +#endif // DYNAMIC_SUPPORT_DISPATCH_HPP_ diff --git a/rosidl_typesupport_c/src/type_support_dispatch.hpp b/rosidl_typesupport_c/src/type_support_dispatch.hpp index eaf821f5..a00d0efc 100644 --- a/rosidl_typesupport_c/src/type_support_dispatch.hpp +++ b/rosidl_typesupport_c/src/type_support_dispatch.hpp @@ -16,17 +16,7 @@ #define TYPE_SUPPORT_DISPATCH_HPP_ #ifndef ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT - -#include -#include -#include - -#include -#include -#include - -#include "rcpputils/shared_library.hpp" - +#include "./dynamic_support_dispatch.hpp" #endif // ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT #include "rcutils/error_handling.h" @@ -57,58 +47,9 @@ get_typesupport_handle_function( } typedef const TypeSupport * (* funcSignature)(void); #ifndef ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT - rcpputils::SharedLibrary * lib = nullptr; - - if (!map->data[i]) { - char library_basename[1024]; - int ret = rcutils_snprintf( - library_basename, 1023, "%s__%s", - map->package_name, identifier); - if (ret < 0) { - RCUTILS_SET_ERROR_MSG("Failed to format library name"); - return nullptr; - } - - std::string library_name; - try { - library_name = rcpputils::get_platform_library_name(library_basename); - } catch (const std::exception & e) { - RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( - "Failed to compute library name for '%s' due to %s", - library_basename, e.what()); - return nullptr; - } - - try { - lib = new rcpputils::SharedLibrary(library_name); - } catch (const std::runtime_error & e) { - RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( - "Could not load library %s: %s", library_name.c_str(), e.what()); - return nullptr; - } catch (const std::bad_alloc & e) { - RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( - "Could not load library %s: %s", library_name.c_str(), e.what()); - return nullptr; - } - map->data[i] = lib; - } - auto clib = static_cast(map->data[i]); - lib = const_cast(clib); - - void * sym = nullptr; - - try { - if (!lib->has_symbol(map->symbol_name[i])) { - RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( - "Failed to find symbol '%s' in library", map->symbol_name[i]); - return nullptr; - } - sym = lib->get_symbol(map->symbol_name[i]); - } catch (const std::exception & e) { - RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( - "Failed to get symbol '%s' in library: %s", - map->symbol_name[i], e.what()); - return nullptr; + void * sym = handle_shared_library_from_name(map, i, identifier); + if (nullptr == sym) { + continue; } funcSignature func = reinterpret_cast(sym); #else From be9c0319d28b0db0ed1c28f23e6831566fb0e160 Mon Sep 17 00:00:00 2001 From: Pablo Garrido Date: Fri, 21 May 2021 13:26:21 +0200 Subject: [PATCH 3/3] Allow single typessuport Signed-off-by: Your Name --- ...dl_typesupport_c_generate_interfaces.cmake | 39 +++++++++++++------ 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/rosidl_typesupport_c/cmake/rosidl_typesupport_c_generate_interfaces.cmake b/rosidl_typesupport_c/cmake/rosidl_typesupport_c_generate_interfaces.cmake index 0c10831e..6240976c 100644 --- a/rosidl_typesupport_c/cmake/rosidl_typesupport_c_generate_interfaces.cmake +++ b/rosidl_typesupport_c/cmake/rosidl_typesupport_c_generate_interfaces.cmake @@ -119,17 +119,19 @@ target_include_directories(${rosidl_generate_interfaces_TARGET}${_target_suffix} # if only a single typesupport is used this package will directly reference it # therefore it needs to link against the selected typesupport if(NOT typesupports MATCHES ";") + set(SINGLE_TYPE_SUPPORT ON) target_include_directories(${rosidl_generate_interfaces_TARGET}${_target_suffix} PUBLIC "$") target_link_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix} ${rosidl_generate_interfaces_TARGET}__${typesupports}) else() + set(SINGLE_TYPE_SUPPORT OFF) if("${rosidl_typesupport_c_LIBRARY_TYPE}" STREQUAL "STATIC") - target_compile_definitions(${rosidl_generate_interfaces_TARGET}${_target_suffix} - PRIVATE - ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT - ) + target_compile_definitions(${rosidl_generate_interfaces_TARGET}${_target_suffix} + PRIVATE + ROSIDL_TYPESUPPORT_STATIC_TYPESUPPORT + ) endif() endif() @@ -157,13 +159,28 @@ add_dependencies( ) if(NOT rosidl_generate_interfaces_SKIP_INSTALL) - install( - TARGETS ${rosidl_generate_interfaces_TARGET}${_target_suffix} - EXPORT ${rosidl_generate_interfaces_TARGET}${_target_suffix} - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - RUNTIME DESTINATION bin - ) + if(SINGLE_TYPE_SUPPORT) + install( + TARGETS + ${rosidl_generate_interfaces_TARGET}${_target_suffix} + ${rosidl_generate_interfaces_TARGET}__${typesupports} + EXPORT ${rosidl_generate_interfaces_TARGET}${_target_suffix} + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin + ) + else() + install( + TARGETS + ${rosidl_generate_interfaces_TARGET}${_target_suffix} + EXPORT ${rosidl_generate_interfaces_TARGET}${_target_suffix} + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin + ) + endif() + + ament_export_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix}) ament_export_targets(${rosidl_generate_interfaces_TARGET}${_target_suffix}) endif()