patchelf: Usage, Options & Common CI Errors
patchelf rewrites a prebuilt binary’s RPATH and dynamic loader without relinking.
patchelf fixes binaries you cannot recompile - setting the RPATH so bundled .so files resolve, or repointing the interpreter so a binary runs on a different libc. It is the backbone of relocatable packaging (AppImage, manylinux wheels).
What it does
patchelf modifies the dynamic linking metadata of an existing ELF executable or shared library: the RPATH/RUNPATH search paths, the ELF interpreter (dynamic loader) path, and the SONAME. It avoids a full relink, which is essential when you only have a prebuilt binary.
Common usage
patchelf --print-rpath app
patchelf --set-rpath '$ORIGIN/lib' app # look beside the binary
patchelf --set-interpreter /lib64/ld-linux-x86-64.so.2 app
patchelf --remove-rpath app
patchelf --replace-needed libold.so libnew.so appOptions
| Flag | What it does |
|---|---|
| --set-rpath <paths> | Replace the RPATH/RUNPATH |
| --print-rpath | Show the current RPATH |
| --set-interpreter <path> | Change the dynamic loader |
| --set-soname <name> | Set a shared library SONAME |
| --replace-needed old new | Swap a DT_NEEDED entry |
Common errors in CI
Quote $ORIGIN as '$ORIGIN/lib' so the shell does not expand it to empty - a classic mistake that bakes an empty rpath and reintroduces "cannot open shared object file". "patchelf: cannot find section .interp" means the file is static or not a dynamic executable. On very old patchelf, growing the RPATH could corrupt the binary; pin a recent version. Verify the result with readelf -d after patching.