13 apr 2015
this posting is about how to get a binary only x86/amd64 game called FTL [1] on nixos. the problem to solve is how to tell the game the proper library locations in the /nix/store!
in order to get the FTL binary to work, you can do either of these possibilities:
with this posting i want to document all three solutions for FTL.
i’ve been using FTL FTL.1.5.13.tar.gz and i extract it like this:
$ tar xzf FTL.1.5.13.tar.gz
the archive contains:
$ du -a FTL
216 FTL/data/amd64/lib/libILU.so.1
1280 FTL/data/amd64/lib/libIL.so.1
224 FTL/data/amd64/lib/libbass.so
2200 FTL/data/amd64/lib/libfreetype.so.6
100 FTL/data/amd64/lib/libz.so.1
40 FTL/data/amd64/lib/libbassmix.so
528 FTL/data/amd64/lib/libpng12.so.0
56 FTL/data/amd64/lib/libILUT.so.1
2104 FTL/data/amd64/lib/libSDL-1.2.so.0
6752 FTL/data/amd64/lib
216 FTL/data/amd64/bin/libILU.so.1
1280 FTL/data/amd64/bin/libIL.so.1
224 FTL/data/amd64/bin/libbass.so
2200 FTL/data/amd64/bin/libfreetype.so.6
100 FTL/data/amd64/bin/libz.so.1
40 FTL/data/amd64/bin/libbassmix.so
528 FTL/data/amd64/bin/libpng12.so.0
56 FTL/data/amd64/bin/libILUT.so.1
2104 FTL/data/amd64/bin/libSDL-1.2.so.0
3500 FTL/data/amd64/bin/FTL
10252 FTL/data/amd64/bin
17008 FTL/data/amd64
196548 FTL/data/resources/resource.dat
1480 FTL/data/resources/data.dat
4 FTL/data/resources/exe_icon.bmp
198036 FTL/data/resources
180 FTL/data/x86/lib/libILU.so.1
1032 FTL/data/x86/lib/libIL.so.1
212 FTL/data/x86/lib/libbass.so
1792 FTL/data/x86/lib/libfreetype.so.6
96 FTL/data/x86/lib/libz.so.1
36 FTL/data/x86/lib/libbassmix.so
456 FTL/data/x86/lib/libpng12.so.0
48 FTL/data/x86/lib/libILUT.so.1
1856 FTL/data/x86/lib/libSDL-1.2.so.0
5712 FTL/data/x86/lib
3396 FTL/data/x86/bin/FTL
3400 FTL/data/x86/bin
9116 FTL/data/x86
28 FTL/data/licenses/LGPL.txt
4 FTL/data/licenses/README-RapidXML.txt
4 FTL/data/licenses/README-zlib.txt
4 FTL/data/licenses/README-SDL.txt
8 FTL/data/licenses/README-FreeType.txt
4 FTL/data/licenses/README-DevIL.txt
56 FTL/data/licenses
20 FTL/data/exe_icon.bmp
4 FTL/data/FTL
224244 FTL/data
12 FTL/FTL_README.html
4 FTL/FTL
224264 FTL
FTL/FTL is a bash script, we skip it and check the FTL/data/amd64/bin/FTL binary:
$ file FTL/data/amd64/bin/FTL
FTL: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.8, stripped
which looks good, now let’s execute it:
$ FTL/data/amd64/bin/./FTL
zsh: no such file or directory: ./FTL
note: this error message is not very helpful!
let’s have a look at the FTL/data/amd64/bin/FTL ELF part (interpreter and RPATH):
$ patchelf --print-interpreter FTL/data/amd64/bin/FTL
/lib64/ld-linux-x86-64.so.2
$ patchelf --print-rpath FTL/data/amd64/bin/FTL
(empty output)
‘/lib64/ld-linux-x86-64.so.2’ won’t be running on nixos, so let’s find a proper interpreter:
$ du -a /nix/store | grep ld-linux-x86-64.so.2
0 /nix/store/93zfs0zzndi7pkjkjxawlafdj8m90kg5-glibc-2.20/lib/ld-linux-x86-64.so.2
0 /nix/store/94n64qy99ja0vgbkf675nyk39g9b978n-glibc-2.19/lib/ld-linux-x86-64.so.2
0 /nix/store/i11d0d4015p0vbdnjq7lb509v9pwp049-glibc-2.19/lib/ld-linux-x86-64.so.2
0 /nix/store/cj7a81wsm1ijwwpkks3725661h3263p5-glibc-2.13/lib/ld-linux-x86-64.so.2
4 /nix/store/kp4m5d52ljhb2fyxvnm6jgkbaf3hkdkv-glibc-multi-2.20/lib/ld-linux-x86-64.so.2
0 /nix/store/la5imi1602jxhpds9675n2n2d0683lbq-glibc-2.20/lib/ld-linux-x86-64.so.2
144 /nix/store/gakif09g14jybn6vkgnzb0kn46kqg1w6-extra-utils/lib/ld-linux-x86-64.so.2
4 /nix/store/g9y2f5awcw9jdgirlv7163k3g5hjak0a-system-path/lib/ld-linux-x86-64.so.2
0 /nix/store/nrxyygy0wqski1klq0305d3h523k41ps-glibc-2.20/lib/ld-linux-x86-64.so.2
0 /nix/store/zm4bhsm8lprkzvrjgqr0klfkvr21als4-glibc-2.17/lib/ld-linux-x86-64.so.2
0 /nix/store/c8lg3m5mr246fvlx6xsrxa0sykv4l9pg-bootstrap-tools/lib/ld-linux-x86-64.so.2
0 /nix/store/ywxpkmy9kagcsvbjjhi46pr4xwpd6sfm-glibc-2.19/lib/ld-linux-x86-64.so.2
0 /nix/store/r2nzgy23qzfn273n9mbqngyidm05670f-glibc-2.19/lib/ld-linux-x86-64.so.2
4 /nix/store/i4bqvffrh47rlbc42dkqhzgmrw40zfvy-system-path/lib/ld-linux-x86-64.so.2
4 /nix/store/qdd4ypr32j1d373779ggnqqmgqm29xyb-system-path/lib/ld-linux-x86-64.so.2
4 /nix/store/vi4r0vw7jipwzfxhrqghzny74jsgxv5c-system-path/lib/ld-linux-x86-64.so.2
0 /nix/store/pdskwizjw8ar31hql2wjnnx6g0s6xc50-glibc-2.19/lib/ld-linux-x86-64.so.2
0 /nix/store/7yvf54nxwmaslcgyqfghqsqr1dwmr8ld-glibc-2.20/lib/ld-linux-x86-64.so.2
4 /nix/store/ggz4x9azga18bs2n2n5ap9qq1m088694-system-path/lib/ld-linux-x86-64.so.2
0 /nix/store/k0vqprjmxybr7clvfljk13zsdjwklcch-bootstrap-tools/lib/ld-linux-x86-64.so.2
0 /nix/store/q784x64hp3nwdxx7lbgb16f74i2bhxxk-glibc-2.18/lib/ld-linux-x86-64.so.2
0 /nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/ld-linux-x86-64.so.2
144 /nix/store/nvxln8cf8aprddpvz5zpx8xgn34w9mz3-extra-utils/lib/ld-linux-x86-64.so.2
4 /nix/store/5rr3d51im48n5y3sx0kr9l61z0b9i5bs-system-path/lib/ld-linux-x86-64.so.2
0 /nix/store/6k9z1sfl7kghmagwd205k3i81pbcw57s-glibc-2.21/lib/ld-linux-x86-64.so.2
now just pick a ‘random’ one and issue:
$ patchelf --set-interpreter /nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/ld-linux-x86-64.so.2 FTL/data/amd64/bin/FTL
and run it again:
$ FTL/data/amd64/bin/FTL
./FTL: error while loading shared libraries: libGL.so.1: cannot open shared object file: No such file or directory
looks much better now, let’s see the library (DSOs - dynamic shared objects) status:
$ ldd FTL/data/amd64/bin/FTL
linux-vdso.so.1 (0x00007fff495e2000)
libSDL-1.2.so.0 => ../lib/libSDL-1.2.so.0 (0x00007f7d2cdc5000)
libGL.so.1 => not found
libfreetype.so.6 => ../lib/libfreetype.so.6 (0x00007f7d2cb42000)
libIL.so.1 => ../lib/libIL.so.1 (0x00007f7d2c827000)
libILU.so.1 => ../lib/libILU.so.1 (0x00007f7d2c612000)
libILUT.so.1 => ../lib/libILUT.so.1 (0x00007f7d2c40c000)
libbass.so => ../lib/libbass.so (0x00007f7d2d127000)
libbassmix.so => ../lib/libbassmix.so (0x00007f7d2c303000)
librt.so.1 => /nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/librt.so.1 (0x00007f7d2c0fb000)
libstdc++.so.6 => not found
libm.so.6 => /nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/libm.so.6 (0x00007f7d2bdf8000)
libc.so.6 => /nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/libc.so.6 (0x00007f7d2ba49000)
libpthread.so.0 => /nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/libpthread.so.0 (0x00007f7d2b82b000)
libdl.so.2 => /nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/libdl.so.2 (0x00007f7d2b627000)
libpng12.so.0 => ../lib/libpng12.so.0 (0x00007f7d2b402000)
/nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/ld-linux-x86-64.so.2 (0x00007f7d2d056000)
libstdc++.so.6 => not found
libgcc_s.so.1 => not found
libGLU.so.1 => not found
libGL.so.1 => not found
libz.so.1 => ../lib/libz.so.1 (0x00007f7d2b1ec000)
wonderful, so all the libraries coming with FTL are already in the RPATH of the binary (as libSDL-1.2.so.0, …), so we have to find the missing ones:
TODO: patchelf for these libraries:
again, use this command to find candidates:
$ du -a /nix/store | grep libGL.so.1
note: DSOs might introduce other DSOs and thus you might have to add even more libraries than shown here. hint: later we are about to find out that we require libasound.so which is not listed just yet!
and again, pick one:
i picked this one: /nix/store/0sgyyrml3j55nx4mmb3v099n7g1fidr4-mesa-10.2.9/lib/libGL.so.1
so the command goes like this:
$ patchelf --set-rpath FTL/data/amd64/lib:/nix/store/0sgyyrml3j55nx4mmb3v099n7g1fidr4-mesa-10.2.9/lib/ FTL/data/amd64/bin/FTL
note: FTL/data/amd64/lib contains the bundled libraries! you should run ‘patchelf –set-rpath’ from the location you want to start the binary later on. in case of FTL this would be ‘FTL/’ but in this example i was using the parent directory of ‘FTL/’. also note that you can set the RPATH to an absolute directory which is good until you move the FTL program into a different location or use relative path names which is good until you decided to run the program from any other directory as the one you issued the ‘patchelf –set-rpath’ from. sigh
and afterwards the ldd output has changed a lot:
$ ldd FTL/data/amd64/bin/FTL
linux-vdso.so.1 (0x00007fff04dcd000)
libSDL-1.2.so.0 => FTL/data/amd64/lib/libSDL-1.2.so.0 (0x00007f512a1c8000)
libGL.so.1 => /nix/store/fiz0mz982n1m03qzbpvl40n51bvr4b0m-mesa-10.4.5/lib/libGL.so.1 (0x00007f5129f3c000)
libfreetype.so.6 => FTL/data/amd64/lib/libfreetype.so.6 (0x00007f5129cb9000)
libIL.so.1 => FTL/data/amd64/lib/libIL.so.1 (0x00007f512999e000)
libILU.so.1 => FTL/data/amd64/lib/libILU.so.1 (0x00007f5129788000)
libILUT.so.1 => FTL/data/amd64/lib/libILUT.so.1 (0x00007f5129582000)
libbass.so => FTL/data/amd64/lib/libbass.so (0x00007f512a52a000)
libbassmix.so => FTL/data/amd64/lib/libbassmix.so (0x00007f5129479000)
librt.so.1 => /nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/librt.so.1 (0x00007ff8f3d18000)
libstdc++.so.6 => /nix/store/jrhjp66sdfv0pc95dwgdz2sly9hima23-gcc-4.8.4/lib/libstdc++.so.6 (0x00007ff8f3a15000)
libm.so.6 => /nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/libm.so.6 (0x00007ff8f3712000)
libc.so.6 => /nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/libc.so.6 (0x00007ff8f3363000)
libpthread.so.0 => /nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/libpthread.so.0 (0x00007ff8f3145000)
libdl.so.2 => /nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/libdl.so.2 (0x00007ff8f2f41000)
libexpat.so.1 => /nix/store/vydr1x0s2lpw2id04388azad7xaw4m8w-expat-2.1.0/lib/libexpat.so.1 (0x00007ff8f2d18000)
libglapi.so.0 => /nix/store/fiz0mz982n1m03qzbpvl40n51bvr4b0m-mesa-10.4.5/lib/libglapi.so.0 (0x00007ff8f2aef000)
libXdamage.so.1 => /nix/store/j292kvvwsfyqx73a6zyn81ykmrbkcf31-libXdamage-1.1.4/lib/libXdamage.so.1 (0x00007ff8f28ed000)
libXfixes.so.3 => /nix/store/98gi4m67cr1cgrw6c1g2r51wyd6x8nld-libXfixes-5.0.1/lib/libXfixes.so.3 (0x00007ff8f26e8000)
libX11-xcb.so.1 => /nix/store/vsk28b0riggcmigbgkzahf93xj3hw7gx-libX11-1.6.2/lib/libX11-xcb.so.1 (0x00007ff8f24e7000)
libxcb-glx.so.0 => /nix/store/16g3p2596fjvkiwlzxgs6qrc0fmj0dnk-libxcb-1.11/lib/libxcb-glx.so.0 (0x00007ff8f22d1000)
libxcb-dri2.so.0 => /nix/store/16g3p2596fjvkiwlzxgs6qrc0fmj0dnk-libxcb-1.11/lib/libxcb-dri2.so.0 (0x00007ff8f20cd000)
libxcb-dri3.so.0 => /nix/store/16g3p2596fjvkiwlzxgs6qrc0fmj0dnk-libxcb-1.11/lib/libxcb-dri3.so.0 (0x00007ff8f1ecb000)
libxcb-present.so.0 => /nix/store/16g3p2596fjvkiwlzxgs6qrc0fmj0dnk-libxcb-1.11/lib/libxcb-present.so.0 (0x00007ff8f1cc9000)
libxcb-randr.so.0 => /nix/store/16g3p2596fjvkiwlzxgs6qrc0fmj0dnk-libxcb-1.11/lib/libxcb-randr.so.0 (0x00007ff8f1abd000)
libxcb-xfixes.so.0 => /nix/store/16g3p2596fjvkiwlzxgs6qrc0fmj0dnk-libxcb-1.11/lib/libxcb-xfixes.so.0 (0x00007ff8f18b7000)
libxcb-render.so.0 => /nix/store/16g3p2596fjvkiwlzxgs6qrc0fmj0dnk-libxcb-1.11/lib/libxcb-render.so.0 (0x00007ff8f16ae000)
libxcb-shape.so.0 => /nix/store/16g3p2596fjvkiwlzxgs6qrc0fmj0dnk-libxcb-1.11/lib/libxcb-shape.so.0 (0x00007ff8f14ab000)
libxcb-sync.so.1 => /nix/store/16g3p2596fjvkiwlzxgs6qrc0fmj0dnk-libxcb-1.11/lib/libxcb-sync.so.1 (0x00007ff8f12a6000)
libxshmfence.so.1 => /nix/store/mib83k6wfp6dg7rffk2k3zrr1vhpdm90-libxshmfence-1.2/lib/libxshmfence.so.1 (0x00007ff8f10a4000)
libXxf86vm.so.1 => /nix/store/alfnyr2zf1y2y348lrrv9r0b7lhamlz2-libXxf86vm-1.1.3/lib/libXxf86vm.so.1 (0x00007ff8f0e9f000)
libXext.so.6 => /nix/store/iaaijiqdji1bhjgpa4rdvdw1a1z9rpn3-libXext-1.3.3/lib/libXext.so.6 (0x00007ff8f0c8d000)
libX11.so.6 => /nix/store/vsk28b0riggcmigbgkzahf93xj3hw7gx-libX11-1.6.2/lib/libX11.so.6 (0x00007ff8f0953000)
libxcb.so.1 => /nix/store/16g3p2596fjvkiwlzxgs6qrc0fmj0dnk-libxcb-1.11/lib/libxcb.so.1 (0x00007ff8f0735000)
libXau.so.6 => /nix/store/4fk2pcy9nwyhsipin43r1svh2h02hk5a-libXau-1.0.8/lib/libXau.so.6 (0x00007ff8f0532000)
libXdmcp.so.6 => /nix/store/khd2573yk3v3d8jspf0m9ad2hma64sc0-libXdmcp-1.1.1/lib/libXdmcp.so.6 (0x00007ff8f032d000)
libdrm.so.2 => /nix/store/zci3rhzh24s6zwfxdysb9mqwrzbn7lyb-libdrm-2.4.59/lib/libdrm.so.2 (0x00007ff8f0121000)
libpng12.so.0 => not found
libgcc_s.so.1 => /nix/store/jrhjp66sdfv0pc95dwgdz2sly9hima23-gcc-4.8.4/lib/libgcc_s.so.1 (0x00007ff8eff0b000)
libpng12.so.0 => /nix/store/i7ifkqarb8m0w58vs96mqvj0giwll2km-libpng-1.2.51/lib/libpng12.so.0 (0x00007ff8efce5000)
libGLU.so.1 => /nix/store/fiz0mz982n1m03qzbpvl40n51bvr4b0m-mesa-10.4.5/lib/libGLU.so.1 (0x00007ff8efa66000)
/nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/ld-linux-x86-64.so.2 (0x00007ff8f4f00000)
libz.so.1 => /nix/store/mvjf7dvnpqz9zlvnq4yi86xbc5k9j94r-zlib-1.2.8/lib/libz.so.1 (0x00007ff8ef84e000)
note: it is common that DSOs depend on other DSOs, just use ‘ldd’ to find out.
patchelf –set-rpath FTL/data/amd64/lib:/nix/store/0sgyyrml3j55nx4mmb3v099n7g1fidr4-mesa-10.2.9/lib/:/nix/store/ds3k0yci9swgglvjmn78p7fcz02ma4vr-gcc-4.8.4/lib64 FTL/data/amd64/bin/FTL
note: sometimes there are folders called /lib and lib64, do NOT mix them as you only want 64bit libraries! but other times also 64bit libraries are in a /lib folder, so happy guessing!
$ ldd FTL/data/amd64/bin/FTL
linux-vdso.so.1 (0x00007fff017d4000)
libSDL-1.2.so.0 => FTL/data/amd64/lib/libSDL-1.2.so.0 (0x00007f8617b76000)
libGL.so.1 => /nix/store/fiz0mz982n1m03qzbpvl40n51bvr4b0m-mesa-10.4.5/lib/libGL.so.1 (0x00007f86178ea000)
libfreetype.so.6 => FTL/data/amd64/lib/libfreetype.so.6 (0x00007f8617667000)
libIL.so.1 => FTL/data/amd64/lib/libIL.so.1 (0x00007f861734c000)
libILU.so.1 => FTL/data/amd64/lib/libILU.so.1 (0x00007f8617137000)
libILUT.so.1 => FTL/data/amd64/lib/libILUT.so.1 (0x00007f8616f31000)
libbass.so => FTL/data/amd64/lib/libbass.so (0x00007f8617ed8000)
libbassmix.so => FTL/data/amd64/lib/libbassmix.so (0x00007f8616e28000)
librt.so.1 => /nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/librt.so.1 (0x00007f8616c20000)
libstdc++.so.6 => /nix/store/jrhjp66sdfv0pc95dwgdz2sly9hima23-gcc-4.8.4/lib/libstdc++.so.6 (0x00007f861691d000)
libm.so.6 => /nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/libm.so.6 (0x00007f861661a000)
libc.so.6 => /nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/libc.so.6 (0x00007f861626b000)
libpthread.so.0 => /nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/libpthread.so.0 (0x00007f861604d000)
libdl.so.2 => /nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/libdl.so.2 (0x00007f8615e49000)
libexpat.so.1 => /nix/store/vydr1x0s2lpw2id04388azad7xaw4m8w-expat-2.1.0/lib/libexpat.so.1 (0x00007f8615c20000)
libglapi.so.0 => /nix/store/fiz0mz982n1m03qzbpvl40n51bvr4b0m-mesa-10.4.5/lib/libglapi.so.0 (0x00007f86159f7000)
libXdamage.so.1 => /nix/store/j292kvvwsfyqx73a6zyn81ykmrbkcf31-libXdamage-1.1.4/lib/libXdamage.so.1 (0x00007f86157f5000)
libXfixes.so.3 => /nix/store/98gi4m67cr1cgrw6c1g2r51wyd6x8nld-libXfixes-5.0.1/lib/libXfixes.so.3 (0x00007f86155f0000)
libX11-xcb.so.1 => /nix/store/vsk28b0riggcmigbgkzahf93xj3hw7gx-libX11-1.6.2/lib/libX11-xcb.so.1 (0x00007f86153ef000)
libxcb-glx.so.0 => /nix/store/16g3p2596fjvkiwlzxgs6qrc0fmj0dnk-libxcb-1.11/lib/libxcb-glx.so.0 (0x00007f86151d9000)
libxcb-dri2.so.0 => /nix/store/16g3p2596fjvkiwlzxgs6qrc0fmj0dnk-libxcb-1.11/lib/libxcb-dri2.so.0 (0x00007f8614fd5000)
libxcb-dri3.so.0 => /nix/store/16g3p2596fjvkiwlzxgs6qrc0fmj0dnk-libxcb-1.11/lib/libxcb-dri3.so.0 (0x00007f8614dd3000)
libxcb-present.so.0 => /nix/store/16g3p2596fjvkiwlzxgs6qrc0fmj0dnk-libxcb-1.11/lib/libxcb-present.so.0 (0x00007f8614bd1000)
libxcb-randr.so.0 => /nix/store/16g3p2596fjvkiwlzxgs6qrc0fmj0dnk-libxcb-1.11/lib/libxcb-randr.so.0 (0x00007f86149c5000)
libxcb-xfixes.so.0 => /nix/store/16g3p2596fjvkiwlzxgs6qrc0fmj0dnk-libxcb-1.11/lib/libxcb-xfixes.so.0 (0x00007f86147bf000)
libxcb-render.so.0 => /nix/store/16g3p2596fjvkiwlzxgs6qrc0fmj0dnk-libxcb-1.11/lib/libxcb-render.so.0 (0x00007f86145b6000)
libxcb-shape.so.0 => /nix/store/16g3p2596fjvkiwlzxgs6qrc0fmj0dnk-libxcb-1.11/lib/libxcb-shape.so.0 (0x00007f86143b3000)
libxcb-sync.so.1 => /nix/store/16g3p2596fjvkiwlzxgs6qrc0fmj0dnk-libxcb-1.11/lib/libxcb-sync.so.1 (0x00007f86141ae000)
libxshmfence.so.1 => /nix/store/mib83k6wfp6dg7rffk2k3zrr1vhpdm90-libxshmfence-1.2/lib/libxshmfence.so.1 (0x00007f8613fac000)
libXxf86vm.so.1 => /nix/store/alfnyr2zf1y2y348lrrv9r0b7lhamlz2-libXxf86vm-1.1.3/lib/libXxf86vm.so.1 (0x00007f8613da7000)
libXext.so.6 => /nix/store/iaaijiqdji1bhjgpa4rdvdw1a1z9rpn3-libXext-1.3.3/lib/libXext.so.6 (0x00007f8613b95000)
libX11.so.6 => /nix/store/vsk28b0riggcmigbgkzahf93xj3hw7gx-libX11-1.6.2/lib/libX11.so.6 (0x00007f861385b000)
libxcb.so.1 => /nix/store/16g3p2596fjvkiwlzxgs6qrc0fmj0dnk-libxcb-1.11/lib/libxcb.so.1 (0x00007f861363d000)
libXau.so.6 => /nix/store/4fk2pcy9nwyhsipin43r1svh2h02hk5a-libXau-1.0.8/lib/libXau.so.6 (0x00007f861343a000)
libXdmcp.so.6 => /nix/store/khd2573yk3v3d8jspf0m9ad2hma64sc0-libXdmcp-1.1.1/lib/libXdmcp.so.6 (0x00007f8613235000)
libdrm.so.2 => /nix/store/zci3rhzh24s6zwfxdysb9mqwrzbn7lyb-libdrm-2.4.59/lib/libdrm.so.2 (0x00007f8613029000)
libpng12.so.0 => not found
libgcc_s.so.1 => /nix/store/jrhjp66sdfv0pc95dwgdz2sly9hima23-gcc-4.8.4/lib/libgcc_s.so.1 (0x00007f8612e13000)
libpng12.so.0 => not found
libGLU.so.1 => /nix/store/fiz0mz982n1m03qzbpvl40n51bvr4b0m-mesa-10.4.5/lib/libGLU.so.1 (0x00007f8612b94000)
/nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/ld-linux-x86-64.so.2 (0x00007f8617e07000)
now repeat the same procedure time and again to get all the DSOs found.
note: sometimes this does not work as you simply don’t have the required libraries installed in the store! then either install them directly or any software which might use them (indirectly). however, when using libraries like this one will have a problem if the libraries are GCed (garbage collected) but the GC does not know that the libraries are still in use (in this case through FTL, by our patchelf hack).
interestinly, using patchelf on the FTL binary with the store paths to libpng12.so.0 seems to have no effect, the outcome is always:
$ ldd FTL/data/amd64/lib/libIL.so.1
linux-vdso.so.1 (0x00007fff3cbcf000)
libpng12.so.0 => not found
libstdc++.so.6 => /nix/store/jrhjp66sdfv0pc95dwgdz2sly9hima23-gcc-4.8.4/lib/libstdc++.so.6 (0x00007f7e2d949000)
libm.so.6 => /nix/store/93zfs0zzndi7pkjkjxawlafdj8m90kg5-glibc-2.20/lib/libm.so.6 (0x00007f7e2d646000)
libc.so.6 => /nix/store/93zfs0zzndi7pkjkjxawlafdj8m90kg5-glibc-2.20/lib/libc.so.6 (0x00007f7e2d2a9000)
libgcc_s.so.1 => /nix/store/jrhjp66sdfv0pc95dwgdz2sly9hima23-gcc-4.8.4/lib/libgcc_s.so.1 (0x00007f7e2d092000)
/nix/store/93zfs0zzndi7pkjkjxawlafdj8m90kg5-glibc-2.20/lib64/ld-linux-x86-64.so.2 (0x00007f7e2df6a000)
the reason is that one of the bundled DSOs are actually depending on libpng12.so.0 (amd64/lib/libIL.so.1), so now one has to patchelf the DSO instead…
the FTL binary is a nice example that patchelf does not work for libGLU.so.1 and libpng12.so.0 because you even though you can try to add a RPATH for either to the FTL binary, it will never work as the problem is not the FTL binary but the bundled libraries as ‘lib/libILUT.so.1’ or ‘libILU.so.1’. here an example:
$ patchelf --set-rpath /nix/store/i7ifkqarb8m0w58vs96mqvj0giwll2km-libpng-1.2.51/lib/:/nix/store/93zfs0zzndi7pkjkjxawlafdj8m90kg5-glibc-2.20/lib/:/nix/store/jrhjp66sdfv0pc95dwgdz2sly9hima23-gcc-4.8.4/lib/ FTL/data/amd64/lib/libIL.so.1
$ ldd FTL/data/amd64/lib/libIL.so.1
linux-vdso.so.1 (0x00007fff207df000)
libpng12.so.0 => /nix/store/i7ifkqarb8m0w58vs96mqvj0giwll2km-libpng-1.2.51/lib/libpng12.so.0 (0x00007f5113b04000)
libstdc++.so.6 => /nix/store/jrhjp66sdfv0pc95dwgdz2sly9hima23-gcc-4.8.4/lib/libstdc++.so.6 (0x00007f5113800000)
libm.so.6 => /nix/store/93zfs0zzndi7pkjkjxawlafdj8m90kg5-glibc-2.20/lib/libm.so.6 (0x00007f51134fd000)
libc.so.6 => /nix/store/93zfs0zzndi7pkjkjxawlafdj8m90kg5-glibc-2.20/lib/libc.so.6 (0x00007f5113160000)
libgcc_s.so.1 => /nix/store/jrhjp66sdfv0pc95dwgdz2sly9hima23-gcc-4.8.4/lib/libgcc_s.so.1 (0x00007f5112f49000)
libz.so.1 => /nix/store/mvjf7dvnpqz9zlvnq4yi86xbc5k9j94r-zlib-1.2.8/lib/libz.so.1 (0x00007f5112d31000)
/nix/store/93zfs0zzndi7pkjkjxawlafdj8m90kg5-glibc-2.20/lib64/ld-linux-x86-64.so.2 (0x00007f511404b000)
note: beware of ELF 32-bit libs as ‘ldd’ will just silently fail and tell you there is no lib, altough you added a RPATH pointing to one:
file /nix/store/55nsmmx7jzpm8i664pbj0adik4z6klcv-glu-9.0.0/lib/libGLU.so.1.3.1
/nix/store/55nsmmx7jzpm8i664pbj0adik4z6klcv-glu-9.0.0/lib/libGLU.so.1.3.1: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, not stripped
note: you need to patch the RPATH from the ‘FTL/’ directory as the binary expects the the ‘data’ directory to be residing there so you have to patch the RPATH for the bundled libraries again as we were doing that wrong in the first place.
finally running the FTL binary:
$ FTL/data/amd64/bin/FTL
Initializing Crash Catcher...
Initializing Video
Video Initialized
Opengl version = 3.0 Mesa 10.2.9
File or path name not found
Error opening resource file
File or path name not found
Error opening resource file
Starting audio library...
BASS_Init: Failed to init BASS Library!
BAS_INIT: 39
File or path name not found
Error opening resource file
Resource Loading Failure (or voluntary quit)!
so we need to make a hack here:
$ ln -s FTL/data/resources
$ FTL/data/amd64/bin/FTL
Initializing Crash Catcher...
Initializing Video
Video Initialized
Opengl version = 3.0 Mesa 10.2.9
Starting audio library...
BASS_Init: Failed to init BASS Library!
BAS_INIT: 39
Resource Preload: 2.530
Loading text....
Initializing animations...
Animations Initialized!
Loading Ship Blueprints....
Blueprints Loaded!
Initializing Sound Data....
Generating world...
Loading achievements...
Loading score file...
Running Game!
and it is working! except that it lacks audio ;P
there seems to be some problem with a BASS_Init thingy:
$ ./FTL
Loading Arch = amd64
Initializing Crash Catcher...
Initializing Video
Video Initialized
Opengl version = 3.0 Mesa 10.2.9
Starting audio library...
BASS_Init: Failed to init BASS Library!
BAS_INIT: 39
Resource Preload: 2.607
Loading text....
Initializing animations...
Animations Initialized!
Loading Ship Blueprints....
Blueprints Loaded!
Initializing Sound Data....
Generating world...
Loading achievements...
Loading score file...
Running Game!
no clue what is going on, let’s try ‘’strace’’ on the binary (not on the FTL shell script):
$ strace -e open FTL/data/amd64/bin/FTL
... (much crap)
write(1, "Starting audio library...\n", 26Starting audio library...
) = 26
open("/nix/store/zwimkmxsgg5h036knq623hzffnpkc7q5-libass-0.11.1/lib/libasound.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/nix/store/nwzpz8lrzry9j223rd84v2r4qs8pc548-libpng-1.2.51/lib/libasound.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/nix/store/0jcjjqm8c4gn2jiklq4f518n8hwlfhml-mesa-9.1.3/lib/libasound.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/home/joachim/Desktop/ftl/FTL/data/amd64/lib/libasound.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/run/opengl-driver/lib/libasound.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/nix/store/93zfs0zzndi7pkjkjxawlafdj8m90kg5-glibc-2.20/lib/libasound.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
write(1, "BASS_Init: Failed to init BASS L"..., 40BASS_Init: Failed to init BASS Library!
) = 40
write(1, "BAS_INIT: 39\n", 13BAS_INIT: 39
... (more crap)
so it seems to not find libasound.so.2 either! so finally i was using this command:
$ LD_LIBRARY_PATH=/nix/store/qhxaivhds8vahb2wzzhcpm820n32acjh-alsa-lib-1.0.28/lib/:$LD_LIBRARY_PATH FTL/data/amd64/bin/FTL
Initializing Crash Catcher...
Initializing Video
Video Initialized
Opengl version = 3.0 Mesa 10.2.9
Starting audio library...
Audio Initialized!
Resource Preload: 3.802
Loading text....
Initializing animations...
Animations Initialized!
Loading Ship Blueprints....
Blueprints Loaded!
Initializing Sound Data....
Generating world...
Loading achievements...
Loading score file...
Running Game!
note: i don’t have an idea where the libasound.so.2 was introduced and thus LD_LIBRARY_PATH is the only working solution so far.
however, FTL seems to be quite unstable and sound does not work, stops working after a while or is just bogus and sounds like noise. after a while FTL crashes, see this:
$ LD_LIBRARY_PATH=/nix/store/qz8wgnwxmw2jwcd83irff3z0l2lbf1s3-alsa-lib-1.0.28/lib/:$LD_LIBRARY_PATH FTL/data/amd64/bin/FTL
Initializing Crash Catcher...
Initializing Video
Video Initialized
Opengl version = 3.0 Mesa 10.2.9
Starting audio library...
Audio Initialized!
Resource Preload: 3.593
Loading text....
Initializing animations...
Animations Initialized!
Loading Ship Blueprints....
Blueprints Loaded!
Initializing Sound Data....
Generating world...
Loading achievements...
Loading score file...
Running Game!
*** Error in `FTL/data/amd64/bin/FTL': double free or corruption (!prev): 0x00000000056e0e40 ***
======= Backtrace: =========
/nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/libc.so.6(+0x74866)[0x7f6aaeed8866]
/nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/libc.so.6(+0x79c16)[0x7f6aaeeddc16]
/nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/libc.so.6(+0x7b3d1)[0x7f6aaeedf3d1]
FTL/data/amd64/lib/libbassmix.so(+0x2f76)[0x7f6aafa23f76]
FTL/data/amd64/lib/libbassmix.so(+0x4603)[0x7f6aafa25603]
FTL/data/amd64/lib/libbassmix.so(+0x5cd5)[0x7f6aafa26cd5]
FTL/data/amd64/lib/libbass.so(+0x2b707)[0x7f6ab0ae1707]
FTL/data/amd64/lib/libbass.so(+0x2819f)[0x7f6ab0ade19f]
FTL/data/amd64/lib/libbass.so(+0x2d052)[0x7f6ab0ae3052]
FTL/data/amd64/lib/libbass.so(+0x2d1e5)[0x7f6ab0ae31e5]
/nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/libpthread.so.0(+0x6f4a)[0x7f6aaec4cf4a]
/nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/libc.so.6(clone+0x6d)[0x7f6aaef4ed5d]
======= Memory map: ========
003fe000-00400000 rw-p 00000000 fe:01 22413413 /home/joachim/Desktop/ftl/FTL/data/amd64/bin/FTL
00400000-00766000 r-xp 00002000 fe:01 22413413 /home/joachim/Desktop/ftl/FTL/data/amd64/bin/FTL
00966000-00967000 rw-p 00368000 fe:01 22413413 /home/joachim/Desktop/ftl/FTL/data/amd64/bin/FTL
00967000-0097a000 rw-p 00000000 00:00 0
00b06000-05718000 rw-p 00000000 00:00 0 [heap]
7f6a58000000-7f6a58021000 rw-p 00000000 00:00 0
7f6a58021000-7f6a5c000000 ---p 00000000 00:00 0
...
cause unknown but other users seem to have this problem as well ;P
instead of using patchelf on the FTL binary nor any DSOs, one can also use LD_LIBRARY_PATH like this:
$ cd FTL/data
$ LD_LIBRARY_PATH=/nix/store/jrhjp66sdfv0pc95dwgdz2sly9hima23-gcc-4.8.4/lib/:/nix/store/fiz0mz982n1m03qzbpvl40n51bvr4b0m-mesa-10.4.5/lib/:amd64/lib:$LD_LIBRARY_PATH /nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/ld-linux-x86-64.so.2 amd64/bin/./FTL
what does this do?
first we set the LD_LIBRARY_PATH to include the required libraries into the DSO search path,
afterwards it uses /nix/store/6h129q168ahnl2nzw6azr239cba884ng-glibc-2.18/lib/ld-linux-x86-64.so.2, the dynamic linker,
to execute the binary FTL in directory amd64/bin/.
note: this solution is realy a ‘fast forward’ one and requires only little effort!
copy FTL.1.5.13.tar.gz to /tmp
$ cp FTL.1.5.13.tar.gz /tmp
the ftl.nix file contains:
{stdenv, pkgs, lib, makeWrapper, gcc, mesa_glu, path, version }:
# build this with:
# 64-bit systems
# nix-build -E 'with import <nixpkgs> { }; callPackage ./ftl.nix { path="/tmp/FTL.1.5.13.tar.gz"; version="1.5.13"; }'
# 32-bit systems
# nix-build -E 'with import <nixpkgs> { }; callPackage_i686 ./ftl.nix { path="/tmp/FTL.1.5.13.tar.gz"; version="1.5.13"; }'
let
arch = if stdenv.system == "x86_64-linux" then "amd64" else "x86";
libmapper = val: (map (x: x + "/lib") val ++ map (x: x + "/lib64") val);
lib_help = if stdenv.system == "x86_64-linux" then "lib64" else "lib";
in
assert (path != null);
assert (version != null);
stdenv.mkDerivation rec {
name = "FTL-${version}";
src = path;
libs = with pkgs; [ stdenv.cc.cc mesa_glu alsaLib zlib ];
buildInputs = [ makeWrapper ];
phases = [ "unpackPhase" "installPhase" ];
installPhase = ''
mkdir -p "$out/opt/FTL"
cp -r data "$out/opt/FTL"
chmod +x "$out/opt/FTL/data/${arch}/bin/FTL"
interpreter=$(echo ${stdenv.glibc}/${lib_help}/ld-linux*.so.2)
patchelf --set-interpreter $interpreter "$out/opt/FTL/data/${arch}/bin/FTL"
patchelf --set-rpath "$out/opt/FTL/data/${arch}/lib" "$out/opt/FTL/data/${arch}/bin/FTL"
mkdir "$out/bin"
# using makeWrapper to create a wrapper around the wrapper
# --run sets the 'working directory'
# --prefix adds the LD_LIBRARY_PATH export to the binary
# (libmapper libs) generates store location of libraries with lib and lib64 suffixes appended
makeWrapper "$out/opt/FTL/data/FTL" "$out/bin/ftl" \
--run "cd $out/opt/FTL/data" \
--prefix LD_LIBRARY_PATH ':' "${lib.concatStringsSep ":" (libmapper libs)}";
'';
}
build this on a 64-bit system:
nix-build -E ‘with import
build this on a 32-bit system:
nix-build -E ‘with import
installing it, this will show something like:
$ nix-build -E 'with import <nixpkgs> { }; callPackage /home/joachim/.nixpkgs/ftl.nix { }'
these derivations will be built:
/nix/store/i0wqnwzdhgdlr2a18v8s8aivivzn9qfj-FTL-1.5.13.drv
building path(s) ‘/nix/store/20k9ch8wafxf8sg7472p2gq1g3d9kjrq-FTL-1.5.13’
unpacking sources
unpacking source archive /tmp/FTL.1.5.13.tar.gz
source root is FTL
installing
/nix/store/20k9ch8wafxf8sg7472p2gq1g3d9kjrq-FTL-1.5.13
now launch the FTL binary with:
$ /nix/store/20k9ch8wafxf8sg7472p2gq1g3d9kjrq-FTL-1.5.13/bin/ftl
if this works for you, issue this command:
$ nix-env -i /nix/store/20k9ch8wafxf8sg7472p2gq1g3d9kjrq-FTL-1.5.13
note: this is very important as it will add /nix/store/20k9ch8wafxf8sg7472p2gq1g3d9kjrq-FTL-1.5.13 to the GCROOTS (garbage collector roots) so it won’t be removed when calling:
$ nix-collect-garbage -d
or
$ nix-store --gc
you can now issue:
$ rm /tmp/FTL.1.5.13.tar.gz
and from now on you can just type ‘ftl’ in any shell to start FTL!
it can be quite some work to get proprietary software running on nixos but thanks to the wiki documentation [2], the good examples at [3] and nix language features like makeWrapper it gets much better.
still waiting for an automation tough ;-)