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

Build packages with more than one .cpp

asked 2014-05-13 02:29:35 -0500

updated 2022-01-22 16:16:27 -0500

Evgeny gravatar image

I have received some packages from Fuerte which I need to compile in Hydro with catkin. Each package has more than one source file .cpp

In rosbuild, there was:

rosbuild_add_executable([file1])

rosbuild_add_executable([file2])

In catkin I did the same but with add_executable

The problem is that if I add both files (with different names of executables of course) the program doesn't compile If I omit one of them, everything works properly, but I need both. I don't know if the solution is to create two packages or I need to add anything to CMakeLists.txt

    cmake_minimum_required(VERSION 2.8.3)
    project(test_imu)

    ## Find catkin macros and libraries
    ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
    ## is used, also find other catkin packages
    find_package(catkin REQUIRED COMPONENTS
        message_generation
        nav_msgs 
        robotnik_msgs
        roscpp 
        sensor_msgs 
        geometry_msgs
        )

    ## System dependencies are found with CMake's conventions
    # find_package(Boost REQUIRED COMPONENTS system)
    find_package(MRPT REQUIRED 
        gui
        slam
        )
    find_package(gazebo REQUIRED)
    include_directories(include ${catkin_INCLUDE_DIRS} ${GAZEBO_INCLUDE_DIRS} ${SDFormat_INCLUDE_DIRS})
    include_directories("/home/summitxl/catkin_ws/src/Ensayos/test_imu/include")


    ## Uncomment this if the package has a setup.py. This macro ensures
    ## modules and global scripts declared therein get installed
    ## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
    # catkin_python_setup()

    ################################################
    ## Declare ROS messages, services and actions ##
    ################################################

    ## To declare and build messages, services or actions from within this
    ## package, follow these steps:
    ## * Let MSG_DEP_SET be the set of packages whose message types you use in
    ##   your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
    ## * In the file package.xml:
    ##   * add a build_depend and a run_depend tag for each package in MSG_DEP_SET
    ##   * If MSG_DEP_SET isn't empty the following dependencies might have been
    ##     pulled in transitively but can be declared for certainty nonetheless:
    ##     * add a build_depend tag for "message_generation"
    ##     * add a run_depend tag for "message_runtime"
    ## * In this file (CMakeLists.txt):
    ##   * add "message_generation" and every package in MSG_DEP_SET to
    ##     find_package(catkin REQUIRED COMPONENTS ...)
    ##   * add "message_runtime" and every package in MSG_DEP_SET to
    ##     catkin_package(CATKIN_DEPENDS ...)
    ##   * uncomment the add_*_files sections below as needed
    ##     and list every .msg/.srv/.action file to be processed
    ##   * uncomment the generate_messages entry below
    ##   * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)

    ## Generate messages in the 'msg' folder
    # add_message_files(
    #   FILES
    #   Message1.msg
    #   Message2.msg
    # )
## Generate services in the 'srv' folder
# add_service_files(
#   FILES
#   Service1.srv
#   Service2.srv
# )

## Generate actions in the 'action' folder
# add_action_files(
#   FILES
#   Action1.action
#   Action2.action
# )

## Generate added messages and services with any dependencies listed here
# generate_messages(
#   DEPENDENCIES
#   std_msgs  # Or other packages containing msgs
# )

###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if you package contains header files
## LIBRARIES: libraries you create in this project that dependent projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES test_imu
#  CATKIN_DEPENDS other_catkin_pkg
   DEPENDS gazebo_ros
)

###########
## Build ##
###########

## Specify additional locations of header files
## Your package locations should be listed before other locations

## Declare a cpp library
# add_library(test_imu
#   src/${PROJECT_NAME}/test_imu.cpp
# )

## Declare ...
(more)
edit retag flag offensive close merge delete

Comments

Can you please edit your question adding your CMakeLists.txt?

Tirjen gravatar image Tirjen  ( 2014-05-13 02:35:51 -0500 )edit

here it is

arenillas gravatar image arenillas  ( 2014-05-13 02:57:42 -0500 )edit
1

I suppose you get the error when the add_executable and the target_link_libraries for the test_imu_node are not commented. There is a missing closed bracket in the target_link_libraries for the test_imu_node. I don't know if this is the problem, can you please say otherwise which error gives you the compiler?

Tirjen gravatar image Tirjen  ( 2014-05-13 03:19:05 -0500 )edit

Are you trying to make 3 different executables with 1 source file each or 1 executable with 3 source files? Can you post the error message?

sterlingm gravatar image sterlingm  ( 2014-05-13 03:24:33 -0500 )edit

2 different executables with two different source files.

