Ask Your Question
0

Proper way of including headers in catkin c++

asked 2017-05-11 16:50:01 -0500

rogi555 gravatar image

Hello there!

I'm experiencing a linking problem when I try to include some header files to my node. My newnode.cpp looks so:

#include <stdio.h>
#include <iostream>
#include <math.h>

#include "newnode_functions.h"

using namespace std;

int a, b;

int main()
{
        cout << "\nInsert number a: ";
        cin >> a;
        cout << "\nInsert number b: ";
        cin >> b;
        cout << "\na + b = " << sum(a,b);
        return 0;
}

my newnode_functions.h looks so:

#include <math.h>

int c;

int sum(int, int);

and my newnode_functions.cpp looks like this:

#include "newnode_functions.h"

int sum(int a, int b)
{
        c = a + b;
        return c;
}

Then my CMakeLists.txt is as follows:

cmake_minimum_required(VERSION 2.8.3)
project(publish_imu_measurements)
find_package(catkin REQUIRED COMPONENTS
  roscpp
  std_msgs
#  message_generation
  rogi_messages
)
catkin_package(
  INCLUDE_DIRS include
#  LIBRARIES publish_imu_measurements
  CATKIN_DEPENDS message_runtime #roscpp std_msgs
#  DEPENDS system_lib
)
include_directories(include ${catkin_INCLUDE_DIRS})
add_executable(newnode src/newnode.cpp src/newnode_functions.cpp)

When i try to compile this package with catkin_make I get the following linking errors:

Base path: /home/ubuntu/catkin_ws
Source space: /home/ubuntu/catkin_ws/src
Build space: /home/ubuntu/catkin_ws/build
Devel space: /home/ubuntu/catkin_ws/devel
Install space: /home/ubuntu/catkin_ws/install
####
#### Running command: "make cmake_check_build_system" in "/home/ubuntu/catkin_ws/build"
####
-- Using CATKIN_DEVEL_PREFIX: /home/ubuntu/catkin_ws/devel
-- Using CMAKE_PREFIX_PATH: /home/ubuntu/catkin_ws/devel;/opt/ros/kinetic
-- This workspace overlays: /home/ubuntu/catkin_ws/devel;/opt/ros/kinetic
-- Using PYTHON_EXECUTABLE: /usr/bin/python
-- Using Debian Python package layout
-- Using empy: /usr/bin/empy
-- Using CATKIN_ENABLE_TESTING: ON
-- Call enable_testing()
-- Using CATKIN_TEST_RESULTS_DIR: /home/ubuntu/catkin_ws/build/test_results
-- Found gtest sources under '/usr/src/gtest': gtests will be built
-- Using Python nosetests: /usr/bin/nosetests-2.7
-- catkin 0.7.6
-- BUILD_SHARED_LIBS is on
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~  traversing 2 packages in topological order:
-- ~~  - rogi_messages
-- ~~  - publish_imu_measurements
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- +++ processing catkin package: 'rogi_messages'
-- ==> add_subdirectory(rogi_messages)
-- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy
-- rogi_messages: 2 messages, 0 services
-- +++ processing catkin package: 'publish_imu_measurements'
-- ==> add_subdirectory(publish_imu_measurements)
-- Configuring done
-- Generating done
-- Build files have been written to: /home/ubuntu/catkin_ws/build
####
#### Running command: "make -j1 -l1" in "/home/ubuntu/catkin_ws/build"
####
[  0%] Built target std_msgs_generate_messages_nodejs
[  0%] Built target _rogi_messages_generate_messages_check_deps_Vector3Int16
[  0%] Built target _rogi_messages_generate_messages_check_deps_ImuData
[ 13%] Built target rogi_messages_generate_messages_nodejs
[ 13%] Built target std_msgs_generate_messages_cpp
[ 26%] Built target rogi_messages_generate_messages_cpp
[ 26%] Built target std_msgs_generate_messages_eus
[ 46%] Built target rogi_messages_generate_messages_eus
[ 46%] Built target std_msgs_generate_messages_py
[ 66%] Built target rogi_messages_generate_messages_py
[ 66%] Built target std_msgs_generate_messages_lisp
[ 80%] Built target rogi_messages_generate_messages_lisp
[ 80%] Built target rogi_messages_generate_messages
[ 86%] Linking CXX executable /home/ubuntu/catkin_ws/devel/lib/publish_imu_measurements/newnode
CMakeFiles/newnode.dir/src/newnode_functions.cpp.o:(.bss+0x0): multiple definition of `c'
CMakeFiles/newnode.dir/src/newnode.cpp.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
publish_imu_measurements/CMakeFiles/newnode.dir/build.make:120: recipe for target '/home/ubuntu/catkin_ws/devel/lib/publish_imu_measurements/newnode' failed
make[2]: *** [/home/ubuntu/catkin_ws/devel/lib/publish_imu_measurements/newnode] Error 1
CMakeFiles/Makefile2:968: recipe for target 'publish_imu_measurements/CMakeFiles/newnode.dir/all' failed
make[1]: *** [publish_imu_measurements/CMakeFiles/newnode.dir/all] Error 2
Makefile:138: recipe for target 'all' failed
make: *** [all] Error 2
Invoking "make -j1 -l1" failed

I have run out of ideas on this. Variable ... (more)

edit retag flag offensive close merge delete

3 Answers

Sort by » oldest newest most voted
1

answered 2017-05-13 11:20:51 -0500

Wolf gravatar image

Apart from the two issues mentioned in the answers before you need to fix the error the Compiler complains about: multiple definitions of c. The Definition is in the Header i.e. it will bei defined twice, once For each cpp File including it.

You need to define int c; in the local scope of int sum(int a, int b) in File newnode_functions.Cpp.

edit flag offensive delete link more
1

answered 2017-05-12 00:39:11 -0500

gvdhoorn gravatar image

Your header file does not have any include guards.

The linked Wikipedia page explains exactly what you're seeing, but just to be complete: without include guards the entire contents of newnode_functions.h will be copied into both newnode_functions.cpp and newnode.cpp. That leads to int c being defined multiple times, just as the compiler error tells you.


PS: this is really a C/C++ problem, not catkin nor ROS.

edit flag offensive delete link more

Comments

thank you for help, but unfortunately adding guards doesn't help...

rogi555 gravatar imagerogi555 ( 2017-05-12 11:00:59 -0500 )edit
1

answered 2017-05-12 04:11:16 -0500

There are two things actually missing:

As mentioned in the first answer the include gards are missing:

#ifndef NEWNODE_FUNCTIONS_H
#define NEWNODE_FUNCTIONS_H

#include <math.h>

int c;

int sum(int, int);
#endif // NEWNODE_FUNCTIONS_H

The second thing whats missing is the target_link_libraries in CMakeLists.txt directly behind the add_executable(newnode src/newnode.cpp src/newnode_functions.cpp):

target_link_libraries(newnode
${catkin_LIBRARIES}
)
edit flag offensive delete link more

Comments

Thank you for this explanation. I have forgotten about guards. Unfortunately after adding them to the newnode_functions.h and placing target_link_libraries into CMakeLists.txt as you described it still doesn't work, and the multiple definition of `c' error persists. Any other ideas?

rogi555 gravatar imagerogi555 ( 2017-05-12 10:58:51 -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

2 followers

Stats

Asked: 2017-05-11 16:50:01 -0500

Seen: 1,838 times

Last updated: May 13 '17