[cmake-developers] Introducing the ${Foo_TARGETS} variable (IntroduceTARGETSVariable branch)
Vadim Zhukov
persgray at gmail.com
Mon Jul 29 05:22:02 EDT 2013
2013/7/27 Alexander Neundorf <neundorf at kde.org>:
> 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}.
Is there a way for Foo_INCLUDE_DIRS and Foo_LIBRARIES to be
automatically populated by find_package() when Foo_TARGETS is set?
This way migration to Foo_TARGETS could be done smoother.
> 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.
It's a very nice feature because it will also automatically fix many
CMakeLists.txt bugs caused by missing include_directories() calls.
E.g., if libjpeg and libpng both has their INCLUDE_DIRS set to
"/usr/include" in the project developer's OS, then developers usually
miss either ${JPEG_INCLUDE_DIRS} or ${PNG_INCLUDE_DIRS}, and that
breaks build on some other platforms. I can see that minor KDE
releases typically close some such bugs, while every major release
does open new ones. :) So moving to Foo_TARGETS will save time for
packagers of CMake-based projects notably; thank you a lot for this
work!
--
WBR,
Vadim Zhukov
More information about the cmake-developers
mailing list