ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

ROS2 Foxy composable node: Failed to load component due to undefined symbol

asked 2021-06-27 05:59:40 -0500

Akron gravatar image

Dear all,

I am developing a composable ROS 2 lifecycle node. The node uses another external library in order to execute EtherCAT Master functionalities. I have followed the composition tutorial page:

  1. I created a container process in terminal.
  2. Then, I tried to load the node.

The error I am getting is the following:

Failed to load component: Failed to load library: could not load library loadlibrary error: /home/mobile/dev_ws/install/ether_ros2/lib/libether_ros2_component.so: undefined symbol: _ztvn10ether_ros220ethercatcommunicatore, at /tmp/binarydeb/ros-foxy-rcutils-1.1.3/src/shared_library.c:84

CMakeLists.txt

cmake_minimum_required(VERSION  3.5)
project(ether_ros2)

# Default to C++17
if(NOT CMAKE_CXX_STANDARD)
  set(CMAKE_CXX_STANDARD 17)
endif()

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)

#find YAML dependency
find_package(yaml_cpp_vendor REQUIRED)

find_package(rclcpp REQUIRED)
find_package(rclcpp_components REQUIRED)
find_package(rclcpp_lifecycle REQUIRED)
find_package(lifecycle_msgs REQUIRED)
find_package(builtin_interfaces REQUIRED)
find_package(rcutils REQUIRED)
find_package(std_msgs REQUIRED)
find_package(rosidl_default_generators REQUIRED)

 # create ament index resource which references the libraries in the binary dir
 set(node_plugins "")
 rosidl_generate_interfaces(${PROJECT_NAME}
      "msg/PdoIn.msg"
      "msg/PdoInXmc.msg"
      "msg/PdoOut.msg"
      "msg/PdoRaw.msg"
      "msg/ModifyPdoVariables.msg"
       DEPENDENCIES builtin_interfaces std_msgs
 )

set(etherlab_include /opt/etherlab/include)
set(etherlab_lib /opt/etherlab/lib/libethercat.so)

set(SOURCES
      src/ether_ros2_component.cpp
      src/utilities.cpp
      src/ethercat_communicator.cpp
      src/ethercat_network.cpp
      src/ethercat_slave.cpp
      src/pdo_in_publisher.cpp
      src/pdo_out_publisher.cpp
      src/pdo_out_listener.cpp
      src/pdo_out_publisher_timer.cpp)

include_directories(include
                    ${etherlab_include})

add_library(${PROJECT_NAME}_component SHARED
  ${SOURCES})

target_compile_definitions(${PROJECT_NAME}_component
      PRIVATE "COMPOSITION_BUILDING_DLL")
target_link_libraries(${PROJECT_NAME}_component
      ${etherlab_lib})

ament_target_dependencies(${PROJECT_NAME}_component
  "rclcpp"
  "rclcpp_components"
  "rclcpp_lifecycle"
  "lifecycle_msgs"
  "rosidl_default_generators"
  "std_msgs"
  "builtin_interfaces"
  "yaml_cpp_vendor"
  "rcutils")

rosidl_target_interfaces(${PROJECT_NAME}_component
          ${PROJECT_NAME} "rosidl_typesupport_cpp")

rclcpp_components_register_nodes(${PROJECT_NAME}_component "ether_ros2::EthercatCommunicator")
set(node_plugins "${node_plugins}ether_ros2::EthercatCommunicator;$<TARGET_FILE:ether_ros2_component>\n")

install(TARGETS
    ${PROJECT_NAME}_component
    ARCHIVE DESTINATION lib
    LIBRARY DESTINATION lib
    RUNTIME DESTINATION bin)

ament_package()

Note that the package has been built successfully. How can I resolve this error ?

Thank you for your help.

Best Regards,

Aris.

edit retag flag offensive close merge delete

Comments

Note that the package has been built successfully.

that doesn't really say anything in this case: when building shared libraries, the linker will assume that any symbols it can't directly resolve will be present in the execution context into which the shared library will be loaded.

So even if you did not link any libraries, it's very likely your package will still build successfully.

gvdhoorn gravatar image gvdhoorn  ( 2021-06-28 02:17:13 -0500 )edit

Is there any way to determine which symbols create this runtime error ?

Akron gravatar image Akron  ( 2021-06-28 11:55:42 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
1

answered 2021-06-28 11:58:50 -0500

gvdhoorn gravatar image

That's already in the error:

Failed to load library: could not load library loadlibrary error: /home/mobile/dev_ws/install/ether_ros2/lib/libether_ros2_component.so: undefined symbol: _ztvn10ether_ros220ethercatcommunicatore

_ztvn10ether_ros220ethercatcommunicatore is the mangled version of the symbol.

I'm not sure why, but c++filt (which you'd normally use to demangle symbols) can't process it.

Is libethercat.so perhaps a C library, and did you perhaps forget to extern C the #includes of the accompanying header?

edit flag offensive delete link more

Comments

It is indeed a C library. I will check for any missing extern C expressions and I will keep you posted. Thanks for the immediate response!

Akron gravatar image Akron  ( 2021-06-28 12:05:39 -0500 )edit

@gvdhoorn it seems that your insight about potential missing extern Cs was right. I had indeed missed some of them. Moreover, even though I had declared a destructor, I forgot to define it. I though I had done it inline, but the brackets {} were missing (newbie mistake). Thank you again!

Akron gravatar image Akron  ( 2021-06-29 12:11:23 -0500 )edit

I had indeed missed some of them.

is this your own library? Or something 3rd party?

In any case: you don't need to declare every function extern C by itself. Something like this would work for all functions declared in header.h:

extern "C" {
  #include </path/to/header.h>
}

it's not too nice, but if header.h is not under your control -- or you can't change it -- it does provide a way to guard the symbols in header.h against name-mangling.

gvdhoorn gravatar image gvdhoorn  ( 2021-06-29 12:20:55 -0500 )edit

Yes it is a third part library. I did what you proposed with the header files. I didn't declare every function.

Akron gravatar image Akron  ( 2021-06-30 04:54:15 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2021-06-27 05:59:40 -0500

Seen: 1,173 times

Last updated: Jun 27 '21