Changing Linkers on Windows

Compiling Haskell is quite slow on Windows and as far as I can tell the two main culprits aren’t GHC.

  • Windows Defender adds ~30% slowdown during most compilations fo rme
  • Linking is glacial

The Windows Defender part can be fixed by by creating exceptions or disabling real-time protection.

But even without, linking really plays down incremental compilation. When recompiling a small-ish change in haskell-language-server

  • compilation takes ~20s
  • linking takes ~1:20

I’ve tried a bunch of combinations along the lines of

ghc-options: “-pgmP clang” “-pgmc clang” “-pgma clang” “-pgml clang” “-optl-fuse-ld=lld”
ld-options: -fuse-ld=lld

But this causes linking errors. Has anyone gotten other linkers to work on Windows? Ideally I’d love a config line I could drop into stack/cabal config files but at this point I’d be ecstatic about any information.

4 Likes

Hi, are you using stack, chocolatey or ghcup?

These all do different things. Afaik:

  1. stack calls the verbatim ghc.exe binary afaik by adjusting internal paths
  2. chocolatey uses a proprietary shimgen: https://github.com/chocolatey/shimgen#why-is-shimgen-closed-source
  3. ghcup uses an open-source shimgen: https://github.com/71/scoop-better-shimexe

I’d guess that especially method 2 and 3 may trigger windows defender, because ghc invocations run via two binaries. So the distinction may be relevant.

I’m using stack. The slowdown from Windows Defender also happens for other compilers and IDE tooling, though. Maybe the slowdown comes from touching many files?
Some other tools prompt the user to create exceptions https://intellij-support.jetbrains.com/hc/en-us/articles/360006298560-Antivirus-Impact-on-Build-Speed

I noticed that occasionally the slowdown is significantly worse for the haskell-language-server startup in large projects. Either way, creating exceptions can effectively circumvent the problem.

ATM, stock windows GHC is incompatible with LLD.

At least the codegen and RTS linker memory allocator shall be fixed, but even then I’m not sure things will go smooth.

I have a pretty hugely modified GHC (closed source ATM), which uses LLD (and can also use MS Link, but this is much slower), but it targets Visual_C/UCRT runtime.

I plan to check if my codegen and RTS linker memory allocator fixes allow using lld with mingw-w64 runtime (perhaps this would also dictate switching from gcc to clang, I don’t know).

I will open the fixes if they work, but I don’t know when I will have the energy to do it.

6 Likes

Hey @awson, that sounds great! My offer still stands, if you throw over some patches, I’ll work them into upstream GHC.

3 Likes

I do think getting @awson’s stuff open source is the best way to improve Windows support. I am quite sure we could wrangle all the patches of everything (including LLVM) in Nixpkgs very quickly for better cross compilation out of the box before any upstreaming happens. Of course, once it does, the native out-of-the-box situation will improve too.