Bad rpath/LD_LIBRARY_PATH settings in kdelibs build scripts?
Alexander Neundorf
neundorf at kde.org
Mon Jun 3 21:51:07 UTC 2013
On Tuesday 21 May 2013, Alex Merry wrote:
> I'm getting issues with building kdelibs-frameworks where I have either
> kdelibs4 installed in /usr or a sufficiently old version of
> kdelibs-frameworks installed somewhere referenced by LD_LIBRARY_PATH.
>
> The issue seems to be that executables built and used in the build
> process (like meinproc, but also tests when running "make test") find
> the installed version of various libraries (like libki18n) rather than
> the just-built versions. The actual error messages I get are from the
> loader about unresolved symbols, like
> /home/kf5-devel/build/kdelibs-frameworks/bin/meinproc4: symbol lookup
> error: ./bin/meinproc4: undefined symbol:
> _ZN18QCommandLineOptionC1ERK11QStringListRK7QStringS5_bS2_
>
> I'm not entirely sure how this stuff is *supposed* to be handled by the
> buildsystem; with kdelibs4 it always just worked.
>
> I guess it may be partly a result of things being
> split-up-but-not-really in the current repo, so we have semi-independent
> build systems that are all run together.
>
> I know that the following makes the build work:
> LD_LIBRARY_PATH=$HOME/build/kdelibs-frameworks/lib:$HOME/build/kdelibs-fram
> eworks/staging/ki18n/src:$HOME/build/kdelibs-frameworks/libkdeqt5staging/sr
> c:$LD_LIBRARY_PATH make
>
> Anyone any ideas? Is there an easy way to fix this, or is this just
> something we'll have to put up with until the repo split?
It works for me.
The mechanism is like this:
toplevel CMakeLists.txt does
find_package(KF5 REQUIRED MODULE COMPONENTS CMake Compiler InstallDirs)
The "CMake" component of FindKF5.cmake (from extra-cmake-modules/find-
modules/) loads the file KDECMakeSettings.cmake (from extra-cmake-modules/kde-
modules/).
This sets among other the RPATH related settings (except if disabled):
if(NOT KDE_SKIP_RPATH_SETTINGS)
...
set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
endif ()
endif (UNIX)
endif()
So this should give the full RPATH in the build tree, so it should always
work.
The "Compiler" component loads the file KDECompilerSettings.cmake (also from
extra-cmake-modules/kde-modules/).
This one sets a whole bunch of compiler-, linker- and operating system
specific flags, among others:
if (CMAKE_SYSTEM_NAME MATCHES Linux OR CMAKE_SYSTEM_NAME STREQUAL GNU)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--enable-new-dtags
-Wl,--fatal-warnings -Wl,--no-undefined -lc ${CMAKE_SHARED_LINKER_FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS "-Wl,--enable-new-dtags
-Wl,--fatal-warnings -Wl,--no-undefined -lc ${CMAKE_MODULE_LINKER_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--enable-new-dtags
${CMAKE_EXE_LINKER_FLAGS}")
endif()
...
endif (CMAKE_SYSTEM_NAME MATCHES Linux OR CMAKE_SYSTEM_NAME STREQUAL GNU)
So here we add --enable-new-dtags to the linker command line.
Later on, the toplevel CMakeLists.txt does
include(FindKDE4Internal)
In kdelibs 4, this file was the place where the compiler and linker flags were
set, but this is not the case anymore, this is, as described above, now being
done in KDECMakeSettings.cmake and KDECompilerSettings.cmake.
Can you please post the full command line when meinproc4 is being linked ?
Can you please also post what the RPATH and RUNPATH entries of meinproc4 look
like, e.g. using readelf -a bin/meinproc4 | grep PATH ?
We are using --enable-new-dtags, and so get RUNPATH entries in the ELF
executables. If your LD_LIBRARY_PATH is pointing to a directory which contains
e.g. an older libkdeqt5staging.so, that older one will be prefered over the
one in the directory pointed to by RUNPATH.
Without that flag, RPATH would be in the executable, and the RPATH entry would
be prefered over whatever you have in LD_LIBRARY_PATH.
--enable-new-dtags was added December 2007:
http://quickgit.kde.org/?p=kdelibs.git&a=commit&h=ad58627f978acdb9a0596090d06a1cdefc3ec137
following this discussion: http://lists.kde.org/?t=119679248000007&r=1&w=2
From that discussion, the argument that relinking takes a long time does not
apply anymore, since a few years (cmake 2.6.0 maybe ?) cmake does not need to
relink anymore, but patches the RUNPATH/RPATH inside the executables itself.
IMO, inside a buildtree RPATH is just fine, I don't see why I would want to
have RUNPATH there.
Distros, at least Debian, IIRC build completely without RPATH/RUNPATH anyway,
so this doesn't matter here.
For which cases do we actually need RPATH/RUNPATH, is this basically only for
developers ?
We could also decide based on the build type whether to use --new-dtags or
not, e.g. RPATH in a debug build, and RUNPATH in a release build.
Comments ?
Alex
More information about the Kde-frameworks-devel
mailing list