Home > Software engineering >  How to set `rpath` with gcc?
How to set `rpath` with gcc?

Time:11-03

I have an executable that uses some shared objects.
These shared objects have other shared objects as dependencies, and I want to set my main executable's rpath to include the directories for those dependencies, since runpath is not used for indirect dependencies.

I'm trying to bake rpath into my ELF, however when using this:
gcc -std=c 20 -o main main.cpp -lstdc -L./lib -Wl,-rpath,./lib

The result is that ./lib is set in the ELF as RUNPATH and not RPATH:

  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libstdc  .so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000001d (RUNPATH)            Library runpath: [./lib]
 0x000000000000000c (INIT)               0x1000
 ...

Can someone explain why this happens? I was expecting ./lib to be defined in the RPATH section and not RUNPATH. Seems like RPATH section does not exist at all.

I am using gcc version 11.1.0, with ld version 2.34.

I know this might not be the best solution for managing indirect dependencies and I'd be happy to hear a better one, however I still wonder why -Wl,-rpath,./lib results in RUNPATH defined in the ELF, and not RPATH.

CodePudding user response:

To get a DT_RUNPATH entry you need --enable-new-dtags.

To get a DT_RPATH entry (which is deprecated) you need --disable-new-dtags.

In your case, something like this:

gcc -std=c  20 -o main main.cpp -lstdc   -L./lib -Wl,--disable-new-dtags,-rpath,./lib 

I'll suggest to use an absolute path with rpath, I'm not sure from which directory relative paths are interpreted. There is also $ORIGIN if you want to use the executable as reference point.

See https://man7.org/linux/man-pages/man1/ld.1.html and https://man7.org/linux/man-pages/man8/ld.so.8.html for more informations.

  • Related