Ask Your Question
0

Linking external headers file in ROS package

asked 2017-09-06 14:12:57 -0500

rabee gravatar image

I am trying to use the Kilobot simulator Kilombo with a ROS package. I am installing Kilombo as normal as a system library. I am then trying to include the Kilombo header file inside the ROS package to create a Kilombo simulation. The CMakeLists.txt of Kilombo looks like this:

add_library(sim display.c skilobot.c kbapi.c params.c stateio.c runsim.c neighbors.c distribution.c gfx/SDL_framerate.c gfx/SDL_gfxPrimitives.c gfx/SDL_gfxBlitFunc.c gfx/SDL_rotozoom.c)

add_library(headless skilobot.c kbapi.c params.c stateio.c runsim.c neighbors.c distribution.c)
set_target_properties(headless PROPERTIES COMPILE_DEFINITIONS "SKILO_HEADLESS")

if(CMAKE_COMPILER_IS_GNUCXX)
    add_definitions(-std=c99)
    add_definitions("-Wall -O2 -g")
#    add_definitions("-Wall -O3 -march=native -g")  
endif()

INSTALL(TARGETS sim headless
  ARCHIVE DESTINATION lib
)

INSTALL(FILES kilombo.h DESTINATION include)

INSTALL(FILES kilolib.h message.h message_crc.h params.h skilobot.h
    DESTINATION include/kilombo)

add_subdirectory(tests)

The CMakeLists.txt of the ROS package I am creating looks like this:

cmake_minimum_required(VERSION 2.8.3)
project(Kilombo_test)
find_package(catkin REQUIRED roscpp std_msgs)
if(CMAKE_COMPILER_IS_GNUCXX)
    add_definitions(-std=c99)
    add_definitions("-Wall -O2 -g")
endif()
include_directories(/usr/local/include /usr/local/lib)
link_directories(/usr/local/include)
add_executable(generated_test orbit.c)
target_link_libraries(generated_test ${catkin_LIBRARIES})

I include the Kilombo header files just as normal: #include <kilombo.h>

However, when I run catkin_make, I get many "undefined reference" errors. Some of those messages are:

orbit.c:53 undefined reference to 'kilo_turn_left'
orbit.c:53 undefined reference to 'set_motors'

These messages are shown after the commands:

####
#### Running command: "make -j2 -l2" in "/home/viki/catkin_ws/build"
####
Linking C executable generated_test

Both, kilo_turn_left and the function set_motors is defined in "kilolib.h" which itself is included in "kilombo.h".

Everything works fine if try running the simulation normally and not as a ROS package. The Makefile when I try to run it normally looks like the following. I have removed the parts which compiled for the real bot and not for the simulation.

SOURCES=orbit.c 
EXECUTABLE=orbit

# path of kilombo.h distributed with the simulator but also needed
# when compiling the user program for the real kilobot (avr-gcc has different default paths)
SIMHEADERS=/usr/local/include

#path to kilolib.a in the official kilolib, needed for real bots only
KILOLIB    =$(KILOHEADERS)/build/kilolib.a

SIM_CFLAGS = -c -g -O2 -Wall -std=c99  

SIM_LFLAGS = -lsim -lSDL -lm -ljansson
sim: $(EXECUTABLE)
hex: $(EXECUTABLE).hex
all: sim hex

clean :
    rm *.o $(EXECUTABLE) *.elf *.hex

However, when running a simulation as a ROS package, we need to define a CMakeLists.txt which is what I am having trouble with. What exactly am I doing wrong? I know there are many similar questions on this board but I have not been able to find a solution to my problem in those questions (though I believe I have gotten closer to the solution)

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
0

answered 2017-09-06 14:16:39 -0500

gvdhoorn gravatar image

updated 2017-09-06 14:38:12 -0500

This is a linking problem (ie: libraries), not a problem with headers.

add_executable(generated_test orbit.c)
target_link_libraries(generated_test ${catkin_LIBRARIES})

You're not linking any of the kilo* libraries, which is why the compiler cannot resolve the symbols.

You'll have to add one (or both? I don't know these libraries) of the sim or headless libs to the target_link_library(..) statement that you already have.


However: note that you are compiling C here: ROS has no client library for C, so you'll have to write something in C++. If/when you do, know that C++ mangles names, so you'll have to take care of that as well. You should get sufficient results if you search for c++ link c library with your favourite search engine.


Edit: some suggestions / questions:

  • /usr/local/lib should already be on the link path, and /usr/local/include should already be on the include path, so I don't believe you need to add those
  • putting /usr/local/include on the linker path seems rather strange to me: do you have libraries in that directory?
  • the same for /usr/local/lib on the include path: headers in a lib dir?
  • CMAKE_COMPILER_IS_GNUCXX is set if the compiler is g++, but -std=c99 is something for the C compiler. Should that be CMAKE_COMPILER_IS_GNUC in the conditional?
edit flag offensive delete link more

Comments

Note btw that this is not a ROS problem, but really a missing statement in your CMake file.

gvdhoorn gravatar imagegvdhoorn ( 2017-09-06 14:17:07 -0500 )edit

Then perhaps you coudl answer here ;) https://stackoverflow.com/questions/4...

rabee gravatar imagerabee ( 2017-09-06 14:20:18 -0500 )edit
2

No, I won't. And this is a classic example of why you should avoid cross-posting questions like this. It leads exactly to this sort of duplicated effort. You've basically now received the same answer twice, in two different places ..

gvdhoorn gravatar imagegvdhoorn ( 2017-09-06 14:26:57 -0500 )edit

And additionally: this question has been asked multiple times already. Please use the search before asking new questions. See #q227146 and #q200205 fi.

gvdhoorn gravatar imagegvdhoorn ( 2017-09-06 14:28:59 -0500 )edit

I didn't receive any answers on that question. Which led me to think that perhaps it was a ROS-specific problem which is why I didn't receive any answers on stackoverflow. Which is why I posted here - after a significant wait on the other question.

rabee gravatar imagerabee ( 2017-09-06 14:48:50 -0500 )edit

You're right, I'd missed the sept 3 posting date. My apologies. But even then, linking back to your other question and adding the "I think this is something specific to ROS, because .." would be good.

gvdhoorn gravatar imagegvdhoorn ( 2017-09-06 14:50:56 -0500 )edit

No worries. Will do so. As to your suggestions:

  1. Yes, those are superfluous, removing them had no effect
  2. Again, not needed.
  3. Once again, not needed.
  4. Correct, fixed it.

As you pointed out, I needed to add the libraries in the in the target_link_library... statement. Thank you.

rabee gravatar imagerabee ( 2017-09-06 15:45:36 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2017-09-06 14:12:03 -0500

Seen: 565 times

Last updated: Sep 06 '17