Build binaries with absolute RPATH on Linux?

I’m trying to build Aravis on x86_64 AlmaLinux 9 (RHEL 9) and install it to /opt/aravis-0.8.34. The build succeeds, but the resulting installed binaries have the wrong RPATH. They have $ORIGIN/:/opt/pkg-2024Q4/lib (the /opt/pkg-2024Q4/lib entry is where libraries that Aravis needs are installed on this system, which is correct), but that’s wrong because $ORIGIN will be the pathname of the directory where the binary is (i.e., /opt/aravis-0.8.34/bin), not the pathname of the lib directory. So, to make that work with $ORIGIN, it would need to be $ORIGIN/../lib:/opt/pkg-2024Q4/lib. But also, I don’t want to use $ORIGIN, I want to use an absolute pathname in RPATH for that entry, so I want it to be /opt/aravis-0.8.34/lib:/opt/pkg-2024Q4/lib. How do I build Aravis so that the installed binaries have the RPATH that I want?

Here’s how I built it:

$ cd /opt/aravis-src-0.8.34
$ meson setup build --prefix=/opt/aravis-0.8.34 --libdir lib --buildtype=release --wrap-mode=nofallback
$ meson compile -C build
$ meson install -C build

Here’s output showing that the RPATH is wrong:

$ /opt/aravis-0.8.34/bin/arv-tool-0.8
/opt/aravis-0.8.34/bin/arv-tool-0.8: error while loading shared libraries: libaravis-0.8.so.0: cannot open shared object file: No such file or directory

$ ldd /opt/aravis-0.8.34/bin/arv-tool-0.8
        linux-vdso.so.1 (0x00007ffc0a777000)
        libaravis-0.8.so.0 => not found
        libglib-2.0.so.0 => /opt/pkg-2024Q4/lib/libglib-2.0.so.0 (0x00007f4a2b40f000)
        libgobject-2.0.so.0 => /opt/pkg-2024Q4/lib/libgobject-2.0.so.0 (0x00007f4a2b3ac000)
        libgio-2.0.so.0 => /opt/pkg-2024Q4/lib/libgio-2.0.so.0 (0x00007f4a2b1c0000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f4a2ae00000)
        libpcre2-8.so.0 => /opt/pkg-2024Q4/lib/libpcre2-8.so.0 (0x00007f4a2b15b000)
        libffi.so.8 => /opt/pkg-2024Q4/lib/libffi.so.8 (0x00007f4a2b14b000)
        libgmodule-2.0.so.0 => /opt/pkg-2024Q4/lib/libgmodule-2.0.so.0 (0x00007f4a2b144000)
        libz.so.1 => /opt/pkg-2024Q4/lib/libz.so.1 (0x00007f4a2b12a000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f4a2b561000)

$ readelf -d /opt/aravis-0.8.34/bin/arv-tool-0.8

Dynamic section at offset 0x7dc0 contains 29 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libaravis-0.8.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libglib-2.0.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libgobject-2.0.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libgio-2.0.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000f (RPATH)              Library rpath: [$ORIGIN/:/opt/pkg-2024Q4/lib]
 0x000000000000000c (INIT)               0x403000
 0x000000000000000d (FINI)               0x405298
 0x0000000000000019 (INIT_ARRAY)         0x408db0
 0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
 0x000000000000001a (FINI_ARRAY)         0x408db8
 0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x4003a0
 0x0000000000000005 (STRTAB)             0x400de8
 0x0000000000000006 (SYMTAB)             0x4003c8
 0x000000000000000a (STRSZ)              2636 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000015 (DEBUG)              0x0
 0x0000000000000003 (PLTGOT)             0x409000
 0x0000000000000002 (PLTRELSZ)           2448 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x4019b8
 0x0000000000000007 (RELA)               0x401940
 0x0000000000000008 (RELASZ)             120 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffe (VERNEED)            0x401910
 0x000000006fffffff (VERNEEDNUM)         1
 0x000000006ffffff0 (VERSYM)             0x401834
 0x0000000000000000 (NULL)               0x0

I can fix it by using patchelf to change RPATH to have an absolute path to the installed Aravis lib directory:

