input-output-hk / haskell.nix

Alternative Haskell Infrastructure for Nixpkgs
https://input-output-hk.github.io/haskell.nix
Apache License 2.0
558 stars 240 forks source link

How can I patch remote-iserv and friends? #1554

Open ramirez7 opened 2 years ago

ramirez7 commented 2 years ago

I have a long-standing issue with remote-iserv that makes it unusable for me (TH + native libraries result in hanging). I currently don't use TH while x-compiling and have a bash script that uses dumped splices.

I think I've diagnosed the bug by looking at the Haskell source code in my nix store.

It wouldn't be too hard to make the necessary changes, but I have no clue how to change what remote-iserv I am using for a few reasons:

So I have a few questions:

  1. Is there a git repo somewhere with the full version of remote-iserv etc that haskell.nix is using? If I want to make a small change, what would the workflow look like?
  2. How would I best go about using my fix? Forking haskell.nix and adding a patch? Is there some way to build iserv stuff in isolation and only use it for my project (so I don't rebuild the work I assume)? For instance, I could create a fresh project by copying the patched source from the nix store and develop it like any normal cabal project.
  3. Should I look to upstream my fix to ghc? Is there a reason haskell.nix has a bunch of patches instead of upstreaming?
hamishmack commented 2 years ago
  1. To get a copy of the source with all the existing patches applied run:

    nix-build -E 'let pkgs = (import ./. {}).pkgs-unstable; in pkgs.srcOnly pkgs.haskell-nix.compiler.ghc923'
  2. Once you have a patch add it to the list in overlays/bootstrap.nix. Unfortunately nix will probably want to rebuild ghc before you can tell if it works.

    Another option to try out a change before making a patch would be to build the broken components derivation like this:

    nix-shell -E '(import ./. {}).pkgs-unstable.pkgsCross.mingwW64.haskell-nix.tool "ghc8107" "hello" {}'
    cd $(mktemp -d)
    unpackPhase
    cd hello-1.0.0.2-src
    eval "$configurePhase"
    eval "$buildPhase"

    If you run echo "$buildPhase" it will include something like this:

    $SETUP_HS build exe:hello -j$(($NIX_BUILD_CORES > 4 ? 4 : $NIX_BUILD_CORES)) --ghc-option=-fexternal-interpreter --ghc-option=-pgmi --ghc-option=/nix/store/vc5k64fbgb4vakknld66whazg3b2r9ry-iserv-wrapper/bin/iserv-wrapper --ghc-option=-L/nix/store/d246ml0p1cqx4j85n4bw3vbjqsb7iynr-mingw-w64-x86_64-w64-mingw32-9.0.0-pthreads-x86_64-w64-mingw32/lib --ghc-option=-L/nix/store/d246ml0p1cqx4j85n4bw3vbjqsb7iynr-mingw-w64-x86_64-w64-mingw32-9.0.0-pthreads-x86_64-w64-mingw32/bin --ghc-option=-L/nix/store/msdrfvd6cg38gdyr2knaawl0q2py78mk-gmp-with-cxx-x86_64-w64-mingw32-6.2.1/lib

    The /nix/store/...-iserv-wrapper/bin/iserv-wrapper is the wrapper script that GHC will use when this command is run. You can copy the script and modify the line that looks like this:

    ln -s /nix/store/9qwwv2hz4d971w4hfhhv1i9sps0h706r-remote-iserv-exe-remote-iserv-x86_64-w64-mingw32-9.2.3/bin/* $REMOTE_ISERV

    Unfortunately I'm not sure what the best way to build an alternative remote-iserv is. One way might be to modify ghc-extra-projects function in overlays/ghc-packages.nix. For instance you could add modules = [{ packages.libiserv.patches = [ ./somepatch ]; }];. Then run:

    nix-build -A pkgs-unstable.pkgsCross.mingwW64.ghc-extra-packages.ghc923.remote-iserv.components.exes.remote-iser
  3. Some of the patches are back ports of fixes or work arounds for old issues (the ones with low upper bounds). Some of the patches are nix specific changes that would not make sense to upstream. The rest should be in the process of being upstreamed.

angerman commented 2 years ago

@ramirez7 I'd be happy to see your patch! Now the whole iserv siatuon is a bit of a mess. Yes we do apply patches ontop of the GHC source, and the GHC devs (against my preference) moved iserv into a separate repository https://gitlab.haskell.org/ghc/iserv-proxy, outside of the main ghc repo. Whether or not this will be re-integrated in the future will have to be seen.

Your best bet, is as @hamishmack outlined to get the source from the compiler you are working on in haskell.nix, and patch it there. We try to upstream patches to GHC as is reasonable; with the current iserv-proxy split I'm a bit uncertain how to proceed properly though. Maybe it will come as a godsend being outside of the main tree, I can't tell yet.