Skip to content

Commit f9996bb

Browse files
committed
Update Stack and VS Code
1 parent 805c2f8 commit f9996bb

File tree

1 file changed

+151
-104
lines changed

1 file changed

+151
-104
lines changed

doc/topics/Stack_and_VS_Code.md

+151-104
Original file line numberDiff line numberDiff line change
@@ -10,112 +10,159 @@ is an extension for VS Code that is popular with Haskell coders.
1010
The 'Haskell' extension can be used with Stack but there are some things to be
1111
aware of, set out below.
1212

13-
## Haskell Language Server
14-
15-
The VS Code extension makes use of the Haskell Language Server (HLS). To work,
16-
HLS has to be built with the same version of GHC that it will support. That is,
17-
a version of HLS is required for each version of GHC in use. It is possible that
18-
the most recent versions of GHC are not supported by HLS.
19-
20-
By default, the VS Code extension uses tools that are in the PATH. However, the
21-
extension's settings (under 'Haskell: Manage HLS') allow a user to specify
22-
that the extension should use a separate application,
23-
[GHCup](https://www.haskell.org/ghcup/), to download and install the versions of
24-
HLS that it needs. GHCup can download and install things other than HLS,
25-
including GHC, MSYS2 (on Windows), Cabal (a tool for building Haskell code), and
26-
Stack itself. GHCup can also update itself. On Windows, GHCup has the capability
27-
of using the Stack-supplied MSYS2 rather than installing a duplicate copy. Cabal
28-
(the tool), like Stack, depends on the Cabal (the library). Cabal (the tool),
29-
unlike Stack, does not have the capability to automatically install necessary
30-
versions of GHC, and (as well as supporting the extension) GHCup fills a
31-
important gap for users of the Cabal tool.
32-
33-
If the VS Code extension is set not to use GHCup, its user needs to ensure that
34-
each version of HLS that the extension needs is on the PATH.
35-
36-
For the most part, the versions of HLS provided by GHCup are built with the same
37-
versions of GHC that Stack downloads from its default `setup-info` dictionary
38-
(see the [`setup-info`](../configure/yaml/non-project.md#setup-info) non-project
39-
specific configuration option documentation). Stack's default is to mirror the
40-
'official' binary distributions published by GHC. However, in some cases, it is
41-
possible that a GHCup-supplied and GHCup-selected HLS has been built with a
42-
different binary distribution of GHC than the one which Stack has installed.
43-
44-
One example of that occurred with the release of GHC 9.0.2. For some Linux users
45-
(Debian 9 and Fedora 27), the version of GHC 9.0.2 linked on GHC’s download
46-
[web page](https://www.haskell.org/ghc/download_ghc_9_0_2.html) was broken. The
47-
GHC developers made alternative ‘9.0.2a’ versions available. For a while, Stack
48-
referred to the versions published by GHC on its download web page while the
49-
GHCup-supplied versions of HLS were built using alternative versions. This
50-
incompatibility led to problems. It was resolved by Stack's default also being
51-
changed to refer to the '9.0.2a' versions. (Where Stack has already installed
52-
GHC 9.0.2, it is necessary to delete GHC 9.0.2 from the `stack path --programs`
53-
directory. This will cause Stack to reinstall the alternative version, when it
54-
first needs GHC 9.0.2. Stack should distinguish what it builds with the
55-
alternative from what it has built, and cached, with the original GHC 9.0.2.)
56-
57-
### GHCup and Stack >= 2.9.1
58-
59-
From Stack 2.9.1, GHCup can configure Stack so that if Stack needs a version of
60-
GHC, GHCup takes over obtaining and installing that version. By default, the
61-
script to install GHCup (which can be run more than once) configures Stack in
62-
that way. For further information about how GHCup configures Stack, see the GHC
63-
installation customisation
13+
## GHCup
14+
15+
The separate [GHCup](https://www.haskell.org/ghcup/) project provides a tool
16+
that can be used to install various tools useful for developing Haskell
17+
projects. Those tools include:
18+
19+
* GHC,
20+
* HLS (see further below),
21+
* MSYS2 (on Windows; see the developing on Windows
22+
[documentation](developing_on_windows.md)),
23+
* Stack, and
24+
* Cabal (the tool).
25+
26+
Stack itself can be used to install GHC and MSYS2. Stack can also be used to
27+
upgrade, or downgrade, Stack.
28+
29+
GHCup can configure Stack so that if Stack needs a version of GHC, GHCup takes
30+
over obtaining and installing that version. By default, the script to install
31+
GHCup (which can be run more than once) configures Stack in that way. For
32+
further information about how GHCup configures Stack, see the GHC installation
33+
customisation
6434
[documentation](../configure/customisation_scripts.md#ghc-installation-customisation).
6535

66-
### Workaround #1
67-
68-
If GHCup does not configure Stack in the way described above, one workaround is
69-
to allow GHCup to install versions of GHC on the PATH and to cause Stack to use
70-
those versions of GHC, by making use of Stack's `install-ghc` option (which
71-
needs to be disabled) and Stack's `system-ghc` option (which needs to be
72-
enabled). For further information about these options, see the
73-
[`install-ghc`](../configure/yaml/non-project.md#install-ghc) documentation and
74-
the [`system-ghc`](../configure/yaml/non-project.md#system-ghc) documentation.
75-
76-
For this workaround to work, each time that a snapshot is used that references a
77-
different version of GHC, then GHCup must be used to install it (if GHCup has
78-
not already installed that version). For example, to use `snapshot: lts-22.28`
79-
(GHC 9.6.6), the command `ghcup install ghc 9.6.6` must have been used to
80-
install GHC 9.6.6. That may be a minor inconvenience for some people, as one the
81-
primary benefits of Stack over other tools for building Haskell code has been
82-
that Stack automatically ensures that the necessary version of GHC is available.
83-
84-
### Workaround #2
85-
86-
If GHCup does not configure Stack, another partial workaround is to install
87-
GHCup so that it is 'empty' except for the current version of HLS, allow the
88-
VS Code extension to use GHCup to manage HLS requirements only, and to ignore
89-
any messages (if any) from the extension on start-up that installation of GHC,
90-
Cabal (the tool) and/or Stack are also necessary (they are not, if only Stack is
91-
being used).
92-
93-
For this workaround to work, however, there can be no differences between the
94-
version of GHC that the GHCup-supplied HLS was built with and the version that
95-
Stack has installed. A slight inconvenience here is also the possibility of
96-
false messages from the start-up that need to be ignored. In principle, those
97-
messages can be disabled by
98-
[setting the following](https://github.com/haskell/vscode-haskell#setting-a-specific-toolchain)
99-
for the VS Code extension:
100-
101-
~~~yaml
102-
"haskell.toolchain": {
103-
"ghc": null,
104-
"cabal": null,
105-
"stack": null
106-
}
107-
~~~
108-
109-
To install a version of GHCup that is 'empty' is a little more complicated than
110-
a default installation of GHCup.
111-
112-
On Unix-like operating systems, the following environment variable must be set
113-
before GHCup's installation `sh` script is run: `BOOTSTRAP_HASKELL_MINIMAL`.
114-
115-
On Windows, the second argument to the PowerShell script must be set to
116-
`$false`, namely:
117-
118-
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 $true,$false
36+
On Windows, GHCup has the capability of using the Stack-supplied MSYS2 rather
37+
than installing a duplicate copy.
38+
39+
## HLS
40+
41+
The VS Code extension makes use of
42+
[HLS](https://github.com/haskell/haskell-language-server) (the Haskell Language
43+
Server). To work, HLS has to be built with the same version of GHC that it will
44+
support. That is, a version of HLS is required for each version of GHC in use.
45+
It is possible that the most recent versions of GHC are not supported by HLS.
46+
47+
VS Code with the 'Haskell' extension can be configured in a number of ways:
48+
49+
=== "GHCup manages HLS"
50+
51+
The VS Code extension's settings (under 'Haskell: Manage HLS') allow a
52+
user to specify that the extension should use GHCup, to download and install
53+
the versions of HLS that it needs.
54+
55+
If GHCup manages versions of HLS, versions of GHC can be managed in a number
56+
of ways:
57+
58+
=== "Stack manages GHC using GHCup"
59+
60+
As identified above, GHCup can configure Stack to use GHCup to manage
61+
versions of GHC.
62+
63+
=== "Stack manages GHC directly"
64+
65+
It is possible to install GHCup so that it is 'empty' except for the
66+
current version of HLS, allow the VS Code extension to use GHCup to
67+
manage HLS requirements only, and to disable messages from the extension
68+
on start-up that installation of GHC, Cabal (the tool)
69+
and/or Stack are also necessary (they are not, if only Stack is being
70+
used).
71+
72+
To install a version of GHCup that is 'empty' is a little more
73+
complicated than a default installation of GHCup.
74+
75+
=== "Unix-like"
76+
77+
The following environment variable must be set before GHCup's
78+
installation `sh` script is run: `BOOTSTRAP_HASKELL_MINIMAL`.
79+
80+
=== "Windows"
81+
82+
The second argument to the PowerShell script must be set to
83+
`$false`, namely:
84+
85+
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 $true,$false
86+
87+
There is the possibility of false messages from the extension on
88+
start-up that need to be ignored. Those messages can be disabled by
89+
[setting the following](https://github.com/haskell/vscode-haskell#setting-a-specific-toolchain)
90+
for the VS Code extension:
91+
92+
~~~yaml
93+
"haskell.toolchain": {
94+
"ghc": null,
95+
"cabal": null,
96+
"stack": null
97+
}
98+
~~~
99+
100+
There can be no differences between the version of GHC that the
101+
GHCup-supplied HLS was built with and the version that Stack has
102+
installed.
103+
104+
For the most part, the versions of HLS provided by GHCup are built with
105+
the same versions of GHC that Stack downloads from its default
106+
`setup-info` dictionary (see the
107+
[`setup-info`](../configure/yaml/non-project.md#setup-info) non-project
108+
specific configuration option documentation). Stack's default is to
109+
mirror the 'official' binary distributions published by GHC.
110+
111+
However, in some cases, it is possible that a GHCup-supplied and
112+
GHCup-selected HLS has been built with a different binary distribution
113+
of GHC than the one which Stack has installed.
114+
115+
??? question "When have the GHCup- and Stack-supplied GHCs differed?"
116+
117+
An example occurred with the release of GHC 9.0.2. For some Linux
118+
users (Debian 9 and Fedora 27), the version of GHC 9.0.2 linked on
119+
GHC’s download
120+
[web page](https://www.haskell.org/ghc/download_ghc_9_0_2.html) was
121+
broken. The GHC developers made alternative ‘9.0.2a’ versions
122+
available. For a while, Stack referred to the versions published by
123+
GHC on its download web page while the GHCup-supplied versions of
124+
HLS were built using alternative versions. This incompatibility led
125+
to problems.
126+
127+
It was resolved by Stack's default also being changed to refer to
128+
the '9.0.2a' versions. Where Stack has already installed GHC 9.0.2,
129+
it is necessary to delete GHC 9.0.2 from the `stack path --programs`
130+
directory. This will cause Stack to reinstall the alternative
131+
version, when it first needs GHC 9.0.2. Stack should distinguish
132+
what it builds with the alternative from what it has built, and
133+
cached, with the original GHC 9.0.2.
134+
135+
=== "Stack uses a GHCup-supplied GHC"
136+
137+
GHCup is used to manage versions of GHC and Stack is configured to use
138+
the version of GHC on the PATH.
139+
140+
That is, GHCup is used to install a version of GHC on the PATH. Stack is
141+
configured to make use of that version, by making use of Stack's
142+
`install-ghc` option (which needs to be disabled) and Stack's
143+
`system-ghc` option (which needs to be enabled).
144+
145+
For further information about these options, see the
146+
[`install-ghc`](../configure/yaml/non-project.md#install-ghc)
147+
documentation and the
148+
[`system-ghc`](../configure/yaml/non-project.md#system-ghc)
149+
documentation.
150+
151+
Each time that a snapshot is used that references a different version of
152+
GHC, then GHCup must be used to install it (if GHCup has not already
153+
installed that version). For example, to use `snapshot: lts-22.28`
154+
(GHC 9.6.6), the command `ghcup install ghc 9.6.6` must have been used
155+
to install GHC 9.6.6. That may be a minor inconvenience for some people,
156+
as one the primary benefits of Stack over other tools for building
157+
Haskell code has been that Stack automatically ensures that the
158+
necessary version of GHC is available.
159+
160+
=== "User manages HLS"
161+
162+
By default, the VS Code extension uses tools that are in the PATH.
163+
164+
If the VS Code extension is set not to use GHCup, its user needs to ensure
165+
that each version of HLS that the extension needs is on the PATH.
119166

120167
### Cradle
121168

0 commit comments

Comments
 (0)