Compare commits

..

No commits in common. "master" and "stack-ci" have entirely different histories.

16 changed files with 155 additions and 270 deletions

View File

@ -21,8 +21,8 @@ jobs:
name: Build linux binary name: Build linux binary
runs-on: [self-hosted, Linux, X64, maerwald] runs-on: [self-hosted, Linux, X64, maerwald]
env: env:
CABAL_VER: 3.10.3.0 CABAL_VER: 3.10.1.0
JSON_VERSION: "0.0.8" JSON_VERSION: "0.0.7"
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
S3_HOST: ${{ secrets.S3_HOST }} S3_HOST: ${{ secrets.S3_HOST }}
@ -31,7 +31,7 @@ jobs:
ARCH: 64 ARCH: 64
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v3
with: with:
submodules: 'true' submodules: 'true'
@ -50,7 +50,7 @@ jobs:
- if: always() - if: always()
name: Upload artifact name: Upload artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v3
with: with:
name: artifacts name: artifacts
path: | path: |
@ -61,13 +61,13 @@ jobs:
needs: "build" needs: "build"
runs-on: [self-hosted, Linux, X64] runs-on: [self-hosted, Linux, X64]
container: container:
image: registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb12:a9297a370025101b479cfd4977f8f910814e03ab image: registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:8d0224e6b2a08157649651e69302380b2bd24e11
options: --user root options: --user root
env: env:
CABAL_VER: 3.10.3.0 CABAL_VER: 3.6.2.0
BUILD_CONF_ARGS: "--enable-unregisterised" BUILD_CONF_ARGS: "--enable-unregisterised"
HADRIAN_FLAVOUR: "" HADRIAN_FLAVOUR: ""
JSON_VERSION: "0.0.8" JSON_VERSION: "0.0.7"
GHC_VER: 8.10.6 GHC_VER: 8.10.6
GHC_TARGET_VERSION: "8.10.7" GHC_TARGET_VERSION: "8.10.7"
ARCH: 64 ARCH: 64
@ -77,11 +77,11 @@ jobs:
WRAPPER: "run" WRAPPER: "run"
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v3
with: with:
submodules: 'true' submodules: 'true'
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v3
with: with:
name: artifacts name: artifacts
path: ./out path: ./out
@ -89,18 +89,11 @@ jobs:
- name: Run test (64 bit linux) - name: Run test (64 bit linux)
run: | run: |
sudo apt-get update -y sudo apt-get update -y
sudo apt-get install -y libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev libbz2-dev git wget lsb-release software-properties-common gnupg2 apt-transport-https gcc autoconf automake build-essential curl gzip libstdc++-11-dev sudo apt-get install -y libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev libbz2-dev git wget lsb-release software-properties-common gnupg2 apt-transport-https gcc autoconf automake build-essential curl gzip
sudo apt-get install -y gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf sudo apt-get install -y gcc-arm-linux-gnueabihf
sudo dpkg --add-architecture armhf sudo dpkg --add-architecture armhf
sudo apt-get update -y sudo apt-get update -y
sudo apt-get install -y libncurses-dev:armhf libstdc++-11-dev:armhf sudo apt-get install -y libncurses-dev:armhf
# ld.bfd is broken on armv7: https://sourceware.org/bugzilla/show_bug.cgi?id=16177
update-alternatives --install "/usr/bin/x86_64-linux-gnu-ld" "ld" "/usr/bin/x86_64-linux-gnu-ld.gold" 20
update-alternatives --install "/usr/bin/x86_64-linux-gnu-ld" "ld" "/usr/bin/x86_64-linux-gnu-ld.bfd" 10
update-alternatives --set "ld" "/usr/bin/x86_64-linux-gnu-ld.gold"
update-alternatives --install "/usr/bin/arm-linux-gnueabihf-ld" "ld-arm" "/usr/bin/arm-linux-gnueabihf-ld.gold" 20
update-alternatives --install "/usr/bin/arm-linux-gnueabihf-ld" "ld-arm" "/usr/bin/arm-linux-gnueabihf-ld.bfd" 10
update-alternatives --set "ld-arm" "/usr/bin/arm-linux-gnueabihf-ld.gold"
sh .github/scripts/cross.sh sh .github/scripts/cross.sh
test-cross-js: test-cross-js:
@ -108,13 +101,13 @@ jobs:
needs: "build" needs: "build"
runs-on: [self-hosted, Linux, X64] runs-on: [self-hosted, Linux, X64]
container: container:
image: registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb12:a9297a370025101b479cfd4977f8f910814e03ab image: registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:8d0224e6b2a08157649651e69302380b2bd24e11
options: --user root options: --user root
env: env:
CABAL_VER: 3.10.3.0 CABAL_VER: 3.6.2.0
BUILD_CONF_ARGS: "" BUILD_CONF_ARGS: ""
HADRIAN_FLAVOUR: "default+native_bignum" HADRIAN_FLAVOUR: "default+native_bignum"
JSON_VERSION: "0.0.8" JSON_VERSION: "0.0.7"
GHC_VER: 9.6.2 GHC_VER: 9.6.2
GHC_TARGET_VERSION: "9.6.2" GHC_TARGET_VERSION: "9.6.2"
ARCH: 64 ARCH: 64
@ -124,11 +117,11 @@ jobs:
WRAPPER: "emconfigure" WRAPPER: "emconfigure"
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v3
with: with:
submodules: 'true' submodules: 'true'
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v3
with: with:
name: artifacts name: artifacts
path: ./out path: ./out

