catkin: multiple "undefined reference to ros::xyz'"
I had to convert a pure CMAKE-Project to catkin, as I needed to use ROS. Therefor I tried to alter the CMakeLists to fit catkin. Unfortunately there are lots of ROS errors now, that tend to believe me there is an or are a couple errors still within.
The order of find_package/include_directories/catkin_package before add_executable seems to be right and there are lots of target_link_libraries..
Currently there is no exact point for me to start from, if you find any please show me, I would really like to understand this.
Deleted build and devel folder to start a clean catkin_make, to no visible change.
Additional Info:
- I am using a custom CUDA Kernel, thats why there needs to be CUDA support and .cu files.
- Also the camera "Zed 2" comes with an own package, that I tried to include, but am not sure as to how good that is working.
- After re-reading everything I noticed that I use "image_transport" in my code and didn't see it in the CMakeLists, added it to no current change in the error result, just FYI.
Build output:
[ 85%] Linking CXX executable /home/xavier/catkin_ws/devel/lib/fire_monitoring/fire_monitoring
CMakeFiles/fire_monitoring.dir/src/main.cpp.o: In function `main':
main.cpp:(.text+0x138): undefined reference to `ros::init(int&, char**, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int)'
main.cpp:(.text+0x14c): undefined reference to `ros::console::g_initialized'
main.cpp:(.text+0x150): undefined reference to `ros::console::g_initialized'
main.cpp:(.text+0x16c): undefined reference to `ros::console::initialize()'
main.cpp:(.text+0x1bc): undefined reference to `ros::console::initializeLogLocation(ros::console::LogLocation*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, ros::console::levels::Level)'
main.cpp:(.text+0x200): undefined reference to `ros::console::setLogLocationLevel(ros::console::LogLocation*, ros::console::levels::Level)'
main.cpp:(.text+0x20c): undefined reference to `ros::console::checkLogLocationEnabled(ros::console::LogLocation*)'
main.cpp:(.text+0x274): undefined reference to `ros::console::print(ros::console::FilterBase*, void*, ros::console::levels::Level, char const*, int, char const*, char const*, ...)'
main.cpp:(.text+0x280): undefined reference to `ros::Rate::Rate(double)'
main.cpp:(.text+0x2b0): undefined reference to `ros::ok()'
main.cpp:(.text+0x510): undefined reference to `ros::spinOnce()'
main.cpp:(.text+0x518): undefined reference to `ros::Rate::sleep()'
main.cpp:(.text+0x528): undefined reference to `ros::spin()'
CMakeFiles/fire_monitoring.dir/src/main.cpp.o: In function `Functions::Functions()':
main.cpp:(.text._ZN9FunctionsC2Ev[_ZN9FunctionsC5Ev]+0x268): undefined reference to `ros::NodeHandle::NodeHandle(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&)'
main.cpp:(.text._ZN9FunctionsC2Ev[_ZN9FunctionsC5Ev]+0x294): undefined reference to `image_transport::ImageTransport::ImageTransport(ros::NodeHandle const&)'
main.cpp:(.text._ZN9FunctionsC2Ev[_ZN9FunctionsC5Ev]+0x5d8): undefined reference to `image_transport::ImageTransport::advertise(std::__cxx11::basic_string<char, std ...
just a comment:
you write this as if it's an unavoidable consequence or requirement, but that's not necessarily the case.
It's perfectly possible for ROS packages to depend on pure CMake packages, as long as those packages export appropriate library targets and install their headers in the expected locations (this is no different from what they'd need to do to be able to use them as dependencies of any other CMake project). That would be no different from depending on any other system dependencies with a ROS package.
So an alternative approach would be to make use of whatever functionality is provided by your "pure CMAKE-Project" as-if it were a regular system dependency, and not convert it to a Catkin project at all.
I believe keywords would be "ros wrapper" then.
You are absolutely right. I figured this way might be easier, as I haven't written a ros wrapper yet - that was what I meant. But I will look into it, hopefully getting a result in both.
A ROS wrapper is nothing special or complicated. It just means you don't embed ROS in your business logic, and link against the libraries which provide your business logic, instead of directly building a set of source files.
@kremerf see this repo. This has been previously discussed as a resource for people looking to learn how to use ROS outside of a workspace. For people (like myself) not too familiar with build systems outside of ROS I found it especially helpful. A little more discussion on this can be found here Incorporating ROS without using catkin for C++ projects
Please note: while potentially helpful, that repository (and approach) was not what I referred to in my comment as a "ros wrapper".
I am currently looking at this ros wrapper tutorial to see whether it works or not. Will come back with more info.
I don't believe that page / tutorial shows you how to depend on a system dependency. It seems to assume "the motor driver" is contained in a single
.cpp
and.h
pair, which are compiled from-source as part of the ROS node.That's OK, if you have something that simple.
For anything else, you're probably going to have to link against whichever libraries your dependency exports, add its headers to your
include_path(..)
and#include
them in your.cpp
files.But just to make sure: a "ROS wrapper" is really nothing special. There are no special tricks. Just consider your plain-CMake package similar to Boost or OpenCV: do you go and copy-paste parts of ROS into Boost or OpenCV? No. You make use of whatever Boost functionality you need by
#include
-ing Boost headers and bytarget_link_library(..)
-ing against Boost's libraries.That's all.
That felt a little short to me as well. I have a couple .h .cpp and .cu files and other stuff that expands from there. It is more than just a couple files.