Howto fix KDE4 Buildsystem with CMake CVS
Brad King
brad.king at kitware.com
Mon Jan 28 14:58:17 CET 2008
Andreas Pakulat wrote:
> CMake CVS changed some behaviour in how it treats
> target_link_directories. Specifically it now doesn't -L switches to the
> linker call unless one explicitly calls link_directories() and sets the
> needed paths.
I'll elaborate on this point. CMake's link line generation uses a new
approach to implement proper linking in more cases. Consider these
libraries:
/path/to/libfoo.a
/path/to/libfoo.so
Previously if someone wrote
target_link_libraries(myexe /path/to/libfoo.a)
CMake would generate this code to link it:
... -L/path/to -Wl,-Bstatic -lfoo -Wl,-Bdynamic ...
This worked most of the time, but some platforms (such as OS X) do not
support the -Bstatic or equivalent flag. This made it impossible to
link to the static version of a library without creating a symlink in
another directory and using that one instead.
Now CMake will generate this code:
... /path/to/libfoo.a ...
This guarantees that the correct library is chosen.
There is a side-effect of this fix. Projects used to be able to write
this (wrong) code and it would work by accident:
add_executable(myexe myexe.c)
target_link_libraries(myexe /path/to/libA.so -lB)
where "-lB" is meant to link "/path/to/libB.so". This code is incorrect
because it asks CMake to link to B but does not provide the proper
linker search path for it. It used to work by accident because the
-L/path/to would get added as part of the implementation of linking to
A. The correct code would be
link_directories(/path/to)
add_executable(myexe myexe.c)
target_link_libraries(myexe /path/to/libA.so -lB)
or even better
add_executable(myexe myexe.c)
target_link_libraries(myexe /path/to/libA.so /path/to/libB.so)
In order to support projects that have this bug, we've added a
compatibility feature that adds the "-L/path/to" paths for all libraries
linked with full paths even though the linker will not need those paths
to find the main libraries. The compatibility mode is enabled when a
link line contains a non-full-path library (like B or -lB) and either
CMAKE_BACKWARDS_COMPATIBILITY is set to 2.4 or lower or
CMAKE_LINK_OLD_PATHS is set to true.
> This breaks building any module in KDE4 (except kdelibs) because we get
> some libraries with absolute path in the KDE_XXX_LIBS variables. Easiest
> way to reproduce is building kdelibs + kdepimlibs with cmake cvs. It
> will error out on linking kresources, because it doesn't find -lsolid.
> The linker line doesn't contain any -L switches, but some libraries like
> QtCore, kdecore and other are referenced with absolute paths which
> works.
This is correct. The -lsolid is an example of the problem I describe above.
> a) introduce KDE_XXX_LIBRARY_DIR (or KDE_LIBRARY_DIR) and add
> link_directories calls for kde libdir and qt libdir in all
> CMakeLists.txt all over trunk/.
>
> pro: clean solution
> con: takes quite some time and effort
In other projects we've used this approach.
find_package(XXX REQUIRED)
include_directories(${XXX_INCLUDE_DIRS})
link_directories(${XXX_LIBRARY_DIRS})
KDE is already using it for include directories:
include_directories( ${KDE4_KDEUI_INCLUDES} )
-Brad
More information about the Kde-buildsystem
mailing list