Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 50 additions & 27 deletions rcl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,34 @@ cmake_minimum_required(VERSION 3.20)

project(rcl)

option(RCL_MICROROS "micro-ROS build mode" OFF)

find_package(ament_cmake_ros REQUIRED)
find_package(ament_cmake_gen_version_h REQUIRED)

find_package(libyaml_vendor REQUIRED)
find_package(rcl_interfaces REQUIRED)
find_package(rcl_logging_interface REQUIRED)
find_package(rcl_yaml_param_parser REQUIRED)
find_package(rcutils REQUIRED)
find_package(rmw REQUIRED)
find_package(rmw_implementation REQUIRED)
find_package(rosidl_runtime_c REQUIRED)
find_package(service_msgs REQUIRED)
find_package(tracetools REQUIRED)
find_package(type_description_interfaces REQUIRED)
find_package(yaml REQUIRED)
if(NOT RCL_MICROROS)
find_package(libyaml_vendor REQUIRED)
find_package(rcl_yaml_param_parser REQUIRED)
find_package(yaml REQUIRED)
endif()

include(cmake/rcl_set_symbol_visibility_hidden.cmake)

# Determine the logging implementation to use
include(cmake/get_default_rcl_logging_implementation.cmake)
get_default_rcl_logging_implementation(RCL_LOGGING_IMPL)
message(STATUS "RCL_LOGGING_IMPLEMENTATION: ${RCL_LOGGING_IMPL}")
if(NOT RCL_MICROROS)
# Determine the logging implementation to use
include(cmake/get_default_rcl_logging_implementation.cmake)
get_default_rcl_logging_implementation(RCL_LOGGING_IMPL)
message(STATUS "RCL_LOGGING_IMPLEMENTATION: ${RCL_LOGGING_IMPL}")
endif()

# Default to C11
if(NOT CMAKE_C_STANDARD)
Expand All @@ -41,7 +47,7 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
endif()

