Compare commits
22 Commits
readthedoc
...
issue-258
| Author | SHA1 | Date | |
|---|---|---|---|
|
2ff2655db0
|
|||
|
c4ab59f7bf
|
|||
|
a62365141e
|
|||
|
5ae649bccb
|
|||
|
2095b17d06
|
|||
|
336514b3e2
|
|||
|
37707e1df8
|
|||
|
57aa30c7af
|
|||
|
78c6dd5404
|
|||
|
c101c228d7
|
|||
|
0f6874bc0f
|
|||
|
399d89dae5
|
|||
|
ba6b540869
|
|||
|
249c5a5c59
|
|||
|
e2c59230b5
|
|||
|
1d1ace096e
|
|||
|
0381ccef64
|
|||
|
e5a0f836a4
|
|||
|
463915da1a
|
|||
|
ae7bc508e8
|
|||
|
d21e0473bc
|
|||
|
df05feb766
|
594
README.md
594
README.md
@@ -1,10 +1,4 @@
|
|||||||
`ghcup` makes it easy to install specific versions of `ghc` on GNU/Linux,
|
## The GHCup Haskell installer
|
||||||
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).
|
|
||||||
|
|
||||||
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://kiwiirc.com/nextclient/irc.libera.chat/?nick=Guest%7C?#haskell,#haskell-ghcup)
|
||||||
[](https://app.element.io/#/room/#haskell-tooling:matrix.org)
|
[](https://app.element.io/#/room/#haskell-tooling:matrix.org)
|
||||||
@@ -12,588 +6,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)
|
[](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>
|
<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)
|
GHCup is an installer for the general purpose language [Haskell](https://www.haskell.org/).
|
||||||
* [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)
|
|
||||||
|
|
||||||
## Installation
|
See the [quick installation](https://www.haskell.org/ghcup/) or browse the [documentation](https://ghcup.readthedocs.io/en/latest/).
|
||||||
|
|
||||||
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.
|
|
||||||
|
|||||||
@@ -20,6 +20,19 @@ code.no-highlight {
|
|||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.gh-badge img {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.donate-badge img {
|
||||||
|
margin-top: 10;
|
||||||
|
margin-bottom: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Definition List styles */
|
/* Definition List styles */
|
||||||
|
|
||||||
dd {
|
dd {
|
||||||
@@ -38,12 +51,72 @@ body.homepage div.jumbotron div.card {
|
|||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.homepage>div.container>div.row>div.col-md-3 {
|
body.homepage>div.container div.col-md-3 {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.homepage>div.container>div.row>div.col-md-9 {
|
body.homepage>div.container div.col-md-9 {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
|
padding-left: 0;
|
||||||
flex: 0 0 100%;
|
flex: 0 0 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-primary {
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#996FC2), color-stop(60%, #6A478D), to(#5E5086)) !important;
|
||||||
|
background-image: linear-gradient(#996FC2, #6A478D 60%, #5E5086) !important;
|
||||||
|
background-repeat: no-repeat !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#996FC2), color-stop(60%, #6A478D), to(#5E5086)) !important;
|
||||||
|
background-image: linear-gradient(#996FC2, #6A478D 60%, #5E5086) !important;
|
||||||
|
background-repeat: no-repeat !important;
|
||||||
|
|
||||||
|
color: #fff;
|
||||||
|
background-color: #996FC1;
|
||||||
|
border-color: #996FC1;
|
||||||
|
|
||||||
|
border-bottom: 1px solid #453A62;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#996FC2), color-stop(60%, #6A478D), to(#5E5086)) !important;
|
||||||
|
background-image: linear-gradient(#996FC2, #6A478D 60%, #5E5086) !important;
|
||||||
|
background-repeat: no-repeat !important;
|
||||||
|
|
||||||
|
color: #fff;
|
||||||
|
background-color: #996FC1;
|
||||||
|
border-color: #996FC1;
|
||||||
|
|
||||||
|
border-bottom: 1px solid #453A62;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #996FC2;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: #674489;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-md-9 img.main-logo {
|
||||||
|
border: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-default .navbar-nav>.active>a, .navbar-default .navbar-nav>.active>a:hover, .navbar-default .navbar-nav>.active>a:focus {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #453A62;
|
||||||
|
border-color: #996FC1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-default .navbar-nav>li>a:hover, .navbar-default .navbar-nav>li>a:focus {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #453A62;
|
||||||
|
}
|
||||||
|
|||||||
BIN
docs/ghcup.gif
BIN
docs/ghcup.gif
Binary file not shown.
|
Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 198 KiB |
@@ -74,7 +74,7 @@ For man pages to work you need [man-db](http://man-db.nongnu.org/) as your `man`
|
|||||||
|
|
||||||
## Shell-completion
|
## Shell-completion
|
||||||
|
|
||||||
Shell completions are in [scripts/shell-completions](./scripts/shell-completions) directory of this repository.
|
Shell completions are in [scripts/shell-completions](https://gitlab.haskell.org/haskell/ghcup-hs/-/tree/master/scripts/shell-completions) directory of this repository.
|
||||||
|
|
||||||
For bash: install `shell-completions/bash`
|
For bash: install `shell-completions/bash`
|
||||||
as e.g. `/etc/bash_completion.d/ghcup` (depending on distro)
|
as e.g. `/etc/bash_completion.d/ghcup` (depending on distro)
|
||||||
@@ -87,7 +87,7 @@ Compiling from source is supported for both source tarballs and arbitrary git re
|
|||||||
for a list of all available options.
|
for a list of all available options.
|
||||||
|
|
||||||
If you need to overwrite the existing `build.mk`, check the default files
|
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
|
in [data/build_mk](https://gitlab.haskell.org/haskell/ghcup-hs/-/tree/master/data/build_mk), copy them somewhere, adjust them and
|
||||||
pass `--config path/to/build.mk` to `ghcup compile ghc`.
|
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).
|
Common `build.mk` options are explained [here](https://gitlab.haskell.org/ghc/ghc/-/wikis/building/using#build-configuration).
|
||||||
|
|
||||||
@@ -136,11 +136,11 @@ This is the complete list of env variables that change GHCup behavior:
|
|||||||
There are a couple of good use cases to install custom bindists:
|
There are a couple of good use cases to install custom bindists:
|
||||||
|
|
||||||
1. manually built bindists (e.g. with patches)
|
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`
|
- 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
|
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`
|
- 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
|
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`
|
- 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
|
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.
|
and produce the binaries `ghc-8.10.2-eff` and `ghc-head` respectively.
|
||||||
@@ -159,23 +159,22 @@ These installs, as the name suggests, are separate from your main installs and D
|
|||||||
|
|
||||||
You need to use the `--isolate` or `-i` flag followed by the directory path.
|
You need to use the `--isolate` or `-i` flag followed by the directory path.
|
||||||
|
|
||||||
Examples:-
|
Examples:
|
||||||
|
|
||||||
1. install an isolated GHC version at location /home/user/isolated_dir/ghc/
|
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`
|
- `ghcup install ghc 8.10.5 --isolate /home/user/isolated_dir/ghc`
|
||||||
|
|
||||||
2. isolated install Cabal at a location you desire
|
2. isolated install Cabal at a location you desire
|
||||||
- `ghcup install cabal --isolate /home/username/my_isolated_dir/`
|
- `ghcup install cabal --isolate /home/username/my_isolated_dir/`
|
||||||
|
|
||||||
3. do an isolated install with a custom bindist
|
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`
|
- `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
|
4. isolated install HLS
|
||||||
- `ghcup install hls --isolate /home/username/dir/hls/`
|
- `ghcup install hls --isolate /home/username/dir/hls/`
|
||||||
|
|
||||||
5. you can even compile ghc to an isolated location.
|
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`
|
- `ghcup compile ghc -j 4 -v 9.0.1 -b 8.10.5 -i /home/username/my/dir/ghc`
|
||||||
---
|
|
||||||
|
|
||||||
## CI
|
## CI
|
||||||
|
|
||||||
|
|||||||
BIN
docs/haskell_logo.png
Normal file
BIN
docs/haskell_logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 93 KiB |
@@ -1,7 +1,21 @@
|
|||||||
# GHCup
|
---
|
||||||
|
hide:
|
||||||
|
- navigation
|
||||||
|
- toc
|
||||||
|
---
|
||||||
|
|
||||||
|
# {: .main-logo style="width:100px"} GHCup
|
||||||
|
|
||||||
GHCup is an installer for the general purpose language [Haskell](https://www.haskell.org/).
|
GHCup is an installer for the general purpose language [Haskell](https://www.haskell.org/).
|
||||||
|
|
||||||
|
<div class="text-center gh-badge">
|
||||||
|
<a href="https://kiwiirc.com/nextclient/irc.libera.chat/?nick=Guest%7C?#haskell,#haskell-ghcup"><img src="https://img.shields.io/badge/chat-on%20libera%20IRC-brightgreen.svg" alt="Join the chat at Libera.chat"></a>
|
||||||
|
<a href="https://app.element.io/#/room/#haskell-tooling:matrix.org"><img src="https://img.shields.io/matrix/haskell-tooling:matrix.org?label=chat%20on%20matrix.org" alt="Join the chat at Matrix.org"></a>
|
||||||
|
<a href="https://discord.gg/pKYf3zDQU7"><img src="https://img.shields.io/discord/280033776820813825?label=chat%20on%20discord" alt="Join the chat at Discord"></a>
|
||||||
|
<a href="https://gitter.im/haskell/ghcup?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img src="https://badges.gitter.im/haskell/ghcup.svg" alt="Join the chat at https://gitter.im/haskell/ghcup"></a>
|
||||||
|
<a href="https://opencollective.com/ghcup#category-CONTRIBUTE" class="donate-badge"><img src="https://opencollective.com/webpack/donate/button@2x.png?color=blue" alt="Donate"></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
GHCup makes it easy to install specific versions of GHC on GNU/Linux,
|
GHCup makes it easy to install specific versions of GHC on GNU/Linux,
|
||||||
@@ -12,9 +26,11 @@ It follows the unix UNIX philosophy of [do one thing and do it well](https://en.
|
|||||||
<a href="https://www.haskell.org/ghcup/" class="btn btn-primary" role="button">Quick Install</a>
|
<a href="https://www.haskell.org/ghcup/" class="btn btn-primary" role="button">Quick Install</a>
|
||||||
<a href="install/" class="btn btn-primary" role="button">Getting Started</a>
|
<a href="install/" class="btn btn-primary" role="button">Getting Started</a>
|
||||||
<a href="guide/" class="btn btn-primary" role="button">User Guide</a>
|
<a href="guide/" class="btn btn-primary" role="button">User Guide</a>
|
||||||
|
<a href="https://gitlab.haskell.org/haskell/ghcup-hs/-/issues" class="btn btn-primary" role="button">Issue tracker</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||

|
{: .center style="width:700px"}
|
||||||
|
|
||||||
|
|||||||
@@ -20,9 +20,7 @@ extra-doc-files:
|
|||||||
data/metadata/ghcup-0.0.4.yaml
|
data/metadata/ghcup-0.0.4.yaml
|
||||||
data/metadata/ghcup-0.0.5.yaml
|
data/metadata/ghcup-0.0.5.yaml
|
||||||
data/metadata/ghcup-0.0.6.yaml
|
data/metadata/ghcup-0.0.6.yaml
|
||||||
docs/CHANGELOG.md
|
CHANGELOG.md
|
||||||
docs/HACKING.md
|
|
||||||
docs/RELEASING.md
|
|
||||||
README.md
|
README.md
|
||||||
|
|
||||||
extra-source-files:
|
extra-source-files:
|
||||||
|
|||||||
67
lib/GHCup.hs
67
lib/GHCup.hs
@@ -1137,6 +1137,7 @@ setGHC ver sghc = do
|
|||||||
SetGHCOnly -> do
|
SetGHCOnly -> do
|
||||||
let sharedir = "share"
|
let sharedir = "share"
|
||||||
let fullsharedir = ghcdir </> sharedir
|
let fullsharedir = ghcdir </> sharedir
|
||||||
|
logDebug $ "Checking for sharedir existence: " <> T.pack fullsharedir
|
||||||
whenM (liftIO $ doesDirectoryExist fullsharedir) $ do
|
whenM (liftIO $ doesDirectoryExist fullsharedir) $ do
|
||||||
let fullF = destdir </> sharedir
|
let fullF = destdir </> sharedir
|
||||||
let targetF = "." </> "ghc" </> ver' </> sharedir
|
let targetF = "." </> "ghc" </> ver' </> sharedir
|
||||||
@@ -2121,10 +2122,6 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour had
|
|||||||
PlatformRequest { .. } <- lift getPlatformReq
|
PlatformRequest { .. } <- lift getPlatformReq
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
|
|
||||||
bghc <- case bstrap of
|
|
||||||
Right g -> pure $ Right g
|
|
||||||
Left bver -> pure $ Left ("ghc-" <> (T.unpack . prettyVer $ bver) <> exeExt)
|
|
||||||
|
|
||||||
(workdir, tmpUnpack, tver) <- case targetGhc of
|
(workdir, tmpUnpack, tver) <- case targetGhc of
|
||||||
-- unpack from version tarball
|
-- unpack from version tarball
|
||||||
Left tver -> do
|
Left tver -> do
|
||||||
@@ -2173,9 +2170,8 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour had
|
|||||||
lEM $ git [ "checkout", "FETCH_HEAD" ]
|
lEM $ git [ "checkout", "FETCH_HEAD" ]
|
||||||
lEM $ git [ "submodule", "update", "--init", "--depth", "1" ]
|
lEM $ git [ "submodule", "update", "--init", "--depth", "1" ]
|
||||||
forM_ patchdir (\dir -> liftE $ applyPatches dir tmpUnpack)
|
forM_ patchdir (\dir -> liftE $ applyPatches dir tmpUnpack)
|
||||||
env <- liftE $ ghcEnv bghc
|
lEM $ execWithGhcEnv "python3" ["./boot"] (Just tmpUnpack) "ghc-bootstrap"
|
||||||
lEM $ execLogged "python3" ["./boot"] (Just tmpUnpack) "ghc-bootstrap" (Just env)
|
lEM $ execWithGhcEnv "sh" ["./configure"] (Just tmpUnpack) "ghc-bootstrap"
|
||||||
lEM $ execLogged "sh" ["./configure"] (Just tmpUnpack) "ghc-bootstrap" (Just env)
|
|
||||||
CapturedProcess {..} <- lift $ makeOut
|
CapturedProcess {..} <- lift $ makeOut
|
||||||
["show!", "--quiet", "VALUE=ProjectVersion" ] (Just tmpUnpack)
|
["show!", "--quiet", "VALUE=ProjectVersion" ] (Just tmpUnpack)
|
||||||
case _exitCode of
|
case _exitCode of
|
||||||
@@ -2212,8 +2208,8 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour had
|
|||||||
Nothing
|
Nothing
|
||||||
(do
|
(do
|
||||||
b <- if hadrian
|
b <- if hadrian
|
||||||
then compileHadrianBindist bghc tver workdir ghcdir
|
then compileHadrianBindist tver workdir ghcdir
|
||||||
else compileMakeBindist bghc tver workdir ghcdir
|
else compileMakeBindist tver workdir ghcdir
|
||||||
bmk <- liftIO $ handleIO (\_ -> pure "") $ B.readFile (build_mk workdir)
|
bmk <- liftIO $ handleIO (\_ -> pure "") $ B.readFile (build_mk workdir)
|
||||||
pure (b, bmk)
|
pure (b, bmk)
|
||||||
)
|
)
|
||||||
@@ -2265,8 +2261,7 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour had
|
|||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadFail m
|
, MonadFail m
|
||||||
)
|
)
|
||||||
=> Either FilePath FilePath
|
=> GHCTargetVersion
|
||||||
-> GHCTargetVersion
|
|
||||||
-> FilePath
|
-> FilePath
|
||||||
-> FilePath
|
-> FilePath
|
||||||
-> Excepts
|
-> Excepts
|
||||||
@@ -2279,19 +2274,19 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour had
|
|||||||
, CopyError]
|
, CopyError]
|
||||||
m
|
m
|
||||||
(Maybe FilePath) -- ^ output path of bindist, None for cross
|
(Maybe FilePath) -- ^ output path of bindist, None for cross
|
||||||
compileHadrianBindist bghc tver workdir ghcdir = do
|
compileHadrianBindist tver workdir ghcdir = do
|
||||||
lEM $ execLogged "python3" ["./boot"] (Just workdir) "ghc-bootstrap" Nothing
|
lEM $ execWithGhcEnv "python3" ["./boot"] (Just workdir) "ghc-bootstrap"
|
||||||
|
|
||||||
liftE $ configureBindist bghc tver workdir ghcdir
|
liftE $ configureBindist tver workdir ghcdir
|
||||||
|
|
||||||
lift $ logInfo "Building (this may take a while)..."
|
lift $ logInfo "Building (this may take a while)..."
|
||||||
hadrian_build <- liftE $ findHadrianFile workdir
|
hadrian_build <- liftE $ findHadrianFile workdir
|
||||||
lEM $ execLogged hadrian_build
|
lEM $ execWithGhcEnv hadrian_build
|
||||||
( maybe [] (\j -> ["-j" <> show j] ) jobs
|
( maybe [] (\j -> ["-j" <> show j] ) jobs
|
||||||
++ maybe [] (\bf -> ["--flavour=" <> bf]) buildFlavour
|
++ maybe [] (\bf -> ["--flavour=" <> bf]) buildFlavour
|
||||||
++ ["binary-dist"]
|
++ ["binary-dist"]
|
||||||
)
|
)
|
||||||
(Just workdir) "ghc-make" Nothing
|
(Just workdir) "ghc-make"
|
||||||
[tar] <- liftIO $ findFiles
|
[tar] <- liftIO $ findFiles
|
||||||
(workdir </> "_build" </> "bindist")
|
(workdir </> "_build" </> "bindist")
|
||||||
(makeRegexOpts compExtended
|
(makeRegexOpts compExtended
|
||||||
@@ -2327,8 +2322,7 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour had
|
|||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadFail m
|
, MonadFail m
|
||||||
)
|
)
|
||||||
=> Either FilePath FilePath
|
=> GHCTargetVersion
|
||||||
-> GHCTargetVersion
|
|
||||||
-> FilePath
|
-> FilePath
|
||||||
-> FilePath
|
-> FilePath
|
||||||
-> Excepts
|
-> Excepts
|
||||||
@@ -2341,8 +2335,8 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour had
|
|||||||
, CopyError]
|
, CopyError]
|
||||||
m
|
m
|
||||||
(Maybe FilePath) -- ^ output path of bindist, None for cross
|
(Maybe FilePath) -- ^ output path of bindist, None for cross
|
||||||
compileMakeBindist bghc tver workdir ghcdir = do
|
compileMakeBindist tver workdir ghcdir = do
|
||||||
liftE $ configureBindist bghc tver workdir ghcdir
|
liftE $ configureBindist tver workdir ghcdir
|
||||||
|
|
||||||
case mbuildConfig of
|
case mbuildConfig of
|
||||||
Just bc -> liftIOException
|
Just bc -> liftIOException
|
||||||
@@ -2463,8 +2457,7 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour had
|
|||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadFail m
|
, MonadFail m
|
||||||
)
|
)
|
||||||
=> Either FilePath FilePath
|
=> GHCTargetVersion
|
||||||
-> GHCTargetVersion
|
|
||||||
-> FilePath
|
-> FilePath
|
||||||
-> FilePath
|
-> FilePath
|
||||||
-> Excepts
|
-> Excepts
|
||||||
@@ -2477,12 +2470,11 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour had
|
|||||||
]
|
]
|
||||||
m
|
m
|
||||||
()
|
()
|
||||||
configureBindist bghc tver workdir ghcdir = do
|
configureBindist tver workdir ghcdir = do
|
||||||
lift $ logInfo [s|configuring build|]
|
lift $ logInfo [s|configuring build|]
|
||||||
|
|
||||||
if | _tvVersion tver >= [vver|8.8.0|] -> do
|
if | _tvVersion tver >= [vver|8.8.0|] -> do
|
||||||
env <- liftE $ ghcEnv bghc
|
lEM $ execWithGhcEnv
|
||||||
lEM $ execLogged
|
|
||||||
"sh"
|
"sh"
|
||||||
("./configure" : maybe mempty
|
("./configure" : maybe mempty
|
||||||
(\x -> ["--target=" <> T.unpack x])
|
(\x -> ["--target=" <> T.unpack x])
|
||||||
@@ -2495,7 +2487,6 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour had
|
|||||||
)
|
)
|
||||||
(Just workdir)
|
(Just workdir)
|
||||||
"ghc-conf"
|
"ghc-conf"
|
||||||
(Just env)
|
|
||||||
| otherwise -> do
|
| otherwise -> do
|
||||||
lEM $ execLogged
|
lEM $ execLogged
|
||||||
"sh"
|
"sh"
|
||||||
@@ -2515,14 +2506,32 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour had
|
|||||||
Nothing
|
Nothing
|
||||||
pure ()
|
pure ()
|
||||||
|
|
||||||
ghcEnv :: MonadIO m => Either FilePath FilePath -> Excepts '[NotFoundInPATH] m [(String, String)]
|
execWithGhcEnv :: ( MonadReader env m
|
||||||
ghcEnv bghc = do
|
, HasSettings env
|
||||||
|
, HasDirs env
|
||||||
|
, MonadIO m
|
||||||
|
, MonadThrow m)
|
||||||
|
=> FilePath -- ^ thing to execute
|
||||||
|
-> [String] -- ^ args for the thing
|
||||||
|
-> Maybe FilePath -- ^ optionally chdir into this
|
||||||
|
-> FilePath -- ^ log filename (opened in append mode)
|
||||||
|
-> m (Either ProcessError ())
|
||||||
|
execWithGhcEnv fp args dir logf = do
|
||||||
|
env <- ghcEnv
|
||||||
|
execLogged fp args dir logf (Just env)
|
||||||
|
|
||||||
|
bghc = case bstrap of
|
||||||
|
Right g -> Right g
|
||||||
|
Left bver -> Left ("ghc-" <> (T.unpack . prettyVer $ bver) <> exeExt)
|
||||||
|
|
||||||
|
ghcEnv :: (MonadThrow m, MonadIO m) => m [(String, String)]
|
||||||
|
ghcEnv = do
|
||||||
cEnv <- liftIO getEnvironment
|
cEnv <- liftIO getEnvironment
|
||||||
bghcPath <- case bghc of
|
bghcPath <- case bghc of
|
||||||
Right ghc' -> pure ghc'
|
Right ghc' -> pure ghc'
|
||||||
Left bver -> do
|
Left bver -> do
|
||||||
spaths <- liftIO getSearchPath
|
spaths <- liftIO getSearchPath
|
||||||
liftIO (searchPath spaths bver) !? NotFoundInPATH bver
|
throwMaybeM (NotFoundInPATH bver) $ liftIO (searchPath spaths bver)
|
||||||
pure (("GHC", bghcPath) : cEnv)
|
pure (("GHC", bghcPath) : cEnv)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -149,6 +149,8 @@ instance Pretty NotInstalled where
|
|||||||
data NotFoundInPATH = NotFoundInPATH FilePath
|
data NotFoundInPATH = NotFoundInPATH FilePath
|
||||||
deriving Show
|
deriving Show
|
||||||
|
|
||||||
|
instance Exception NotFoundInPATH
|
||||||
|
|
||||||
instance Pretty NotFoundInPATH where
|
instance Pretty NotFoundInPATH where
|
||||||
pPrint (NotFoundInPATH exe) =
|
pPrint (NotFoundInPATH exe) =
|
||||||
text $ "The exe " <> exe <> " was not found in PATH."
|
text $ "The exe " <> exe <> " was not found in PATH."
|
||||||
|
|||||||
@@ -283,6 +283,16 @@ throwEither' e eth = case eth of
|
|||||||
Left _ -> throwM e
|
Left _ -> throwM e
|
||||||
Right r -> pure r
|
Right r -> pure r
|
||||||
|
|
||||||
|
throwMaybe :: (Exception a, MonadThrow m) => a -> Maybe b -> m b
|
||||||
|
throwMaybe a m = case m of
|
||||||
|
Nothing -> throwM a
|
||||||
|
Just r -> pure r
|
||||||
|
|
||||||
|
throwMaybeM :: (Exception a, MonadThrow m) => a -> m (Maybe b) -> m b
|
||||||
|
throwMaybeM a am = do
|
||||||
|
m <- am
|
||||||
|
throwMaybe a m
|
||||||
|
|
||||||
|
|
||||||
verToBS :: Version -> ByteString
|
verToBS :: Version -> ByteString
|
||||||
verToBS = E.encodeUtf8 . prettyVer
|
verToBS = E.encodeUtf8 . prettyVer
|
||||||
|
|||||||
@@ -25,3 +25,5 @@ markdown_extensions:
|
|||||||
- admonition
|
- admonition
|
||||||
- attr_list
|
- attr_list
|
||||||
- def_list
|
- def_list
|
||||||
|
- meta
|
||||||
|
|
||||||
|
|||||||
@@ -26,19 +26,19 @@
|
|||||||
<div id="platform-instructions-linux" class="instructions" style="display: none;">
|
<div id="platform-instructions-linux" class="instructions" style="display: none;">
|
||||||
<p>On Linux, run the following in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
<p>On Linux, run the following in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
||||||
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
||||||
<p class="other-help"><a href="https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/scripts/bootstrap/bootstrap-haskell" target="_blank">What does this do?</a> <b> · </b> <a href="https://gitlab.haskell.org/haskell/ghcup-hs#manual-install">I don't like curl | sh</a> <b> · </b> <a class="default-platform-button" href="#">I'm not running Linux</a></p>
|
<p class="other-help"><a href="https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/scripts/bootstrap/bootstrap-haskell" target="_blank">What does this do?</a> <b> · </b> <a href="https://ghcup.readthedocs.io/en/latest/install/#manual-install">I don't like curl | sh</a> <b> · </b> <a class="default-platform-button" href="#">I'm not running Linux</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="platform-instructions-mac" class="instructions" style="display: none;">
|
<div id="platform-instructions-mac" class="instructions" style="display: none;">
|
||||||
<p>On macOS, run the following in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
<p>On macOS, run the following in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
||||||
<div class="command-button"><pre><span class='ghcup-command' id="ghcup-command-normal">curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
<div class="command-button"><pre><span class='ghcup-command' id="ghcup-command-normal">curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
||||||
<p class="other-help"><a href="https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/scripts/bootstrap/bootstrap-haskell" target="_blank">What does this do?</a> <b> · </b> <a href="https://gitlab.haskell.org/haskell/ghcup-hs#manual-install">I don't like curl | sh</a> <b> · </b> <a class="default-platform-button" href="#">I'm not running macOS</a></p>
|
<p class="other-help"><a href="https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/scripts/bootstrap/bootstrap-haskell" target="_blank">What does this do?</a> <b> · </b> <a href="https://ghcup.readthedocs.io/en/latest/install/#manual-install">I don't like curl | sh</a> <b> · </b> <a class="default-platform-button" href="#">I'm not running macOS</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="platform-instructions-freebsd" class="instructions" style="display: none;">
|
<div id="platform-instructions-freebsd" class="instructions" style="display: none;">
|
||||||
<p>On FreeBSD Run the following in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
<p>On FreeBSD Run the following in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
||||||
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
||||||
<p class="other-help"><a href="https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/scripts/bootstrap/bootstrap-haskell" target="_blank">What does this do?</a> <b> · </b> <a href="https://gitlab.haskell.org/haskell/ghcup-hs#manual-install">I don't like curl | sh</a> <b> · </b> <a class="default-platform-button" href="#">I'm not running FreeBSD</a></p>
|
<p class="other-help"><a href="https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/scripts/bootstrap/bootstrap-haskell" target="_blank">What does this do?</a> <b> · </b> <a href="https://ghcup.readthedocs.io/en/latest/install/#manual-install">I don't like curl | sh</a> <b> · </b> <a class="default-platform-button" href="#">I'm not running FreeBSD</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="platform-instructions-win32" class="instructions">
|
<div id="platform-instructions-win32" class="instructions">
|
||||||
@@ -101,7 +101,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<p>If you are running Linux, macOS, FreeBSD or Windows Subsystem 2 for Linux, run the following in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
<p>If you are running Linux, macOS, FreeBSD or Windows Subsystem 2 for Linux, run the following in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
||||||
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
||||||
<p class="other-help"><a href="https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/scripts/bootstrap/bootstrap-haskell" target="_blank">What does this do?</a> <b> · </b> <a href="https://gitlab.haskell.org/haskell/ghcup-hs#manual-install">I don't like curl | sh</a></p>
|
<p class="other-help"><a href="https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/scripts/bootstrap/bootstrap-haskell" target="_blank">What does this do?</a> <b> · </b> <a href="https://ghcup.readthedocs.io/en/latest/install/#manual-install">I don't like curl | sh</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
@@ -120,7 +120,7 @@
|
|||||||
<p>To install Haskell, if you are running Linux, macOS, FreeBSD or Windows Subsystem 2 for Linux, run the following
|
<p>To install Haskell, if you are running Linux, macOS, FreeBSD or Windows Subsystem 2 for Linux, run the following
|
||||||
in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
in your terminal (as a user other than root), then follow the onscreen instructions.</p>
|
||||||
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
<div class="command-button"><pre><span class='ghcup-command'>curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh</span></pre><button class="tooltip" onclick="copyToClipboard()"><img src="copy.svg" alt="" /><span class="tooltiptext">Copy to clipboard</span></button></div>
|
||||||
<p class="other-help"><a href="https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/scripts/bootstrap/bootstrap-haskell" target="_blank">What does this do?</a> <b> · </b> <a href="https://gitlab.haskell.org/haskell/ghcup-hs#manual-install">I don't like curl | sh</a></p>
|
<p class="other-help"><a href="https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/master/scripts/bootstrap/bootstrap-haskell" target="_blank">What does this do?</a> <b> · </b> <a href="https://ghcup.readthedocs.io/en/latest/install/#manual-install">I don't like curl | sh</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
@@ -152,7 +152,7 @@
|
|||||||
<br/>
|
<br/>
|
||||||
<a href="https://www.haskell.org/downloads/">other installation options</a>
|
<a href="https://www.haskell.org/downloads/">other installation options</a>
|
||||||
<b> · </b>
|
<b> · </b>
|
||||||
<a href="https://gitlab.haskell.org/haskell/ghcup-hs">about ghcup</a>
|
<a href="https://ghcup.readthedocs.io/en/latest/">read the docs</a>
|
||||||
<b> · </b>
|
<b> · </b>
|
||||||
<a href="https://github.com/rust-lang/rustup.rs/tree/master/www">web design from rustup</a>
|
<a href="https://github.com/rust-lang/rustup.rs/tree/master/www">web design from rustup</a>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
Reference in New Issue
Block a user