Ask Your Question
0

How can I wrap a system library/dependency in a catkin package, and then use that package to provide the system lib in other packages?

asked 2014-04-17 03:48:51 -0600

trianta2 gravatar image

updated 2016-10-24 09:10:28 -0600

ngrennan gravatar image

I have a system library, such as OpenCV 3.0.0 (for example), installed on my computer in the directory /opt/OpenCV3.

I want to wrap the dependencies on OpenCV in my own package, opencv3. This way I can use catkin like this:

find_package(catkin REQUIRED COMPONENTS
  opencv3
)

So I went ahead and created the opencv3 package. I'm able to find the system library's external .cmake file and build. Here are the important parts of opencv3's CMakeLists.txt :

cmake_minimum_required(VERSION 2.8.3)
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "/opt/OpenCV3")
...
find_package(catkin REQUIRED)
find_package(OpenCV 3.0.0 EXACT)
...
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES opencv3
#  CATKIN_DEPENDS
   DEPENDS OpenCV
)

Now when I include opencv3, my custom package, in other packages as a dependency, the other packages cannot find the OpenCV libraries, and thus they cannot link/build! The OpenCV include directories do transfer over to other packages, however. So when I have this in my CMakeLists.txt of other packages which use opencv3:

message(STATUS ${opencv3_INCLUDE_DIRS})

I get the output:

/opt/OpenCV3/include

Which is correct. I just can't find out how the DEPENDS field of catkin_package(...) makes the system dependency libraries transfer to new packages. catkin_LIBRARIES and opencv3_LIBRARIES did not have the OpenCV libraries in them either...

Edit for Dirk Thomas :

The OpenCV_LIBS variable doesn't contain the full absolute filepath to the OpenCV libraries. Doing:

message(STATUS ${OpenCV_LIBS} )

yields

opencv_videostabopencv_videoopencv_superresopencv_stitchingopencv_softcascadeopencv_shapeopencv_photoopencv_optimopencv_oclopencv_objdetectopencv_nonfreeopencv_mlopencv_legacyopencv_imgprocopencv_highguiopencv_flannopencv_features2dopencv_cudawarpingopencv_cudastereoopencv_cudaoptflowopencv_cudaimgprocopencv_cudafiltersopencv_cudafeatures2dopencv_cudacodecopencv_cudabgsegmopencv_cudaarithmopencv_cudaopencv_coreopencv_contribopencv_calib3d

So when I do as you say here:

catkin_package(
    INCLUDE_DIRS ${OpenCV_INCLUDE_DIRS}
    LIBRARIES ${OpenCV_LIBS}
)

I get linker errors. My own custom variable works however, which is:

set(exec_prefix ${OpenCV_INSTALL_PATH})

catkin_package(
   INCLUDE_DIRS ${OpenCV_INCLUDE_DIRS}
   LIBRARIES ${exec_prefix}/lib/libopencv_calib3d.so ${exec_prefix}/lib/libopencv_contrib.so ${exec_prefix}/lib/libopencv_core.so ${exec_prefix}/lib/libopencv_cuda.so ${exec_prefix}/lib/libopencv_cudaarithm.so ${exec_prefix}/lib/libopencv_cudabgsegm.so ${exec_prefix}/lib/libopencv_cudacodec.so ${exec_prefix}/lib/libopencv_cudafeatures2d.so ${exec_prefix}/lib/libopencv_cudafilters.so ${exec_prefix}/lib/libopencv_cudaimgproc.so ${exec_prefix}/lib/libopencv_cudaoptflow.so ${exec_prefix}/lib/libopencv_cudastereo.so ${exec_prefix}/lib/libopencv_cudawarping.so ${exec_prefix}/lib/libopencv_features2d.so ${exec_prefix}/lib/libopencv_flann.so ${exec_prefix}/lib/libopencv_highgui.so ${exec_prefix}/lib/libopencv_imgproc.so ${exec_prefix}/lib/libopencv_legacy.so ${exec_prefix}/lib/libopencv_ml.so ${exec_prefix}/lib/libopencv_nonfree.so ${exec_prefix}/lib/libopencv_objdetect.so ${exec_prefix}/lib/libopencv_ocl.so ${exec_prefix}/lib/libopencv_optim.so ${exec_prefix}/lib/libopencv_photo.so ${exec_prefix}/lib/libopencv_shape.so ${exec_prefix}/lib/libopencv_softcascade.so ${exec_prefix}/lib/libopencv_stitching.so ${exec_prefix}/lib/libopencv_superres.so ${exec_prefix}/lib/libopencv_ts.a ${exec_prefix}/lib/libopencv_video.so ${exec_prefix}/lib/libopencv_videostab.so tbb /usr/lib/x86_64-linux-gnu/libXext.so /usr/lib/x86_64-linux-gnu/libX11.so /usr/lib/x86_64-linux-gnu/libICE.so /usr/lib/x86_64-linux-gnu/libSM.so /usr/lib/x86_64-linux-gnu/libGL.so /usr/lib/x86_64-linux-gnu/libGLU.so rt pthread m dl
)

Which is incredibly ugly, but at least the ugliness is captured in a single package opencv3 and not distributed to other packages.

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
1

answered 2014-04-18 10:29:40 -0600

Dirk Thomas gravatar image

updated 2014-04-18 12:18:58 -0600

catkin_package(DEPENDS foo) only works if foo follows the recommendation to name its variables foo_INCLUDE_DIRS, foo_LIBRARIES etc.

OpenCV does not follow that recommendation. While the variable for include directories exists the variable containing the libraries is named OpenCV_LIBS.

You must therefore pass all individual variable manually since catkin can not infer them:

catkin_package(
    INCLUDE_DIRS ${OpenCV_INCLUDE_DIRS}
    LIBRARIES ${OpenCV_LIBS}
)

Update:

You should not use OpenCV_INSTALL_PATH to prefix your libraries but OpenCV_LIB_DIR since the former one is not available on Windows (please read the OpenCV-config.cmake for reference).

Furthermore if you only need a specific subset of OpenCV components you should only find them (rather than implicitly all). That is also one reason why creating a ROS package to only wrap the third-party dependency which already has a decent CMake config file might not make sense...

Anyway you should also avoid listing all libraries explicitly. Instead you can loop over all found libraries in OpenCV_LIBS and use find_library with the hint to search in OpenCV_LIB_DIR to actually resolve the exact library file.

edit flag offensive delete link more

Comments

Hi Dirk. Please see my edit.

trianta2 gravatar imagetrianta2 ( 2014-04-18 10:59:39 -0600 )edit
0

answered 2014-04-17 10:40:17 -0600

trianta2 gravatar image

I ended up following the instructions here: http://docs.ros.org/hydro/api/catkin/...

Even though I was finding OpenCV with find_package(), the exported OpenCV_LIBRARIES variable did not include full paths to the library files, only the names. This caused the libraries to not show up in other packages which included my opencv3 package.

The solution was to create a variable which contained the full path to the OpenCV libraries, and place that variable in the LIBRARIES part of catkin_package(). Only then were packages dependent on opencv3 able to link and build properly.

I'm mostly happy with this solution, but it still requires me to create a custom variable which contains the absolute paths to all OpenCV libraries. I would much rather just have DEPENDS OpenCV in catkin_package() and be done with it.

edit flag offensive delete link more

Comments

demmeln gravatar imagedemmeln ( 2014-04-18 01:48:52 -0600 )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: 2014-04-17 03:48:51 -0600

Seen: 1,293 times

Last updated: Apr 18 '14