# Build packages with more than one .cpp

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:

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 ...
edit retag close merge delete

( 2014-05-13 02:35:51 -0600 )edit

here it is

( 2014-05-13 02:57:42 -0600 )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?

( 2014-05-13 03:19:05 -0600 )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?

( 2014-05-13 03:24:33 -0600 )edit

2 different executables with two different source files.

( 2014-05-13 03:40:26 -0600 )edit

( 2014-05-13 03:55:37 -0600 )edit

Sort by » oldest newest most voted

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

## Declare a cpp executable


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

## Declare a cpp executable


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. more 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.

more

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.

( 2014-05-14 00:09:00 -0600 )edit

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

more

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.

more

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.

( 2017-08-27 02:32:47 -0600 )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?

( 2017-08-27 17:54:44 -0600 )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.

( 2017-08-28 02:01:33 -0600 )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.

( 2017-08-30 08:17:55 -0600 )edit