Comments (15)
At the moment ament_cmake
neither generates any .pc
files nor does it use pkg-config
to look for packages. Therefore I don't see why ament_cmake
should use / handle / set / touch the environment variable PKG_CONFIG_PATH
.
A package which installs .pc
files should probably export an environment hook which prepends the installed location to the environment variable PKG_CONFIG_PATH
. Then downstream packages can find it without modifying the environment themselves.
If the package doesn't extend the environment variable packages trying to use it can do it for them before trying to call pkg-config
. Assuming that you are using pkg-config
in your package and dependency provides a .pc
file but doesn't extend the environment variable PKG_CONFIG_PATH
it seems appropriate to me that your package extends the environment variable.
If you think ament_cmake
should "support" this use case somehow can you please describe how you expect this to happen. "When" do you expect it to do "what" exactly? Probably best with a specific step-by-step example.
from ament_cmake.
If the "plain cmake" packages are built as part of the workspace I could see an argument for ament_tools
adding those plain cmake package's to the pkg-config path. But not ament_cmake
, since ament_cmake
packages can provide their own environment hooks and do it themselves.
from ament_cmake.
With this use-case I am specifically targeting plain cmake packages (e.g. directly from upstream) without any additional package.xml
. The motivation is that reusing existing repositories of libraries is facilitated without patching ros2 or ament specific build information into it.
Say you want to use a library A (libA
) in a ros2 node B (nodeB
). Typically, libA
will install its *.pc
files in <prefix>/lib/pkgconfig
(e.g. /usr/lib/pkgconfig
when built as plain cmake). When a workspace wsA
containing libA
is built, the pc files will be installed to install/lib/pkgconfig
and this folder should be prepended to PKG_CONFIG_PATH
and exported with the workspace's setup
scripts.
When sourcing workspace wsA
with libA
and building a new workspace wsB
with nodeB
, PKG_CONFIG_PATH
should contain <path_to_wsA>/install/lib/pkgconfig
such that ament_cmake
can find libA
for building nodeB
.
The workaround that I am using (set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${CMAKE_INSTALL_PREFIX}/lib/pkgconfig")
) only works if libA
and nodeB
are in the same workspace.
I hope the motivation for this is clearer now. I think this is a very relevant issue since ros nodes are mostly used as wrappers around libraries and using libraries directly from upstream simplifies development.
from ament_cmake.
Thanks for detailed description. From what I understand ament_cmake
can't do much about this. Instead the build tool ament_tools
could "introspect" the install space after installing a plain CMake package and if there is a file matching lib/pkgconfig/*.pc
then it could add an environment hook which extends PKG_CONFIG_PATH
when sourcing the setup file of the plain CMake package.
One (big?) downside would be that if a user builds A
and B
manually (using the command cmake
, make
, make install
) that "magic" is not available and therefore the .pc
file wouldn't be found.
While extending ament_tools
is certainly an option I am wondering if this shouldn't be better taken care of in package B
. Since B
uses A
and knows that A
doesn't provide the correct environment to be used it can fix that before trying to use it, e.g.:
find_package(a REQUIRED)
set(a_prefix "${a_DIR}/../../..") # depending on where the CMake config file for package A is located
set(ENV{PKG_CONFIG_PATH} "${a_prefix}/lib/pkgconfig:$ENV{PKG_CONFIG_PATH}")
find_package(PkgConfig REQUIRED)
pkg_check_modules(pkg_a REQUIRED a)
from ament_cmake.
Libraries (3rd party, upstream) that install pc files usually install them to <prefix>/lib/pkgconfig
. It would not be required to search for all *.pc
files and add their folders; adding <prefix>/lib/pkgconfig
per workspace should be sufficient.
When libA
gets built and installed without ament
, e.g. the usual cmake
& make
way, it typically gets installed to a default directory (e.g. /usr/lib/pkgconfig
). For a ros2/ament package like nodeB
, is there a scenario where one wants to build it with plain cmake commands (e.g. outside a workspace without ament)? I would not see the missing "magic" outside of ament as a problem.
I would like to see PKG_CONFIG_PATH
extended by install/lib/pkgconfig
for each sourced workspace instead of dealing with this in each ament package to prevent duplicated cmake code.
Would there be a downside of extending PKG_CONFIG_PATH
this way?
from ament_cmake.
I would not see the missing "magic" outside of ament as a problem.
When a Debian package is being built that toolchain uses only the "plain" tools. So that might be a problem if pkg A is installed in a non-standard location like /opt/ros/r2b3
.
If you don't want to duplicate the CMake logic you could create an ament_cmake
package named a_wrapper
which depends on A and exports the necessary environment variable. All downstream packages should then use the wrapper package.
from ament_cmake.
@christianrauch Can this be closed?
from ament_cmake.
Even if this issue is related to ament_tools
I still don't see how ament
is supporting plain cmake library packages. E.g. CMakeLists.txt
projects that install their *.pc
or *.cmake
files to locations that are different from where regular ament packages install their *.cmake
files.
A more concrete example would be the apriltag2 library, which can (and should) also be used outside of ament. At the moment, I am using the workaround of manually adding lib/pkgconfig/
of the same workspace to PKG_CONFIG_PATH
if I want to use that library in a ROS2 node. But this has the mentioned drawbacks. How is ament
going to support the use of this library?
What will be a more systematic way of supporting plain cmake library packages?
from ament_cmake.
For the example of the apriltag2 library: how do you expect a user to use the library? Well, I would argue if they don't use a build tool like ament_tools
they would need to read your README file and then build the package using cmake
, make
, make install
and then in order to use it (if they have installed to a custom location rather than /usr
) set environment variables to e.g. find the .pc
file.
When a package decides to be a plain CMake package it means that it is not using any of the benefits provided by ament_cmake
(which includes generating CMake config files, setting up environment variables, etc.). Therefore it is the responsibility of that package to do "everything" on its own.
If the user does use a build tool like ament_tools
it can provide "some level" of support for plain CMake packages. It e.g. add the <install-prefix>/bin
folder to the PATH
environment variable if the package installs executables into that location. Something similar happens for libraries and LD_LIBRARY_PATH
as well as CMake config files and CMAKE_PREFIX_PATH
. It is certainly possible to extend it to do something for pkg-config
(as suggested in this comment).
As mentioned before relying on the build tool to help you out in this case will not work when users build with the "normal" tools or when a packages is being released. Therefore I suggested to consider handling this within your package. If you don't want to do that and only care about the use case with ament_tools
than extending the build tool to look for .pc
files will be sufficient.
from ament_cmake.
A user that wants to use a library that provides *.pc
files, would request the package in cmake via pkg_search_module(apriltag REQUIRED apriltag)
and links against ${apriltag_LIBRARIES}
. If the package is system wide installed, a user does not need to know it installation path.
If ament could be extended to behave like in your suggestion:
Instead the build tool ament_tools could "introspect" the install space after installing a plain CMake package and if there is a file matching lib/pkgconfig/*.pc then it could add an environment hook which extends PKG_CONFIG_PATH when sourcing the setup file of the plain CMake package.
this would simplify the use of plain cmake packages.
from ament_cmake.
If ament could be extended to behave like in your suggestion this would simplify the use of plain cmake packages.
As long as you are aware that this only works when the user uses the build tool ament_tools
. Imo this is kind of a lock-in which we typically try to avoid.
Anyway please see ament/ament_tools#171 which should add that feature. Please comment there if it works for your use case. For trying it you will also need the patch from the referenced ament_package
PR.
from ament_cmake.
@christianrauch It would be great if you could comment on the PR ament/ament_tools#171.
from ament_cmake.
@dirk-thomas Sorry for responding so late. I couldn't find time earlier to look into this this again.
While looking into this issue, I found a workspace setup that does not require special handling of the plain cmake package in my ROS node to build. I couldn't figure out yet, why it is like that.
My workspace is consisting of three packages
- apriltag2 (library)
- apriltag_msgs (message definitions)
- apriltag2_node (ROS2 node).
I found that adding apriltag_msgs
to my CMakeLists.txt
by:
find_package(apriltag_msgs REQUIRED)
ament_target_dependencies(AprilTag2Node ... apriltag_msgs ...)
makes my workspace compile successfully.
If you checkout all packages at master (using apriltag_msgs
), e.g.:
mkdir -p apriltag_ws/src
cd apriltag_ws/src
git clone [email protected]:christianrauch/apriltag2.git
git clone [email protected]:christianrauch/apriltag_msgs.git
git clone [email protected]:christianrauch/apriltag2_node.git
cd ..
source /opt/ros/r2b3/setup.bash
ament build
the workspace will successfully build, event though there is no special workarounds in apriltag2_node.
If you switch apriltag2_node
to branch no_msgs_cmake
(not using apriltag_msgs
):
mkdir -p apriltag_ws/src
cd apriltag_ws/src
git clone [email protected]:christianrauch/apriltag2.git
git clone [email protected]:christianrauch/apriltag_msgs.git
git clone -b no_msgs_cmake [email protected]:christianrauch/apriltag2_node.git
cd ..
source /opt/ros/r2b3/setup.bash
ament build
the build will fail with with None of the required 'apriltag' found
because of the missing pkg-config path.
Why does the workspace build successfully by adding apriltag_msgs
?
Which part of apriltag_msgs
makes the ROS2 node apriltag2_node
find the library apriltag
?
from ament_cmake.
It looks like your package apriltag2_node
doesn't declare a dependency on the plain CMake package aprilta. If you add <depend>apriltag</depend>
to the apriltag2_node
package.xml
file the build tool will make sure to source the environment of the apriltag
package when building apriltag2_node
. This will then define/extend the PKG_CONFIG_PATH
environment variable and you shouldn't need to patch the CMake code anymore.
from ament_cmake.
@dirk-thomas Thanks for this hint. I didn't know that an ament package can depend on a plain cmake package this way. I thought that ament packages can only depend on other ament packages (e.g. those that have a package.xml
)
from ament_cmake.
Related Issues (20)
- Resolving ament packages at build time HOT 4
- ament_vendor should be able to use mirror site of git HOT 2
- ament_vendor() does not install vendor project to correct path HOT 1
- How to install ament on ubuntu20.04? Or build front the source? HOT 1
- Question about `ament_export_include_directories(include)` and `${PACKAGE_INCLUDE_DIRS}`. HOT 3
- Exporting dependencies of header-only (interface) libraries to downstream packages HOT 3
- ament_pack_build_configuration is very slow for many dependencies HOT 4
- PRIVATE option to ament_target_dependencies does not work HOT 1
- Add support for gmock in ament_cmake_auto
- Enable compulsory sign-off for ament organization or ament_cmake repo? HOT 3
- Backport `ament_auto_add_gmock` to humble HOT 3
- Fix compiler warnings related to gtest/gmock (backport #408 to humble) HOT 2
- ament cmake core fails on unexpected keyword argument 'encoding' HOT 1
- Installing Python3.12 causes import error: No module named 'distutils' HOT 3
- ament_export_dependencies can't export all PkgConfig projects found in CMake HOT 2
- Support propagation of version compatibility to consuming libraries HOT 2
- BUG: ament_cmake_core doesn't work in CMake 3.5 anymore but doesn't declare a minimum cmake version to use it HOT 7
- ament_cmake_python: Update ament_python_install_package() to allow installing more files into an existing package. HOT 9
- Corrupt ament_cmake_symlink_install.cmake may be generated HOT 1
- Ament Cmake doesnt extend LD_LIBRARY_PATH for libTorch (Ros2 Humble) HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ament_cmake.