haskell.nix icon indicating copy to clipboard operation
haskell.nix copied to clipboard

How can I patch remote-iserv and friends?

Open ramirez7 opened this issue 2 years ago • 2 comments

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:

  • The programs' source seem to be bundled with ghc.
  • haskell.nix applies multiple patches to this source code.

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?

ramirez7 avatar Jul 21 '22 18:07 ramirez7

  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.

hamishmack avatar Jul 22 '22 06:07 hamishmack

@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.

angerman avatar Jul 22 '22 08:07 angerman