Skip to content
This repository has been archived by the owner on Oct 7, 2020. It is now read-only.

expand documentation on the build system #1200

Merged
merged 2 commits into from
Apr 25, 2019
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 45 additions & 19 deletions docs/Build.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,67 @@ 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.
* fails with meaningful error messages in known circumstances
nponeccop marked this conversation as resolved.
Show resolved Hide resolved
* 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`
nponeccop marked this conversation as resolved.
Show resolved Hide resolved
* `cabal-*`: execute the same task as the original target, but with `cabal` instead of `stack`
nponeccop marked this conversation as resolved.
Show resolved Hide resolved

* 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. Moreover, it specifies the correct version of `shake` and is used for installing all run-time dependencies such as `cabal` and `hoogle` if necessary.
nponeccop marked this conversation as resolved.
Show resolved Hide resolved

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-<X>.yaml install` or `cabal new-install -w ghc-<X>`
5. rename `hie` binary to `hie-<X>` in `$HOME/.local/bin`, where `<X>` 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` does not work in windows. Trying to install `hie-8.6.3` on windows is not possible
Anrock marked this conversation as resolved.
Show resolved Hide resolved
* `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`:
We are open to suggestions of other build systems that honor the requirements above, but are executable without `stack`.

* finding the local install-dir `stack path --local-bin`
* finding and installing different `ghc` versions
#### `install.hs` installs a GHC before running

#### `install.hs` executes `cabal install Cabal`

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