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?
My question is how can I avoid other packages importing
Pkg
into their project from having to specify whereFoo
and more importantly whereBar
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
andBar_ROOT
and put it into myPkgConfig.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.