cmakeconfigurationcmake-modules

Find secondary dependencies in CMake config files


Following modern CMake guidelines (e.g. see https://www.slideshare.net/DanielPfeifer1/effective-cmake, particularly slide 46), I am trying to write out a PkgConfig.cmake file for my Pkg.

Pkg depends on Foo which in turn depends on Bar. Neither Foo nor Bar have config files - rather I am using FindFoo.cmake and FindBar.cmake to find them.

My PkgConfig.cmake file looks like this

set(Pkg_LIBRARIES Pkg::Pkg)

include(CMakeFindDependencyMacro)

find_dependency(Foo)  # Use FindFoo.cmake find and import as target Foo::Foo
                      # Foo depends on Bar which is similarly imported using
                      # FindBar.cmake as target Bar::Bar

include("${CMAKE_CURRENT_LIST_DIR}/PkgTargets.cmake")

My resultant PkgTargets.cmake looks like

add_library(Pkg::Pkg STATIC IMPORTED_
set_target_properties(Pkg::Pkg PROPERTIES
  INTERFACE_LINK_LIBRARIES "Foo::Foo")

# Load information for each installed configuration
.
.
.

My question is how can I avoid other packages importing Pkg into their project from having to specify where Foo and more importantly where Bar is to be found?

Doesn't it defeat the purpose of building transitive dependencies if the locations of Foo and Bar packages have to be specified again either through variables Foo_ROOT and Bar_ROOT or CMAKE_PREFIX_PATH?

My Pkg already knows where it was found, so should I parse/set Foo_ROOT and Bar_ROOT and put it into my PkgConfig.cmake file?


Solution

  • My question is how can I avoid other packages importing Pkg into their project from having to specify where Foo and more importantly where Bar is to be found?

    It is perfectly allowed for PkgConfig.cmake to specify (hint) locations of its dependencies.

    My Pkg already knows where it was found, so should I parse/set Foo_ROOT and Bar_ROOT and put it into my PkgConfig.cmake file?

    Note, that XXXConfig.cmake files are generally prepared for the installed project to be moved into other directory on the build machine or, more important, to be copied into other machine and be used there.

    Because location of Foo and Bar on the other machine may differ from one on the build machine, knowing their locations on build machine cannot help to find them on the target machine.

    Nevertheless, it is up to you (as the project's developer) to specify project's usage constraints. You may, e.g., specify that the project can be used only on that machine where it has been built. In that case reusing build locations of Foo and Bar in the PkgConfig.cmake script is justified.

    Moreover, even when allowing to copy the installed project into other machine, you still can use build locations of Foo and Bar as a hint for search them in the PkgConfig.cmake. So, if the project will be used on the same machine where it was built, then dependencies will be found without an user intervention. The same is true if the project will be copied to the other machine which has Foo and Bar on the same locations as on the build machine.