0
$\begingroup$

Rosanswers logo

I have a pre-compiled shared library foo.so, and I'd like to wrap it in a catkin package for use by other catkin packages. So far I can accomplish all the linking issues if foo.so is in the same package as the targets that use it, but I am unable to get other packages to find the library externally. I have the following lines:

add_library(foo SHARED IMPORTED)
set_property(TARGET foo PROPERTY IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/lib/foo.so)

It compiles and runs great if in the same CMakeLists.txt I have something like:

add_library(bar src/bar.cpp}
target_link_libraries(bar
  foo
  ${catkin_LIBRARIES}
)

But if I put this bar library in a different catkin package, it compiles fine but at runtime I get linking errors that then say missing symbols:

symbol lookup error: foo.so: undefined symbol

I have been researching and playing with adding things such as

set(${PROJECT_NAME}_EXPORTED_TARGETS foo)

or

export(TARGET foo)

But I'm really over my head. How do I export a pre-compiled shared library from one catkin package to another? I'm using catkin-tools.

Thanks!


Originally posted by Dave Coleman on ROS Answers with karma: 1396 on 2016-01-11

Post score: 1

$\endgroup$

2 Answers 2

0
$\begingroup$

Rosanswers logo

You could copy also the foo lib since it is shared and bar need foo to run. Or you copy the foo lib in /usr/local/lib or you add the path of foe in the lib search path.


Originally posted by duck-development with karma: 1999 on 2016-01-11

This answer was NOT ACCEPTED on the original site

Post score: 1


Original comments

Comment by Dave Coleman on 2016-01-11:
this is what we kind of ended up doing, thanks!

$\endgroup$
0
$\begingroup$

Rosanswers logo

With the help of @wjwwood we came up with this workaround solution that still seems reliable. From what I can tell, CMake does not have proper support for exporting or installing imported targets, as per this discussion:

Imported targets were originally designed for importing from an existing installation of some external package so installing did not make sense at the time.

Our Solution:

In the first package's CMakeLists.txt that contains the pre-compiled shared object that you want to share, you need the following. Note that in this example ${PROJECT_NAME} and "foo" must be the same name, since we are using ${PROJECT_NAME} as the name of the library. This can be changed though.

# Configure Locations
set(foo_LOCATION ${PROJECT_SOURCE_DIR}/lib/libfoo.so)
set(foo_DESTINATION ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_LIB_DESTINATION}/lib${PROJECT_NAME}.so)
MESSAGE( STATUS "foo_LOCATION:         " ${foo_LOCATION} )
MESSAGE( STATUS "foo_DESTINATION:      " ${foo_DESTINATION} )

# Foo library
add_library(${PROJECT_NAME} SHARED IMPORTED)
set_property(TARGET ${PROJECT_NAME} PROPERTY IMPORTED_LOCATION ${foo_LOCATION})

# Unfortuantly an imported target is not copied to the devel/lib folder, so we do it manually
# so that installation of a catkin workspace is not required
# See http://answers.ros.org/question/223866/cmakecatkin-how-to-export-imported-target/
file(COPY ${foo_LOCATION}
  DESTINATION ${foo_DESTINATION}
)


# Mark imported library for installation using a workaround since imported
# targets do not have proper support for installation in CMakeLists
install(FILES ${foo_LOCATION} DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION})

And in the second packge's CMakeLists.txt the foo library is automatically linked using the normal

target_link_libraries(bar
  ${catkin_LIBRARIES}
)

Originally posted by Dave Coleman with karma: 1396 on 2016-01-11

This answer was ACCEPTED on the original site

Post score: 2


Original comments

Comment by gvdhoorn on 2016-01-12:
A similar thing is done in the prosilica_gige_sdk package (here).

Comment by Mitch Woodside on 2020-01-06:
First of all, awesome work with this solution! I've been using this and the prosilica_gige_sdk to piece together a ROS package for a pre-compiled dll library on Windows. For lack of a better word, it has been... fun.

@Dave Coleman, quick question about your solution, what is the purpose of this section?

# Foo library
add_library(${PROJECT_NAME} SHARED IMPORTED)
set_property(TARGET ${PROJECT_NAME} PROPERTY IMPORTED_LOCATION ${foo_LOCATION})

Since you are copying the library files directly to the devel and install spaces, why do you need to create a CMAKE target for the imported library?

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.