RPATH support
This page documents support for RPATH across the board and support for expansion
of the $ORIGIN
token. The platforms are based on the one listed in CMake
(those for which a PLATFORM_ID
is defined).
General observations:
- Almost all platforms use
-Wl,-rpath,
. Exceptions are SunPro, SunOS (Solaris) and OSF/1 which use-R
or-Wl,-R
or-rpath
. - Many platforms support multiple colon-separated paths for their linker.
- Some BSDs only expand
$ORIGIN
if-z origin
linker option is included. - According to NetBSD,
$ORIGIN
expansion was introduced in Solaris 10. - GNU libc (glibc) started supporting
$ORIGIN
in RPATH since 1998-08-27, commit f787edde1dcd0f35feff9c8fd6384bd564558180 - binutils gained the
-z origin
option since 2000-07-19, commit e0ee487bb566f047bbc43dee18e81bab14cba096
Information sources:
- CMake platform modules.
- Git history of projects.
Contents:
What is RPATH?
When an executable or library dynamically loads another library, the runtime
linker will search through a list of paths. One of the paths that are queried is
the RPATH
property. For ELF binaries, this is either the DT_RPATH
or the
newer DT_RUNPATH
property. (Some linkers used to lack support for the latter.)
When the RPATH property contains $ORIGIN
, the linker will substitute that
token by the directory containing the referring executable or library. Example:
/build/curl
depends onlibcurl.so.4
withRPATH=$ORIGIN/libs
./build/libs/libcurl.so.4
depends onlibz.so.1
withRPATH=$ORIGIN/../syslibs
.- The loader for
/build/curl
will try to load/build/libs/libcurl.so.4
. - The loader for
/build/libs/libcurl.so.4
will try to load/build/libs/../syslibs/libz.so.1
. If not found, it tries the RPATH of the main executable:/build/libs/libz.so.1
.
With the GNU libc dynamic linker, set the environment variable LD_DEBUG=libs
in order to see the paths that are being queried. Consult the Linux
ld.so(8) manual for further
details.
Platforms
The names below are often based on the PLATFORM_ID
identifiers from CMake.
Unless stated otherwise, if RPATHs and $ORIGIN
expansion are supported, no
additional linker option (like -z origin
) is necessary.
Unless stated otherwise, the linker accepts multiple colon-separated paths (e.g.
-Wl,-rpath,/libs:/libs2
).
Linux
Supports $ORIGIN
(GNU libc).
Android has a different userspace and its linker (Bionic linker) does not support RPATH.
musl-libc supports $ORIGIN
expansion since v0.9.13 (2013-08-23,
https://git.musl-libc.org/cgit/musl/commit/?id=a897a20a57b461d388447858b9404fc81f107bcd).
Darwin (Apple macOS)
Does not use ELF as binary format, but Mach-O.
Does not support $ORIGIN
, but has @loader_path
which appears to be similar.
While the ELF format has a single DT_RPATH
or DT_RUNPATH
field with
colon-separated paths, macOS is different. The -rpath
linker option accepts a
single path which is added as a “LC_RPATH load command” to a Mach-O binary.
Each path can start with a token that is substituted by dyld:
@executable_path/
: path containing the main executable for the process.@loader_path/
: directory containing the referring binary. Since Mac OS X 10.4.@rpath/
: expanded by substitution with each path in the “run path list”. This list is populated based on the LC_RPATH load commands in the dependency chain. Since Mac OS X 10.5
See also man dyld(1), section DYNAMIC LIBRARY LOADING and https://wincent.com/wiki/@executable_path,_@load_path_and_@rpath
SunOS (Solaris)
Supports $ORIGIN
since Solaris 7.
Source for the $ORIGIN
support claim:
https://docs.oracle.com/cd/E19455-01/805-6331/6j5vgg69j/index.html
The original SunOS was discontinued in 1994, Solaris continues to be the new name. CMake internally refers to SunOS for both the original and the new platform.
NetBSD
Supports $ORIGIN
.
2001-05-18: Support Solaris-like $ORIGIN etc. expansions in paths. https://github.com/NetBSD/src/commit/37c782c48280f61ef3be93ad04956648d6cda166
FreeBSD
Supports $ORIGIN
, no longer requires -z origin
since 10.2-RELEASE.
2015-04-27 (10.2-RELEASE): Change interpretation of the DF_ORIGIN and DF_1_ORIGIN flags. https://github.com/freebsd/freebsd/commit/786bb3891ba8d170598e34d1e54467e31cb5014d
2009-03-18: Implement the dynamic string token substitution in the rpath and soneeded pathes. https://github.com/freebsd/freebsd/commit/46713086a1c3b7565c0b42b823b0d6d209228ce6
OpenBSD
Supports $ORIGIN
, but requires -z origin
(even in its current version from 2018-10-01).
OpenBSD was forked from NetBSD in 1995.
CMake inherits the NetBSD config which also declares $ORIGIN
support.
2013-04-05: Add ORIGIN, OSNAME, OSREL and PLATFORM substitution support for rpaths. https://github.com/openbsd/src/commit/337bd349eb33d0246bac63f39f4679daba26f895
DragonFly BSD
Supports $ORIGIN
, but requires -z origin
(even in its current version from 2018-10-01).
DragonFly BSD was forked from FreeBSD in 2003.
CMake inherits the FreeBSD config which also declares $ORIGIN
support, but has
no dedicated PLATFORM_ID
identifier and seems to rely on FreeBSD instead.
The current version still checks for -z origin
support before substitution:
https://github.com/DragonFlyBSD/DragonFlyBSD/blob/347aefc6a85af5bf5b7a1a6918f706878a8232ef/libexec/rtld-elf/rtld.c#L1275
Windows
Not using ELF, no RPATH support.
AIX
Might not support RPATHs (based on CMake’s platform module), but the ld
documentation suggests that the -R
linker option can be used to define a
colon-separated list of directories. This -R
option is ignored unless the
-bsvr4
option is given.
This information can be found for AIX 5.3 up to at least AIX 7.2: https://public.dhe.ibm.com/systems/power/docs/aix/53/aixcmds3.pdf https://www.ibm.com/support/knowledgecenter/ssw_aix_72/com.ibm.aix.cmds3/ld.htm
HP-UX
Might not support $ORIGIN
although RPATHs are supported (depending on the
linker settings).
Uses -Wl,+b
instead of -Wl,-rpath
.
Supporting references for support in HP-UX 11i: Signs that RPATHs are supported, found in the dld.so manual page for HP-UX 11i: https://nixdoc.net/man-pages/HP-UX/man5/dld.so.5.html (Itanium) https://nixdoc.net/man-pages/HP-UX/man5/dld.sl.5.html (PA-RISC). https://administratosphere.wordpress.com/2007/10/19/shared-libraries-hp-ux/
QNX
Might not support RPATHs (based on CMake’s platform module),
but a news group post “rpath usage” from 2003 mentions GCC, GNU LD, DT_RPATH and
-Wl,-rpath
with multiple colon-separated paths:
https://www.openqnx.com/newsgroups/viewtopic.php?t=16751
Haiku
Supports $ORIGIN
.
2013-11-26: runtime loader: Add support for $ORIGIN in rpath https://github.com/haiku/haiku/commit/8d23c440f7b0433f0daccf7e4018f99b8d3c3459
2005-03-12: Refactored open_container(). We now also support DT_RPATH https://github.com/haiku/haiku/commit/2d890ffaa22db3e09cfe138b75218adcd1dfdf3a
RISC OS
Probably does not support RPATHs (based on CMake’s platform module).
Checking the source tarball for “RPATH” and “ld” does not suggest availability of RPATH support either. Checked src-bcm2835-dev.5.25.tar.bz2 (2018-10-05 01:36:55) from https://www.riscosopen.org/content/downloads/risc-os-tarballs
Historic platforms
These platforms used to be supported by CMake, but are no longer supported.
IRIX
Might support RPATHs (based on CMake’s platform module). Retired since 2013-12 according to https://en.wikipedia.org/wiki/IRIX
OSF/1 (Digital Unix)
Supports RPATHs (based on CMake’s platform module). Retired since 2012-12 according to https://en.wikipedia.org/wiki/Tru64_UNIX
SINIX
Probably does not support RPATHs (based on CMake’s platform module). Discontinued based on https://en.wikipedia.org/wiki/SINIX
BeOS
Supports RPATHs (based on CMake’s platform module). Discontinued based on https://en.wikipedia.org/wiki/BeOS, reportedly succeeded by the opensource Haiku.
Xenix (SCO XENIX)
Probably does not support RPATHs (based on CMake’s platform module). Discontinued based on https://en.wikipedia.org/wiki/Xenix
ULTRIX
Probably does not support RPATHs (based on CMake’s platform module). Discontinued based on https://en.wikipedia.org/wiki/Ultrix
BSD/OS
Probably does not support RPATHs (based on CMake’s platform module). Discontinued based on https://en.wikipedia.org/wiki/BSD/OS
MP RAS
Probably does not support RPATHs (based on CMake’s platform module). NCR UNIX SVR4 MP-RAS according to https://www.albion.com/security/intro-3.html Likely a dead platform.
UNIX SV
Probably does not support RPATHs (based on CMake’s platform module). SCO UnixWare (pre release 7) according to CMake.
SCO SV
Probably does not support RPATHs (based on CMake’s platform module). SCO OpenServer Release 5 Operating System, probably no longer supported. OpenServer 10 is based on FreeBSD which probably does not define SCO_SV.
Tru64
Probably does not support RPATHs (based on CMake’s platform module). Retired since 2012-12 according to https://en.wikipedia.org/wiki/Tru64_UNIX