I’ve noticed that all go binaries in nixpkgs built with CGO_ENABLED=1 are not “pure”, meaning that the resulting binaries don’t set RUNPATH at all. Is this expected or am I missing something?
For example building any C++ binary produces the correct RUNPATH as expected:
$ readelf -d "$(nix build github:NixOS/nixpkgs/nixos-24.05#envoy --print-out-paths)/bin/envoy"
Dynamic section at offset 0x376d5c0 contains 33 entries:
Tag Type Name/Value
...
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [librt.so.1]
0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x0000000000000001 (NEEDED) Shared library: [ld-linux-x86-64.so.2]
0x000000000000000c (INIT) 0x4bc768
0x000000000000000d (FINI) 0x2a00324
0x000000000000001a (FINI_ARRAY) 0x3607950
0x000000000000001c (FINI_ARRAYSZ) 16 (bytes)
0x0000000000000019 (INIT_ARRAY) 0x3607960
0x000000000000001b (INIT_ARRAYSZ) 20456 (bytes)
0x000000000000001d (RUNPATH) Library runpath: [/nix/store/c10zhkbp6jmyh0xc5kd123ga8yy2p4hk-glibc-2.39-52/lib]
...
However if I do the same for most packages built with buildGoModule with CGO_ENABLED=1 (which is the default behavior), I get something like the following:
$ readelf -d "$(nix build github:NixOS/nixpkgs/nixos-24.05#opentofu --print-out-paths)/bin/tofu"
Dynamic section at offset 0x4efca00 contains 20 entries:
Tag Type Name/Value
0x0000000000000004 (HASH) 0x3c96cc0
0x0000000000000006 (SYMTAB) 0x3c970a0
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000005 (STRTAB) 0x3c96dc0
0x000000000000000a (STRSZ) 732 (bytes)
0x0000000000000007 (RELA) 0x3c967a8
0x0000000000000008 (RELASZ) 24 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x0000000000000003 (PLTGOT) 0x52fcb40
0x0000000000000015 (DEBUG) 0x0
0x0000000000000001 (NEEDED) Shared library: [libresolv.so.2]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000006ffffffe (VERNEED) 0x3c96be0
0x000000006fffffff (VERNEEDNUM) 1
0x000000006ffffff0 (VERSYM) 0x3c96c40
0x0000000000000014 (PLTREL) RELA
0x0000000000000002 (PLTRELSZ) 1056 (bytes)
0x0000000000000017 (JMPREL) 0x3c967c0
0x0000000000000000 (NULL) 0x0
As you can see RUNPATH is nowhere to be found and often causes when the binary is executed inside an FHS environment.
While adding these options to individual buildGoModule
s works as expected
nativeBuildInputs = [ autoPatchelfHook ];
buildInputs = [ glibc ];
autoPatchelfFlags = ["--keep-libc"];
I wonder why this is not the default?