arenillas gravatar image arenillas  ( 2014-05-13 03:40:26 -0500 )edit

Your add_executable calls only have 1 source file. You need to add more source files. I added it as an answer.

sterlingm gravatar image sterlingm  ( 2014-05-13 03:55:37 -0500 )edit

4 Answers

Sort by ยป oldest newest most voted
5

answered 2014-05-13 03:52:16 -0500

sterlingm gravatar image

updated 2014-05-14 03:38:39 -0500

You need to add all of source files that will build an executable to the add_executable command.

## Declare a cpp executable
add_executable(executable_one src/source_one.cpp src/source_two.cpp ... src/source_n.cpp)

To create multiple executables, you just add multiple instances of that line:

## Declare a cpp executable
add_executable(executable_one src/source_one.cpp src/source_two.cpp ... src/source_n.cpp) 
add_executable(executable_two src/source_one.cpp src/source_two.cpp ... src/source_n.cpp) 
add_executable(executable_three src/source_one.cpp src/source_two.cpp ... src/source_n.cpp)

Each add_executable is self-contained so it will only use the files you list to build the executable. So make sure you list all source files needed, even they are also used for a different executable. Also, make sure you have the target_link_library(executable ${catkin_LIBRARIES}) for each executable.

edit flag offensive delete link more
2

answered 2014-05-13 20:47:09 -0500

Tirjen gravatar image

The undefined reference error means that it can't find the target library. If you haven't done it, you must add the command:

target_link_libraries(test_imu_results ${catkin_LIBRARIES})

Since the roscpp package is in the find_package command I think the problem should be something similar.

P.S.

If I'm not wrong the command catkin_make test_imu compiles all except test_imu package. To compile a single package you should use the command catkin_make --pkg <my_package_name>, but I never tried it.

edit flag offensive delete link more

Comments

Thanks a lot. It was exactly what you had said. I'm new to CMakeLists and I didn't know how to write them properly.

arenillas gravatar image arenillas  ( 2014-05-14 00:09:00 -0500 )edit
0

answered 2014-05-13 03:35:55 -0500

The problem appears when I uncomment the second add_executable and it is:

 Linking CXX executable /home/summitxl/catkin_ws/devel/lib/test_imu/test_imu_results
    CMakeFiles/test_imu_results.dir/src/test_imu_results.cpp.o: In function `test_imu_results::test_imu_results()':
    /home/summitxl/catkin_ws/src/Ensayos/test_imu/src/test_imu_results.cpp:10: undefined reference to `ros::NodeHandle::NodeHandle(std::string const&, std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > > const&)'
    /home/summitxl/catkin_ws/src/Ensayos/test_imu/src/test_imu_results.cpp:15: undefined reference to `ros::console::g_initialized'

... and much more similar The thing is that this only appears when I do catkin_make When I try catkin_make test_imu it doesn't happens

edit flag offensive delete link more
0

answered 2017-08-26 15:28:35 -0500

Void gravatar image

My problem of compiling with multiple executables was due to the fact that I was including 2 or more main functions within add_library because the add_library takes from the file(GLOB ${PROJECT_NAME}_src.. part, and it had a regex that took 2 or more executables.

The solution is to put your executables in a folder that isn't grabbed by the file(GLOB ${PROJECT_NAME}_src.. part and when you declare executables using add_executable, make sure to include within target_link_libraries the ${PROJECT_NAME variable, which is usually all non-executable .cpp files in your package.

edit flag offensive delete link more

Comments

Actually, using GLOB is not recommended in any case, and the issue you ran into is one of the reasons why. See this question on SO for some additional rationale.

gvdhoorn gravatar image gvdhoorn  ( 2017-08-27 02:32:47 -0500 )edit

I see your point; but the problem can easily be solved with an automatic build system, using Continuous Integration. What other option is their to link a large number of .cpp files as a library?

Void gravatar image Void  ( 2017-08-27 17:54:44 -0500 )edit

I'm not entirely sure how CI can be used to 'solve' this: GLOB has inherent problems.

What other option is their to link a large number of .cpp files as a library?

There is no 'other' option: the recommended way in CMake is to explicitly list your source files for each target.

gvdhoorn gravatar image gvdhoorn  ( 2017-08-28 02:01:33 -0500 )edit

With GLOB you'd have to re-run catkin_make because the regex might not pick up on newly added files. One could have conventions to only put non-executable library files in a certain folder and run continuous builds that clean and remake the file; but manually attaching is good too.

Void gravatar image Void  ( 2017-08-30 08:17:55 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2014-05-13 02:29:35 -0500

Seen: 8,435 times

Last updated: Aug 26 '17