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

How can catkin find ROS libraries in non-standard locations?

asked 2015-01-15 03:15:07 -0500

galou gravatar image

updated 2015-01-15 03:21:05 -0500

Actually the complete question would be: How can catkin find ROS libraries in non-standard locations, or is it ok not to write a library for Python in catkin_package(...)?

I wrote a library in C++ for Python to wrap a C++ class. For it to be usable in Python I needed to change the default location. Extract of CMakeLists.txt in package crossing_detector:

set_target_properties(crossing_detector_wrapper_cpp PROPERTIES

PREFIX ""

LIBRARY_OUTPUT_DIRECTORY ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_PYTHON_DESTINATION})

This work well in the sense that I can use it in Python with

from crossing_detector.crossing_detector_wrapper_cpp import CrossingDetectorWrapper

The problem comes when I want to compile separately (catkin_make_isolated or catkin build) another package that depends on crossing_detector, catkin complains about a missing library:

Project 'dataset_analyzer' tried to find library 'crossing_detector_wrapper_cpp'. The library is neither a target nor built/installed properly The library is not even needed there.

The problem doesn't occur when compiling both packages together (catkin_make).

See also: https://github.com/catkin/catkin_tool...

I'm thinking of solving the problem by removing the library from catkin_package(...). Is this ok to do so?

edit retag flag offensive close merge delete

3 Answers

Sort by ยป oldest newest most voted
1

answered 2015-05-26 05:31:23 -0500

Adolfo Rodriguez T gravatar image

The strategy proposed by William works well with catkin_make_isolated and catkin build, where multiple CMake projects exist, and the dependency is built before it is required. It however breaks under catkin_make, where there is a single CMake project and the dependency has not yet been built when it is required (hence find_library fails). For completeness, I have put together a a slightly modified version that is compatible with both single- and multi-CMake projects:

CMakeLists.txt

catkin_package(
  ...
  LIBRARIES # NOTE: Not specified here, but in extras file
  CFG_EXTRAS foo-extras.cmake
)

foo-extras.cmake.in

find_library(@PROJECT_NAME@_LIBRARY
            NAMES @PROJECT_NAME@
            PATHS "${@PROJECT_NAME@_DIR}/../../../@CATKIN_GLOBAL_LIB_DESTINATION@/funky/path/to/foo"
            NO_DEFAULT_PATH)

if(@PROJECT_NAME@_LIBRARY)
  # Multiple CMake projects case (i.e. 'catkin build'):
  # - The target has already been built when its dependencies require it
  # - Specify full path to found library
  list(APPEND @PROJECT_NAME@_LIBRARIES ${@PROJECT_NAME@_LIBRARY})
else()
  # Single CMake project case (i.e. 'catkin_make'):
  # - The target has not been built when its dependencies require it
  # - Specify target name only
  list(APPEND @PROJECT_NAME@_LIBRARIES @PROJECT_NAME@)
endif()
edit flag offensive delete link more
1

answered 2015-01-15 18:39:10 -0500

William gravatar image

One strategy would be to calculate the relative path to the library on installation and then add it explicitly to the ${crossing_detector_LIBRARIES} variable using a CMake extra's file. The extra's file would look something like this:

# generated from the cmake/crossing_detector-extras.cmake.in file

# Calculate the path to the library
find_library(crossing_detector_wrapper_cpp_library NAMES crossing_detector_wrapper_cpp PATHS "${crossing_detector_DIR}/../../../@CATKIN_GLOBAL_LIB_DESTINATION@/" NO_DEFAULT_PATH)

# I think this next part will work, but it is optional.
# If you don't include it then dependent packages
# will need to use the crossing_detector_wrapper_cpp_library explicitly.
list(APPEND crossing_detector_LIBRARIES ${crossing_detector_wrapper_cpp_library})

So you'd use find_library so that it handles the library prefix and suffix correctly, but if you messed with the library name (it looks like you did) then you may need to do something slightly different, see the find_library docs:

http://www.cmake.org/cmake/help/v3.0/...

Additionally you'll need to do this in your CMakeLists.txt to get that file expanded and installed into the devel space and install space:

catkin_package(...
CFG_EXTRAS crossing_detector-extras.cmake
...)

Also, I _think_ you can safely extend the crossing_detector_LIBRARIES variable at this point, maybe @Dirk Thomas can chime in on that. However, if not you will need to explicitly use the crossing_detector_wrapper_cpp_library variable in downstream packages after calling find_package(... crossing_detector ...). Something like this:

find_package(catkin REQUIRED COMPONENTS crossing_detector ...)

add_executable(foo ...)
target_link_libraries(foo ${catkin_LIBRARIES} ${crossing_detector_wrapper_cpp_library})
edit flag offensive delete link more
0

answered 2015-01-15 18:06:54 -0500

ahendrix gravatar image

The libraries listed in catkin_package(...) instruct any packages that depend on your package to link against those libraries. If the library you're compiling isn't intended to be linked against by downstream C++ packages, you shouldn't list it there.

It sounds like everything else you're doing is correct.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2015-01-15 03:15:07 -0500

Seen: 4,237 times

Last updated: May 26 '15