Robotics StackExchange | Archived questions

undefined Reference to ros::init on kinetic in non-ros-domain workspace

Hi All,
I am trying to compile a .cpp file which uses some of the ROS library functions like "ros/ros.h" , "std_msgs/String.h". In the make file , I have included the path for the respective include files in the include section.

But when I am compiling the .cpp , I am getting errors like

Undefined reference to 'ros::init(int&, char**, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, unsigned int)'.

Like wise I am getting some other errors like

:Undefined reference to ros::NodeHandle

:Undefined reference to ros::Rate::Rate(double)

:Undefined reference to ros::ok()

etc.

What could be the reason for such errors? can I get some suggestion to overcome these errors?

Thank you for your suggestion in advance?

Asked by rama_bhuyan on 2018-05-09 07:05:50 UTC

Comments

"Undefined reference" is probably a linker error. You don't just need to add directories for searching for headers, you also need to add directories for the linker to search in (-L), and you need to specify which libraries to search in when linking (-l).

Asked by jarvisschultz on 2018-05-09 07:31:06 UTC

This is partially why tools like CMake/catkin exist - writing a Makefile for complex projects can be tough. It might help if we could see your Makefile or your compile command.

Asked by jarvisschultz on 2018-05-09 07:32:06 UTC

Hello @jarvisscchultz But I could not figure out which exact libraries are being used while I am creating .cpp file as a node in a ros package in catkin_ws.

Asked by rama_bhuyan on 2018-05-17 05:58:56 UTC

It uses std_msgs and roscpp in the find_package() section of CMakeLists.txt. Is there any way to find out the libs used by the created ros package in the catkin_ws.

Asked by rama_bhuyan on 2018-05-17 06:00:37 UTC

Not sure I understand your question. find_package only creates variables that can be used later. For example, if you find_package std_msgs and roscpp then you would be able to use target_link_libraries with the catkin_LIBRARIES variable to link against all libs found in find_package

Asked by jarvisschultz on 2018-05-17 10:30:07 UTC

Again, it would be helpful to actually see your Makefile. One other thought that might help is using ldd to test what libraries are dynamically loaded when running an executable. E.g. ldd /home/user/catkin_ws/devel/lib/package_name/executable_name

Asked by jarvisschultz on 2018-05-17 10:32:22 UTC

Thank you so much @jarvisschultz. ldd command really helped me a lot. I could able to run my .cpp ros program outside of catkin_ workspace. I was struggling for last 2 weeks.

Asked by rama_bhuyan on 2018-05-18 00:40:28 UTC

Answers

Through comment conversation with OP, I believe his question really boiled down to not knowing which ROS libraries he would need to link against if trying to compile a ROS node using a hand-written Makefile that didn't take advantage of catkin's ability to find ROS packages and automatically create CMake variables for this exact purpose.

I'm not sure what the purpose of this hand-written Makefile is.

I mentioned that OP could use ldd to identify which libraries were loaded at runtime when running the executable generated by catkin (e.g. ldd /home/user/catkin_ws/devel/lib/package_name/executable_name). OP said that was able to help him solve the problem.

One could also use CMake to figure out the value of the relevant variables. For example, adding

message(STATUS "catkin_LIBRARIES=${catkin_LIBRARIES}")

to a CMakeLists.txt file in a package would cause CMake to print the value of the variables that you are linking against when using something like target_link_libraries(example_node ${catkin_LIBRARIES}). Although this might return more libraries than are actually needed.

Asked by jarvisschultz on 2018-05-18 14:19:04 UTC

Comments

The CMake files for ROS also set up package-config files, which can be queried for the build flags for a specific set of libraries. You can use the pkg-config command-line utility for these queries.

On my desktop that has ROS installed, I can do:

Source the bashrc for my ROS workspace (in my case, I have indigo installed, but this can be the setup file for any ROS workspace). In particular, this sets the PKG_CONFIG_PATH to include the ROS directories, so pkg-config can find ROS packages.

$ source /opt/ros/indigo/setup.bash

Query pkg-config for the required include flags (ie compiler flags):

$ pkg-config roscpp --cflags
-I/opt/ros/indigo/include

Query pkg-config for the required link flags:

$ pkg-config roscpp --libs
-L/opt/ros/indigo/lib -lroscpp -lpthread -l:/usr/lib/x86_64-linux-gnu/libboost_signals.so -l:/usr/lib/x86_64-linux-gnu/libboost_filesystem.so -lrosconsole -lrosconsole_log4cxx -lrosconsole_backend_interface -l:/usr/lib/liblog4cxx.so -l:/usr/lib/x86_64-linux-gnu/libboost_regex.so -lxmlrpcpp -lroscpp_serialization -lrostime -l:/usr/lib/x86_64-linux-gnu/libboost_date_time.so -lcpp_common -l:/usr/lib/x86_64-linux-gnu/libboost_system.so -l:/usr/lib/x86_64-linux-gnu/libboost_thread.so -l:/usr/lib/x86_64-linux-gnu/libpthread.so -l:/usr/lib/x86_64-linux-gnu/libconsole_bridge.so

Your computer will give different results, depending on which version of ROS you have installed and how you've installed it.

You can run these commands once and copy the result into your makefile, or you can set up your makefile to run them and automatically include the output in your build flags.

Asked by ahendrix on 2018-05-18 14:41:08 UTC

Comments