nh2 / static-haskell-nix

easily build most Haskell programs into fully static Linux executables
388 stars 36 forks source link

mpv, or: how do I override derivation args #101

Closed tek closed 4 years ago

tek commented 4 years ago

https://github.com/tek/static-mpv

See above an example project for building a c2hs binding for libmpv.

First problem I'm running into is that several deps are failing (libapparmor and atomicparsley), both of which are optional and I don't need them. So my impulse was to just pass the flags to deactivate them to the derivation of mpv, as in:

let
  pkgs = builder.haskell-static-nix_output.pkgs;
  mpvPackage = pkgs.mpv.override { sambaSupport = false; };
in
  pkgs.haskell.lib.appendConfigureFlag (
  pkgs.staticHaskellHelpers.addStaticLinkerFlagsWithPkgconfig builder.static_package [mpvPackage] "--libs libmpv"
  ) "--ld-option=-Wl,--start-group --ld-option=-Wl,-lstdc++"

sambaSupport is what triggers the dep on libapparmor, but nix is trying to download it anyway (there is a missing patch).

Can you tell me what is responsible for this? I assume that the cabal2nix generated dep is somehow separated from the one I added manually, so I tried this:

let
  overlay = self: super: {
    mpv = super.mpv.override { sambaSupport = false; };
  };
  pkgs = builder.haskell-static-nix_output.pkgs.appendOverlays [overlay];

but it makes no difference.

tek commented 4 years ago

naturally, describing the problem manifested the solution to me, which is to append the overlay to the normalPkgs argument to static-stack2nix-builder :sweat_smile:

I'll keep this issue open for a minute, since there might be more to do to get mpv working.

tek commented 4 years ago

If you have any suggestions as to fixing the concrete errors, which is a missing patch for libapparmor and a compilation error for atomicparsley, I would attempt to take care of that as well.

FTR:

src/parsley.cpp: In function ‘void APar_MergeTempFile(FILE*, FILE*, uint64_t, uint64_t, char*&)’:                                                                                                                                               
src/parsley.cpp:4393:23: error: cannot convert ‘off_t*’ {aka ‘long int*’} to ‘const fpos_t*’ {aka ‘const _G_fpos64_t*’}
 4393 |    fsetpos(dest_file, &file_offset);                                                                 
      |                       ^~~~~~~~~~~~                                                                   
      |                       |                                                                              
      |                       off_t* {aka long int*}   
In file included from src/AtomicParsley.h:52,                                                                
                 from src/parsley.cpp:30:                                                                    
/nix/store/f1bhhdcjk87i6mz2d34d0lsq2swk11la-musl-1.1.24-dev/include/stdio.h:85:21: note:   initializing argument 2 of ‘int fsetpos(FILE*, const fpos_t*)’
   85 | int fsetpos(FILE *, const fpos_t *);                                                                 
      |                     ^~~~~~~~~~~~~~                                                                   
src/parsley.cpp:4408:23: error: cannot convert ‘off_t*’ {aka ‘long int*’} to ‘const fpos_t*’ {aka ‘const _G_fpos64_t*’}
tek commented 4 years ago

seems I'm hitting a wall with -lEGL…does opengl not work at all?

nh2 commented 4 years ago

seems I'm hitting a wall with -lEGL…does opengl not work at all?

I don't think it does:

https://github.com/nh2/static-haskell-nix/blob/dbce18f4808d27f6a51ce31585078b49c86bd2b5/survey/default.nix#L1342

https://github.com/nh2/static-haskell-nix/blob/dbce18f4808d27f6a51ce31585078b49c86bd2b5/survey/default.nix#L1350

https://github.com/nh2/static-haskell-nix/blob/dbce18f4808d27f6a51ce31585078b49c86bd2b5/survey/default.nix#L1353

OpenGL is traditionally difficult. This is because most OpenGL stacks are set up to find some libGL.so at runtime via dynamic linking, which can then be either provided by AMD, Intel, NVIDIA, and so on.

So while I'm not an expert at this specific topic yet, I think OpenGL requires dynamic linking for now. I have a branch in my nixpkgs submodule where I managed to build statically linked C GTK executables (with Rust and Haskell planned to follow), but IIRC there i compile in software rendering statically, so that isn't proper OpenGL either. I would not be surprised if open-source GPU drivers (like the ones Mesa provides) are the only ones that would even theoretically make it possible to link them statically -- I would be very surprised if NVIDIA allowed to link in their OpenGL implementation statically (but I might be wrong).

nh2 commented 4 years ago

which is a missing patch for libapparmor

This one I cannot reproduce (at least on current nixpkgs master, where pkgsMusl.libapparmor builds fine). Is this for master or my pinned version?

If you have any suggestions as to fixing [...] a compilation error for atomicparsley

For this one I actually have.

When things don't compile with musl, I usually first look in Alpine Linux. In this case: https://git.alpinelinux.org/aports/tree/testing/atomicparsley?h=master (pinned link) which shows that they have a patch musl-fpos_t.patch that sounds related.

I then usually put that patch into my nixpkgs, PR it into nixpkgs, and then also usually PR the patch upstream (in this case to atomicparsley).

tek commented 4 years ago

yes, it's the pinned version. I shall switch to master and try again.

How would I configure the executable to build with only libGL linked dynamically?

As for the compile error, I will take a look at your suggestion!

nh2 commented 4 years ago

How would I configure the executable to build with only libGL linked dynamically?

I'm not super sure, but I expect that linking libgGL.so (or some other realted libraries, see e.g. the various ones listed on https://github.com/NVIDIA/libglvnd/tree/cad3b5230d7be6d65bbabe4e5940c8158e8dd1a7#code-overview) will also require you to link all its dependencies (including a libc) dynamically.

Beyond that I think you can tell it to link specific libraries statically (let's say libpng) via one of those ways:

But these require individual overrides, and and you most likely cannot use the --enable-executable-static Cabal flag that static-haskell-nix defaults to for that because that does fuly static linking.

tek commented 4 years ago

right, I guess then it would be sensible to just link everything dynamically. I'll close this for now, thanks for the advice!