[cmake-developers] INTERFACE_LIBRARY target type
Stephen Kelly
steveire at gmail.com
Tue Apr 23 16:26:25 EDT 2013
Hi,
Last year, the new INTERFACE_LIBRARY target type was to be part of the
'target usage requirements' feature, but it was deferred until after 2.8.11.
It was discussed a bit though, in my point 3 in this thread and some follow
up messages:
http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/3615/focus=5247
The idea of the INTERFACE_LIBRARY is that it creates no output itself, but
it can have content in its INTERFACE_* properties. That makes it suitable
for defining header-only libraries for example like in boost.
My implementation of it is in the INTERFACE_LIBRARY-target-type branch in my
clone.
Other potential uses for it would be for an umbrella-target. In KDE
frameworks the libkdecore.so library will no longer be present, but it will
have been split into several smaller libraries. The kdecore target is
install(EXPORT)ed as KDE4__kdecore. That target name is rarely used because
the KDE4_KDECORE_LIBS variable is used instead. So, we will be able to
populate that variable or a similar one with the smaller libraries for
compatibility. In the future as imported targets are used more, it might
make sense to introduce compatibility libraries like that, and the
INTERFACE_LIBRARY would be a candidate for implementing that. However, in
that case, the order of libraries resulting from
tll(foo directdep1 iface directdep2)
might have an effect. Maybe we could also introduce an ALIAS_LIBRARY or so
which would be expanded in-place?
Another potential use-case for INTERFACE_LIBRARY/alias is a non-deprecated
way of aliasing a target. Currently that can be done like this by relying on
export() being executed at configure-time:
export(TARGETS foo NAMESPACE BuiltIn:: FILE fooTarget.cmake)
include(fooTarget.cmake)
# Use BuiltIn::foo
The new/alternative use would look something like:
add_library(BuiltIn::foo INTERFACE)
target_link_libraries(BuiltIn::foo INTERFACE_LINK_LIBRARIES foo)
# Use BuiltIn::foo
Another use-case (which again is mostly about aliasing) is being able to
build example code as part of the same build-system or using an external
package. For example, the QtWidgets examples can be built as part of the Qt
build, or not by specifying -nomake examples. Any example can also be built
using an installed Qt.
For a cmake project, a buildsystem for an example application could look
like this:
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
find_package(KArchive NO_MODULE REQUIRED)
endif()
add_executable(bzip_example main.cpp)
target_link_libraries(bzip_example KF5::KArchive)
The problem is that in the case of the example being in the same build-
system as the KArchive target itself, KF5::KArchive has no meaning. The two
solutions to that are
1. The Aliasing above
2. Create a KArchive_LIBRARIES variable and use that in the example
The KArchive_LIBRARIES would be defined as KArchive in the KArchive
buildsystem and KF5::KArchive in the KArchiveConfig.cmake.
I generally would prefer to not require variables like that (I would like to
move towards the direct result of install(EXPORT) being a usable and
conventional Config file), and I think the kind of aliasing allowed by the
INTERFACE_LIBRARY makes that possible.
add_library(KArchive ...)
add_library(KF5::KArchive INTERFACE)
target_link_libraries(KF5::KArchive INTERFACE_LINK_LIBRARIES KArchive)
So, the question is, should we design the INTERFACE_LIBRARY type to be
suitable for all of these use-cases? Header-only libraries, aliasing of
single targets, and encapsulating multiple targets (while resulting in a
somewhat funny, or expected depending how you think of it, link order)?
Thanks,
Steve.
More information about the cmake-developers
mailing list