Using target names directly vs. variables

Alexander Neundorf neundorf at kde.org
Sun Jul 14 09:42:26 UTC 2013


Hi,

in CMake, to link against a target, you use its target name:

target_link_libraries(hello mylib)

That's what we do in kdelibs, and this is fine.

In CMake, to make use of an external package, you use find_package(), and then 
use the variables it provides, as documented in readme.txt and find_package():

"We would like all FindXxx.cmake files to produce consistent variable names.

Please use the following consistent variable names for general use.

Xxx_INCLUDE_DIRS        The final set of include directories listed in one 
variable for use by client code.
                        This should not be a cache entry.
Xxx_LIBRARIES           The libraries to link against to use Xxx. These should
                        include full paths.
                        This should not be a cache entry."



Those naming conventions have been defined to make using external packages 
easier. I common complaint about cmake I hear is that not all packages follow 
these naming conventions.
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.


This is a step forward for developers using cmake.
I strongly support this.


Another option would be to use imported target names.
I agree that this looks nicer.
But this is the only advantage I see.

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

* 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.

* 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 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}.

* 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.


So, I strongly oppose to change from using variables to imported target names 
directly.


Alex


More information about the Kde-frameworks-devel mailing list