Awesome! I’ve been using this since it was integrated in to the Miso example repo a few weeks ago, but it’s still great to see a proper writeup.
When GHC cross compiles and evaluates a TH splice, it has to load and run code that’s compiled for the target platform.
It’s cool that we’re able to work around this using the external interpreter (I think this is essentially the same as what Haskell.nix does?), though I do hope it all becomes a bit simpler eventually. Most splices are morally platform-independent and should be able to be run on the host. This recent proposal is a big step in the right direction.
That’s right, one thing that impressed me most is haskell.nix has logic for using wine to support windows as a cross target with TH support. It’s a pity this configuration is not yet tested in upstream CI, but understandably IOG teams have their own priorities.
Most splices are morally platform-independent and should be able to be run on the host.
AFAIK there already exist hacks in reflex platform/obelisk to do so (@ryantrinkle doesn’t want to run iserv on an iphone and you gotta agree with him on this one!). Adding support upstream is a huge amount of work though and require changes in both GHC, Cabal as well as all downstream build tools that depend on Cabal.
I fully support the future where we can run TH on the host not the target. Just keep in mind this is not happening anytime soon
I’m curious to try the wasm backend. I tried out the JS backend by compiling Hell (patched to strip out TH) and it worked but was slower than running Hell in GHCi GHC JS backend · GitHub
When I get a spare afternoon I’ll try out the wasm backend and see how it runs. Nice to hear there’s TH support now! Means I could viably do a full “try in your browser” thing.
This is largely a non-issue these days since the advent of the M1 Mac’s. Simplex-Chat for example does build iOS native including TH via iserv on macOS.
Looking forward to your trial report!
I’m curious so I digged a bit; if anyone else wants to figure out how ios works as a Haskell cross target in simplex-chat, simplex-chat/flake.nix at v6.1.1 · simplex-chat/simplex-chat · GitHub might be a good starting point to dig. @angerman Here’s my understanding of your ios cross stack, would be nice if you can correct me if I’m wrong:
simplex does not use the iphone64-simulator
nixpkgs cross target at all. Instead it uses mac2ios to patch regular macos macho objects to ios objects so the objects can be linked into the final ios app. For TH it runs iserv-proxy
on the macos host, since regular iserv
doesn’t support cross compilation, but iserv-proxy
still loads mac objects under the hood?
It’s probably a ways off, but shipping better cross support with ghc proper for stuff like linux-host/mingw-target would be a dream. Maybe the JS and wasm backends are going to be forcing functions to get things more amenable to that.
Not that I dislike using haskell.nix. It works great (although I have run into very niche bugs because…I’m doing very niche stuff) but it is giant layer of indirection & patches etc. Compared to, say, Golang where it’s super simple and batteries included. Lots of implementation details why that is of course, but still
It’s possible but takes extra work:
- Move
iserv-proxy
back to the GHC tree. It introduces extra dependencies likenetwork
which need to be acknowledged by hadrian, which was the main reason it was moved out of tree in the first place to avoid adding extra boot libraries and block GHC releases. But if someone is there to keep this maintained then it should be fine, especially since it’s not built by most GHC configurations. - Add a CI job that tests linux->windows cross compilation using
iserv-proxy
andwine
for TH. haskell.nix/overlays/mingw_w64.nix at master · input-output-hk/haskell.nix · GitHub is the place where this logic is implemented in haskell.nix and this needs to be ported to a non-nix ci-images container.
Update: I’ve opened #25523: Support invoking iserv via target wrapper · Issues · Glasgow Haskell Compiler / GHC · GitLab to track this feature request. iserv-proxy
might not be needed, we just need to build iserv
as a target executable and teach ghc to invoke it via a target wrapper. I’ll likely not work on it myself any time soon though.