ament_export_dependencies can't export all PkgConfig projects found in CMake
- Dominant language
- CMake
- Stars
- 125
- Forks
- 147
- PR merge metrics
- No merged PRs in 30d
Description
I'm refactoring a large repository to be installable with ament_cmake. It's a CMake project, and relies on library `libav`, which does not support CMake. `libav` only comes with Pkgconfig support. Gstreamer is pulled in through pkgconfig also.
I'm using CMake 3.28, so I have full access to the latest language features.
## Current Behavior
Thus, here's how the library `foo` brings it in with CMake's built in [PkgConfig](https://cmake.org/cmake/help/latest/module/FindPkgConfig.html) support.
Some details omitted for brevity.
```cmake
pkg_check_modules(LIBAV REQUIRED IMPORTED_TARGET libavcodec>=50)
pkg_check_modules(GST REQUIRED IMPORTED_TARGET gstreamer-1.0>=1.2)
add_executable(my_node)
target_link_libraries(my_node PRIVATE PkgConfig::LIBAV PkgConfig::GST)
ament_export_dependencies(
LIBAV
GST
)
ament_package()
```
This builds fine. But, a consuming package `bar` can't use the exported dependencies.
```
--- stderr: bar
CMake Error at /ws/install/foo/share/foo/cmake/ament_cmake_export_dependencies-extras.cmake:21 (find_package):
By not providing "FindLIBAV.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "LIBAV", but
CMake did not find one.
Could not find a package configuration file provided by "LIBAV" with any of
the following names:
LIBAVConfig.cmake
libav-config.cmake
Add the installation prefix of "LIBAV" to CMAKE_PREFIX_PATH or set
"LIBAV_DIR" to a directory containing one of the above files. If "LIBAV"
provides a separate development package or SDK, be sure it has been
installed.
Call Stack (most recent call first):
/ws/install/foo/share/foo/cmake/fooConfig.cmake:41 (include)
CMakeLists.txt:84 (find_package)
```
Library `foo` has this as the INTERFACE_INCLUDE_DIRECTORIES: `INTERFACE_LINK_LIBRARIES "PkgConfig::GST;PkgConfig::LIBAV" in the export.
And, in ament_cmake_export_dependencies-extras.cmake
```
set(_exported_dependencies "GST;LIBAV")
```
## Expected Behavior
ament_export_dependencies can support and recognize targets created with `PkgConfig` and support downstream packages with PkgConfig.
## Workarounds
* Write my own find script for the library and install that with config-extras.
* Vendor the package and add CMake support
* Wait for CMake to add a maintained find script: https://gitlab.kitware.com/cmake/cmake/-/issues/24064
* Wait for ffmpeg devs to cave in to CMake: https://trac.ffmpeg.org/ticket/9881
## Proposal
Amend `ament_cmake_export_dependencies-extras.cmake` to also try to find PkgConfig projects as a backup using `pkg_check_modules`. Note that the flag `IMPORTED_TARGET` means that users of this will have to use that also.
```cmake
set(_exported_dependencies "LIBAV;GST")
find_package(ament_cmake_libraries QUIET REQUIRED)
if(NOT _exported_dependencies STREQUAL "")
find_package(ament_cmake_core QUIET REQUIRED)
set(Foo_DEPENDENCIES ${_exported_dependencies})
set(Foo_RECURSIVE_DEPENDENCIES ${_exported_dependencies})
set(_libraries)
foreach(_dep ${_exported_dependencies})
if(NOT ${_dep}_FOUND)
find_package("${_dep}" QUIET)
endif()
if(NOT ${_dep}_FOUND)
pkg_check_modules(${_dep} IMPORTED_TARGET)
endif()
if(NOT ${_dep}_FOUND)
find_package("${_dep}" REQUIRED)
endif()
```
This will work because of the following in FooTargetExport.cmake
```
set_target_properties(Foo::FooPROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
INTERFACE_LINK_LIBRARIES "PkgConfig::GST;PkgConfig::LIBAV"
)
```
Contributor guide
Assessment
This issue has not been assessed yet.