[cmake-developers] Introducing the ${Foo_TARGETS} variable (IntroduceTARGETSVariable branch)
Alexander Neundorf
neundorf at kde.org
Fri Jul 26 16:17:52 EDT 2013
Hi,
I pushed the IntroduceTARGETSVariable branch to stage.
It introduces the new variable Foo_TARGETS to be used in Config files,
additionally to or maybe better instead of Foo_LIBRARIES and Foo_INCLUDE_DIRS.
This variable shall be used to list the target(s) imported by the package Foo.
So it can be used in tll() calls to link against the library (package).
What makes it differ from Foo_LIBRARIES, is that CMake checks that each of the
items listed in this variable
* is an existing target
* has the INTERFACE_INCLUDE_DIRS property set.
This should make sure that using this variable in a tll() call should suffice
to give the target the required include dirs and libraries.
IMO this has multiple advantages:
* using
tll(hello ${Foo_TARGETS} )
instead of
tll(hello foo )
gives the reader a strong hint that ${Foo_TARGETS} comes from a
find_package(Foo) call, while in the second case it is not clear at
all whether "foo" is an in-project target, an imported target or
the basename of a library.
This doesn't matter much for the developer who added the dependency
to foo himself, since he knows what he's doing at this moment, but it
matters a lot for everybody else, who have to find out what's going on, be
it a developer new to this code or somebody trying to debug build problems
of somebody else's project via a mailing list.
* using
tll(hello ${Foo_TARGETS} )
instead of
tll(hello ${Foo_LIBRARIES} )
tells the reader that by using ${Foo_TARGETS} there is need for
an additional call to set the include dirs, but that the include dirs are
coming attached to the targets listed in ${Foo_TARGETS}.
This is actually enforced with this patch.
Again, this helps a lot when reading cmake code you didn't write yourself.
* there is a direct mapping from the package name "Foo" used in
find_package(Foo) to the variable name "Foo_TARGETS". This is something
I heard many people wishing for/complaining about.
This cannot be enforced when using target names directly (this would mean
that the name of the Config.cmake file must be exactly the name of the
target to use, and there is no enforcement of namespaces like "Foo::"
possible).
* with this variable, for many projects Foo_TARGETS will be the only variable
which needs to be set in the Config.cmake file, so they become simpler.
It has one disadvantage, which is that with this new variable there are now
two standards: either use ${Foo_LIBRARIES} and ${Foo_INCLUDE_DIRS}, or use
${Foo_TARGETS}.
Error messages
--------------
In the case that a target does not exist, the following error message is
generated:
CMake Warning at /opt/ecm/share/ECM/find-modules/FindKF5.cmake:180
(find_package):
Found package configuration file:
/opt/kf5/lib/cmake/KCoreAddons/KCoreAddonsConfig.cmake
but "KCoreAddons" is considered to be NOT FOUND because the variable
KCoreAddons_TARGETS set by it lists the following non-existant targets: Foo
Call Stack (most recent call first):
CMakeLists.txt:14 (find_package)
In the case that a target is listed. which does not have the include dirs set,
the following error message is generated:
CMake Warning at /opt/ecm/share/ECM/find-modules/FindKF5.cmake:180
(find_package):
Found package configuration file:
/opt/kf5/lib/cmake/KCoreAddons/KCoreAddonsConfig.cmake
but "KCoreAddons" is considered to be NOT FOUND because the variable
KCoreAddons_TARGETS set by it lists the following targets which do not have
the required INTERFACE_INCLUDE_DIRECTORIES target property set:
KF5::KCoreAddons
Call Stack (most recent call first):
CMakeLists.txt:14 (find_package)
TODO
----
* Tests are still missing.
* Should the variable be mentioned in the documentation for find_package() ?
* There is the theoretical risk that there are Config.cmake files out there
which set a variable with that name already, but without the include dir
property. Should this be based on a policy, so that the error is only
generated if cmake 2.8.12 or higher is required ? Or should there be an
emergency switch -DCMAKE_IGNORE_MISSING_INCLUDE_DIRS_ON_IMPORTED_TARGETS for
this case ?
Comments ?
If possible, I'd like to get that into 2.8.12.
Thanks
Alex
More information about the cmake-developers
mailing list