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

Using a system library #200

Closed
1 task done
sonelu opened this issue Aug 20, 2024 · 4 comments
Closed
1 task done

Using a system library #200

sonelu opened this issue Aug 20, 2024 · 4 comments
Labels
bug Something isn't working

Comments

@sonelu
Copy link

sonelu commented Aug 20, 2024

Solution to issue cannot be found in the documentation.

  • I checked the documentation.

Issue

The context is very simple: a robot using a Raspberry Pi (Bookworm) with ROS2 installed in a Conda/Mamba environment that needs to access GPIO, I2C, etc. (like you would expect from a robot).

If you use Python, it's not a big issue: as long as the packages are available in Conda-Forge or even PyPi you can install over in the environment and then use them in the ROS package.

The problem is when you try to write C++ packages (for instance when using ros2_control. If there are no Conda packages (very likely as there are a lot of system specific requirements tailored for the physical machine) you might only have the option of installing libraries with apt. If the ROS installation is on an Ubuntu system from Debian packages, that seems to be no problem (see this package for instance): your C++ packages could use the system libraries as any other package.

But that does't happen in a Conda environment. The apt installed libraries can't seemed to be found by the ament-cmake (or at least I could not find a way to cleanly do this).

The only way I could work around this (and is very ugly) is to explicitly include full path. For instance the CPP file will include:

#include </usr/include/pigpiod_if2.h>

and the CMakeLists.txt would link:

target_link_libraries(trilobot_hardware
  /usr/lib/libpigpiod_if2.so   
)

It works, but it is very ugly and very possible would create problems of porting.

Do you have any idea how this can we dealt with in a more elegant way? Like creating a "link library" in the conda environment, or even a ROS package that mirrors the include and the libraries from the system?

Thanks.

Installed packages

-- not really important in this case --
-- will supply if needed --

Environment info

Raspberry Pi CM4 with Waveshare Carrier IO Board B
Raspberry OS Bookwork (kernel 6.1 - I think I am not at the robot right now)
@sonelu sonelu added the bug Something isn't working label Aug 20, 2024
@sonelu
Copy link
Author

sonelu commented Aug 20, 2024

Solving this would also deal with #180.

@traversaro
Copy link
Member

Do you have any idea how this can we dealt with in a more elegant way? Like creating a "link library" in the conda environment, or even a ROS package that mirrors the include and the libraries from the system?

In general, making sure that it is not possible to find system libraries is a desirable property, as in general apt packages and conda packages may use different versions (with different ABIs) of the same libraries, and mixing them can lead to runtime crashes that are quite hard to debug. In the quite rare case of a system library that can be cleanly used (typically if it is a library without any dependency, but even in that cases there could be problems), cmake needs to be pointed to the library to use using the canonical way to let CMake aware of where a package is, that depends on how the package is found. To help you, it is probably easier if you:

  • Specify which system C++ package you want to use
  • Specify what you mean "The apt installed libraries can't seemed to be found by the ament-cmake (or at least I could not find a way to cleanly do this)." What library did you try to find? How did you try to find it? How is ament-cmake involved, as packages are typically found via find_package that is a pure CMake construct?

@sonelu
Copy link
Author

sonelu commented Aug 22, 2024

@traversaro thanks for the information. I have dug a more in the CMake documentation and I find the way to make it work.

Now to answer your question there are two low level hardware interfaces that I have tried to work with on Raspberry Pi: wiringPi and pigpio. They both have very convoluted ways of installing, for instance wiringPi compiles from sources and makes a Debian package that needs to be installed with apt install, while pigpio is build from source with make. In the end I had to settle on pigpio because I needed PWM and both libraries would require sudo ro run because of some restrictions in the RPi kernel. pigpio has a very elegant solution around that where it runs a daemon pigpiod under sudo, and calls from user space go through this daemon.

Now, the way I had the CMakeLists.txt to work was to use:

find_library(PIGPIO_LIB pigpiod_if2 REQUIRED)
find_path(PIGPIO_INCLUDEDIR pigpiod_if2.h REQUIRED)

to find them and then to use them:

target_link_libraries(trilobot_hardware
  ${PIGPIO_LIB}
)

target_include_directories(trilobot_hardware PUBLIC
  ${PIGPIO_INCLUDEDIR}
  ${CMAKE_CURRENT_SOURCE_DIR}/include
)

That seems to be doing the trick and would also work if the libraries are installed in different directories (ex. /usr/** vs. /usr/local/**.

@sonelu sonelu closed this as completed Aug 22, 2024
@traversaro
Copy link
Member

Ok, thanks for the info!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants