Trying to use autoPatchelf

I have some binaries compiled for a standard aarch64 Linux target. I wish to make these work on my NixOS machine. For the sake of a minimal reproducer, these are simple Haskell and Rust "hello world"s, which I’m calling hello-hs and hello-rs respectively. Both exhibit exactly the same issues, so I’ll mostly stick to the former.

I used to use (long ago, on another device), autoPatchelf, but this produces a rather odd output:

$ nix-shell -p autoPatchelfHook --run 'autoPatchelf hello-hs'
automatically fixing dependencies for ELF files
{'ignore_missing': [],
 'libs': [PosixPath('/nix/store/j831pkzchi8ah96x14dbc7lg4c299whq-patchelf-0.14.5/lib'),
          PosixPath('/nix/store/43v65lf5pwgh7mv2jgki6jgz563gi31x-hook/lib'),
          PosixPath('/nix/store/59jmzisg8fkm9c125fw384dqq1np602l-move-docs.sh/lib'),
          PosixPath('/nix/store/kxw6q8v6isaqjm702d71n2421cxamq68-make-symlinks-relative.sh/lib'),
          PosixPath('/nix/store/m54bmrhj6fqz8nds5zcj97w9s9bckc9v-compress-man-pages.sh/lib'),
          PosixPath('/nix/store/bkxq1nfi6grmww5756ynr1aph7w04lkk-strip.sh/lib'),
          PosixPath('/nix/store/bnj8d7mvbkg3vdb07yz74yhl3g107qq5-patch-shebangs.sh/lib'),
          PosixPath('/nix/store/cickvswrvann041nqxb0rxilc46svw1n-prune-libtool-files.sh/lib'),
          PosixPath('/nix/store/8zxndz5ag0p6s526c2xyllhk1nrn4c3i-audit-tmpdir.sh/lib'),
          PosixPath('/nix/store/c8n9kcdddp9np665xz6ri61b383nxvz8-move-systemd-user-units.sh/lib'),
          PosixPath('/nix/store/1i5y55x4b4m9qkx5dqbmr1r6bvrqbanw-multiple-outputs.sh/lib'),
          PosixPath('/nix/store/kd4xwxjpjxi71jkm6ka0np72if9rm3y0-move-sbin.sh/lib'),
          PosixPath('/nix/store/fyaryjvghbkpfnsyw97hb3lyb37s1pd6-move-lib64.sh/lib'),
          PosixPath('/nix/store/ngg1cv31c8c7bcm2n8ww4g06nq7s4zhm-set-source-date-epoch-to-latest.sh/lib'),
          PosixPath('/nix/store/wlwcf1nw2b21m4gghj70hbg1v7x53ld8-reproducible-builds.sh/lib'),
          PosixPath('/nix/store/4vxnh97l284ammy3qqlh1ylsjbwlmcc7-gcc-wrapper-9.3.0/lib'),
          PosixPath('/nix/store/vpgnynpbbkkqn309ll4psa851wb28vkh-binutils-wrapper-2.38/lib'),
          PosixPath('/nix/store/vg7i0q8zf9nk4qih979gk0pqs4bfs22b-auto-patchelf-hook/lib'),
          PosixPath('/nix/store/bivfm73cdnrkm5a7pqc7y1v271aq71m3-binutils-wrapper-2.38/lib')],
 'paths': [PosixPath('hello-hs')],
 'recursive': True,
 'runtime_dependencies': []}
auto-patchelf: 0 dependencies could not be satisfied

I’m pretty sure this used to produce little or no output when successful. Error code 0 though, so presumably it worked? Nope:

$ ./hello-hs
-bash: ./hello-hs: No such file or directory

The file hello-hs itself does exist. But I believe this error indicates a shared library not being found. The output of ldd shows the same paths as before patching, albeit with different hex addresses:

$ ldd hello-hs
        linux-vdso.so.1 (0x0000ffff86add000)
        libc.so.6 => /nix/store/g14swv4f0rg83naqj87g1mjmyvrmrxmf-glibc-2.35-163/lib/libc.so.6 (0x0000ffff868f0000)
        libm.so.6 => /nix/store/g14swv4f0rg83naqj87g1mjmyvrmrxmf-glibc-2.35-163/lib/libm.so.6 (0x0000ffff86840000)
        librt.so.1 => /nix/store/g14swv4f0rg83naqj87g1mjmyvrmrxmf-glibc-2.35-163/lib/librt.so.1 (0x0000ffff86810000)
        libdl.so.2 => /nix/store/g14swv4f0rg83naqj87g1mjmyvrmrxmf-glibc-2.35-163/lib/libdl.so.2 (0x0000ffff867e0000)
        libpthread.so.0 => /nix/store/g14swv4f0rg83naqj87g1mjmyvrmrxmf-glibc-2.35-163/lib/libpthread.so.0 (0x0000ffff867b0000)
        /lib/ld-linux-aarch64.so.1 => /nix/store/g14swv4f0rg83naqj87g1mjmyvrmrxmf-glibc-2.35-163/lib/ld-linux-aarch64.so.1 (0x0000ffff86aa0000)

So I have no idea what’s going on.

PS. I’d prefer to use flakes these days anyway. But nix shell nixpkgs#autoPatchelfHook doesn’t even put any autoPatchelf on PATH.

1 Like

I’ve never tried invoking autoPatchElf this way, but it appears that it is not actually changing the interpreter path.

On my machine,

$ ldd $(which ls)
	linux-vdso.so.1 (0x00007ffe66dfb000)
	libcrypto.so.1.1 => /nix/store/6j3kwyp4cqr41i5d8dc1gmy84i6cp15f-openssl-1.1.1o/lib/libcrypto.so.1.1 (0x00007f316e19e000)
	libacl.so.1 => /nix/store/jrrrv0d1fy4n58l55jcj2f074vlrill2-acl-2.3.1/lib/libacl.so.1 (0x00007f316e193000)
	libattr.so.1 => /nix/store/8rcmwyigsxd31azkzf380r7g4l1jv1dy-attr-2.5.1/lib/libattr.so.1 (0x00007f316e18b000)
	libc.so.6 => /nix/store/lyl6nysc3i3aqhj6shizjgj0ibnf1pvg-glibc-2.34-210/lib/libc.so.6 (0x00007f316df8d000)
	libdl.so.2 => /nix/store/lyl6nysc3i3aqhj6shizjgj0ibnf1pvg-glibc-2.34-210/lib/libdl.so.2 (0x00007f316df88000)
	libpthread.so.0 => /nix/store/lyl6nysc3i3aqhj6shizjgj0ibnf1pvg-glibc-2.34-210/lib/libpthread.so.0 (0x00007f316df81000)
	/nix/store/lyl6nysc3i3aqhj6shizjgj0ibnf1pvg-glibc-2.34-210/lib/ld-linux-x86-64.so.2 => /nix/store/lyl6nysc3i3aqhj6shizjgj0ibnf1pvg-glibc-2.34-210/lib64/ld-linux-x86-64.so.2 (0x00007f316e493000)

note the last line has a nix store path on the left of the arrow, while yours has a nonexistent path.

Oh, that’s what I get for not reading thoroughly. You already know it’s not working. Why not just make a derivation and use autoPatchElfHook the way it’s intended? Normally it only uses libraries in buildInputs, so the fact that you haven’t included any could also be a problem?

Making a derivation isn’t ideal for my purposes.

Anyway, I managed to hack something together a but more manually: nix-shell -p patchelf --run 'patchelf --set-interpreter $(cat $NIX_CC/nix-support/dynamic-linker) hello-hs'.

But I’m still interested in why autoPatchelf isn’t working. Especially as this gets messier when I need to link to more dynamic libraries, requiring args like --add-needed $(nix eval --raw nixpkgs#libevdev)/lib/libevdev.so.

3 Likes