View File

@ -126,7 +126,6 @@ jobs:
AWS_SECRET_ACCESS_KEY: ${{ env.AWS_SECRET_ACCESS_KEY }} AWS_SECRET_ACCESS_KEY: ${{ env.AWS_SECRET_ACCESS_KEY }}
AWS_ACCESS_KEY_ID: ${{ env.AWS_ACCESS_KEY_ID }} AWS_ACCESS_KEY_ID: ${{ env.AWS_ACCESS_KEY_ID }}
S3_HOST: ${{ env.S3_HOST }} S3_HOST: ${{ env.S3_HOST }}
LD: ld.gold
- if: matrix.ARCH == 'ARM64' - if: matrix.ARCH == 'ARM64'
uses: docker://hasufell/arm64v8-debian-haskell:10 uses: docker://hasufell/arm64v8-debian-haskell:10
@ -398,7 +397,6 @@ jobs:
ARCH: ${{ matrix.ARCH }} ARCH: ${{ matrix.ARCH }}
GHC_VER: ${{ matrix.GHC_VER }} GHC_VER: ${{ matrix.GHC_VER }}
DISTRO: Ubuntu DISTRO: Ubuntu
LD: ld.gold
- if: matrix.ARCH == 'ARM64' - if: matrix.ARCH == 'ARM64'
uses: docker://hasufell/arm64v8-debian-haskell:10 uses: docker://hasufell/arm64v8-debian-haskell:10

View File

@ -90,7 +90,6 @@ toSettings options = do
gpgSetting = fromMaybe (fromMaybe (Types.gpgSetting defaultSettings) uGPGSetting) optGpg gpgSetting = fromMaybe (fromMaybe (Types.gpgSetting defaultSettings) uGPGSetting) optGpg
platformOverride = optPlatform <|> (uPlatformOverride <|> Types.platformOverride defaultSettings) platformOverride = optPlatform <|> (uPlatformOverride <|> Types.platformOverride defaultSettings)
mirrors = fromMaybe (Types.mirrors defaultSettings) uMirrors mirrors = fromMaybe (Types.mirrors defaultSettings) uMirrors
defGHCConfOptions = fromMaybe (Types.defGHCConfOptions defaultSettings) uDefGHCConfOptions
in (Settings {..}, keyBindings) in (Settings {..}, keyBindings)
#if defined(INTERNAL_DOWNLOADER) #if defined(INTERNAL_DOWNLOADER)
defaultDownloader = Internal defaultDownloader = Internal

View File

@ -128,12 +128,3 @@ mirrors:
authority: authority:
host: "mirror.sjtu.edu.cn" host: "mirror.sjtu.edu.cn"
# Arguments to pass to the configure script of the prebuilt bindist.
#
# Do not pass '--prefix' here.
#
# GHCup by default passes '--disable-ld-override', so if you want to enable
# the vanilla way, which aggressively favors 'ld.gold' linker, add the following:
def-ghc-conf-options:
- "--enable-ld-override"

@ -1 +1 @@
Subproject commit c9dae0c58799854823e8c41858ca4cc172ef4c8b Subproject commit 7e1a50cfff66fdc4039535ea2251fd62a0521579

1
docs/BUGS.md Normal file
View File

@ -0,0 +1 @@
# Known BUGS

39
docs/TODO.md Normal file
View File

@ -0,0 +1,39 @@
# TODOs and Remarks
## Now
* ghcup init?
* merge two download files
* fetch/unpack functionality
* installing multiple versions of the same
* post-install
* proper test suite
* !! update of 0.1.5 must go in ghcup-0.0.1.json !!
* try to run exe before upgrade (backup to ~/.ghcup/bin/ghcup.old)
* stdout flushing?
* resume support (for make-install only)
## Maybe
* version ranges in json
* sign the JSON? (Or check gpg keys?)
* testing (especially distro detection -> unit tests)
## Later
* add support for RC/alpha/HEAD versions
## Cleanups
* avoid alternative for IO
* use plucky or oops instead of Excepts
## Questions
* move out GHCup.Version module, bc it's not library-ish?
* mirror support
* interactive handling when distro doesn't exist and we know the tarball is incompatible?
* ghcup-with wrapper to execute a command with a given ghc in PATH?

View File