set(${PROJECT_NAME}_sources
src/rcl/arguments.c
$<$<NOT:$<BOOL:${RCL_MICROROS}>>:src/rcl/arguments.c>
src/rcl/client.c
src/rcl/common.c
src/rcl/context.c
Expand All @@ -57,13 +63,13 @@ set(${PROJECT_NAME}_sources
src/rcl/init_options.c
src/rcl/lexer.c
src/rcl/lexer_lookahead.c
src/rcl/logging_rosout.c
src/rcl/logging.c
src/rcl/log_level.c
$<$<NOT:$<BOOL:${RCL_MICROROS}>>:src/rcl/logging_rosout.c>
$<$<NOT:$<BOOL:${RCL_MICROROS}>>:src/rcl/logging.c>
$<$<NOT:$<BOOL:${RCL_MICROROS}>>:src/rcl/log_level.c>
src/rcl/network_flow_endpoints.c
src/rcl/node.c
src/rcl/node_options.c
src/rcl/node_type_cache.c
$<$<NOT:$<BOOL:${RCL_MICROROS}>>:src/rcl/node_type_cache.c>
src/rcl/publisher.c
src/rcl/remap.c
src/rcl/node_resolve_name.c
Expand All @@ -75,13 +81,16 @@ set(${PROJECT_NAME}_sources
src/rcl/time.c
src/rcl/timer.c
src/rcl/type_hash.c
src/rcl/type_description_conversions.c
$<$<NOT:$<BOOL:${RCL_MICROROS}>>:src/rcl/type_description_conversions.c>
src/rcl/validate_enclave_name.c
src/rcl/validate_topic_name.c
src/rcl/wait.c
)

add_library(${PROJECT_NAME} ${${PROJECT_NAME}_sources})
if(RCL_MICROROS)
target_compile_definitions(${PROJECT_NAME} PUBLIC RCL_MICROROS)
endif()
target_include_directories(${PROJECT_NAME} PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>"
Expand All @@ -91,33 +100,44 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
rcl_interfaces::rcl_interfaces
# TODO(clalancette): rcl_logging_interface should be PRIVATE, but downstream depends on it for now
rcl_logging_interface::rcl_logging_interface
rcl_yaml_param_parser::rcl_yaml_param_parser
rcutils::rcutils
rmw::rmw
# TODO(clalancette): rmw_implementation should be PRIVATE, but downstream depends on it for now
rmw_implementation::rmw_implementation
rosidl_runtime_c::rosidl_runtime_c
type_description_interfaces::type_description_interfaces
)
if(NOT RCL_MICROROS)
target_link_libraries(${PROJECT_NAME} PUBLIC
rcl_yaml_param_parser::rcl_yaml_param_parser
)
endif()

target_link_libraries(${PROJECT_NAME} PRIVATE
service_msgs::service_msgs
tracetools::tracetools
yaml
)

# Link logging implementation based on configuration
if(RCL_LOGGING_IMPL STREQUAL "rcl_logging_implementation")
# Dynamic loading: use rcl_logging_implementation abstraction
target_link_libraries(${PROJECT_NAME} PRIVATE
rcl_logging_implementation::rcl_logging_implementation
)
else()
# Static linking: use specific logging implementation
if(NOT RCL_MICROROS)
target_link_libraries(${PROJECT_NAME} PRIVATE
${RCL_LOGGING_IMPL}::${RCL_LOGGING_IMPL}
service_msgs::service_msgs
yaml
)
endif()

if(NOT RCL_MICROROS)
# Link logging implementation based on configuration
if(RCL_LOGGING_IMPL STREQUAL "rcl_logging_implementation")
# Dynamic loading: use rcl_logging_implementation abstraction
target_link_libraries(${PROJECT_NAME} PRIVATE
rcl_logging_implementation::rcl_logging_implementation
)
else()
# Static linking: use specific logging implementation
target_link_libraries(${PROJECT_NAME} PRIVATE
${RCL_LOGGING_IMPL}::${RCL_LOGGING_IMPL}
)
endif()
endif()

# Allow configuring the default discovery range
if(DEFINED RCL_DEFAULT_DISCOVERY_RANGE)
target_compile_definitions(${PROJECT_NAME} PRIVATE
Expand Down Expand Up @@ -156,13 +176,16 @@ ament_export_dependencies(ament_cmake)
ament_export_dependencies(rcl_interfaces)
# TODO(clalancette): rcl_logging_interface shouldn't be exported, but downstream depends on it for now
ament_export_dependencies(rcl_logging_interface)
ament_export_dependencies(rcl_yaml_param_parser)
ament_export_dependencies(rcutils)
ament_export_dependencies(rmw)
# TODO(clalancette): rmw_implementation shouldn't be exported, but downstream depends on it for now
ament_export_dependencies(rmw_implementation)
ament_export_dependencies(rosidl_runtime_c)
ament_export_dependencies(tracetools)
ament_export_dependencies(type_description_interfaces)
if(NOT RCL_MICROROS)
ament_export_dependencies(rcl_yaml_param_parser)
endif()
ament_generate_version_header(${PROJECT_NAME})

if(BUILD_TESTING)
Expand Down
4 changes: 4 additions & 0 deletions rcl/include/rcl/arguments.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@
#include "rcl/macros.h"
#include "rcl/types.h"
#include "rcl/visibility_control.h"
#ifndef RCL_MICROROS
#include "rcl_yaml_param_parser/types.h"
#else
typedef bool rcl_params_t;
#endif // RCL_MICROROS

#ifdef __cplusplus
extern "C"
Expand Down
10 changes: 9 additions & 1 deletion rcl/include/rcl/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ extern "C"
#include "rmw/init.h"

#include "rcl/allocator.h"
#ifndef RCL_MICROROS
#include "rcl/arguments.h"
#endif // RCL_MICROROS
#include "rcl/init_options.h"
#include "rcl/macros.h"
#include "rcl/types.h"
Expand Down Expand Up @@ -112,9 +114,11 @@ typedef struct rcl_context_impl_s rcl_context_impl_t;
*/
typedef struct rcl_context_s
{
#ifndef RCL_MICROROS
/// Global arguments for all nodes which share this context.
/** Typically generated by the parsing of argc/argv in rcl_init(). */
rcl_arguments_t global_arguments;
#endif // RCL_MICROROS

/// Implementation specific pointer.
rcl_context_impl_t * impl;
Expand All @@ -123,7 +127,7 @@ typedef struct rcl_context_s
// ensured with a static_assert in the context.c file.
// In most cases it should just be a plain uint64_t.
/// @cond Doxygen_Suppress
#if !defined(RCL_CONTEXT_ATOMIC_INSTANCE_ID_STORAGE_SIZE)
#if !defined(RCL_CONTEXT_ATOMIC_INSTANCE_ID_STORAGE_SIZE) && !defined(RCL_MICROROS)
#define RCL_CONTEXT_ATOMIC_INSTANCE_ID_STORAGE_SIZE sizeof(uint_least64_t)
#endif
/// @endcond
Expand All @@ -146,7 +150,11 @@ typedef struct rcl_context_s
* See this paper for an effort to make this possible in the future:
* http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0943r1.html
*/
#ifdef RCL_MICROROS
uint32_t instance_id_storage;
#else
RCL_ALIGNAS(8) uint8_t instance_id_storage[RCL_CONTEXT_ATOMIC_INSTANCE_ID_STORAGE_SIZE];
#endif // RCL_MICROROS
} rcl_context_t;

/// Return a zero initialization context object.
Expand Down
2 changes: 2 additions & 0 deletions rcl/include/rcl/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ extern "C"
#include <stdint.h>

#include "rcl/allocator.h"
#ifndef RCL_MICROROS
#include "rcl/arguments.h"
#endif // RCL_MICROROS
#include "rcl/context.h"
#include "rcl/guard_condition.h"
#include "rcl/macros.h"
Expand Down
6 changes: 5 additions & 1 deletion rcl/include/rcl/node_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ extern "C"
#endif

#include "rcl/allocator.h"
#ifndef RCL_MICROROS
#include "rcl/arguments.h"

#endif // RCL_MICROROS
#include "rcl/domain_id.h"
#include "rcl/macros.h"

/// Constant which indicates that the default domain id should be used.
#define RCL_NODE_OPTIONS_DEFAULT_DOMAIN_ID RCL_DEFAULT_DOMAIN_ID
Expand All @@ -46,8 +48,10 @@ typedef struct rcl_node_options_s
/// If false then only use arguments in this struct, otherwise use global arguments also.
bool use_global_arguments;

#ifndef RCL_MICROROS
/// Command line arguments that apply only to this node.
rcl_arguments_t arguments;
#endif // RCL_MICROROS

/// Flag to enable rosout for this node
bool enable_rosout;
Expand Down
4 changes: 4 additions & 0 deletions rcl/src/rcl/arguments_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@

#include "rcl/arguments.h"
#include "rcl/log_level.h"
#ifndef RCL_MICROROS
#include "rcl_yaml_param_parser/types.h"
#else
typedef bool rcl_params_t;
#endif // RCL_MICROROS
#include "./remap_impl.h"

#ifdef __cplusplus
Expand Down
6 changes: 6 additions & 0 deletions rcl/src/rcl/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ extern "C"

#include "rcl/error_handling.h"
#include "rcl/node.h"
#ifndef RCL_MICROROS
#include "rcl/node_type_cache.h"
#endif // RCL_MICROROS
#include "rcl/publisher.h"
#include "rcl/time.h"
#include "rcutils/logging_macros.h"
Expand Down Expand Up @@ -169,6 +171,7 @@ rcl_client_init(
atomic_init(&client->impl->sequence_number, 0);
client->impl->in_use_by_waitset = false;

#ifndef RCL_MICROROS
const rosidl_type_hash_t * hash = type_support->get_type_hash_func(type_support);
if (hash == NULL) {
RCL_SET_ERROR_MSG("Failed to get the type hash");
Expand All @@ -186,6 +189,7 @@ rcl_client_init(
goto destroy_client;
}
client->impl->type_hash = *hash;
#endif // RCL_MICROROS

RCUTILS_LOG_DEBUG_NAMED(ROS_PACKAGE_NAME, "Client initialized");
TRACETOOLS_TRACEPOINT(
Expand Down Expand Up @@ -248,13 +252,15 @@ rcl_client_fini(rcl_client_t * client, rcl_node_t * node)
result = RCL_RET_ERROR;
}

#ifndef RCL_MICROROS
if (
ROSIDL_TYPE_HASH_VERSION_UNSET != client->impl->type_hash.version &&
RCL_RET_OK != rcl_node_type_cache_unregister_type(node, &client->impl->type_hash))
{
RCUTILS_SAFE_FWRITE_TO_STDERR(rcl_get_error_string().str);
result = RCL_RET_ERROR;
}
#endif // RCL_MICROROS

allocator.deallocate(client->impl->remapped_service_name, allocator.state);
client->impl->remapped_service_name = NULL;
Expand Down
12 changes: 12 additions & 0 deletions rcl/src/rcl/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ rcl_get_zero_initialized_context(void)
.impl = NULL,
.instance_id_storage = {0},
};
#ifndef RCL_MICROROS
// this is not constexpr so it cannot be in the struct initialization
context.global_arguments = rcl_get_zero_initialized_arguments();
// ensure assumption about static storage
Expand All @@ -40,6 +41,7 @@ rcl_get_zero_initialized_context(void)
"expected rcl_context_t's instance id storage to be >= size of atomic_uint_least64_t");
// initialize atomic
atomic_init((atomic_uint_least64_t *)(&context.instance_id_storage), 0);
#endif // RCL_MICROROS
return context;
}

Expand Down Expand Up @@ -76,7 +78,11 @@ rcl_context_instance_id_t
rcl_context_get_instance_id(const rcl_context_t * context)
{
RCL_CHECK_ARGUMENT_FOR_NULL(context, 0);
#ifdef RCL_MICROROS
return context->instance_id_storage;
#else
return rcutils_atomic_load_uint64_t((atomic_uint_least64_t *)(&context->instance_id_storage));
#endif // RCL_MICROROS
}

rcl_ret_t
Expand Down Expand Up @@ -110,8 +116,13 @@ __cleanup_context(rcl_context_t * context)
{
rcl_ret_t ret = RCL_RET_OK;
// reset the instance id to 0 to indicate "invalid" (should already be 0, but this is defensive)
#ifdef RCL_MICROROS
context->instance_id_storage = 0;
#else
rcutils_atomic_store((atomic_uint_least64_t *)(&context->instance_id_storage), 0);
#endif // RCL_MICROROS

#ifndef RCL_MICROROS
// clean up global_arguments if initialized
if (NULL != context->global_arguments.impl) {
ret = rcl_arguments_fini(&(context->global_arguments));
Expand All @@ -124,6 +135,7 @@ __cleanup_context(rcl_context_t * context)
rcl_reset_error();
}
}
#endif // RCL_MICROROS

// if impl is null, nothing else can be cleaned up
if (NULL != context->impl) {
Expand Down
Loading