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