@ -40,80 +40,6 @@ All you wanted to know about GHCup.
* [haskell.org](https://www.haskell.org/haskell-org-committee/) via CI and infrastructure * [haskell.org](https://www.haskell.org/haskell-org-committee/) via CI and infrastructure
* [Haskell Foundation](https://haskell.foundation/affiliates/) via affiliation * [Haskell Foundation](https://haskell.foundation/affiliates/) via affiliation
## Project ownership and hierarchy
The project at the time of writing (2024-04-22) follows the model of
[benevolent dictator for life](https://en.wikipedia.org/wiki/Benevolent_dictator_for_life), which is
Julian Ospald at the moment.
Ideally, the ownership should be shared across a core team of collaborators sharing the same vision and
engagement in the future.
I do not believe in people making decisions over projects they are barely involved in. Instead I believe
in listening to end users needs very carefully and making decisions based on that. People who want a direct
influence on the decision process have to both demonstrate they share the vision of GHCup and do the actual
work.
"Work" here doesn't have to be "writing code". There are many ways to be engaged in a project.
### Transition plan in case of maintainer absence
In case the current maintainer of GHCup (Julian Ospald) is unreachable for a prolonged period of time (3 months),
the ownership of this project will be automatically transferred to the following individuals:
- [Moritz Angerman](https://github.com/angerman)
- [Andrew Lelechenko](https://github.com/Bodigrim)
They will be tasked with finding new maintainers in whatever way they see fit (be it appointing themselves or asking HF for help).
The appointed owners may choose to stay owners after the transition period (whether it's in a passive or active capacity) or
fully transfer ownership to someone else or an organization.
The community shall be informed about this process.
If not otherwise specified by the newly appointed owners, the following principles shall apply to the *transition period*:
#### During the transition period
During the transition period, no other individual or organization is allowed to drive changes to
[ghcup-hs](https://github.com/haskell/ghcup-hs) repository, unless they are explicitly allowed to do so by the appointed owners.
The following people (in addition to the owners) shall have full write access to the
[ghcup-metadata](https://github.com/haskell/ghcup-metadata) repository
(all files) for the length of the transition period, unless otherwise specified by the appointed owners:
- [Ben Gamari](https://github.com/bgamari)
- [Hécate Moonlight](https://github.com/Kleidukos)
- [Mike Pilgrem](https://github.com/mpilgrem)
- [Jens Petersen](https://github.com/juhp)
Contributions to the metadata are expected to follow a review process. If that turns out to be impractical due to lack of engagement, a wait
time of 2 days before merging shall be followed anyway, except for the `-vanilla` files, which may be merged at any time.
#### Access
The GHCup website, various scripts and unofficial bindists are hosted on haskell.org infrastructure. Contact the
[Haskell.org committee](https://www.haskell.org/haskell-org-committee/) for access.
The backup owners should already have admin rights on the GHCup repositories, which are hosted on the
[Github haskell namespace](https://github.com/haskell). In case of issues contact one of the
organization admins for access, e.g.:
- [Andrew Lelechenko](https://github.com/orgs/haskell/people/Bodigrim)
- [gbaz](https://github.com/orgs/haskell/people/gbaz)
- [Hécate Moonlight](https://github.com/Kleidukos)
- [davean](https://github.com/orgs/haskell/people/davean)
- [chessai](https://github.com/orgs/haskell/people/chessai)
The owners should already have access to the [hackage package](https://hackage.haskell.org/package/ghcup/maintainers/).
In case of issues contact the [hackage trustees](https://github.com/haskell-infra/hackage-trustees).
#### Private runners
Private runners maintained by Julian Ospald may cease to work. Moritz Angerman will have SSH access to the machines.
However, no one will have access to the Hetzner account and billing information. As such, those runners will simply
have to be replaced.
## How to help ## How to help
* if you want to contribute code or documentation, check out the [issue tracker](https://github.com/haskell/ghcup-hs/issues) and the [Development guide](./dev.md) * if you want to contribute code or documentation, check out the [issue tracker](https://github.com/haskell/ghcup-hs/issues) and the [Development guide](./dev.md)
@ -187,7 +113,7 @@ cabal-install/HLS/stack are installed in `~/.ghcup/bin/<tool>-<ver>` and have un
### Custom ghc version names ### Custom ghc version names
When installing ghc bindists with custom version names as outlined in When installing ghc bindists with custom version names as outlined in
[installing custom bindists](guide.md#installing-custom-bindists), then cabal might [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)) 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: 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 `cabal build --with-compiler=$HOME/.ghcup/ghc/<version-name>/bin/ghc` or set that GHC version

View File

@ -146,14 +146,6 @@ a:hover {
color: #996FC2; color: #996FC2;
} }
#toc-collapse a.nav-link {
color: var(--link-pink);
}
#toc-collapse a:hover.nav-link {
color: #996FC2;
}
.col-md-9 img.main-logo { .col-md-9 img.main-logo {
border: 0px; border: 0px;
padding: 0px; padding: 0px;

View File

@ -151,7 +151,7 @@ of metadata files to understand their purpose. These can be combined.
For example, if you want access to both prerelease and cross bindists, you'd do: For example, if you want access to both prerelease and cross bindists, you'd do:
```sh ```sh
ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.8.yaml ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.7.yaml
ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-cross-0.0.8.yaml ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-cross-0.0.8.yaml
``` ```
@ -180,7 +180,7 @@ url-source:
Also see [config.yaml](https://github.com/haskell/ghcup-hs/blob/master/data/config.yaml) Also see [config.yaml](https://github.com/haskell/ghcup-hs/blob/master/data/config.yaml)
for more options. for more options.
You can also use an alternative metadata via the one-shot CLI option: You can also use an alternative metadata via one-shot cli option:
```sh ```sh
ghcup --url-source=https://some-url/ghcup-0.0.8.yaml tui ghcup --url-source=https://some-url/ghcup-0.0.8.yaml tui
@ -200,14 +200,14 @@ url-source:
- https://mirror.sjtu.edu.cn/ghcup/yaml/ghcup/data/ghcup-0.0.6.yaml - https://mirror.sjtu.edu.cn/ghcup/yaml/ghcup/data/ghcup-0.0.6.yaml
``` ```
Note that later versions of GHCup allow more sophisticated mirror support, see [here](#mirrors-proper). Note that later versions of GHCup allow more sophisticated mirror support, see [here](./#mirrors-proper).
#### Known mirrors #### Known mirrors
1. [https://mirror.sjtu.edu.cn/docs/ghcup](https://mirror.sjtu.edu.cn/docs/ghcup) 1. [https://mirror.sjtu.edu.cn/docs/ghcup](https://mirror.sjtu.edu.cn/docs/ghcup)
2. [https://mirrors.ustc.edu.cn/help/ghcup.html](https://mirrors.ustc.edu.cn/help/ghcup.html) 2. [https://mirrors.ustc.edu.cn/help/ghcup.html](https://mirrors.ustc.edu.cn/help/ghcup.html)
### Git-based metadata config ### Git based metadata config
If you don't like the way ghcup updates its metadata with caching and fetching via curl, you can also do as follows: If you don't like the way ghcup updates its metadata with caching and fetching via curl, you can also do as follows:
@ -322,24 +322,8 @@ Stack metadata doesn't have a concept of those and we don't try to be smart when
### Windows ### Windows
#### Using GHCup's MSYS2 installation On windows, you may find the following config options useful too:
`skip-msys`, `extra-path`, `extra-include-dirs`, `extra-lib-dirs`.
Stack usually maintains its own msys2 installation. However, you can instruct it to use GHCup's MSYS2 or any other. E.g. if you
had GHCup install msys2 into `C:\ghcup\msys64\`, then you would add the following config to stack's `config.yaml`
(you can find its location via `stack path --stack-root`):
```yaml
skip-msys: true
extra-lib-dirs:
- C:\ghcup\msys64\mingw64\lib
- C:\ghcup\msys64\mingw64\bin
extra-path:
- C:\ghcup\msys64\mingw64\bin
- C:\ghcup\msys64\usr\bin
- C:\ghcup\msys64\usr\local\bin
extra-include-dirs:
- C:\ghcup\msys64\mingw64\include
```
Also check out: [https://docs.haskellstack.org/en/stable/yaml_configuration](https://docs.haskellstack.org/en/stable/yaml_configuration) Also check out: [https://docs.haskellstack.org/en/stable/yaml_configuration](https://docs.haskellstack.org/en/stable/yaml_configuration)
@ -376,28 +360,6 @@ mirrors:
The configuration depends on the host of the mirror and they have to provide the correct configuration. The configuration depends on the host of the mirror and they have to provide the correct configuration.
## Linkers
The GHC bindist configure script by default doesn't honour the system `ld` that is set, but instead
probes for `ld.lld`, `ld.gold` and only then `ld` in order, see
[find_ld.m4](https://gitlab.haskell.org/ghc/ghc/-/blob/master/m4/find_ld.m4?ref_type=heads).
This is controlled by the configure switch `--enable-ld-override`/`--disable-ld-override`, which is enabled by default in GHC.
GHCup however [has decided](https://github.com/haskell/ghcup-hs/issues/1032) **to disable this switch by default**,
for reasons of stability and simplicity.
That means, when `--disable-ld-override` is passed, the linker is picked simply by:
* checking if `LD` env var is set, then use whatever is specified
* otherwise use `ld` binary in PATH (system/distro default)
You can restore the GHC vanilla default by adding this to your `~/.ghcup/config.yaml`:
```yaml
def-ghc-conf-options:
- "--enable-ld-override"
```
# More on installation # More on installation
## Customisation of the installation scripts ## Customisation of the installation scripts
@ -559,24 +521,19 @@ The next sections explain how to install each cross bindist.
### GHC JS cross bindists (experimental) ### GHC JS cross bindists (experimental)
You need the required emscripten JS toolchain. GHC JS cross bindists might require you to install a specific You need the required emscripten JS toolchain:
version of emscripten. If that is the case, then ghcup will display the required emscripten version in the
pre install message. You can use the following commands to install the emscripten toolchain on your system,
substituting the required version for the bindist that you want to install.
(Cf. [GHC-MR 10918](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/10918))
```sh ```sh
git clone https://github.com/emscripten-core/emsdk.git git clone https://github.com/emscripten-core/emsdk.git
cd emsdk cd emsdk
./emsdk install VERSION ./emsdk install latest
./emsdk activate VERSION ./emsdk activate latest
source ./emsdk_env.sh source ./emsdk_env.sh
``` ```
Instructions are also here: [Download and install — Emscripten documentation](https://emscripten.org/docs/getting_started/downloads.html). Instructions are also here: [Download and install — Emscripten 3.1.43-git (dev) documentation](https://emscripten.org/docs/getting_started/downloads.html).
To install you can either use the tui interface by invoking `emconfigure ghcup tui` or To install we need to invoke ghcup like so:
you can install directly like so:
```sh ```sh
emconfigure ghcup install ghc --set javascript-unknown-ghcjs-9.6.2 emconfigure ghcup install ghc --set javascript-unknown-ghcjs-9.6.2

View File

@ -1,7 +1,7 @@
# Installation # Installation
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,
macOS (aka Darwin), FreeBSD and Windows and can also bootstrap a fresh [Haskell developer environment](#supported-tools) from scratch. macOS (aka Darwin), FreeBSD and Windows and can also bootstrap a fresh [Haskell developer environment](./#supported-tools) from scratch.
It follows the 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). It follows the 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).
## How to install ## How to install
@ -32,7 +32,7 @@ GHCup has two main channels for every tool: **recommended** and **latest**. By d
*latest* follows the latest release of every tool, while *recommended* is at the discretion of the GHCup maintainers and based on community adoption (hackage libraries, tools like HLS, stackage support, etc.) and known bugs. *latest* follows the latest release of every tool, while *recommended* is at the discretion of the GHCup maintainers and based on community adoption (hackage libraries, tools like HLS, stackage support, etc.) and known bugs.
Also see [tags and shortcuts](guide.md#tags-and-shortcuts) for more information. Also see [tags and shortcuts](../guide/#tags-and-shortcuts) for more information.
## System requirements ## System requirements
@ -121,9 +121,9 @@ On Windows, msys2 should already have been set up during the installation, so mo
## Next steps ## Next steps
1. Follow the [First steps guide](steps.md) on how to build a "Hello world" program, use `ghc`, run an interactive REPL and create a Haskell project 1. Follow the [First steps guide](../steps) on how to build a "Hello world" program, use `ghc`, run an interactive REPL and create a Haskell project
2. To understand the difference and overlap of `stack` and `cabal`, read on [here](https://gist.github.com/merijn/8152d561fb8b011f9313c48d876ceb07) 2. To understand the difference and overlap of `stack` and `cabal`, read on [here](https://gist.github.com/merijn/8152d561fb8b011f9313c48d876ceb07)
3. To learn Haskell proper check out the links at [How to learn Haskell proper](steps.md#how-to-learn-haskell-proper) 3. To learn Haskell proper check out the links at [How to learn Haskell proper](../steps#how-to-learn-haskell-proper)
4. To learn more about Haskell Toolchain management, check out the [ghcup user guide](./guide.md) 4. To learn more about Haskell Toolchain management, check out the [ghcup user guide](./guide.md)
## Uninstallation ## Uninstallation
@ -382,7 +382,7 @@ All set. You can run `cabal init` now in an empty directory to start a project.
### Void Linux ### Void Linux
Since void linux can be installed with glibc and musl, it's hard to support correctly with ghcup. Since void linux can be installed with glibc and musl, it's hard to support correctly with ghcup.
One way to make ghcup work on **Void Linux musl** is to follow the [Overriding distro detection](guide.md#overriding-distro-detection) One way to make ghcup work on **Void Linux musl** is to follow the [Overriding distro detection](../guide/#overriding-distro-detection)
section and tell it to consider Alpine bindists only. E.g.: section and tell it to consider Alpine bindists only. E.g.:
```sh ```sh

View File

@ -13,7 +13,7 @@ installed a Haskell toolchain:
The Glorious Glasgow Haskell Compilation System, version 8.10.7 The Glorious Glasgow Haskell Compilation System, version 8.10.7
``` ```
If this fails, consult [the Getting started page](install.md) for information on If this fails, consult [the Getting started page](../install) for information on
how to install Haskell on your computer. how to install Haskell on your computer.
This guide is partly based on [Gil Mizrahi's blog](https://gilmi.me/blog/post/2021/08/14/hs-core-tools). This guide is partly based on [Gil Mizrahi's blog](https://gilmi.me/blog/post/2021/08/14/hs-core-tools).

View File

@ -133,8 +133,7 @@ updateSettings usl usr =
gpgSetting' = uGPGSetting usl <|> uGPGSetting usr gpgSetting' = uGPGSetting usl <|> uGPGSetting usr
platformOverride' = uPlatformOverride usl <|> uPlatformOverride usr platformOverride' = uPlatformOverride usl <|> uPlatformOverride usr
mirrors' = uMirrors usl <|> uMirrors usr mirrors' = uMirrors usl <|> uMirrors usr
defGHCconfOptions' = uDefGHCConfOptions usl <|> uDefGHCConfOptions usr in UserSettings cache' metaCache' metaMode' noVerify' verbose' keepDirs' downloader' (updateKeyBindings (uKeyBindings usl) (uKeyBindings usr)) urlSource' noNetwork' gpgSetting' platformOverride' mirrors'
in UserSettings cache' metaCache' metaMode' noVerify' verbose' keepDirs' downloader' (updateKeyBindings (uKeyBindings usl) (uKeyBindings usr)) urlSource' noNetwork' gpgSetting' platformOverride' mirrors' defGHCconfOptions'
where where
updateKeyBindings :: Maybe UserKeyBindings -> Maybe UserKeyBindings -> Maybe UserKeyBindings updateKeyBindings :: Maybe UserKeyBindings -> Maybe UserKeyBindings -> Maybe UserKeyBindings
updateKeyBindings Nothing Nothing = Nothing updateKeyBindings Nothing Nothing = Nothing

View File

@ -439,22 +439,39 @@ installUnpackedGHC path inst tver forceInstall addConfArgs
liftE $ mergeGHCFileTree path inst tver forceInstall liftE $ mergeGHCFileTree path inst tver forceInstall
| otherwise = do | otherwise = do
PlatformRequest {..} <- lift getPlatformReq PlatformRequest {..} <- lift getPlatformReq
Settings {..} <- lift getSettings
addConfArgs' <- sanitizefGHCconfOptions (T.unpack <$> addConfArgs) let ldOverride
defGHCConfOptions' <- sanitizefGHCconfOptions defGHCConfOptions | _tvVersion tver >= [vver|8.2.2|]
, _rPlatform `elem` [Linux Alpine, Darwin]
= ["--disable-ld-override"]
| otherwise
= []
lift $ logInfo "Installing GHC (this may take a while)" lift $ logInfo "Installing GHC (this may take a while)"
env <- case _rPlatform of
-- https://github.com/haskell/ghcup-hs/issues/967
Linux Alpine
-- lets not touch LD for cross targets
| Nothing <- _tvTarget tver -> do
cEnv <- liftIO getEnvironment
spaths <- liftIO getSearchPath
has_ld_bfd <- isJust <$> liftIO (searchPath spaths "ld.bfd")
let ldSet = isJust $ lookup "LD" cEnv
-- only set LD if ld.bfd exists in PATH and LD is not set
-- already
if has_ld_bfd && not ldSet
then do
lift $ logInfo "Detected alpine linux... setting LD=ld.bfd"
pure $ Just (("LD", "ld.bfd") : cEnv)
else pure Nothing
_ -> pure Nothing
lEM $ execLogged "sh" lEM $ execLogged "sh"
("./configure" : ("--prefix=" <> fromInstallDir inst) ("./configure" : ("--prefix=" <> fromInstallDir inst)
: (maybe mempty (\x -> ["--target=" <> T.unpack x]) (_tvTarget tver) : (maybe mempty (\x -> ["--target=" <> T.unpack x]) (_tvTarget tver) <> ldOverride <> (T.unpack <$> addConfArgs))
<> ldOverride (_tvVersion tver)
<> defGHCConfOptions'
<> addConfArgs')
) )
(Just $ fromGHCupPath path) (Just $ fromGHCupPath path)
"ghc-configure" "ghc-configure"
Nothing env
tmpInstallDest <- lift withGHCupTmpDir tmpInstallDest <- lift withGHCupTmpDir
lEM $ make ["DESTDIR=" <> fromGHCupPath tmpInstallDest, "install"] (Just $ fromGHCupPath path) lEM $ make ["DESTDIR=" <> fromGHCupPath tmpInstallDest, "install"] (Just $ fromGHCupPath path)
liftE $ catchWarn $ lEM @_ @'[ProcessError] $ darwinNotarization _rPlatform (fromGHCupPath tmpInstallDest) liftE $ catchWarn $ lEM @_ @'[ProcessError] $ darwinNotarization _rPlatform (fromGHCupPath tmpInstallDest)
@ -462,7 +479,6 @@ installUnpackedGHC path inst tver forceInstall addConfArgs
pure () pure ()
mergeGHCFileTree :: ( MonadReader env m mergeGHCFileTree :: ( MonadReader env m
, HasPlatformReq env , HasPlatformReq env
, HasDirs env , HasDirs env
@ -1297,8 +1313,6 @@ compileGHC targetGhc crossTarget vps bstrap jobs mbuildConfig patches aargs buil
(_tvTarget tver) (_tvTarget tver)
++ ["--prefix=" <> ghcdir] ++ ["--prefix=" <> ghcdir]
++ (if isWindows then ["--enable-tarballs-autodownload"] else []) ++ (if isWindows then ["--enable-tarballs-autodownload"] else [])
-- https://github.com/haskell/ghcup-hs/issues/1032
++ ldOverride (_tvVersion tver)
++ fmap T.unpack aargs ++ fmap T.unpack aargs
) )
(Just workdir) (Just workdir)
@ -1373,16 +1387,3 @@ postGHCInstall ver@GHCTargetVersion {..} = do
forM_ v' $ \(mj, mi) -> lift (getGHCForPVP (PVP (fromIntegral mj :| [fromIntegral mi])) _tvTarget) forM_ v' $ \(mj, mi) -> lift (getGHCForPVP (PVP (fromIntegral mj :| [fromIntegral mi])) _tvTarget)
>>= mapM_ (\v -> liftE $ setGHC v SetGHC_XY Nothing) >>= mapM_ (\v -> liftE $ setGHC v SetGHC_XY Nothing)
ldOverride :: Version -> [String]
ldOverride ver
| ver >= [vver|8.2.2|]
= ["--disable-ld-override"]
| otherwise
= []
sanitizefGHCconfOptions :: MonadFail m => [String] -> m [String]
sanitizefGHCconfOptions args
| "--prefix" `elem` fmap (takeWhile (/= '=')) args = fail "Don't explicitly set --prefix ...aborting"
| otherwise = pure args

View File

@ -150,7 +150,7 @@ executeOut' :: MonadIO m
-> m CapturedProcess -> m CapturedProcess
executeOut' path args chdir env' = do executeOut' path args chdir env' = do
cp <- createProcessWithMingwPath ((proc path args){ cwd = chdir, env = env' }) cp <- createProcessWithMingwPath ((proc path args){ cwd = chdir, env = env' })
(exit, out, err) <- liftIO $ withRestorePath (env cp) $ readCreateProcessWithExitCodeBS cp "" (exit, out, err) <- liftIO $ readCreateProcessWithExitCodeBS cp ""
pure $ CapturedProcess exit out err pure $ CapturedProcess exit out err
@ -166,21 +166,20 @@ execLogged :: ( MonadReader env m
-> FilePath -- ^ log filename (opened in append mode) -> FilePath -- ^ log filename (opened in append mode)
-> Maybe [(String, String)] -- ^ optional environment -> Maybe [(String, String)] -- ^ optional environment
-> m (Either ProcessError ()) -> m (Either ProcessError ())
execLogged exe args chdir lfile env' = do execLogged exe args chdir lfile env = do
Dirs {..} <- getDirs Dirs {..} <- getDirs
logDebug $ T.pack $ "Running " <> exe <> " with arguments " <> show args logDebug $ T.pack $ "Running " <> exe <> " with arguments " <> show args
let stdoutLogfile = fromGHCupPath logsDir </> lfile <> ".stdout.log" let stdoutLogfile = fromGHCupPath logsDir </> lfile <> ".stdout.log"
stderrLogfile = fromGHCupPath logsDir </> lfile <> ".stderr.log" stderrLogfile = fromGHCupPath logsDir </> lfile <> ".stderr.log"
cp <- createProcessWithMingwPath ((proc exe args) cp <- createProcessWithMingwPath ((proc exe args)
{ cwd = chdir { cwd = chdir
, env = env' , env = env
, std_in = CreatePipe , std_in = CreatePipe
, std_out = CreatePipe , std_out = CreatePipe
, std_err = CreatePipe , std_err = CreatePipe
}) })
fmap (toProcessError exe args) fmap (toProcessError exe args)
$ liftIO $ liftIO
$ withRestorePath (env cp)
$ withCreateProcess cp $ withCreateProcess cp
$ \_ mout merr ph -> $ \_ mout merr ph ->
case (mout, merr) of case (mout, merr) of
@ -214,9 +213,16 @@ exec :: MonadIO m
-> Maybe FilePath -- ^ optionally chdir into this -> Maybe FilePath -- ^ optionally chdir into this
-> Maybe [(String, String)] -- ^ optional environment -> Maybe [(String, String)] -- ^ optional environment
-> m (Either ProcessError ()) -> m (Either ProcessError ())
exec exe args chdir env' = do exec exe args chdir env = do
cp <- createProcessWithMingwPath ((proc exe args) { cwd = chdir, env = env' }) -- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/375
exit_code <- liftIO $ withRestorePath (env cp) $ withCreateProcess cp $ \_ _ _ p -> waitForProcess p forM_ (Map.fromList <$> env) $ \cEnv -> do
let paths = ["PATH", "Path"]
curPaths = (\x -> maybe [] splitSearchPath (Map.lookup x cEnv)) =<< paths
newPath = intercalate [searchPathSeparator] curPaths
liftIO $ setEnv "PATH" ""
liftIO $ setEnv "Path" newPath
cp <- createProcessWithMingwPath ((proc exe args) { cwd = chdir, env = env })
exit_code <- liftIO $ withCreateProcess cp $ \_ _ _ p -> waitForProcess p
pure $ toProcessError exe args exit_code pure $ toProcessError exe args exit_code
-- | Like 'exec', except doesn't add msys2 stuff to PATH. -- | Like 'exec', except doesn't add msys2 stuff to PATH.
@ -227,6 +233,13 @@ execNoMinGW :: MonadIO m
-> Maybe [(String, String)] -- ^ optional environment -> Maybe [(String, String)] -- ^ optional environment
-> m (Either ProcessError ()) -> m (Either ProcessError ())
execNoMinGW exe args chdir env = do execNoMinGW exe args chdir env = do
-- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/375
forM_ (Map.fromList <$> env) $ \cEnv -> do
let paths = ["PATH", "Path"]
curPaths = (\x -> maybe [] splitSearchPath (Map.lookup x cEnv)) =<< paths
newPath = intercalate [searchPathSeparator] curPaths
liftIO $ setEnv "PATH" ""
liftIO $ setEnv "Path" newPath
let cp = (proc exe args) { cwd = chdir, env = env } let cp = (proc exe args) { cwd = chdir, env = env }
exit_code <- liftIO $ withCreateProcess cp $ \_ _ _ p -> waitForProcess p exit_code <- liftIO $ withCreateProcess cp $ \_ _ _ p -> waitForProcess p
pure $ toProcessError exe args exit_code pure $ toProcessError exe args exit_code
@ -257,27 +270,7 @@ createProcessWithMingwPath cp = do
newPath = intercalate [searchPathSeparator] (mingWPaths ++ curPaths) newPath = intercalate [searchPathSeparator] (mingWPaths ++ curPaths)
envWithoutPath = foldr (\x y -> Map.delete x y) cEnv paths envWithoutPath = foldr (\x y -> Map.delete x y) cEnv paths
envWithNewPath = Map.insert "Path" newPath envWithoutPath envWithNewPath = Map.insert "Path" newPath envWithoutPath
liftIO $ setEnv "Path" newPath
pure $ cp { env = Just $ Map.toList envWithNewPath } pure $ cp { env = Just $ Map.toList envWithNewPath }
withRestorePath :: MonadIO m => Maybe [(String, String)] -- ^ optional env we want to extract 'PATH' from
-> m a -- ^ action to perform
-> m a
withRestorePath env action = do
-- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/375
oldPATH <- liftIO $ lookupEnv "PATH"
oldPath <- liftIO $ lookupEnv "Path"
forM_ (Map.fromList <$> env) $ \cEnv -> do
let paths = ["PATH", "Path"]
curPaths = (\x -> maybe [] splitSearchPath (Map.lookup x cEnv)) =<< paths
newPath = intercalate [searchPathSeparator] curPaths
liftIO $ setEnv "PATH" ""
liftIO $ setEnv "Path" newPath
liftIO $ print newPath
r <- action
liftIO $ maybe (unsetEnv "PATH") (setEnv "PATH") oldPATH
liftIO $ maybe (unsetEnv "Path") (setEnv "Path") oldPath
pure r

View File

@ -392,12 +392,11 @@ data UserSettings = UserSettings
, uGPGSetting :: Maybe GPGSetting , uGPGSetting :: Maybe GPGSetting
, uPlatformOverride :: Maybe PlatformRequest , uPlatformOverride :: Maybe PlatformRequest
, uMirrors :: Maybe DownloadMirrors , uMirrors :: Maybe DownloadMirrors
, uDefGHCConfOptions :: Maybe [String]
} }
deriving (Show, GHC.Generic, Eq) deriving (Show, GHC.Generic, Eq)
defaultUserSettings :: UserSettings defaultUserSettings :: UserSettings
defaultUserSettings = UserSettings Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing defaultUserSettings = UserSettings Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
fromSettings :: Settings -> Maybe KeyBindings -> UserSettings fromSettings :: Settings -> Maybe KeyBindings -> UserSettings
fromSettings Settings{..} Nothing = fromSettings Settings{..} Nothing =
@ -415,7 +414,6 @@ fromSettings Settings{..} Nothing =
, uGPGSetting = Just gpgSetting , uGPGSetting = Just gpgSetting
, uPlatformOverride = platformOverride , uPlatformOverride = platformOverride
, uMirrors = Just mirrors , uMirrors = Just mirrors
, uDefGHCConfOptions = Just defGHCConfOptions
} }
fromSettings Settings{..} (Just KeyBindings{..}) = fromSettings Settings{..} (Just KeyBindings{..}) =
let ukb = UserKeyBindings let ukb = UserKeyBindings
@ -442,7 +440,6 @@ fromSettings Settings{..} (Just KeyBindings{..}) =
, uGPGSetting = Just gpgSetting , uGPGSetting = Just gpgSetting
, uPlatformOverride = platformOverride , uPlatformOverride = platformOverride
, uMirrors = Just mirrors , uMirrors = Just mirrors
, uDefGHCConfOptions = Just defGHCConfOptions
} }
data UserKeyBindings = UserKeyBindings data UserKeyBindings = UserKeyBindings
@ -528,7 +525,6 @@ data Settings = Settings
, noColor :: Bool -- this also exists in LoggerConfig , noColor :: Bool -- this also exists in LoggerConfig
, platformOverride :: Maybe PlatformRequest , platformOverride :: Maybe PlatformRequest
, mirrors :: DownloadMirrors , mirrors :: DownloadMirrors
, defGHCConfOptions :: [String]
} }
deriving (Show, GHC.Generic) deriving (Show, GHC.Generic)
@ -536,7 +532,7 @@ defaultMetaCache :: Integer
defaultMetaCache = 300 -- 5 minutes defaultMetaCache = 300 -- 5 minutes
defaultSettings :: Settings defaultSettings :: Settings
defaultSettings = Settings False defaultMetaCache Lax False Never Curl False GHCupURL False GPGNone False Nothing (DM mempty) [] defaultSettings = Settings False defaultMetaCache Lax False Never Curl False GHCupURL False GPGNone False Nothing (DM mempty)
instance NFData Settings instance NFData Settings