nh2 / static-haskell-nix

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

Cross-compiling from MacOS #64

Open aidangilmore opened 4 years ago

aidangilmore commented 4 years ago

Is there a way that I could build a statically-linked Linux from Nix on MacOS?

Thanks

nh2 commented 4 years ago

Hey,

not yet, because to my knowledge GHC and Cabal do not have the necessary cross-compiling support for that yet.

But @Ericson2314 is working on that so it may work in the not-too-far future.

Ericson2314 commented 4 years ago

Does

nix-build '<nixpkgs>' --arg crossSystem '{ config = "x86_64-unknown-linux-musl"; useLLVM = true; }' -A hello

work? I don't remember any Haskell-specific issues, but could easily be forgetting things. Maybe @angerman knows?

aidangilmore commented 4 years ago

I can confirm that cross-compiling hello on Darwin works as expected. How would I tweak my default.nix to use cross compiling with static-stack2nix-builder?

nh2 commented 4 years ago

I'm not sure!

If anybody knows, please chime in. I haven't tried to cross-compile static Haskell exes myself yet, so any contributions or insights would be appreciated.

I gave a super quick shot at passing config = "x86_64-unknown-linux-musl"; useLLVM = true; directly to nixpkgs imports, but that currently gets an infinite recursion problem.

angerman commented 4 years ago

static muslc is a special case on Linux. The special part is that you can natively run the muslc executable. This makes issues like TH and others (e.g. you can have a proper stage2 compiler) go away. If you want macOS as a build host you now need some form of executing haskell Linux binaries at compile time (if you want comprehensive compilation capabilities). We can do this for windows with WINE. For macOS there are a few projects that promise a Linux execution layer (e.g. the noah project). But last I checked (for macOS -> Linux cross compilation), it needed substantial patching and even then didn’t support enough Linux to make the programs run.

Even if they run, making sure they behave sufficiently similar is another issue.

What you could do is use vbox to start up a virtual Linux machine and delegate all cl pipe time requirements to that. Or use the splice dumping/loading approach that zeroTH/evil-splicer and obsidian.systems do to get macOS -> Linux cross compilation. Is it worth it? I can’t tell. Would it be cool to have? Absolutely!