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 support.
Some details omitted for brevity.
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.
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"
)