CMake RPATH handling: Difference between revisions

From KitwarePublic
Jump to navigationJump to search
(Replace content with link to new CMake community wiki)
 
(26 intermediate revisions by 8 users not shown)
Line 1: Line 1:
CMake gives the user complete control over the RPATH of executables and libraries created using CMake.
{{CMake/Template/Moved}}


==What is RPATH ?==
This page has moved [https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/RPATH-handling here].
 
If an executable ''foo'' links to the shared library ''bar'', the library ''bar'' has to be found and loaded when the executable foo is executed. This is the job of the linker, under Linux this is usually ld.so.
The linker searches a set of directories for the library bar, which will under most UNIXes have the name "libbar.so".
The linker will search the libraries in the following directories in the given order:
 
* RPATH - a list of directories which is linked into the executable, supported on most UNIX systems
* LD_LIBRARY_PATH - an environment variable which holds a list of directories
* RUNPATH - same as RPATH, but searched ''after'' LD_LIBRARY_PATH, supported only on some newer UNIX systems, e.g. on most current Linux systems
* /etc/ld.so.conf - configuration file for ld.so which lists additional library directories
* builtin directories - basically /lib and /usr/lib
 
There are different reasons why search directories additonal to the builtin ones can be needed - a user may install a library privately into his home directory, e.g. ~/lib/, or there may be two or more versions of the same library installed, e.g. /opt/kde3/lib/libkdecore.so and /opt/kde4/lib/libkdecore.so.
 
For the first case it would work if the user would set LD_LIBRARY_PATH accordingly:
<pre>
export LD_LIBRARY_PATH=$HOME/lib:$LD_LIBRARY_PATH
</pre>
 
This will break for the second case, where for some programs /opt/kde3/lib has to be searched and for other applications /opt/kde4/lib has to be searched, but in no case both. The only way to have an executable-dependent library search path is by using RPATH (or RUNPATH, but this isn't supported everywhere).
 
==CMake and the RPATH==
 
With CMake the developer has full control over the RPATH of his executables and shared libraries. This is controlled over various target properties, see the documentation of SET_TARGET_PROPERTIES(). These properties are initialized from a set of global CMake variables with the respective name.
There is not something like the one "correct" RPATH set up, it depends on the wishes of the developer or distribution policies.
 
Different RPATH settings may be required when running a program from the build tree and when running it from its install location. If the program links to shared libraries which have been also built in the same project, then the RPATH needs to point to the directories in the build tree when running the executable from the build tree, and it must not point to the build tree anymore once the executable has been installed. Unfortunately there is no easy and fast way to change the RPATH of an executable or shared library, so to change the RPATH CMake links the executable again with the new RPATH.
 
If you want the same RPATH settings for executables and shared libraries in your source tree, all you have to do is to set the CMake variables CMAKE_INSTALL_RPATH, CMAKE_SKIP_BUILD_RPATH, CMAKE_BUILD_WITH_INSTALL_RPATH, CMAKE_INSTALL_RPATH_USE_LINK_PATH once, e.g. in the top level CMakeLists.txt.
 
===Default RPATH settings===
 
By default if you don't change any RPATH related settings, CMake will link the executables and shared libraries with full RPATH to all used libraries in the build tree. When installing, it will link all these targets again so they are installed with an empty RPATH.
This is equivalent to:
<pre>
# use, i.e. don't skip the full RPATH for the build tree
SET(CMAKE_SKIP_BUILD_RPATH  FALSE)
 
# when building, don't use the install RPATH already
# (but later on when installing)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
 
# the RPATH to be used when installing
SET(CMAKE_INSTALL_RPATH "")
 
# don't add the automatically determined parts of the RPATH
# which point to directories outside the build tree to the install RPATH
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
</pre>
 
With these settings you are able to run the programs directly from the build tree. Once installed, you have to ensure that they find the required shared libraries (e.g. by setting LD_LIBRARY_PATH, or by installing  shared libraries into one of the default library directories).
 
 
===Always full RPATH===
 
In many cases you will want to make sure that the required libraries are always found independent from LD_LIBRARY_PATH and the install location.
Then you can use these settings:
 
 
<pre>
# use, i.e. don't skip the full RPATH for the build tree
SET(CMAKE_SKIP_BUILD_RPATH  FALSE)
 
# when building, don't use the install RPATH already
# (but later on when installing)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
 
# the RPATH to be used when installing
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
 
# add the automatically determined parts of the RPATH
# which point to directories outside the build tree to the install RPATH
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
</pre>
 
With these settings you will be able to execute your programs from the build tree and they will find the shared libraries in the build tree and also the shared libraries outside your project, when installing all executables and shared libraries will be relinked, so they will find all libraries they need.

Latest revision as of 15:41, 30 April 2018


The CMake community Wiki has moved to the Kitware GitLab Instance.

This page has moved here.