$ patchelf --set-rpath /opt/aravis-0.8.34/lib:/opt/pkg-2024Q4/lib /opt/aravis-0.8.34/bin/arv-tool-0.8

And now the RPATH is correct:

$ readelf -d /opt/aravis-0.8.34/bin/arv-tool-0.8

Dynamic section at offset 0x9dc0 contains 29 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libaravis-0.8.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libglib-2.0.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libgobject-2.0.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libgio-2.0.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000001d (RUNPATH)            Library runpath: [/opt/aravis-0.8.34/lib:/opt/pkg-2024Q4/lib]
 0x000000000000000c (INIT)               0x403000
 0x000000000000000d (FINI)               0x405298
 0x0000000000000019 (INIT_ARRAY)         0x408db0
 0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
 0x000000000000001a (FINI_ARRAY)         0x408db8
 0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x3fe410
 0x0000000000000005 (STRTAB)             0x3fee58
 0x0000000000000006 (SYMTAB)             0x3fe438
 0x000000000000000a (STRSZ)              2679 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000015 (DEBUG)              0x0
 0x0000000000000003 (PLTGOT)             0x409000
 0x0000000000000002 (PLTRELSZ)           2448 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x4019b8
 0x0000000000000007 (RELA)               0x401940
 0x0000000000000008 (RELASZ)             120 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffe (VERNEED)            0x401910
 0x000000006fffffff (VERNEEDNUM)         1
 0x000000006ffffff0 (VERSYM)             0x401834
 0x0000000000000000 (NULL)               0x0

And libaravis-0.8.so.0 can be found:

$ ldd /opt/aravis-0.8.34/bin/arv-tool-0.8
        linux-vdso.so.1 (0x00007fff2c986000)
        libaravis-0.8.so.0 => /opt/aravis-0.8.34/lib/libaravis-0.8.so.0 (0x00007f47a3055000)
        libglib-2.0.so.0 => /opt/pkg-2024Q4/lib/libglib-2.0.so.0 (0x00007f47a2f0c000)
        libgobject-2.0.so.0 => /opt/pkg-2024Q4/lib/libgobject-2.0.so.0 (0x00007f47a2ea9000)
        libgio-2.0.so.0 => /opt/pkg-2024Q4/lib/libgio-2.0.so.0 (0x00007f47a2cbd000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f47a2a00000)
        libxml2.so.2 => /opt/pkg-2024Q4/lib/libxml2.so.2 (0x00007f47a2897000)
        libz.so.1 => /opt/pkg-2024Q4/lib/libz.so.1 (0x00007f47a2c9a000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f47a27bc000)
        libusb-1.0.so.0 => /opt/pkg-2024Q4/lib/libusb-1.0.so.0 (0x00007f47a2c7b000)
        libpcre2-8.so.0 => /opt/pkg-2024Q4/lib/libpcre2-8.so.0 (0x00007f47a2c18000)
        libffi.so.8 => /opt/pkg-2024Q4/lib/libffi.so.8 (0x00007f47a27ac000)
        libgmodule-2.0.so.0 => /opt/pkg-2024Q4/lib/libgmodule-2.0.so.0 (0x00007f47a2c0f000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f47a30f3000)
        liblzma.so.5 => /opt/pkg-2024Q4/lib/liblzma.so.5 (0x00007f47a277b000)

And arv-tool-0.8 works:

$ /opt/aravis-0.8.34/bin/arv-tool-0.8 | awk '{print $1}'
FLIR-Blackfly
FLIR-Blackfly
FLIR-Blackfly
FLIR-Blackfly

Ping? It’s been ten days. Did I post to the right group, or should I have posted elsewhere? Thanks!

Thank you for detailed description of the issue. I think it is just that ppl mostly don’t know about this low-level stuff, that’s why you are not getting answers here.

Couldn’t you just use --prefix=/opt/pkg-2024Q4?

Apart from that, I think you could set LDFLAGS when running meson, so that it is passed to the linker by meson, instead of running patchelf. Please let me/us know if this was helpful by posting back, or if you found some other solution.