Ask Your Question
0

catkin_make_isolated /usr/bin/ld: cannot find -l<lib_name>

asked 2019-01-29 15:34:38 -0500

venkisagunner gravatar image

I'm trying to run catkin_make_isolated on my workspace and it fails.

==> Processing catkin package: 'motor_driver_pkg'
==> Building with env: '/home/user/catkin_ws/devel_isolated/kinematics/env.sh'
Makefile exists, skipping explicit cmake invocation...
==> make cmake_check_build_system in '/home/user/catkin_ws/build_isolated/motor_driver_pkg'
==> make -j6 -l6 in '/home/user/catkin_ws/build_isolated/motor_driver_pkg'
[ 50%] Linking CXX executable /home/user/catkin_ws/devel_isolated/motor_driver_pkg/lib/motor_driver_pkg/dc_motor_driver
/usr/bin/ld: cannot find -lkinematics
collect2: error: ld returned 1 exit status
CMakeFiles/dc_motor_driver.dir/build.make:119: recipe for target '/home/user/catkin_ws/devel_isolated/motor_driver_pkg/lib/motor_driver_pkg/dc_motor_driver' failed
make[2]: *** [/home/user/catkin_ws/devel_isolated/motor_driver_pkg/lib/motor_driver_pkg/dc_motor_driver] Error 1
CMakeFiles/Makefile2:1091: recipe for target 'CMakeFiles/dc_motor_driver.dir/all' failed
make[1]: *** [CMakeFiles/dc_motor_driver.dir/all] Error 2
Makefile:138: recipe for target 'all' failed
make: *** [all] Error 2
<== Failed to process package 'motor_driver_pkg': 
  Command '['/home/user/catkin_ws/devel_isolated/kinematics/env.sh', 'make', '-j6', '-l6']' returned non-zero exit status 2

Reproduce this error by running:
==> cd /home/user/catkin_ws/build_isolated/motor_driver_pkg && /home/user/catkin_ws/devel_isolated/kinematics/env.sh make -j6 -l6

Command failed, exiting.

I have a package called kinematics, this is the CMakeLists.txt of that package

cmake_minimum_required(VERSION 2.8.3)
project(kinematics)

find_package(catkin REQUIRED COMPONENTS
  controller_interface
  roscpp
)

###################################
## catkin specific configuration ##
###################################
## DEPENDS: system dependencies of this project that dependent projects also need
catkin_package()

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

## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
 include
  ${catkin_INCLUDE_DIRS}
)

add_library(kinematics 
  src/ackermann.cpp
  src/diff_drive.cpp)
target_link_libraries(kinematics ${catkin_LIBRARIES})


#############
## Install ##
#############

install(DIRECTORY include/${PROJECT_NAME}/
  DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
  FILES_MATCHING PATTERN "*.h"
  PATTERN ".svn" EXCLUDE)

install(TARGETS kinematics
  LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
)

I have another package called motor_driver_pkg that takes uses the library "kinematics" from kinematics package. This is the CMakeLists.txt for that package.

cmake_minimum_required(VERSION 2.8.3)
project(motor_driver_pkg)

find_package(catkin REQUIRED COMPONENTS
  roscpp
  tf
  kinematics
)

###################################
## catkin specific configuration ##
###################################
catkin_package()

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

## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(include 
  ${catkin_INCLUDE_DIRS}
  ${kinematics_INCLUDE_DIRS}
)

add_executable(dc_motor_driver src/dc_motor_driver.cpp)
target_link_libraries(dc_motor_driver kinematics ${catkin_LIBRARIES})

This works completely fine with catkin_make. But fails when I run catkin_make_isolated. I understand that the motor_driver_pkg is not able to find the kinematics library. Need help. Don't know what is going wrong.

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2019-01-30 02:56:29 -0500

gvdhoorn gravatar image

updated 2019-01-30 03:12:23 -0500

tl;dr: change the catkin_package() call in the CMakeLists.txt of your kinematics package to the following:

catkin_package(
  INCLUDE_DIRS include
  LIBRARIES kinematics)

Refer to Building and installing C++ libraries and headers in the Catkin documentation for more information about exporting information from Catkin packages.


Longer explanation:

Don't know what is going wrong.

You have this in the motor_driver_pkg:

target_link_libraries(dc_motor_driver kinematics ${catkin_LIBRARIES})

Thing is, CMake assumes that if you provide the name of a library directly (as you do with kinematics) you're referring to something it calls a target. It takes the name of the target you specify and then tries to look up information about it in its internal data structures.

If the target is defined in the same CMake context, this will work fine. It'll find the information it needs (such as the actual filename and path associated with that target) and then essentially replace the name of the target with whatever information is required by the particular CMake statement that the target's name is being used in.

In this case that would be the absolute path to the actual file that constitutes the kinematics library (probably something like /path/to/your/catkin_ws/devel/lib/kinematics/libkinematics.so (or something like that, could be different)).

This works completely fine with catkin_make. But fails when I run catkin_make_isolated.

So the issue here is the "CMake context": catkin_make combines all of the CMakeLists.txt it finds in your workspace into one and then begins the build process (it doesn't really do this, but for this explanation we're pretending it does). That creates a single context, in which the target name kinematics actually means something, namely: the target defined in the CMakeLists.txt of your kinematics package. So when CMake encounters the target_link_libraries(dc_motor_driver kinematics ..) it can look up the name kinematics and it'll find the information it needs to make that statement succeed.

With catkin_make_isolated things are completely different: as the isolated in the name implies, catkin_make_isolated does not coalesce all CMakeLists.txt into a single context, but keeps everything .. isolated.

It should now be clear why looking up the target name kinematics fails in this case: kinematics is only a defined target in the context of the CMakeLists.txt of your kinematics package. Nowhere else. So CMake fails to lookup the information it needs with the error message you show as a result.

I understand that the motor_driver_pkg is not able to find the kinematics library

It should also be clear that motor_driver_pkg is not actually looking for anything. It's CMake.


To fix this, we need to make some information available to consuming packages that allows them to find the information (and files) they need.

For Catkin packages that would like to make libraries available to other Catkin packages, that is done by the catkin_package(..) statement, in particular with the LIBRARIES argument followed by a list of library targets of which the information should be exported.

Your kinematics package does have ... (more)

edit flag offensive delete link more

Comments

Note also that this is a CMake problem: you cannot just refer to target names that are not defined (or imported) in the current context.

gvdhoorn gravatar image gvdhoorn  ( 2019-01-30 02:57:35 -0500 )edit

Yes. Thank you very much. That was the issue. While linking shared libraries while performing catkin_make_isolated, we have to use the catkin_package macro and do not use target_link_libraries. It was actually working and I broke it by adding a library to the target_link_libraries.

venkisagunner gravatar image venkisagunner  ( 2019-01-30 15:31:24 -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: 2019-01-29 15:34:38 -0500

Seen: 789 times

Last updated: Jan 30 '19