Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Catkin does not respect non-standard link directories for exported dependencies #535

Closed
meyerj opened this issue Oct 16, 2013 · 6 comments
Closed

Comments

@meyerj
Copy link
Contributor

meyerj commented Oct 16, 2013

The new hydro-devel branch of rtt_ros_integration uses

catkin_package(
  DEPENDS rtt ocl
  ...
)

to declare a dependency to Orocos RTT and OCL, which are not catkin packages. Due to a previous call to find_package(OROCOS-RTT...) the variables rtt_FOUND, rtt_INCLUDE_DIRS, rtt_LIBRARY_DIRS, rtt_LIBRARIES, rtt_CFLAGS_OTHER and rtt_LDFLAGS_OTHER are defined at that time.

Unfortunately the export mechanism of catkin currently does not work for this use case unless the rtt_LIBRARIES variable contains absolute paths, as these libraries are not within a CMAKE_PREFIX_PATH/lib folder and catkin does not look at the rtt_LIBRARY_DIRS variable, which would contain the correct paths to the RTT libraries. If rtt_LIBRARIES contains only the names of the libraries, catkin produces linker error messages like this in every package that depends on the exporting package (rtt_roscomm) in this case:

/usr/bin/ld: cannot find -lrtt-geometry_msgs-typekit-gnulinux
/usr/bin/ld: cannot find -lrtt-geometry_msgs-ros-transport-gnulinux
/usr/bin/ld: cannot find -lorocos-rtt-gnulinux
collect2: ld returned 1 exit status

I guess this problem does not only affect this special use case with Orocos RTT, but also all other dependencies that are find_package()-able but have libraries in non-standard link directories. Catkin also does not export the CFLAGS_OTHER and LDFLAGS_OTHER variables, if set.

Is it possible to fix this in catkin itself or is this just a use case that is not supported? One option would probably be to resolve ${depend_name}_LIBRARIES to absolute paths in catkin_pacakge.cmake:159 by calling find_library(... PATHS ${${depend_name}_LIBRARY_DIRS})?

@wjwwood
Copy link
Member

wjwwood commented Oct 16, 2013

We had this discussion internally a while back.

We recommend using absolute paths and only the LIBRARIES component of the catkin_package(...) macro. We recommend this because of LIBRARY_DIRS ordering. It is something we have to deal with in the INCLUDE_DIRS, and in my opinion using LIBRARY_DIRS does not scale with overlaying of packages in our use cases.

This is what I would recommend when a library you need to pass along provides names and dirs rather than paths, e.g. OROCOS-RTT, in the package which find_package(...)'s that library, use find_library(...) to get absolute paths out of the _LIBRARIES and _LIBRARY_DIRS variables and pass the result along to the LIBRARIES directive in the catkin_package(...) macro.

Another option would be to make an "extras" file for your package which sets the appropriate variables you are talking about and instruct users of your package to call the appropriate link_directories(...) after finding your package. This is probably not desirable, because every downstream package which also needs to export this dependency will have to do the same.

We talked about having catkin automatically transform these libraries, but we decided that there were too many variables involved in how you might want to go about doing that, so for the time being we do not plan to do that.

Personally, I think having the first person to export a dependency like this use find_library(...) on it is a good solution.

@wjwwood
Copy link
Member

wjwwood commented Oct 16, 2013

A little more about the ordering issue...

Consider you have a system package, like orocos-rtt, which exports as libraries and library directories, and is installed into /opt/ros/hydro and from source in ~/my_ws/install_isolated. Then you have a package which finds it in the ~/my_ws/install_isolated folder and it gives -lrtt and -L~/my_ws/install_isolated/lib. Later another package finds some other library which behaves this way and adds these flags: -lsomethingelse and -L/opt/ros/hydro. How this actually occurs depends on more complex dependencies, but basically what is happening now is that even though you found orocos-rtt in ~/my_ws/install_isolated and added the right flags, at linkedit time the linker will get the -lrtt from /opt/ros/hydro instead.

@wjwwood
Copy link
Member

wjwwood commented Oct 16, 2013

Also, the extras files are definitively the solution for more exotic variables like rtt_CFLAGS_OTHER.

@meyerj
Copy link
Contributor Author

meyerj commented Oct 16, 2013

Okay, I understand. Then we probably will only use absolute paths in catkin_package(...) or add an CFG_EXTRAS file which takes care of the variables. Many thanks for your explanation!

@adolfo-rt
Copy link

I've also encountered this situation, and the proposed solution works for me just fine. I was wondering if an automated solution to the problem would be possible: Catkin could query the LIBRARY_OUTPUT_DIRECTORY property of a target and take appropriate action if the returned path is different from project_name_DIR. At this moment this is more of an intellectual curiosity, but would there be any obvious gotcha against this approach?.

@adolfo-rt
Copy link

For the record, see the answer I posted to this question where a solution that is compatible with both multi-CMake project (catkin build, catkin_make_isolated) and single, nested CMake projects (catkin_make) is proposed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants