diff --git a/docs/Build.md b/docs/Build.md index 2bdf9341a..68e0d7d96 100644 --- a/docs/Build.md +++ b/docs/Build.md @@ -10,41 +10,69 @@ The design of the build system has the following main goals: * works identically on every platform * has minimal run-time dependencies: - - a working installation of `stack` + - `stack` - `git` -* is completely functional right after simple `git clone` -* one-stop-shop for building all executables required for using `hie` in IDEs. +* is completely functional right after a simple `git clone` and after every `git pull` +* one-stop-shop for building and naming all executables required for using `hie` in IDEs. +* prevents certain build failures by either identifying a failed precondition (such as wrong `stack` version) or by performing the necessary steps so users can't forget them (such as invoking `git` to update submodules) + + +* is able to modify the environment such that `hie` can be run + - setup `hoogle` database + - setup `hlint` data-files See the project's `README` for detailed information about installing `hie`. -### Tradeoffs +### Targets -#### `shake.yaml` +The build script `install.hs` defines several targets using the `shake` build system. The targets are roughly: -A `shake.yaml` is required for executing the `install.hs` file. +* `hie-*`: builds and installs the `hie` binaries. Also renames the binaries to contain the correct version-number. +* `build`: builds and installs `hie` binaries for all supported `ghc` versions. +* `build-doc`: builds the hoogle-db required by `hie` +* `cabal-*`: execute the same task as the original target, but with `cabal` instead of `stack` -* It contains the required version of `shake`. -* In contrast to the other `*.yaml` it does not contain the submodules, which is necessary for `stack` to work even before the submodules have been initialized. +Each `stack-*.yaml` contains references to packages in the submodules. Calling `stack` with one of those causes the build to fail if the submodules have not been initialized already. The file `shake.yaml` solves this issue invoking the `git` binary itself to update the submodules. Moreover, it specifies the correct version of `shake` and is used for installing all run-time dependencies such as `cabal` and `hoogle` if necessary. -It is necessary to update the `resolver` field of the `shake.yaml` if the script should run with a different `GHC`. +### Run-time dependencies -#### `install.hs` installs a GHC +`hie` depends on a correct environment in order to function properly: -Before the code in `install.hs` can be executed, `stack` installs a `GHC`, depending on the `resolver` field in `shake.yaml`. This is necessary if `install.hs` should be completely functional right after a fresh `git clone` without further configuration. +* `cabal-install`: If no `cabal` executable can be found or has an outdated version, `cabal-install` is installed via `stack`. +* The `hoogle` database: `hoogle generate` needs to be called with the most-recent `hoogle` version. -This may lead to an extra `GHC` to be installed by `stack` if not all versions of `haskell-ide-engine` are installed. +### Steps to build `hie` + +Installing `hie` is a multi-step process: + +1. `git submodule sync && git submodule update --init` +2. `hoogle generate` (`hoogle>=5.0.17` to be safe) +3. ensure that `cabal-install` is installed in the correct version +4. `stack --stack-yaml=stack-.yaml install` or `cabal new-install -w ghc-` +5. rename `hie` binary to `hie-` in `$HOME/.local/bin`, where `` is the GHC version used +6. repeat step 4 and 5 for all desired GHC versions + +This ensures that a complete install is always possible after each `git pull` or a `git clone`. + +### Safety checks + +The `install.hs` script performs some checks to ensure that a correct installation is possible and provide meaningful error messages for known issues. + +* `stack` needs to be up-to-date. Version `1.9.3` is required +* `ghc-8.6.3` is broken on windows. Trying to install `hie-8.6.3` on windows is not possible. +* `cabal new-build` does not work on windows at the moment. All `cabal-*` targets exit with an error message about that. +* When the build fails, an error message, that suggests to remove `.stack-work` directory, is displayed. + +### Tradeoffs #### `stack` is a build dependency Currently, it is not possible to build all `hie-*` executables automatically without `stack`, since the `install.hs` script is executed by `stack`. -Other parts of the script also depend on `stack`: - -* finding the local install-dir `stack path --local-bin` -* finding and installing different `ghc` versions +We are open to suggestions of other build systems that honor the requirements above, but are executable without `stack`. -#### `install.hs` executes `cabal install Cabal` +#### `install.hs` installs a GHC before running -`ghc-mod` installs `cabal-helper` at runtime depending on the `ghc` used by the project, which can take a long time upon startup of `hie`. The `install.hs` script speeds up this process by calling `cabal install Cabal` upon build. +Before the code in `install.hs` can be executed, `stack` installs a `GHC`, depending on the `resolver` field in `shake.yaml`. This is necessary if `install.hs` should be completely functional right after a fresh `git clone` without further configuration. -Hopefully, this behaviour can be removed in the future. +This may lead to an extra `GHC` to be installed by `stack` if not all versions of `haskell-ide-engine` are installed.