diff --git a/README.md b/README.md index 1ee5fd4..c794a35 100644 --- a/README.md +++ b/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 +---- [![Join the chat at Libera.chat](https://img.shields.io/badge/chat-on%20libera%20IRC-brightgreen.svg)](https://kiwiirc.com/nextclient/irc.libera.chat/?nick=Guest%7C?#haskell,#haskell-ghcup) [![Join the chat at Matrix.org](https://img.shields.io/matrix/haskell-tooling:matrix.org?label=chat%20on%20matrix.org)](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 [![Join the chat at https://gitter.im/haskell/ghcup](https://badges.gitter.im/haskell/ghcup.svg)](https://gitter.im/haskell/ghcup?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) Donate - * [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 `. - -### 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/`, and places `ghc-` 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//bin/ghc` or set that GHC version -as the current one via: `ghcup set ghc `. - -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 `. - -#### 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/).