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

catkin: multiple "undefined reference to ros::xyz'"

asked 2021-01-11 05:37:56 -0500

kremerf gravatar image

updated 2021-01-11 06:18:06 -0500

gvdhoorn gravatar image

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 ...
(more)
edit retag flag offensive close merge delete

Comments

3

just a comment:

I had to convert a pure CMAKE-Project to catkin, as I needed to use ROS.

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.

gvdhoorn gravatar image gvdhoorn  ( 2021-01-11 05:54:34 -0500 )edit

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.

kremerf gravatar image kremerf  ( 2021-01-11 06:08:34 -0500 )edit

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.

gvdhoorn gravatar image gvdhoorn  ( 2021-01-11 06:20:45 -0500 )edit

@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

JackB gravatar image JackB  ( 2021-01-11 08:20:17 -0500 )edit

Please note: while potentially helpful, that repository (and approach) was not what I referred to in my comment as a "ros wrapper".

gvdhoorn gravatar image gvdhoorn  ( 2021-01-11 08:36:59 -0500 )edit

I am currently looking at this ros wrapper tutorial to see whether it works or not. Will come back with more info.

kremerf gravatar image kremerf  ( 2021-01-12 01:19:07 -0500 )edit
1

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 by target_link_library(..)-ing against Boost's libraries.

That's all.

gvdhoorn gravatar image gvdhoorn  ( 2021-01-12 01:47:30 -0500 )edit

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.

kremerf gravatar image kremerf  ( 2021-01-12 01:52:39 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2021-01-18 01:36:02 -0500

kremerf gravatar image

updated 2021-01-18 01:40:30 -0500

After rewatching my code I noticed, that the project I build around the ZED SDK was basically already some sort of wrapper itself. Noticing that I tried to make it work itself with catkin, rather than writing something else instead.

How?

Well, turns out when you work with a CMakeLists you should really get to know that file.. I remade it several times, without success and then googled every single line, and thought about it with a colleague (I cannot stress enough how much of a help another mind in this is, when you are not that familiar with catkin..)

Today I revisited my CMakeList and commented in and out every single package and line to see whether I included some not crucial stuff. Re-ordered it (as there are lots of people in the internet that tell you to include or find_package in the end of the file.. turns out that was unnecessary for me. So now I am ready to go with a fresh looking file.

Just because I'd like to see additional code fragments myself if I had this kind of error:

project(name LANGUAGES CXX CUDA)

#Didn't find mine, so here goes
set(OpenCV_DIR __path__)

# included some ROS-Packages here, if you do not need any of them, just throw them out
find_package(catkin REQUIRED COMPONENTS
  roscpp
  rosconsole
  nodelet
  image_transport
  sensor_msgs
  stereo_msgs
  std_msgs
)
# Other important stuff, like ZED, CUDA, OpenCV, ...
find_package(__other stuff__)
# almost the same as with the catkin components
catkin_package(
  INCLUDE_DIRS ${OpenCV_INCLUDE_DIRS}
  CATKIN_DEPENDS
    roscpp
    rosconsole
    sensor_msgs
    stereo_msgs
    image_transport
)
# Not necessary, but I do not like to have paths to files in my lists..
set(NODE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp)

#All packages you need again..
include_directories(
        ${catkin_INCLUDE_DIRS}
        ${CUDA_INCLUDE_DIRS}
        ${ZED_INCLUDE_DIRS}
    ${OpenCV_INCLUDE_DIRS}
    ${GLUT_INCLUDE_DIR}
    ${GLEW_INCLUDE_DIRS} 
    ${OPENGL_INCLUDE_DIRS}
)

# Again, no paths for me please
FILE(GLOB CUDA_FILES cu/*.cu)
# If you use cuda, just put everything here, works just fine. You probably could split it, but the computer seems to know which actual compiler to use I guess, the files have explicit endings..
cuda_add_executable(name ${NODE_SRC} ${CUDA_FILES})

#Important again
TARGET_LINK_LIBRARIES(name 
    ${catkin_LIBRARIES}
    ${OpenCV_LIBRARIES}
    ${GLUT_LIBRARIES}
    ${GLEW_LIBRARIES}
    ${OPENGL_LIBRARIES}
    ${ZED_LIBRARIES}
)

I ommited these:

#set(CUDA_ARCH_BIN " 30 " CACHE STRING "Specify 'real' GPU arch to build binaries for, BIN(PTX) format is supported. Example: 1.3 2.1(1.3) or 13 21(13)")
#set(CUDA_ARCH_PTX "" CACHE STRING "Specify 'virtual' PTX arch to build PTX intermediate code for. Example: 1.0 1.2 or 10 12")    
#set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS}  "-Xcompiler;-fPIC;-std=c++11")
#set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "--ftz=true;--prec-div=false;--prec-sqrt=false; -rdc=true")

as they are used by CUDA_COMPILE - if I am not mistaken - and the compiling "just works". This may be the case for me, but it might not for you, so just letting you know.

Wth my beautiful lack of knowledge I figured this now very clean file (and the according package.xml) should be able to be automatically generated by a smart piece of software, but maybe not for more complex ones - if someone knows, please let me know.

It ... (more)

edit flag offensive delete link more

Comments

Well, I would accept it, but I do not have >10 Points.

kremerf gravatar image kremerf  ( 2021-01-18 01:37:32 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2021-01-11 05:36:46 -0500

Seen: 452 times

Last updated: Jan 18 '21