[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