Pin version of nixpkgs for static Haskell building
nh2 opened this issue · 3 comments
Hi! I saw you at ZuriHac, but didn't get a chance to chat more.
I'm trying https://vaibhavsagar.com/blog/2018/01/03/static-haskell-nix/ but have some issues with it:
Pinning nixpkgs
With the nixpkgs version on my system, simply running nix-build
doesn't work. I get:
/nix/store/bm7pb1s7rx1ad80706b5xqrznq7fgpgx-gcc-7.3.0/lib/gcc/x86_64-unknown-linux-gnu/7.3.0/libgcc_eh.a(unwind-dw2-fde-dip.o): In function `_Unwind_Find_FDE':
(.text+0x1d21): undefined reference to `pthread_mutex_unlock'
/nix/store/bm7pb1s7rx1ad80706b5xqrznq7fgpgx-gcc-7.3.0/lib/gcc/x86_64-unknown-linux-gnu/7.3.0/libgcc_eh.a(unwind-dw2-fde-dip.o): In function `__register_frame_info_bases.part.6':
(.text+0x1834): undefined reference to `pthread_mutex_unlock'
/nix/store/bm7pb1s7rx1ad80706b5xqrznq7fgpgx-gcc-7.3.0/lib/gcc/x86_64-unknown-linux-gnu/7.3.0/libgcc_eh.a(unwind-dw2-fde-dip.o): In function `__register_frame_info_table_bases':
(.text+0x1944): undefined reference to `pthread_mutex_unlock'
collect2: error: ld returned 1 exit status
`cc' failed in phase `Linker'. (Exit code: 1)
builder for '/nix/store/v3mwl9jnw29hizhw6rcngs7nrh50c5aj-blank-me-up-0.1.0.0.drv' failed with exit code 1
But if I use a different version of nixpkgs, then it works:
NIX_PATH=nixpkgs=https://github.com/NixOS/nixpkgs/archive/9fdd97fad85ea422549055b8a784139b621a8cdf.tar.gz nix-build
succeeds and creates a nice statically linked executable. That is the latest release-17.09
nixpkgs commit. It doesn't work with the latest release-18.03
nixpkgs commit, so I think pinning is quite important for reproducibility.
Mention in the post what the latest approach to build is
In the blog post you first describe the approach with $ $(nix-build static.nix)/bin/fhs
and so on.
Only much later, in
Edit 1: This turned out to be fairly easy.
do you create default.nix
. But you don't say what do do with it, so a Haskeller not familiar with nix may not guess that they can just run nix-build
at this stage.
It would be nice if you could update the post, mentioning directly something like "the following below is my old approach, right now you can just clone my repo and run nix-build
, it will pick up the default.nix
I made in Edit 1".
Dependency on non-nix stuff in the old approach and build failure
In your old approach you do
$ cabal install --only-dependencies --extra-include-dirs=/usr/include --extra-lib-dirs=/usr/lib
That doesn't look very nixy -- e.g. /usr/include
doesn't exist in nix's concept, and I'm quite sure that can't work on NixOS. What does that do?
Also, on my Ubuntu the next step
$ cabal configure --disable-executable-dynamic --disable-shared --ghc-option=-optl=-static --ghc-option=-optl=-L/usr/lib
failed with
cabal: Encountered missing dependencies:
scotty -any
Where is scotty
supposed to come from in that approach?
Thanks for the post, it is very helpful!
Hi Niklas! It was great to meet you at ZuriHac 😃.
I think pinning is quite important for reproducibility.
I agree, and it is silly that this isn't pinned when I also have another blog post about the importance of pinning nixpkgs
. However, in this case the issue seems to be with GHC 8.2, and adding --ghc-option=-optl=-pthread
to configureFlags
resolves this issue. I will update the blog post. My hope is that the general approach will continue to work so I'd like to avoid pinning nixpkgs
in this blog post if that's feasible.
It would be nice if you could update the post, mentioning directly something like "the following below is my old approach,
The first line of the blog post (in italics) is
Skip to the end for a faster and easier way of getting this working.
but your wording is better. I will think about how to update the post so that it's more apparent that the good stuff is at the end.
That doesn't look very nixy
You're right, it's not, but the approach is useful enough that it's worth talking about anyway. static.nix
sets up a chroot where the FHS is obeyed and directories like /usr/include
exist. The general idea is that Nix (and NixOS) can pretend to be a normal FHS-compliant distro when necessary, which is very useful if there doesn't seem to be a Nix-friendly way of doing something but you need to get it working with minimal modifications. Afterwards it's possible to investigate the Nix-native way of doing things, which is what I did. I think that's the right progression, which is why my blog post is structured like this.
Where is scotty supposed to come from in that approach?
I just ran into the same problem when trying to reproduce my results! I forgot to put cabal update
in the commands to run and I will do that now.
Does this answer your questions?
static.nix sets up a chroot where the FHS is obeyed and directories like /usr/include exist
Aaah, OK, then I just misunderstood it! Makes sense, thanks for the explanation!
My hope is that the general approach will continue to work so I'd like to avoid pinning nixpkgs in this blog post if that's feasible.
It will still quite certainly break when nixpkgs, cabal, ghc and so on change in the future.
If you don't want to pin it in your repository, I recommend to at least write in the blog post something like
To build with exactly the same version I used when writing this post, build with
NIX_PATH=nixpkgs=https://github.com/NixOS/nixpkgs/archive/9fdd97fad85ea422549055b8a784139b621a8cdf.tar.gz nix-build
.
That'll make sure that the first try always works for your readers, and they can leave NIX_PATH
away if they want to build against their current nixpkgs.
Good idea, I've updated the blog post. Thanks for the suggestions!