cmake news: RPATH

Brad King brad.king at kitware.com
Thu Mar 23 01:21:39 CET 2006


David Faure wrote:
> On Thursday 16 March 2006 22:30, Alexander Neundorf wrote:
>>"none" - don't use RPATH at all
>>When installed, the libs have to be in the system library path 
>>(ld.so.conf/LD_LIBRARY_PATH)
>>To run the executables during the build, simple wrapper shell scripts are 
>>created which set (DY)LD_LIBRARY_PATH accordingly.

This is a good option to support platforms that discourage RPATHs.

>>"install" - (not on OS X)
>>Compile with RPATH set to the installation directory, the kde library 
>>directory and the Qt library directory.
>>To run the executables during the build, simple wrapper shell scripts are 
>>created which set (DY)LD_LIBRARY_PATH accordingly.
> 
> (strange, why does this option say "not on OSX", but then mention DYLD_LIBRARY_PATH
> which is the OSX one?)

On OSX there is no RPATH but the install_name field of the libraries can 
point to their location.  Without a search path the location of Qt 
cannot be included, but as mentioned in

  http://mail.kde.org/pipermail/kde-buildsystem/2006-February/000973.html

that is not a problem.  The problem is for executables that need to run 
during the build and the shared libraries they use.  The shared 
libraries must be found at build time.  On OSX compiling with an 
install_name pointing at the install tree location will cause the 
library to not be found or an old already-installed version used when 
running executables in the build tree.

Since OSX has the install_name_tool and can quickly transform 
executables and libraries from build-tree to install-tree during 
installation the "install" option is not particularly helpful.  I 
suggest the RPATH option just not be provided on OSX in favor of letting 
CMake's default behavior take care of things.

>>"both" - (not on OS X)
>>Compile with RPATH set to the build directory, the installation directory, the 
>>kde library directory and the Qt library directory.
>>Executables can simply be run during the build. If both libs, the installed 
>>and the not-yet-installed ones are available, the not-yet-installed ones are 
>>prefered. This is probably mostly useful for developers.

I really don't like this option.  The whole reason I added all this 
fancy RPATH support to CMake was to avoid installing binaries that have 
an RPATH pointing to the build tree.  It is "unclean" and can produce 
unexpected and surprising behavior.

>>"default" or everything else:
>>Compile with RPATH set to the builddir, link again when installing and set  
>>RPATH to the install dir, the kde lib dir and the Qt lib dir.
> 
> It should be noted that since this triggers a relink during make install,
> it screws everything up for people compiling as user and doing make install
> as root.

FYI, I anticipated this dilemma and provided a "preinstall" target that 
can be built by the user to do the relinking before changing to root:

make && make preinstall && sudo make install

As described below, relinking should only be needed for developers that 
want to run applications from the build tree but still install from the 
same tree.

> Why is the default, the slow option, anyway?
> Shouldn't the default be "install", which seems to be the sensible one to me?
> (OK running e.g. kconfig_compiler is a tad slower but it's the option that generates
> correct binaries for users and packagers, and doesn't relink during install).
> 
> Then of course the "default" option must be renamed to something else, like "builddir".

The nice thing about RPATH and RUNPATH is that they can be configured 
differently for different executables using the same shared library. 
(On platforms supporting -Wl,--enable-new-dtags we should add the option 
to the linker flags, possibly using the LINK_FLAGS target property, to 
convert RPATH to RUNPATH.)  Having one global RPATH option may not be 
the right approach.  There are three kinds of executables in kdelibs 
that should be considered separately:

1.) Executables that are not run during the build but are installed.
2.) Executables that are run during the build and not installed.
3.) Executables that are run during the build and are installed.

-------------------------------------------------------------------------
For #1 there is a choice for developers and a choice for users.  Setting 
the target property BUILD_WITH_INSTALL_RPATH will cause the executables 
to get built with an RPATH meant for the install tree.  No relinking is 
needed for installation but the executables will not run from the build 
tree (except on RUNPATH platforms with LD_LIBRARY_PATH set properly). 
This is the choice for users and should be the default.

Developers on non-RUNPATH platforms (and those on RUNPATH platforms that 
do not feel like setting LD_LIBRARY_PATH) may prefer that 
BUILD_WITH_INSTALL_RPATH is not set.  In this case CMake will build the 
executables with the ability to run from the build tree.  This is useful 
for rapid application debugging because no install is required.  The 
cost is that relinking is needed if the developer also wants to install 
from the same tree.  In this case the developer should run "make 
preinstall" as his/her user before running "make install" as root.  If 
installing to a home directory then just "make install" is enough.

-------------------------------------------------------------------------
For #2 there is no problem.  There is no install rule for them.  No 
special options should be set, especially not the 
BUILD_WITH_INSTALL_RPATH target property.  CMake will build these 
executables with an RPATH pointing to the build tree library locations 
and they will be able to run during the build.  Since they are not 
installed there is no relinking.

-------------------------------------------------------------------------
For #3 there is potential trouble.  When running from the build tree we 
need to make sure the build tree libraries are used, and when running 
from the install tree we need to make sure the install tree libraries 
are used.

If BUILD_WITH_INSTALL_RPATH is set on a non-RUNPATH platform and there 
is an existing old install the wrong libraries will be used when running 
during the build.  Even on a RUNPATH platform the environment must have 
the proper LD_LIBRARY_PATH for the build tree.

If BUILD_WITH_INSTALL_RPATH is not set then relinking is required for 
installation even for users.  Everyone would have to do "make 
preinstall" as described above.

There are a few ways to resolve this problem:

   a.) Link these executables statically and build into them all the 
sources they need.  Then no RPATH is needed at all.  Since executables 
run during the build tend to be small generators this may not be too bad.
   b.) Do not set BUILD_WITH_INSTALL_RPATH, document it for users, and 
live with the relinking.  Since executables run during the build tend to 
be small generators relinking is not too slow.
   c.) Enable the SKIP_BUILD_RPATH target property and set the 
INSTALL_RPATH property to empty.  This will remove RPATHs completely 
from these executables.  Then wrap them in a shell script or a 
forwarding executable like that described for option 2 in

  http://mail.kde.org/pipermail/kde-buildsystem/2006-January/000445.html

   d.) Other suggestions?

Option (c) is a pain to setup the first time but will work very well if 
there are only a few such executables.

-------------------------------------------------------------------------

The decision for #3 may depend on the number, size, and role of such 
executables.  Can anyone respond and enumerate them please?

-Brad


More information about the Kde-buildsystem mailing list