diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c8940937da..c945f51517 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -48,6 +48,11 @@ jobs: echo "tests: false" >> cabal.project.local echo "benchmarks: false" >> cabal.project.local + - name: Disable -dynamic + run: | + echo "package haskell-language-server" >> cabal.project.local + echo " flags: -dynamic" >> cabal.project.local + - uses: ./.github/actions/setup-build with: ghc: ${{ matrix.ghc }} diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index fa42040364..842b54d9a9 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -165,34 +165,34 @@ Using an explicit `hie.yaml` to configure the cradle can resolve the problem, se Static binaries use the GHC linker for dynamically loading dependencies when typechecking TH code, and this can run into issues when loading shared objects linked against mismatching system libraries, or into GHC linker bugs (mainly the Mach linker used in Mac OS, but also potentially the ELF linker). Dynamically linked binaries (including`ghci`) use the system linker instead of the GHC linker and avoid both issues. -The easiest way to obtain a dynamically linked HLS binary is to build it locally. With `cabal` this can be done as follows: +The easiest way to obtain a dynamically linked HLS binary is to build HLS locally. With `cabal` this can be done as follows: ```bash -cabal update && cabal install pkg:haskell-language-server --ghc-options="-dynamic" +cabal update && cabal install pkg:haskell-language-server" ``` If you are compiling with a ghc version with a specific `cabal-ghc${ghcVersion}.project` in the repo you will have to use it. For example for ghc-9.0.x: ```bash -cabal update && cabal install pkg:haskell-language-server --project-file=cabal-ghc90.project --ghc-options="-dynamic" +cabal update && cabal install pkg:haskell-language-server --project-file=cabal-ghc90.project" ``` -With `stack` you also need add the ghc option `-dynamic`. +Or with `stack`: ```bash -stack install haskell-language-server --stack-yaml=stack-${ghcVersion}.yaml --ghc-options="-dynamic" +stack install haskell-language-server --stack-yaml=stack-${ghcVersion}.yaml" ``` You also can leverage `ghcup compile hls`: ```bash -ghcup compile hls -g master --ghc 8.10.7 -- --ghc-options="-dynamic" +ghcup compile hls -v 1.6.1.0 --ghc 8.10.7 ``` as it uses cabal underneath you might need to use a specific cabal.project for some ghc versions: ```bash -ghcup compile hls -g master --ghc 9.0.2 --project-file cabal-ghc90.project -- --ghc-options="-dynamic" +ghcup compile hls -v 1.6.1.0 --ghc 9.0.2 --cabal-project cabal-ghc90.project ``` ### Preprocessors diff --git a/haskell-language-server.cabal b/haskell-language-server.cabal index a2a1debdda..689a99e3b5 100644 --- a/haskell-language-server.cabal +++ b/haskell-language-server.cabal @@ -208,6 +208,11 @@ flag brittany default: True manual: True +flag dynamic + description: Build with the dyn rts + default: True + manual: True + common example-plugins hs-source-dirs: plugins/default/src other-modules: Ide.Plugin.Example, @@ -364,6 +369,15 @@ executable haskell-language-server -Wno-unticked-promoted-constructors if flag(pedantic) ghc-options: -Werror + if !os(windows) && flag(dynamic) + -- We want to link against the dyn rts just like official GHC binaries do; + -- the linked rts determines how external libs are loaded dynamically by TH. + -- The standard way of doing this is via the --enable-dynamic-executables Cabal option + -- Unfortunately it doesnt' work, see https://github.com/haskell/haskell-language-server/issues/2659 + -- One can use --ghc-options=-dynamic but this gets applied to the dependencies as well, + -- which results in massive rebuilds and incompatibilities with profiling. + -- So instead we set the -dynamic flag diretly here. + ghc-options: -dynamic build-depends: , aeson