Skip to content

ament_export_dependencies can't export all PkgConfig projects found in CMake #504

Open
@Ryanf55

Description

@Ryanf55

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

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"
)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions