What's the difference between CMAKE_INSTALL_PREFIX and CMAKE_INSTALL_RPATH

On a system which supports paths of the form c:/ABC/DEF (i.e. Windows), none. Windows binaries don't have a notion of rpath.

On systems which do have DT_RPATH and DT_RUNPATH (= those which use ELF binaries), the CMake variable CMAKE_INSTALL_RPATH is used to set up the value of DT_RPATH (or DT_RUNPATH) tags which will be written into the binaries at installation.


This is explained at CMake RPATH handling.

On Unix systems, dynamic libraries are searched for in a system-defined list of directories. (/etc/ld.so.conf -- Windows does this in its own way that is so convoluted that it usually boils down to "just use PATH". ;-) )

If you install a library (like the one you just compiled) in a custom directory not in that list, it will not be found if you run a dependent executable. RPATH is one way to fix this.

See the Wiki page linked above for details.


Firstly, CMAKE_INSTALL_PREFIX determines a "root" for the installed location of headers, libraries, executables, and other resources.

On a system which does not support the notion of a "search hierachy" for dependencies, CMAKE_INSTALL_RPATH is not used. However, on ELF-based systems (e.g. Linux) and Mach-based systems (e.g. macOS 10.5 and later) a set of additional locations to search can be set in executables and dynamic libraries (e.g. .so/.dylib files); this is the "Rpath" and you can set it during cmake's install phase, either for all targets by setting CMAKE_INSTALL_RPATH or for individual targets by setting INSTALL_RPATH on that target.

Static libraries are not dynamic (obviously!) so, CMAKE_INSTALL_RPATH has no utility at all for static libraries.

When installing dynamic objects, CMake will write the Rpath into the dynamic object provided CMAKE_SKIP_RPATH and CMAKE_SKIP_INSTALL_RPATH are both false. By default, the Rpath written will be set to CMAKE_INSTALL_PREFIX followed by the library destination, e.g. CMAKE_INSTALL_PREFIX/lib. On Linux systems, this would by default see an Rpath of /usr/local/lib written as Rpath.

You can examine the Rpath on Linux thus:

readelf -d libmylib.so

which produces something like:

0x000000000000000f (RPATH)              Library rpath: [/usr/local/lib]

or on macOS:

otool -l libmylib.dylib | grep -A 2 LC_RPATH

which produces something like:

          cmd LC_RPATH
      cmdsize 40
         path @loader_path/../Frameworks (offset 12)

To override the install Rpath you can set the variable CMAKE_INSTALL_RPATH. E.g. on Linux:

set(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib")

or on macOS:

set(CMAKE_INSTALL_RPATH "@loader_path/../lib")

Tags:

Cmake