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