Skip to content

Undefined references when linking MicroROS with an SMT32CubeMX project #309

@acarophobicitch

Description

@acarophobicitch

Describe the bug

I am trying to integrate MicroROS in an existing STM32CubeMX CMake project. Linking the final binary fails with errors about unresolved references in librmw_microxrcedds.a to symbols in Micro XRCE-DDS Client and to symbols in Micro XRCE-DDS typesupport:

../../install/lib/librmw_microxrcedds.a(rmw_client.c.obj): in function `rmw_destroy_client':
MicroROS/microros/rmw_microxrcedds/rmw_microxrcedds_c/src/rmw_client.c:220:(.text.rmw_destroy_client+0x9e): undefined reference to `uxr_buffer_cancel_data'
...
../../install/lib/libstd_msgs__rosidl_typesupport_c.a(int32__type_support.cpp.obj):
./build/std_msgs/rosidl_typesupport_c/std_msgs/msg/int32__type_support.cpp:67:(.data._ZN8std_msgs3msg20rosidl_typesupport_cL31_Int32_message_typesupport_dataE+0x0): undefined reference to `rosidl_typesupport_introspection_c__get_message_type_support_handle__std_msgs__msg__Int32'

Everything, including the main project, is a colcon package built with Ninja. The project layout is:

<project root>
├── Core
│   ├── Inc
│   │   └── <CubeMX generated headers>
│   └── Src
│       ├── <CubeMX generated sources>
│       ├── cubemx_uart_transport.c
│       ├── microros_allocator.c
│       └── main.c
├── MicroROS
│   ├── microros
│   │   └── <MicroROS packages>
│   ├── ros2
│   │   └── <ROS2 packages>
│   └── microros.repos
├── App
│   └── int32_publisher
│       ├── src
│       ├── CMakeLists.txt
│       └── package.xml
├── <other Cubemx generated files>
├── colcon.meta
├── colcon.pkg
└── CMakeLists.txt

The default task in main.c initializes MicroROS, calls into application packages, which are built as static libraries, to initialize node(s) etc., and then calls rclc_executor_spin_some() in a loop.

The project is built with colcon build --packages-up-to cubemx-microros-cmake --packages-ignore-regex=".*_cpp" --metas ./colcon.meta --merge-install --paths . --base-paths ./MicroROS ./App --cmake-args -G Ninja --no-warn-unused-cli -DCMAKE_POSITION_INDEPENDENT_CODE=OFF -DTHIRDPARTY=ON -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTING=OFF -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE="$(pwd)/cmake/gcc-arm-none-eabi.cmake"

Relevant parts of CMakeLists.txt:

Application package(s):

find_package(ament_cmake REQUIRED)
find_package(ament_cmake_ros REQUIRED)

find_package(rclc REQUIRED)
find_package(std_msgs REQUIRED)
                                                                                                                      
# Basic MicroROS publisher                                                                  
add_library(int32_publisher STATIC
  src/int32_publisher.c
)
ament_target_dependencies(int32_publisher
  std_msgs rclc
)

# ...

install(
  TARGETS int32_publisher
  EXPORT  export_${PROJECT_NAME}
  ARCHIVE DESTINATION lib
)

ament_export_targets(
  export_${PROJECT_NAME} HAS_LIBRARY_TARGET
)
ament_export_dependencies(std_msgs rclc)

ament_package()

Main CMakeLists.txt:

find_package(microxrcedds_client REQUIRED)
find_package(rmw_microxrcedds REQUIRED)
find_package(rcutils REQUIRED)
find_package(rcl REQUIRED)
find_package(rclc REQUIRED)
find_package(int32_publisher REQUIRED)

add_executable(${CMAKE_PROJECT_NAME})

# ...

target_link_libraries(${CMAKE_PROJECT_NAME}
    int32_publisher::int32_publisher
    ${rmw_microxrcedds_LIBRARIES}
    rclc::rclc rcl::rcl rcutils::rcutils
)

I also tried to make the top level project an ament_cmake_ros package using ament_target_dependencies(), to no avail.

Expected behavior:

Linking the binary works without errors, all required MicroROS libraries are passed to the linker in the correct order.

System information:

  • OS: FreeRTOS+POSIX, CMSIS v2
  • ROS 2 Humble

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions