Using target names directly vs. variables

David Faure faure at kde.org
Sun Jul 14 16:46:22 UTC 2013


On Sunday 14 July 2013 11:42:26 Alexander Neundorf wrote:
> A good step forward to improve the experience for the user is to follow
> those naming conventions as good as possible, so that if you do
> 
> find_package(WhatEverItIs)
> 
> you know, that you can use ${WhateEverItIs_LIBRARIES} and
> ${WhatEverItIs_INCLUDE_DIRS} later on without looking at the documentation
> for this specific module.

Yes, this is "the old way" :-)

With Qt5 and KF5, however, there's no need for the _INCLUDE_DIRS variable;
linking to the target name brings the include dirs automatically. It works 
differently, so it's not crazy to use a different syntax for it.
Different feature -> different syntax.

To anyone only knowing the "old way", it would actually be quite confusing to 
see cmakelists using ${Foo_LIBRARIES} and NOT using ${Foo_INCLUDE_DIRS}. 

We could still set the variables, of course, for the principle of less 
surprises you mention, so that app developers can use the variables the "old 
way". But this doesn't mean we have to use these variables internally.

> OTOH it has a couple of disadvantages:
> * the developer first has to check the documentation of the specific module
> whether it provides the standard variables or only the imported targets

Right. Let's provide both.

> * if a package provides only the imported targets, there is no naming
> standard for targets, so the developer has to read the documentation for
> each package to find out what the name of the imported target is. This is a
> step backward, not foward. Stephen agrees that he does not see a standard
> way to name targets in relation to their cmake package names.

Well, one needs to find the name of the package too, in the first place.
Should I find_package(attica) or find_package(Attica) or 
find_package(LibAttica)?
At some point, someone needs to read some documentation.
In fact, I'm confused. If there's multiple libs in the package (e.g. kiocore 
and kiowidgets), with a single find_package(KIO COMPONENTS core widgets) call, 
then with variables the same problem happens, surely a KIO_LIBRARIES isn't 
good enough.

> * if we use target names now directly in kdelibs, there will be breakage
> when moving them to separate builds, and a big switch day. Within kdelibs,
> the target name is e.g. KService. When exporting them as cmake targets,
> they get a "namespace" prepended, to give a strong hint that the thing you
> see is an imported target. So the name of the imported target is
> "KF5::KService". When moving a framework out of kdelibs, all places where
> this target is used have to be changed accordingly. We avoid this work
> (basically thanks to the standard naming of variables) if we right now
> start to use
> ${KService_LIBRARIES}. This can be set to "KService" right now in the
> toplevel CMakeLists.txt in kdelibs. Inside the framework, there will be
> find_package(KF5 .... COMPONENTS KService)
> or
> find_package(KService)
> which will set, as every find_package() should do, the ${KService_LIBRARIES}
> variable, and there will be no additional work and no breakage and no
> switch day when finally separating the frameworks out of kdelibs. This is
> done now already for all frameworks which are already in tier1/ and tier2/,
> they cab right now be built as part of kdelibs or as a standalone project.

I can write a perl script to replace KService with KF5::KService (and same for 
the other targets) in target_link_libraries lines in 15 minutes tops.
Changing A to B now so that we don't have to change A to C later doesn't save 
anything (same script...).

> * I don't see an advantage in having to teach our developers that for KDE
> packages they have to use imported target names (including Qt5), while for
> all other packages they can follow what they know from cmake for years, and
> continue to use ${Foo_LIBRARIES}.

See above - it's different because it takes care of the include dirs too.

> * I have never heard a complaint from a cmake user that he can't use
> imported target names directly but has to use variables for external
> packages. So I don't see any motivation to change this.

The complaint is: if I use a variable that is not set, it is expanded to 
nothing, and all I get is undefined symbols. If I use a target name that is 
unknown, I get an error about that very target name, much easier to debug.

-- 
David Faure, faure at kde.org, http://www.davidfaure.fr
Working on KDE, in particular KDE Frameworks 5



More information about the Kde-frameworks-devel mailing list