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

Bjørn Forsman bjorn.forsman at gmail.com
Thu Aug 25 21:33:08 CEST 2016


On 25 August 2016 at 21:08, Nick Sabalausky
<bus_nixos_list at semitwist.com> wrote:
> 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/...')

libstdc++ is in the "gcc" package, it seems. (So adding "gcc" to the
for loop should fix it.)

> 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?

Both are hacks :-) The first method breaks when you garbage collect
the system and the paths embedded into the binary are removed. The
second method (may) break when you update the system so that the links
in /run/current-system/sw/lib/... point to different and incompatible
libraries.

Best regards,
Bjørn Forsman


More information about the nix-dev mailing list