Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

correct usage of rpath (relative vs absolute)

Tags:

gcc

linker

rpath

When building a binary or library, specifying the rpath, i.e.

-Wl,rpath,<path/to/lib>

tells the linker where to find the required library at runtime of the binary.

What is the UNIX philosphy regarding absolute and relative paths here? Is it better to use an absolute path so the lib can be found from everywhere? Or is it better to make it relative so copying an entire directory or renaming a higher level path won't render the binary unusable?

Update

Using $ORIGIN is usually the preferred way of building binaries. For libraries I like to put in the absolute path, because otherwise you won't be able to link to the library. A symbolic link will change the $ORIGIN to point to the path of the link and not of the link target.

like image 389
mattmilten Avatar asked Jun 27 '16 15:06

mattmilten


People also ask

Should I use absolute or relative path?

Relative links show the path to the file or refer to the file itself. A relative URL is useful within a site to transfer a user from point to point within the same domain. Absolute links are good when you want to send the user to a page that is outside of your server.

Can RPATH be relative?

The RPATH entries for directories contained within the build tree can be made relative to enable relocatable builds and to help achieve reproducible builds by omitting the build directory from the build environment.

How do you use absolute and relative paths?

An absolute path is defined as specifying the location of a file or directory from the root directory(/). In other words,we can say that an absolute path is a complete path from start of actual file system from / directory. Relative path is defined as the path related to the present working directly(pwd).

What is the differences between absolute and relative pathnames?

In simple words, an absolute path refers to the same location in a file system relative to the root directory, whereas a relative path points to a specific location in a file system relative to the current directory you are working on.


3 Answers

In the case of rpath, it makes no sense to use a relative path, since a relative path will be relative to the current working directory, NOT relative to the directory where the binary/library was found. So it simply won't work for executables found in $PATH or libraries in pretty much any case.

Instead, you can use the $ORIGIN "special" path to have a path relative to the executable with
-Wl,-rpath,'$ORIGIN' -- note that you need quotes around it to avoid having the shell interpret it as a variable, and if you try to do this in a Makefile, you need $$ to avoid having make interpret the $ as well.

like image 64
Chris Dodd Avatar answered Oct 21 '22 12:10

Chris Dodd


What is the UNIX philosphy regarding absolute and relative paths here?

Using relative path makes an executable that only works when invoked from a particular directory, which is almost never what you want. E.g. if the executable is in /app/foo/bin/exe and has DT_RUNPATH of lib/, and a dependent library is in /app/foo/lib/libfoo.so, then the exe would only run when invoked from /app/foo, and not when invoked from any other directory.

Using absolute path is much better: you can do cd /tmp; /app/foo/bin/exe and have the executable still work. This is still however less than ideal: you can't easily have multiple versions of the binary (important during development), and you dictate to end-users where they must install the package.

On systems that support $ORIGIN, using DT_RUNPATH of $ORIGIN/../lib would give you an executable what works when installed anywhere and invoked from any directory, so long as relative paths to bin/ and lib/ are preserved.

like image 36
Employed Russian Avatar answered Oct 21 '22 12:10

Employed Russian


From The Linux Programming Interface:

Using $ORIGIN in rpath

Suppose that we want to distribute an application that uses some of its own shared libraries, but we don’t want to require the user to install the libraries in one of the standard directories. Instead, we would like to allow the user to unpack the application under an arbitrary directory of their choice and then immediately be able to run the application. The problem is that the application has no way of determining where its shared libraries are located, unless it requests the user to set LD_LIBRARY_PATH or we require the user to run some sort of installation script that identifies the required directories. Neither of these approaches is desirable. To get around this problem, the dynamic linker is built to understand a special string, $ORIGIN (or, equivalently, ${ORIGIN}), in an rpath specification. The dynamic linker interprets this string to mean “the directory containing the application.” This means that we can, for example, build an application with the following command:

$ gcc -Wl,-rpath,'$ORIGIN'/lib ...

This presumes that at run time the application’s shared libraries will reside in the subdirectory lib under the directory that contains the application executable. We can then provide the user with a simple installation package that contains the application and associated libraries, and the user can install the package in any location and then run the application (i.e., a so-called “turn-key application”).

like image 44
Rick Avatar answered Oct 21 '22 14:10

Rick