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; }