How let other catkin packages depend on a library built with ExternalProject_Add(...)? [closed]

Hi,

I encountered difficulties wrapping an external driver into a catkin package such that other catkin packages can depend on it. The driver is provided by a company as open-source, it builds without cmake, and it is distributed through a public mercurial repository.

To conveniently pull in upstream updates, I wanted to have the build process checkout and build a specific commit. I know this is discouraged behavior for releasing ROS packages through the build-farm. But for the moment I do not intend to release the package through the build-farm.

I tried using the CMake command ExternalProject_Add because of the following question: http://answers.ros.org/question/63259...

Building the driver library works fine, but any depending catkin package is not aware of the build target for the library. Does anybody know how to properly expose the library and the build target itself to other catkin packages?

Here are the details. In my package igh_eml I successfully build a library called ethercat. igh_eml's CMakeLists.txt looks like this:

project(igh_eml)

find_package(catkin REQUIRED)

catkin_package(
INCLUDE_DIRS ${CATKIN_DEVEL_PREFIX}/include LIBRARIES ethercat) include(ExternalProject) ExternalProject_Add(upstream_igh_eml # #--Download step---------- HG_REPOSITORY http://hg.code.sf.net/p/etherlabmaster/code # URL of mercurial repo HG_TAG 792892ab4806 # Mercurial branch name, commit id or tag TIMEOUT 30 # Time allowed for file download operations # #--Update/Patch step---------- UPDATE_COMMAND touch <SOURCE_DIR>/config.h COMMAND mkdir -p <SOURCE_DIR>/include <SOURCE_DIR>/lib # Source work-tree update command # #--Configure step------------- CONFIGURE_COMMAND touch <SOURCE_DIR>/ChangeLog COMMAND autoreconf -i <SOURCE_DIR> COMMAND <SOURCE_DIR>/configure --prefix=<INSTALL_DIR> --disable-kernel --enable-hrtimer --enable-tool # Build tree configuration command # #--Build step----------------- BUILD_IN_SOURCE 1 # Use source dir for build dir ) ExternalProject_Get_Property(upstream_igh_eml source_dir) add_custom_command(TARGET upstream_igh_eml POST_BUILD COMMAND cp${source_dir}/../../include/ecrt.h
${CATKIN_DEVEL_PREFIX}/include/ ) add_custom_command(TARGET upstream_igh_eml POST_BUILD COMMAND cp${source_dir}/../../include/ectty.h
${CATKIN_DEVEL_PREFIX}/include ) add_custom_command(TARGET upstream_igh_eml POST_BUILD COMMAND cp${source_dir}/../../lib/libethercat.so
${CATKIN_DEVEL_PREFIX}/lib )  Here is a link to the actual file: https://github.com/code-iai/iai_robot... My second package omnidriver_ethercat depends on igh_eml on gives this error: CMake Error at /home/georg/ros/indigo/boxy_refactoring/devel/share/igh_eml/cmake/igh_emlConfig.cmake:141 (message): Project 'omni_ethercat' tried to find library 'ethercat'. The library is neither a target nor built/installed properly. Did you compile project 'igh_eml'? Did you find_package() it before the subdirectory containing its code is included?  Here is a link to CMakeLists of omnidrive_ethercat : https://github.com/code-iai/iai_robot... Does anybody know how I declare that the library ethercat will be build through ExternalProject_Add? Furthermore, how can I make other catkin packages wait for that build target to finish? Thanks in advance for any help! edit retag reopen merge delete Closed for the following reason the question is answered, right answer was accepted by Georg Bartels close date 2019-09-20 01:44:54.322716 2 Answers Sort by » oldest newest most voted Does anybody know how I declare that the library ethercat will be build through ExternalProject_Add? One option would be to use CMake's IMPORTED TARGET support for that. Let the external library build, install everything in the proper locations (ie: CATKIN_PACKAGE_LIB_DESTINATION etc) and then import the library. After importing, export it in your catkin_package(LIBRARIES ..) call. Dependent packages should now automatically pick it up. Furthermore, how can I make other catkin packages wait for that build target to finish? This will most likely start to work as soon as you import & export the library properly. more Comments Thank you for your answer! It pointed me into the right direction. ( 2016-05-03 06:37:38 -0500 )edit gvdhoorn's answer pointed me into the right direction. I provide my own solution for documentation. Here is the CMakeLists of igh_eml which checks out and builds the external mercurial repository: cmake_minimum_required(VERSION 2.8.3) project(igh_eml) find_package(catkin REQUIRED) include(ExternalProject) ExternalProject_Add(upstream_igh_eml HG_REPOSITORY http://hg.code.sf.net/p/etherlabmaster/code HG_TAG 792892ab4806 TIMEOUT 30 UPDATE_COMMAND touch <SOURCE_DIR>/config.h COMMAND mkdir -p <SOURCE_DIR>/include <SOURCE_DIR>/lib CONFIGURE_COMMAND touch <SOURCE_DIR>/ChangeLog COMMAND autoreconf -i <SOURCE_DIR> COMMAND <SOURCE_DIR>/configure --prefix=<INSTALL_DIR> --disable-kernel --enable-hrtimer --enable-tool BUILD_IN_SOURCE 1 INSTALL_DIR${CATKIN_DEVEL_PREFIX}
)

set_target_properties(ethercat PROPERTIES IMPORTED_LOCATION ${CATKIN_DEVEL_PREFIX}/lib/libethercat.so) add_dependencies(ethercat upstream_igh_eml) catkin_package( LIBRARIES ethercat )  Important notes: (1) catkin_package has to be called AFTER the build and import calls. (2) Exporting the include files at ${CATKIN_DEVEL_PREFIX}/include with catkin_package was not possible, that directory does not exist when catkin_package is interpreted.

The depending package omnidrive_ethercat has the following CMakeLIsts:

cmake_minimum_required(VERSION 2.8.3)
project(omni_ethercat)

find_package(catkin REQUIRED COMPONENTS ... igh_eml ...)

catkin_package(
CATKIN_DEPENDS ... igh_eml ...)

include_directories(include ${catkin_INCLUDE_DIRS}) add_executable(omni_ethercat src/omni_ethercat.cpp src/omnilib/omnilib.c src/omnilib/realtime.c) target_link_libraries(omni_ethercat${catkin_LIBRARIES})


Important note: I have to directly depend on the build target upstream_igh_eml to halt compilation until all the h-files and so-files in igh_eml have been downloaded and built. The target ethercat was not enough. Also, I did not find out how to export this target through a CMake variable.

So, this a working solution, but there is room for improvement...

more

A bit late, but:

I have to directly depend on the build target upstream_igh_eml to halt compilation until all the h-files and so-files in igh_eml have been downloaded and built.

by explicitly adding the upstream_igh_eml to the exported targets of igh_eml, you should be able to avoid having to manually call add_dependencies(.. upstream_igh_eml) for consuming targets.

You can do that with something like:

list(APPEND \${PROJECT_NAME}_EXPORTED_TARGETS upstream_igh_eml)


This statement probably needs to be placed before the call to catkin_package(..), but I'm not sure about that.

( 2019-08-28 08:05:39 -0500 )edit

Stats

Asked: 2016-05-02 07:57:30 -0500

Seen: 1,571 times

Last updated: May 03 '16