[Nix-dev] Generating nixos-compatible binaries? And bootstrapped packages.

Nick Sabalausky bus_nixos_list at semitwist.com
Thu Aug 25 21:08:51 CEST 2016


On 08/25/2016 01:52 PM, Bjørn Forsman wrote:
> On 25 August 2016 at 18:54, Nick Sabalausky
> <bus_nixos_list at semitwist.com> wrote:
>> On 08/24/2016 01:29 PM, stewart mackenzie wrote:
>>> Have a look at patchelf
>>
>> Ok, so according to <https://nixos.org/patchelf.html>, what I do is:
>>
>> % patchelf --set-interpreter PATH_TO_LOADER program_binary
>> % patchelf --set-rpath LINKER_SEARCH_PATHS program_binary
>>
>> But how do I know what my paths for PATH_TO_LOADER and LINKER_SEARCH_PATHS
>> are?
>
> A place to start would be to look at the output of
>
>    readelf -a $MYPROG | grep "NEEDED\|interpreter
>
> For instance,
>
>    $ readelf -a $(which ls) | grep "NEEDED\|interpreter"
>        [Requesting program interpreter:
> /nix/store/dad9vxniabwzidvvxfsfj6vb0xncsbbb-glibc-2.23/lib/ld-linux-x86-64.so.2]
>     0x0000000000000001 (NEEDED)             Shared library: [libacl.so.1]
>     0x0000000000000001 (NEEDED)             Shared library: [librt.so.1]
>     0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
>     0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
>
> Then try with:
>
>    PATH_TO_LOADER=$(nix-build -A glibc '<nixpkgs>'
> --no-out-link)/lib/ld-linux-x86-64.so.2
>
> (Assuming 64-bit program.)
>
> When the interpreter is in place, I think you can use 'ldd' to figure
> out the recursive set of libraries it needs. If not, one can do the
> trial and error method by trying to run the program and seeing what it
> says is missing.
>
> LINKER_SEARCH_PATHS can be built like this:
>
>    $ for p in acl glibc; do echo $(nix-build -A $p '<nixpkgs>'
> --no-out-link)/lib; done | tr '\n' ':'
>    /nix/store/mq5a5h2p9wwwbpv0i7lmjzw2a503ph22-acl-2.2.52/lib:/nix/store/gwl3ppqj4i730nhd4f50ncl5jc4n97ks-glibc-2.23/lib:
>
>    (TODO: strip the trailing colon)
>
> Best regards,
> Bjørn Forsman
>

Doing LINKER_SEARCH_PATHS like that, it left the executable complaining 
about missing libstdc++, which I had trouble finding until I looked into 
the '/run/current-profile/sw/lib' path Tomasz mentioned and realized I 
could find the paths by checking the symlinks inside there (Although for 
me it was '/run/current-system/...'. I don't have a 
'/run/current-profile/...')

Anyway, I tried doing this, which seems to work:

% PATH_TO_INTERP=$(nix-build -A glibc '<nixpkgs>' 
--no-out-link)/lib/ld-linux-x86-64.so.2
% patchelf --set-interpreter $PATH_TO_INTERP path/to/program_binary
% patchelf --set-rpath /run/current-system/sw/lib path/to/program_binary
% path/to/program_binary

Any downsides to setting the RPATH that way? By just setting it to 
/run/current-system/sw/lib?



More information about the nix-dev mailing list