Update README
This commit is contained in:
		
							parent
							
								
									e5a0f836a4
								
							
						
					
					
						commit
						0381ccef64
					
				
							
								
								
									
										594
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										594
									
								
								README.md
									
									
									
									
									
								
							@ -1,10 +1,6 @@
 | 
			
		||||
`ghcup` makes it easy to install specific versions of `ghc` on GNU/Linux,
 | 
			
		||||
macOS (aka Darwin), FreeBSD and Windows and can also bootstrap a fresh Haskell developer environment from scratch.
 | 
			
		||||
It follows the unix UNIX philosophy of [do one thing and do it well](https://en.wikipedia.org/wiki/Unix_philosophy#Do_One_Thing_and_Do_It_Well).
 | 
			
		||||
## The GHCup Haskell installer
 | 
			
		||||
 | 
			
		||||
Similar in scope to [rustup](https://github.com/rust-lang-nursery/rustup.rs), [pyenv](https://github.com/pyenv/pyenv) and [jenv](http://www.jenv.be).
 | 
			
		||||
 | 
			
		||||
## Table of Contents
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
[](https://kiwiirc.com/nextclient/irc.libera.chat/?nick=Guest%7C?#haskell,#haskell-ghcup)
 | 
			
		||||
[](https://app.element.io/#/room/#haskell-tooling:matrix.org)
 | 
			
		||||
@ -12,588 +8,6 @@ Similar in scope to [rustup](https://github.com/rust-lang-nursery/rustup.rs), [p
 | 
			
		||||
[](https://gitter.im/haskell/ghcup?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
 | 
			
		||||
<a href="https://opencollective.com/ghcup#category-CONTRIBUTE"><img src="https://opencollective.com/webpack/donate/button@2x.png?color=blue" alt="Donate" width="150"></a>
 | 
			
		||||
 | 
			
		||||
   * [Installation](#installation)
 | 
			
		||||
     * [Supported platforms](#supported-platforms)
 | 
			
		||||
     * [Manual install](#manual-install)
 | 
			
		||||
     * [Vim integration](#vim-integration)
 | 
			
		||||
   * [Usage](#usage)
 | 
			
		||||
     * [Configuration](#configuration)
 | 
			
		||||
     * [GPG verification](#gpg-verification)
 | 
			
		||||
     * [Manpages](#manpages)
 | 
			
		||||
     * [Shell-completion](#shell-completion)
 | 
			
		||||
     * [Compiling GHC from source](#compiling-ghc-from-source)
 | 
			
		||||
     * [XDG support](#xdg-support)
 | 
			
		||||
     * [Env variables](#env-variables)
 | 
			
		||||
     * [Installing custom bindists](#installing-custom-bindists)
 | 
			
		||||
     * [Isolated Installs](#isolated-installs)
 | 
			
		||||
     * [CI](#ci)
 | 
			
		||||
     * [Tips and tricks](#tips-and-tricks)
 | 
			
		||||
   * [Design goals](#design-goals)
 | 
			
		||||
   * [How](#how)
 | 
			
		||||
   * [Known users](#known-users)
 | 
			
		||||
   * [Known problems](#known-problems)
 | 
			
		||||
   * [FAQ](#faq)
 | 
			
		||||
GHCup is an installer for the general purpose language [Haskell](https://www.haskell.org/).
 | 
			
		||||
 | 
			
		||||
## Installation
 | 
			
		||||
 | 
			
		||||
Most users should follow the instructions at [https://www.haskell.org/ghcup/](https://www.haskell.org/ghcup/).
 | 
			
		||||
Advanced users may want to perform a [manual installation](#manual-install).
 | 
			
		||||
 | 
			
		||||
### Supported platforms
 | 
			
		||||
 | 
			
		||||
This list may not be exhaustive and specifies support for bindists only.
 | 
			
		||||
 | 
			
		||||
| Platform | Architecture | ghcup | GHC | cabal | HLS | stack | 
 | 
			
		||||
| ------ | ------ | ------ | ------ | ------ | ------ | ------ |
 | 
			
		||||
| Windows 7 | amd64 | ❔ | ✅ | ✅ | ✅ | ✅ |
 | 
			
		||||
| Windows 10 | amd64 | ✅ | ✅ | ✅ | ✅ | ✅ |
 | 
			
		||||
| Windows Server 2016 | amd64 | ✅ | ✅ | ✅ | ✅ | ✅ |
 | 
			
		||||
| Windows Server 2019 | amd64 | ✅ | ✅ | ✅ | ✅ | ✅ |
 | 
			
		||||
| Windows Server 2022 | amd64 | ✅ | ✅ | ✅ | ✅ | ✅ |
 | 
			
		||||
| Windows WSL1 | amd64 | ❌ | ❔ | ❔ | ❔ | ❔ |
 | 
			
		||||
| Windows WSL2 | amd64 | ✅ | ✅ | ✅ | ✅ | ✅ |
 | 
			
		||||
| MacOS >=13 | amd64 | ✅ | ✅ | ✅ | ✅ | ✅ |
 | 
			
		||||
| MacOS <13 | amd64 | ❌ | ❔ | ❔ | ❔ | ❔ |
 | 
			
		||||
| MacOS | aarch64 | ✅ | ✅ | ✅ | ⚠️ | ❌ |
 | 
			
		||||
| FreeBSD | amd64 | ✅ | ⚠️ | ✅ | ⚠️ | ❌ |
 | 
			
		||||
| Linux generic | x86 | ✅ | ✅ | ✅ | ✅ | ✅ |
 | 
			
		||||
| Linux generic | amd64 | ✅ | ✅ | ✅ | ✅ | ✅ |
 | 
			
		||||
| Linux generic | aarch64 | ✅ | ⚠️ | ✅ | ⚠️ | ❌ |
 | 
			
		||||
| Linux generic | armv7 | ✅ | ⚠️ | ✅ | ⚠️ | ❌ |
 | 
			
		||||
 | 
			
		||||
#### Windows 7
 | 
			
		||||
 | 
			
		||||
May or may not work, several issues:
 | 
			
		||||
 | 
			
		||||
* https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/140
 | 
			
		||||
* https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/197
 | 
			
		||||
 | 
			
		||||
#### WSL1
 | 
			
		||||
 | 
			
		||||
Unsupported. GHC may or may not work. Upgrade to WSL2.
 | 
			
		||||
 | 
			
		||||
#### MacOS <13
 | 
			
		||||
 | 
			
		||||
Not supported. Would require separate binaries, since >=13 binaries are incompatible.
 | 
			
		||||
Please upgrade.
 | 
			
		||||
 | 
			
		||||
#### MacOS aarch64
 | 
			
		||||
 | 
			
		||||
HLS bindists are still experimental. Stack is theoretically supported, but has no binaries yet.
 | 
			
		||||
 | 
			
		||||
#### FreeBSD
 | 
			
		||||
 | 
			
		||||
Lacks some upstream bindists and may need compat libs, since most bindists are built on FreeBSD-12.
 | 
			
		||||
HLS bindists are experimental.
 | 
			
		||||
 | 
			
		||||
#### Linux ARMv7/AARCH64
 | 
			
		||||
 | 
			
		||||
Lower availability of bindists. HLS only has experimental ones. Stack not supported currently.
 | 
			
		||||
 | 
			
		||||
### Manual install
 | 
			
		||||
 | 
			
		||||
Download the binary for your platform at [https://downloads.haskell.org/~ghcup/](https://downloads.haskell.org/~ghcup/)
 | 
			
		||||
and place it into your `PATH` anywhere.
 | 
			
		||||
 | 
			
		||||
Then adjust your `PATH` in `~/.bashrc` (or similar, depending on your shell) like so:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
export PATH="$HOME/.cabal/bin:$HOME/.ghcup/bin:$PATH"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Vim integration
 | 
			
		||||
 | 
			
		||||
See [ghcup.vim](https://github.com/hasufell/ghcup.vim).
 | 
			
		||||
 | 
			
		||||
## Usage
 | 
			
		||||
 | 
			
		||||
See `ghcup --help`.
 | 
			
		||||
 | 
			
		||||
For the simple interactive TUI, run:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
ghcup tui
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For the full functionality via cli:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
# list available ghc/cabal versions
 | 
			
		||||
ghcup list
 | 
			
		||||
 | 
			
		||||
# install the recommended GHC version
 | 
			
		||||
ghcup install ghc
 | 
			
		||||
 | 
			
		||||
# install a specific GHC version
 | 
			
		||||
ghcup install ghc 8.2.2
 | 
			
		||||
 | 
			
		||||
# set the currently "active" GHC version
 | 
			
		||||
ghcup set ghc 8.4.4
 | 
			
		||||
 | 
			
		||||
# install cabal-install
 | 
			
		||||
ghcup install cabal
 | 
			
		||||
 | 
			
		||||
# update ghcup itself
 | 
			
		||||
ghcup upgrade
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
GHCup works very well with [`cabal-install`](https://hackage.haskell.org/package/cabal-install), which
 | 
			
		||||
handles your haskell packages and can demand that [a specific version](https://cabal.readthedocs.io/en/latest/nix-local-build.html#cfg-flag---with-compiler)  of `ghc` is available, which `ghcup` can do.
 | 
			
		||||
 | 
			
		||||
### Configuration
 | 
			
		||||
 | 
			
		||||
A configuration file can be put in `~/.ghcup/config.yaml`. The default config file
 | 
			
		||||
explaining all possible configurations can be found in this repo: [config.yaml](./data/config.yaml).
 | 
			
		||||
 | 
			
		||||
Partial configuration is fine. Command line options always override the config file settings.
 | 
			
		||||
 | 
			
		||||
### GPG verification
 | 
			
		||||
 | 
			
		||||
GHCup supports verifying the GPG signature of the metadata file. The metadata file then contains SHA256 hashes of all downloads, so
 | 
			
		||||
this is cryptographically secure.
 | 
			
		||||
 | 
			
		||||
First, obtain the gpg key:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
gpg --batch --keyserver keys.openpgp.org --recv-keys 7784930957807690A66EBDBE3786C5262ECB4A3F
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Then verify the gpg key in one of these ways:
 | 
			
		||||
 | 
			
		||||
1. find out where I live and visit me to do offline key signing
 | 
			
		||||
2. figure out my mobile phone number and call me to verify the fingerprint
 | 
			
		||||
3. more boring: contact me on Libera IRC (`maerwald`) and verify the fingerprint
 | 
			
		||||
 | 
			
		||||
Once you've verified the key, you have to figure out if you trust me.
 | 
			
		||||
 | 
			
		||||
If you trust me, then you can configure gpg in `~/.ghcup/config.yaml`:
 | 
			
		||||
 | 
			
		||||
```yml
 | 
			
		||||
gpg-setting: GPGLax # GPGStrict | GPGLax | GPGNone
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
In `GPGStrict` mode, ghcup will fail if verification fails. In `GPGLax` mode it will just print a warning.
 | 
			
		||||
You can also pass the mode via `ghcup --gpg <strict|lax|none>`.
 | 
			
		||||
 | 
			
		||||
### Manpages
 | 
			
		||||
 | 
			
		||||
For man pages to work you need [man-db](http://man-db.nongnu.org/) as your `man` provider, then issue `man ghc`. Manpages only work for the currently set ghc.
 | 
			
		||||
`MANPATH` may be required to be unset.
 | 
			
		||||
 | 
			
		||||
### Shell-completion
 | 
			
		||||
 | 
			
		||||
Shell completions are in [scripts/shell-completions](./scripts/shell-completions) directory of this repository.
 | 
			
		||||
 | 
			
		||||
For bash: install `shell-completions/bash`
 | 
			
		||||
as e.g. `/etc/bash_completion.d/ghcup` (depending on distro)
 | 
			
		||||
and make sure your bashrc sources the startup script
 | 
			
		||||
(`/usr/share/bash-completion/bash_completion` on some distros).
 | 
			
		||||
 | 
			
		||||
### Compiling GHC from source
 | 
			
		||||
 | 
			
		||||
Compiling from source is supported for both source tarballs and arbitrary git refs. See `ghcup compile ghc --help`
 | 
			
		||||
for a list of all available options.
 | 
			
		||||
 | 
			
		||||
If you need to overwrite the existing `build.mk`, check the default files
 | 
			
		||||
in [data/build_mk](./data/build_mk), copy them somewhere, adjust them and
 | 
			
		||||
pass `--config path/to/build.mk` to `ghcup compile ghc`.
 | 
			
		||||
Common `build.mk` options are explained [here](https://gitlab.haskell.org/ghc/ghc/-/wikis/building/using#build-configuration).
 | 
			
		||||
 | 
			
		||||
Make sure your system meets all the [prerequisites](https://gitlab.haskell.org/ghc/ghc/-/wikis/building/preparation).
 | 
			
		||||
 | 
			
		||||
#### Cross support
 | 
			
		||||
 | 
			
		||||
ghcup can compile and install a cross GHC for any target. However, this
 | 
			
		||||
requires that the build host has a complete cross toolchain and various
 | 
			
		||||
libraries installed for the target platform.
 | 
			
		||||
 | 
			
		||||
Consult the GHC documentation on the [prerequisites](https://gitlab.haskell.org/ghc/ghc/-/wikis/building/cross-compiling#tools-to-install).
 | 
			
		||||
For distributions with non-standard locations of cross toolchain and
 | 
			
		||||
libraries, this may need some tweaking of `build.mk` or configure args.
 | 
			
		||||
See `ghcup compile ghc --help` for further information.
 | 
			
		||||
 | 
			
		||||
### XDG support
 | 
			
		||||
 | 
			
		||||
To enable XDG style directories, set the environment variable `GHCUP_USE_XDG_DIRS` to anything.
 | 
			
		||||
 | 
			
		||||
Then you can control the locations via XDG environment variables as such:
 | 
			
		||||
 | 
			
		||||
* `XDG_DATA_HOME`: GHCs will be unpacked in `ghcup/ghc` subdir (default: `~/.local/share`)
 | 
			
		||||
* `XDG_CACHE_HOME`: logs and download files will be stored in `ghcup` subdir (default: `~/.cache`)
 | 
			
		||||
* `XDG_BIN_HOME`: binaries end up here (default: `~/.local/bin`)
 | 
			
		||||
* `XDG_CONFIG_HOME`: the config file is stored in `ghcup` subdir as `config.yaml` (default: `~/.config`)
 | 
			
		||||
 | 
			
		||||
**Note that `ghcup` makes some assumptions about structure of files in `XDG_BIN_HOME`. So if you have other tools
 | 
			
		||||
installing e.g. stack/cabal/ghc into it, this will likely clash. In that case consider disabling XDG support.**
 | 
			
		||||
 | 
			
		||||
### Env variables
 | 
			
		||||
 | 
			
		||||
This is the complete list of env variables that change GHCup behavior:
 | 
			
		||||
 | 
			
		||||
* `GHCUP_USE_XDG_DIRS`: see [XDG support](#xdg-support) above
 | 
			
		||||
* `TMPDIR`: where ghcup does the work (unpacking, building, ...)
 | 
			
		||||
* `GHCUP_INSTALL_BASE_PREFIX`: the base of ghcup (default: `$HOME`)
 | 
			
		||||
* `GHCUP_CURL_OPTS`: additional options that can be passed to curl
 | 
			
		||||
* `GHCUP_WGET_OPTS`: additional options that can be passed to wget
 | 
			
		||||
* `GHCUP_GPG_OPTS`: additional options that can be passed to gpg
 | 
			
		||||
* `GHCUP_SKIP_UPDATE_CHECK`: Skip the (possibly annoying) update check when you run a command
 | 
			
		||||
* `CC`/`LD` etc.: full environment is passed to the build system when compiling GHC via GHCup
 | 
			
		||||
 | 
			
		||||
### Installing custom bindists
 | 
			
		||||
 | 
			
		||||
There are a couple of good use cases to install custom bindists:
 | 
			
		||||
 | 
			
		||||
1. manually built bindists (e.g. with patches)
 | 
			
		||||
  - example: `ghcup install ghc -u 'file:///home/mearwald/tmp/ghc-eff-patches/ghc-8.10.2-x86_64-deb10-linux.tar.xz' 8.10.2-eff`
 | 
			
		||||
2. GHC head CI bindists
 | 
			
		||||
  - example: `ghcup install ghc -u 'https://gitlab.haskell.org/api/v4/projects/1/jobs/artifacts/master/raw/ghc-x86_64-fedora27-linux.tar.xz?job=validate-x86_64-linux-fedora27' head`
 | 
			
		||||
3. DWARF bindists
 | 
			
		||||
  - example: `ghcup install ghc -u 'https://downloads.haskell.org/~ghc/8.10.2/ghc-8.10.2-x86_64-deb10-linux-dwarf.tar.xz' 8.10.2-dwarf`
 | 
			
		||||
 | 
			
		||||
Since the version parser is pretty lax, `8.10.2-eff` and `head` are both valid versions
 | 
			
		||||
and produce the binaries `ghc-8.10.2-eff` and `ghc-head` respectively.
 | 
			
		||||
GHCup always needs to know which version the bindist corresponds to (this is not automatically
 | 
			
		||||
detected).
 | 
			
		||||
 | 
			
		||||
### Isolated installs
 | 
			
		||||
 | 
			
		||||
Ghcup also enables you to install a tool (GHC, Cabal, HLS, Stack) at an isolated location of your choosing.
 | 
			
		||||
These installs, as the name suggests, are separate from your main installs and DO NOT conflict with them.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
- No symlinks are made to these isolated installed tools, you'd have to manually point to them wherever you intend to use them.
 | 
			
		||||
 | 
			
		||||
- These installs, can also NOT be deleted from ghcup, you'd have to go and manually delete these.
 | 
			
		||||
 | 
			
		||||
You need to use the `--isolate` or `-i` flag followed by the directory path.
 | 
			
		||||
 | 
			
		||||
Examples:-
 | 
			
		||||
 | 
			
		||||
1. install an isolated GHC version at location /home/user/isolated_dir/ghc/  
 | 
			
		||||
   - `ghcup install ghc 8.10.5 --isolate /home/user/isolated_dir/ghc`
 | 
			
		||||
 | 
			
		||||
2. isolated install Cabal at a location you desire  
 | 
			
		||||
   - `ghcup install cabal --isolate /home/username/my_isolated_dir/`
 | 
			
		||||
 | 
			
		||||
3. do an isolated install with a custom bindist  
 | 
			
		||||
   - `ghcup install ghc --isolate /home/username/my_isolated_dir/ -u 'https://gitlab.haskell.org/api/v4/projects/1/jobs/artifacts/master/raw/ghc-x86_64-fedora27-linux.tar.xz?job=validate-x86_64-linux-fedora27' head`
 | 
			
		||||
 | 
			
		||||
4. isolated install HLS  
 | 
			
		||||
   - `ghcup install hls --isolate /home/username/dir/hls/`
 | 
			
		||||
 | 
			
		||||
5. you can even compile ghc to an isolated location.  
 | 
			
		||||
   - `ghcup compile ghc -j 4 -v 9.0.1 -b 8.10.5 -i /home/username/my/dir/ghc` 
 | 
			
		||||
   ---  
 | 
			
		||||
 | 
			
		||||
### CI
 | 
			
		||||
 | 
			
		||||
On windows, ghcup can be installed automatically on a CI runner like so:
 | 
			
		||||
 | 
			
		||||
```ps
 | 
			
		||||
Set-ExecutionPolicy Bypass -Scope Process -Force;[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;Invoke-Command -ScriptBlock ([ScriptBlock]::Create((Invoke-WebRequest https://www.haskell.org/ghcup/sh/bootstrap-haskell.ps1 -UseBasicParsing))) -ArgumentList $false,$true,$true,$false,$false,$false,$false,"C:\"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
On linux/darwin/freebsd, run the following on your runner:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | BOOTSTRAP_HASKELL_NONINTERACTIVE=1 BOOTSTRAP_HASKELL_MINIMAL=1 sh
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This will just install `ghcup` and on windows additionally `msys2`.
 | 
			
		||||
 | 
			
		||||
#### Example github workflow
 | 
			
		||||
 | 
			
		||||
On github workflows you can use https://github.com/haskell/actions/
 | 
			
		||||
 | 
			
		||||
If you want to install ghcup manually though, here's an example config:
 | 
			
		||||
 | 
			
		||||
```yml
 | 
			
		||||
name: Haskell CI
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches: [ master ]
 | 
			
		||||
  pull_request:
 | 
			
		||||
    branches: [ master ]
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build-cabal:
 | 
			
		||||
 | 
			
		||||
    runs-on: ${{ matrix.os }}
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
      matrix:
 | 
			
		||||
        os: [ubuntu-latest, macOS-latest, windows-latest]
 | 
			
		||||
        ghc: ['8.10.7', '9.0.1']
 | 
			
		||||
        cabal: ['3.4.0.0']
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
    - uses: actions/checkout@v2
 | 
			
		||||
 | 
			
		||||
    - if: matrix.os == 'windows-latest'
 | 
			
		||||
      name: Install ghcup on windows
 | 
			
		||||
      run: Set-ExecutionPolicy Bypass -Scope Process -Force;[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;Invoke-Command -ScriptBlock ([ScriptBlock]::Create((Invoke-WebRequest https://www.haskell.org/ghcup/sh/bootstrap-haskell.ps1 -UseBasicParsing))) -ArgumentList $false,$true,$true,$false,$false,$false,$false,"C:\"
 | 
			
		||||
 | 
			
		||||
    - if: matrix.os == 'windows-latest'
 | 
			
		||||
      name: Add ghcup to PATH
 | 
			
		||||
      run: echo "/c/ghcup/bin" >> $GITHUB_PATH
 | 
			
		||||
      shell: bash
 | 
			
		||||
 | 
			
		||||
    - if: matrix.os != 'windows-latest'
 | 
			
		||||
      name: Install ghcup on non-windows
 | 
			
		||||
      run: curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | BOOTSTRAP_HASKELL_NONINTERACTIVE=1 BOOTSTRAP_HASKELL_MINIMAL=1 sh
 | 
			
		||||
 | 
			
		||||
    - name: Install ghc/cabal
 | 
			
		||||
      run: |
 | 
			
		||||
        ghcup install ghc ${{ matrix.ghc }}
 | 
			
		||||
        ghcup install cabal ${{ matrix.cabal }}
 | 
			
		||||
      shell: bash
 | 
			
		||||
 | 
			
		||||
    - name: Update cabal index
 | 
			
		||||
      run: cabal update
 | 
			
		||||
      shell: bash
 | 
			
		||||
 | 
			
		||||
    - name: Build
 | 
			
		||||
      run: cabal build --enable-tests --enable-benchmarks
 | 
			
		||||
      shell: bash
 | 
			
		||||
 | 
			
		||||
    - name: Run tests
 | 
			
		||||
      run: cabal test
 | 
			
		||||
      shell: bash
 | 
			
		||||
```
 | 
			
		||||
   
 | 
			
		||||
### Tips and tricks
 | 
			
		||||
 | 
			
		||||
#### with_ghc wrapper (e.g. for HLS)
 | 
			
		||||
 | 
			
		||||
Due to some HLS [bugs](https://github.com/mpickering/hie-bios/issues/194) it's necessary that the `ghc` in PATH
 | 
			
		||||
is the one defined in `cabal.project`. With some simple shell functions, we can start our editor with the appropriate
 | 
			
		||||
path prepended.
 | 
			
		||||
 | 
			
		||||
For bash, in e.g. `~/.bashrc` define:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
with_ghc() {
 | 
			
		||||
  local np=$(ghcup --offline whereis -d ghc $1 || { ghcup --cache install ghc $1 && ghcup whereis -d ghc $1 ;})
 | 
			
		||||
  if [ -e "${np}" ] ; then
 | 
			
		||||
    shift
 | 
			
		||||
    PATH="$np:$PATH" "$@"
 | 
			
		||||
  else
 | 
			
		||||
    >&2 echo "Cannot find or install GHC version $1"
 | 
			
		||||
    return 1
 | 
			
		||||
  fi
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For fish shell, in e.g. `~/.config/fish/config.fish` define:
 | 
			
		||||
 | 
			
		||||
```fish
 | 
			
		||||
function with_ghc
 | 
			
		||||
  set --local np (ghcup --offline whereis -d ghc $argv[1] ; or begin ghcup --cache install ghc $argv[1] ; and ghcup whereis -d ghc $argv[1] ; end)
 | 
			
		||||
  if test -e "$np"
 | 
			
		||||
    PATH="$np:$PATH" $argv[2..-1]
 | 
			
		||||
  else
 | 
			
		||||
    echo "Cannot find or install GHC version $argv[1]" 1>&2
 | 
			
		||||
    return 1
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Then start a new shell and issue:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
# replace 'code' with your editor
 | 
			
		||||
with_ghc 8.10.5 code path/to/haskell/source
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Cabal and HLS will now see `8.10.5` as the primary GHC, without the need to
 | 
			
		||||
run `ghcup set` all the time when switching between projects.
 | 
			
		||||
 | 
			
		||||
## Design goals
 | 
			
		||||
 | 
			
		||||
1. simplicity
 | 
			
		||||
2. non-interactive
 | 
			
		||||
3. portable (eh)
 | 
			
		||||
4. do one thing and do it well (UNIX philosophy)
 | 
			
		||||
 | 
			
		||||
### Non-goals
 | 
			
		||||
 | 
			
		||||
1. invoking `sudo`, `apt-get` or *any* package manager
 | 
			
		||||
2. handling system packages
 | 
			
		||||
3. handling cabal projects
 | 
			
		||||
4. being a stack alternative
 | 
			
		||||
 | 
			
		||||
## How
 | 
			
		||||
 | 
			
		||||
Installs a specified GHC version into `~/.ghcup/ghc/<ver>`, and places `ghc-<ver>` symlinks in `~/.ghcup/bin/`.
 | 
			
		||||
 | 
			
		||||
Optionally, an unversioned `ghc` link can point to a default version of your choice.
 | 
			
		||||
 | 
			
		||||
This uses precompiled GHC binaries that have been compiled on fedora/debian by [upstream GHC](https://www.haskell.org/ghc/download_ghc_8_6_1.html#binaries).
 | 
			
		||||
 | 
			
		||||
Alternatively, you can also tell it to compile from source (note that this might fail due to missing requirements).
 | 
			
		||||
 | 
			
		||||
In addition this script can also install `cabal-install`.
 | 
			
		||||
 | 
			
		||||
## Known users
 | 
			
		||||
 | 
			
		||||
* Github actions:
 | 
			
		||||
	- [actions/virtual-environments](https://github.com/actions/virtual-environments)
 | 
			
		||||
	- [haskell/actions/setup](https://github.com/haskell/actions/tree/main/setup)
 | 
			
		||||
* mirrors:
 | 
			
		||||
	- [sjtug](https://mirror.sjtu.edu.cn/docs/ghcup)
 | 
			
		||||
* tools:
 | 
			
		||||
	- [vabal](https://github.com/Franciman/vabal)
 | 
			
		||||
 | 
			
		||||
## Known problems
 | 
			
		||||
 | 
			
		||||
### Custom ghc version names
 | 
			
		||||
 | 
			
		||||
When installing ghc bindists with custom version names as outlined in
 | 
			
		||||
[installing custom bindists](#installing-custom-bindists), then cabal might
 | 
			
		||||
be unable to find the correct `ghc-pkg` (also see [#73](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/73))
 | 
			
		||||
if you use `cabal build --with-compiler=ghc-foo`. Instead, point it to the full path, such as:
 | 
			
		||||
`cabal build --with-compiler=$HOME/.ghcup/ghc/<version-name>/bin/ghc` or set that GHC version
 | 
			
		||||
as the current one via: `ghcup set ghc <version-name>`.
 | 
			
		||||
 | 
			
		||||
This problem doesn't exist for regularly installed GHC versions.
 | 
			
		||||
 | 
			
		||||
### Limited distributions supported
 | 
			
		||||
 | 
			
		||||
Currently only GNU/Linux distributions compatible with the [upstream GHC](https://www.haskell.org/ghc/download_ghc_8_6_1.html#binaries) binaries are supported.
 | 
			
		||||
 | 
			
		||||
### Precompiled binaries
 | 
			
		||||
 | 
			
		||||
Since this uses precompiled binaries you may run into
 | 
			
		||||
several problems.
 | 
			
		||||
 | 
			
		||||
#### Missing libtinfo (ncurses)
 | 
			
		||||
 | 
			
		||||
You may run into problems with *ncurses* and **missing libtinfo**, in case
 | 
			
		||||
your distribution doesn't use the legacy way of building
 | 
			
		||||
ncurses and has no compatibility symlinks in place.
 | 
			
		||||
 | 
			
		||||
Ask your distributor on how to solve this or
 | 
			
		||||
try to compile from source via `ghcup compile <version>`.
 | 
			
		||||
 | 
			
		||||
#### Libnuma required
 | 
			
		||||
 | 
			
		||||
This was a [bug](https://ghc.haskell.org/trac/ghc/ticket/15688) in the build system of some GHC versions that lead to
 | 
			
		||||
unconditionally enabled libnuma support. To mitigate this you might have to install the libnuma
 | 
			
		||||
package of your distribution. See [here](https://gitlab.haskell.org/haskell/ghcup/issues/58) for a discussion.
 | 
			
		||||
 | 
			
		||||
### Compilation
 | 
			
		||||
 | 
			
		||||
Although this script can compile GHC for you, it's just a very thin
 | 
			
		||||
wrapper around the build system. It makes no effort in trying
 | 
			
		||||
to figure out whether you have the correct toolchain and
 | 
			
		||||
the correct dependencies. Refer to [the official docs](https://ghc.haskell.org/trac/ghc/wiki/Building/Preparation/Linux)
 | 
			
		||||
on how to prepare your environment for building GHC.
 | 
			
		||||
 | 
			
		||||
### Stack support
 | 
			
		||||
 | 
			
		||||
There may be a number of bugs when trying to make ghcup installed GHC versions work with stack,
 | 
			
		||||
such as:
 | 
			
		||||
 | 
			
		||||
- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/188
 | 
			
		||||
 | 
			
		||||
Further, stack's upgrade procedure may break/confuse ghcup. There are a number of integration
 | 
			
		||||
issues discussed here:
 | 
			
		||||
 | 
			
		||||
- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/153
 | 
			
		||||
 | 
			
		||||
### Windows support
 | 
			
		||||
 | 
			
		||||
Windows support is in early stages. Since windows doesn't support symbolic links properly,
 | 
			
		||||
ghcup uses a [shimgen wrapper](https://github.com/71/scoop-better-shimexe). It seems to work
 | 
			
		||||
well, but there may be unknown issues with that approach.
 | 
			
		||||
 | 
			
		||||
Windows 7 and Powershell 2.0 aren't well supported at the moment, also see:
 | 
			
		||||
 | 
			
		||||
- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/140
 | 
			
		||||
- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/197
 | 
			
		||||
 | 
			
		||||
## FAQ
 | 
			
		||||
 | 
			
		||||
### Why reimplement stack?
 | 
			
		||||
 | 
			
		||||
GHCup is not a reimplementation of stack. The only common part is automatic installation of GHC,
 | 
			
		||||
but even that differs in scope and design.
 | 
			
		||||
 | 
			
		||||
### Why should I use ghcup over stack?
 | 
			
		||||
 | 
			
		||||
GHCup is not a replacement for stack. Instead, it supports installing and managing stack versions.
 | 
			
		||||
It does the same for cabal, GHC and HLS. As such, It doesn't make a workflow choice for you.
 | 
			
		||||
 | 
			
		||||
### Why should I let ghcup manage stack?
 | 
			
		||||
 | 
			
		||||
You don't need to. However, some users seem to prefer to have a central tool that manages cabal and stack
 | 
			
		||||
at the same time. Additionally, it can allow better sharing of GHC installation across these tools.
 | 
			
		||||
Also see:
 | 
			
		||||
 | 
			
		||||
* https://docs.haskellstack.org/en/stable/yaml_configuration/#system-ghc
 | 
			
		||||
* https://github.com/commercialhaskell/stack/pull/5585
 | 
			
		||||
 | 
			
		||||
### Why does ghcup not use stack code?
 | 
			
		||||
 | 
			
		||||
Oddly, this question has been asked a couple of times. For the curious, here are a few reasons:
 | 
			
		||||
 | 
			
		||||
1. GHCup started as a shell script. At the time of rewriting it in Haskell, the authors didn't even know that stack exposes *some* of its [installation API](https://hackage.haskell.org/package/stack-2.5.1.1/docs/Stack-Setup.html)
 | 
			
		||||
2. Even if they did, it doesn't seem it would have satisfied their needs
 | 
			
		||||
	  - it didn't support cabal installation, which was the main motivation behind GHCup back then
 | 
			
		||||
	  - depending on a codebase as big as stack for a central part of one's application without having a short contribution pipeline would likely have caused stagnation or resulted in simply copy-pasting the relevant code in order to adjust it
 | 
			
		||||
	  - it's not clear how GHCup would have been implemented with the provided API. It seems the codebases are fairly different. GHCup does a lot of symlink handling to expose a central `bin/` directory that users can easily put in PATH, without having to worry about anything more. It also provides explicit removal functionality, GHC cross-compilation, a TUI, etc etc.
 | 
			
		||||
3. GHCup is built around unix principles and supposed to be simple.
 | 
			
		||||
 | 
			
		||||
### Why not unify...
 | 
			
		||||
 | 
			
		||||
#### ...stack and Cabal and do away with standalone installers
 | 
			
		||||
 | 
			
		||||
GHCup is not involved in such decisions. cabal-install and stack might have a
 | 
			
		||||
sufficiently different user experience to warrant having a choice.
 | 
			
		||||
 | 
			
		||||
#### ...installer implementations and have a common library
 | 
			
		||||
 | 
			
		||||
This sounds like an interesting goal. However, GHC installation isn't a hard engineering problem
 | 
			
		||||
and the shared code wouldn't be too exciting. For such an effort to make sense, all involved
 | 
			
		||||
parties would need to collaborate and have a short pipeline to get patches in.
 | 
			
		||||
 | 
			
		||||
It's true this would solve the integration problem, but following unix principles, we can
 | 
			
		||||
do similar via **hooks**. Both cabal and stack can support installation hooks. These hooks
 | 
			
		||||
can then call into ghcup or anything else, also see:
 | 
			
		||||
 | 
			
		||||
* https://github.com/haskell/cabal/issues/7394
 | 
			
		||||
* https://github.com/commercialhaskell/stack/pull/5585
 | 
			
		||||
 | 
			
		||||
#### ...installers (like, all of it)
 | 
			
		||||
 | 
			
		||||
So far, there hasn't been an **open** discussion about this. Is this even a good idea?
 | 
			
		||||
Sometimes projects converge eventually if their overlap is big enough, sometimes they don't.
 | 
			
		||||
 | 
			
		||||
While unification sounds like a simplification of the ecosystem, it also takes away choice.
 | 
			
		||||
Take `curl` and `wget` as an example.
 | 
			
		||||
 | 
			
		||||
How bad do we need this?
 | 
			
		||||
 | 
			
		||||
### Why not support windows?
 | 
			
		||||
 | 
			
		||||
Windows is supported since GHCup version 0.1.15.1.
 | 
			
		||||
 | 
			
		||||
### Why the haskell reimplementation?
 | 
			
		||||
 | 
			
		||||
GHCup started as a portable posix shell script of maybe 50 LOC. GHC installation itself can be carried out in
 | 
			
		||||
about ~3 lines of shell code (download, unpack , configure+make install). However, much convenient functionality
 | 
			
		||||
has been added since, as well as ensuring that all operations are safe and correct. The shell script ended up with
 | 
			
		||||
over 2k LOC, which was very hard to maintain.
 | 
			
		||||
 | 
			
		||||
The main concern when switching from a portable shell script to haskell was platform/architecture support.
 | 
			
		||||
However, ghcup now re-uses GHCs CI infrastructure and as such is perfectly in sync with all platforms that
 | 
			
		||||
GHC supports.
 | 
			
		||||
 | 
			
		||||
### Is GHCup affiliated with the Haskell Foundation?
 | 
			
		||||
 | 
			
		||||
There has been some collaboration: Windows and Stack support were mainly requested by the Haskell Foundation
 | 
			
		||||
and those seemed interesting features to add.
 | 
			
		||||
 | 
			
		||||
Other than that, GHCup is dedicated only to its users and is supported by haskell.org through hosting and CI
 | 
			
		||||
infrastructure.
 | 
			
		||||
See the [quick installation](https://www.haskell.org/ghcup/) or browse the [documentation](https://ghcup.readthedocs.io/en/latest/).
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user