tesseract-robotics / tesseract_ros

ROS Interface for the Tesseract Planning Environment.
http://tesseract-docs.rtfd.io
61 stars 24 forks source link

Linker issues when initializing environment #223

Open ruffson opened 1 year ago

ruffson commented 1 year ago

Hi there, when I try to initialize a previously declared environment like this:

env_ = std::make_shared<tesseract_environment::Environment>();

I am getting a linker error like below:

/usr/bin/ld: CMakeFiles/generate_path_server.dir/src/generate_path_server.cpp.o: in function `tesseract_environment::Environment::Environment()':
generate_path_server.cpp:(.text._ZN21tesseract_environment11EnvironmentC2Ev[_ZN21tesseract_environment11EnvironmentC5Ev]+0x9c): undefined reference to `tesseract_kinematics::KinematicsPluginFactory::KinematicsPluginFactory()'
/usr/bin/ld: generate_path_server.cpp:(.text._ZN21tesseract_environment11EnvironmentC2Ev[_ZN21tesseract_environment11EnvironmentC5Ev]+0x1c1): undefined reference to `tesseract_collision::ContactManagersPluginFactory::ContactManagersPluginFactory()'
/usr/bin/ld: generate_path_server.cpp:(.text._ZN21tesseract_environment11EnvironmentC2Ev[_ZN21tesseract_environment11EnvironmentC5Ev]+0x434): undefined reference to `tesseract_kinematics::KinematicsPluginFactory::~KinematicsPluginFactory()'
/usr/bin/ld: CMakeFiles/generate_path_server.dir/src/generate_path_server.cpp.o: in function `tesseract_environment::Environment::~Environment()':
generate_path_server.cpp:(.text._ZN21tesseract_environment11EnvironmentD2Ev[_ZN21tesseract_environment11EnvironmentD5Ev]+0x98): undefined reference to `tesseract_collision::ContactManagersPluginFactory::~ContactManagersPluginFactory()'
/usr/bin/ld: generate_path_server.cpp:(.text._ZN21tesseract_environment11EnvironmentD2Ev[_ZN21tesseract_environment11EnvironmentD5Ev]+0x128): undefined reference to `tesseract_kinematics::KinematicsPluginFactory::~KinematicsPluginFactory()'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/generate_path_server.dir/build.make:214: /home/my_user/catkin_ws/devel/.private/bot_arm_planner/lib/bot_arm_planner/generate_path_server] Error 1
make[1]: *** [CMakeFiles/Makefile2:3558: CMakeFiles/generate_path_server.dir/all] Error 2
make: *** [Makefile:146: all] Error 2
cd /home/my_user/catkin_ws/build/bot_arm_planner; catkin build --get-env bot_arm_planner | catkin env -si  /usr/bin/make --jobserver-auth=3,4; cd -

These are the relevant parts of my CMakelist. In my desperation, I have added a lot of dependencies everywhere:

find_package(ros_industrial_cmake_boilerplate required)
cmake_minimum_required(version 2.8.12)
project(my_project)
set(cmake_cxx_standard 17)
set(cmake_cxx_flags "-mno-avx") # not adding this flag kept crashing the path server node in arjun's pc
include($env{ros_root}/core/rosbuild/rosbuild.cmake)

## find catkin macros and libraries
find_package(boost required)
find_package(catkin required components
    dynamic_reconfigure
    pluginlib
    rosbag
    rosconsole
    roscpp
    roslib
    tf
    tf_conversions
    eigen_conversions
    std_msgs
    sensor_msgs
    cmake_modules 
    message_generation
    moveit_core
    moveit_ros_planning
    moveit_ros_planning_interface
    moveit_planners_ompl
    pluginlib
    tesseract_msgs
    tesseract_monitoring
    tesseract_rosutils
    tesseract_environment
    tesseract_kinematics
)

find_package(eigen required)
# find_package(tesseract_environment required)
find_package(tesseract_environment required)
find_package(tesseract_command_language required)
find_package(tesseract_motion_planners required)
find_package(tesseract_task_composer required)
find_package(tesseract_collision required)
find_package(tesseract_common required)
find_package(tesseract_support required)
find_package(trajopt_sqp required)
find_package(trajopt_ifopt required)
find_package(tesseract_rosutils required)
find_package(tesseract_kinematics required)

catkin_python_setup()

rosbuild_find_ros_package(dynamic_reconfigure)

## add link directories
link_directories(
    ${boost_library_dirs}
    ${pcl_library_dirs}
    ${eigen_library_dirs}
)

add_service_files(
  files
  # ...omitted for brevity
)

generate_messages(
  dependencies
  std_msgs
  geometry_msgs
  trajectory_msgs
  moveit_msgs
  sensor_msgs
  tesseract_msgs
)

catkin_package(
    catkin_depends dynamic_reconfigure
    moveit_core
    moveit_ros_planning_interface
    moveit_planners_ompl
    message_runtime
  depends
    eigen3
)

# tried explicityly linking to tesseract stuff but get error:
# "cannot find -ltinyxml2:tinyxml2" even though it is installed,
# ld path is set and invoking ld -ltinyxml2 can find the lib
add_executable(generate_path_server src/generate_path_server.cpp)
target_link_libraries(generate_path_server
    # tesseract::tesseract_environment
    # tesseract::tesseract_motion_planners_core
    # tesseract::tesseract_motion_planners_ompl
    # tesseract::tesseract_motion_planners_trajopt
    # tesseract::tesseract_motion_planners_trajopt_ifopt
    # trajopt::trajopt_sqp
    # trajopt::trajopt_ifopt
    # tesseract::tesseract_task_composer
    # tesseract::tesseract_task_composer_planning
    # console_bridge::console_bridge
    ${catkin_libraries}
    )
add_dependencies(omitted)

(In this example, I lowercased everything by accident.)

The missing tesseract_kinematics package which builds to tesseract_kinematics_core can be found inside my catkin_ws/build/tesseract_kinematics/core/libtesseract_kinematics_core.so

As a side-note it would be nice if the example were isolated. Instead, the examples mostly import cmake configuration and headers from tesseract_examples. I understand how you don't want to repeat yourself, but it is harder to isolated what is needed per project.

marip8 commented 1 year ago

I think you just need to link against the appropriate tesseract_environment and tesseract_kinematics targets. It's not totally obvious what these targets are, but as a rule of thumb they are usually tesseract::<name_of_package> or tesseract::<name_of_package>_<module> for packages that have a core component and modules that build on other libraries (e.g., tesseract::tesseract_kinematics_core, tesseract::tesseract_motion_planners_trajopt, etc.). You may have to investigate the package's CMakeLists to identify what these targets are called specifically.

find_package(tesseract_environment REQUIRED)
find_package(tesseract_kinematics REQUIRED)
...
target_link_libraries(generate_path_server
  tesseract::tesseract_environment
  tesseract::tesseract_kinematics_core
  ...
)

FWIW, all tesseract packages that are not in tesseract_ros are regular CMake projects, not catkin components.

find_package(catkin required components
    dynamic_reconfigure
    pluginlib
    rosbag
    rosconsole
    roscpp
    roslib
    tf
    tf_conversions
    eigen_conversions
    std_msgs
    sensor_msgs
    cmake_modules 
    message_generation
    moveit_core
    moveit_ros_planning
    moveit_ros_planning_interface
    moveit_planners_ompl
    pluginlib
    tesseract_msgs
    tesseract_monitoring
    tesseract_rosutils
-   tesseract_environment
-   tesseract_kinematics
)
+find_package(tesseract_environment REQUIRED)
+find_package(tesseract_kinematics REQUIRED)

As a side-note it would be nice if the example were isolated. Instead, the examples mostly import cmake configuration and headers from tesseract_examples. I understand how you don't want to repeat yourself, but it is harder to isolated what is needed per project.

Here is a decent example from tesseract_planning about how to link to some of the relevant targets

ruffson commented 1 year ago

I think you just need to link against the appropriate tesseract_environment and tesseract_kinematics targets. It's not totally obvious what these targets are, but as a rule of thumb they are usually tesseract::<name_of_package> or tesseract::<name_of_package>_<module> for packages that have a core component and modules that build on other libraries (e.g., tesseract::tesseract_kinematics_core, tesseract::tesseract_motion_planners_trajopt, etc.). You may have to investigate the package's CMakeLists to identify what these targets are called specifically.

find_package(tesseract_environment REQUIRED)
find_package(tesseract_kinematics REQUIRED)
...
target_link_libraries(generate_path_server
  tesseract::tesseract_environment
  tesseract::tesseract_kinematics_core
  ...
)

@marip8 Thank you for your response!

Hmm I tried this in the past (see my commented-out target-link-libraries) but when I do this I get a linker error:

/usr/bin/ld: cannot find -ltinyxml2::tinyxml2
collect2: error: ld returned 1 exit status

which is weird because I:

  1. have a bunch of tinyxml packages installed (libtinyxml-dev libtinyxml2-6a libtinyxml2-dev libtinyxml2.6.2v5-dbg libtinyxml2.6.2v5),
  2. I can find the .so in /usr/lib/x86_64-linux-gnu/libtinyxml2.so, I even tried sym-linking the file to /usr/local/lib, I set the LD_LIBRARY_PATH,
  3. I added libxml2 as a build_depend to the package.xml and find_package(TinyXML2 REQUIRED) to my CMakeList
  4. when I run ld -ltinyxml2, I only get a warning (ld: warning: cannot find entry symbol _start; not setting start address)
  5. and I can build the whole tesseract_ws by itself fine, and tinyxml2 is a dependency pretty much throughout ros.

Do you have any idea why it would not be able to find libxml2? I also installed ros-cmake-modules.

Edit: I should add, that I am using this from a ROS noetic package. And I thought that the inter-package linking would be done by the build dependencies from the package.xml?