Linking to lib is using -lmylib instead of ws/install/pkg/lib/

asked 2021-09-20 19:47:31 -0600

flo gravatar image

Hello there,

I need help regarding linking of a shared library. I managed to package an existing non-ROS library mostly properly to be found by find_package(), has a pacakge.xml and use most of the structure provided by this template here:

I'm currently failing in the linking step after build:

/usr/bin/ld: cannot find -linotify-cpp

when using cmake verbose I see that all other .so are propagated with their path to the .so and not -lmylib ..

I also notice that no pkg_config hook is generated by my library instead of the example template (lib_foo).

What I hope for: A way to alter the usage of -lmylib to /path/to/ as a CMakeList command that I can use from the package I want to use the shared library from..

For more code context, this is what I managed so far: (see the last 2 commits)

Really appriciate some help on this.. Thank you!!! :-)

Some verbose output from the cmake:

/usr/bin/cmake -E cmake_link_script CMakeFiles/manager_core.dir/link.txt --verbose=1
/usr/bin/c++ -fPIC -O3 -DNDEBUG  -shared -Wl,-soname, -o CMakeFiles/manager_core.dir/src/plugin_manager.cpp.o  -Wl,-rpath,/opt/ros/galactic/lib:/workspaces/vscode_ros2_workspace/install/bt_bot_msgs/lib /opt/ros/galactic/lib/ /opt/ros/galactic/lib/ /opt/ros/galactic/lib/ /opt/ros/galactic/lib/ /opt/ros/galactic/lib/ /opt/ros/galactic/lib/ /workspaces/vscode_ros2_workspace/install/bt_bot_msgs/lib/ /workspaces/vscode_ros2_workspace/install/bt_bot_msgs/lib/ -linotify-cpp /opt/ros/galactic/lib/ <...more/>

notice the last 2 parameters. Out of nowhere the -lmylib is stated. I just could not figure it out where to find a proper way to alter that input. I can alter the name of the library but not the -l. Also the library folder is included in LD_LIBRARY_PATH (..:/workspaces/vscode_ros2_workspace/install/inotify-cpp/lib:..), everything running on Docker with a ros-base image on galactic.

Could the - be a problem in the name..?

edit retag flag offensive close merge delete



Let's take a step back.

Should you be wrapping a system dependency in a ROS package? If it's not a ROS package, don't try to make it one.

Do you have a specific reason for not just keeping it a plain cmake build type?

Out of nowhere the -lmylib is stated. I just could not figure it out where to find a proper way to alter that input.

In general, when you start asking yourself "how do I manually fiddle with this automatically generated artefact?" it may be a sign something is not right, or should not be used in that way.

gvdhoorn gravatar image gvdhoorn  ( 2021-09-21 02:12:52 -0600 )edit

Hey there,

That‘s a really good question. I somehow expected that I only can use a ros-packaged library. Are there any hints to just use the cmake way? I sadly am a absolut noob regarding CMakeList..

In the end I want to use that library in a ROS2 package. But I do not need to make that lib a ros library. I just thought I had to or otherwise find_package and all that is not gonna find it..

Thank you!

flo gravatar image flo  ( 2021-09-21 02:26:30 -0600 )edit

But of course, I would like to know what small little detail I‘m missing to make it right. If feels like I‘m just one step away.

Although the adapter Interface Export feels like it will haunt me in the next step.. 😅

Just wanted to have a nice way of watching a file directory with inotify..

flo gravatar image flo  ( 2021-09-21 02:29:49 -0600 )edit

No, you don't need to make everything "a ROS lib".

In the end, both Catkin and Ament are all "just CMake wrappers/macros", so if you can find_package(..) your library / project from a plain CMakeLists.txt, you can use it in a ROS project (ie: a CMakeLists.txt with ROS specific content).

There are quite a few Q&As here on ROS Answers discussing how to "use external libraries with ROS" (or similar phrasing). ROS 2 has not changed much there. It's still all CMake (perhaps even more so).

I sadly am a absolut noob regarding CMakeList..

you may want to follow some tutorials on CMake first then. Don't mix in ROS / ROS 2. It will only complicate things.

gvdhoorn gravatar image gvdhoorn  ( 2021-09-21 02:30:29 -0600 )edit

I somehow found my root problem:

target_link_libraries(${PROJECT_NAME}_node ${lib_foo_LIBRARIES})

As there is only a name of the shared library given by _LIBRARIES (i.e. mylib), target_link_libraries interprets that sort of correctly like a installed system library. See explaination from documentation:

If an imported library has the IMPORTED_NO_SONAME target property set, CMake may ask the linker to search for the library instead of using the full path (e.g. /usr/lib/ becomes -lfoo).

So with this tweak, I got my package to successfully link my .so: target_link_libraries(${executable_name} "${inotify-cpp_LIBRARY_DIRS}/lib${inotify-cpp_LIBRARIES}.so")

But I still wonder what causes my library to set the IMPORTED_NO_SONAME and where I need to include this..

flo gravatar image flo  ( 2021-09-21 05:06:21 -0600 )edit


Actually I found in myLibTargets-noconfig.cmake this:

# Import target "inotify-cpp::inotify-cpp-shared" for configuration ""
set_property(TARGET inotify-cpp::inotify-cpp-shared APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG)
set_target_properties(inotify-cpp::inotify-cpp-shared PROPERTIES

So I'm asking myself now what I need to do to load the generated Targets-noconfig.cmake to properly load into my CMakeList.txt so that I can again use the lib-name. I'm using inotify-cpp in the linker script. But this seems to be a little bit more advanced inotify-cpp::inotify-cpp-shared, some sort of namespace..

flo gravatar image flo  ( 2021-09-21 09:35:51 -0600 )edit