Skip to content
This repository was archived by the owner on Oct 7, 2020. It is now read-only.

Commit e332055

Browse files
hasufelljneira
andcommitted
Don't mix stack with cabal (#1557)
Fixes #1380 and #1556 * Simplifify targets * Updating docs Co-authored-by: Javier Neira <[email protected]>
1 parent 22c69c6 commit e332055

9 files changed

+89
-214
lines changed

.azure/linux-installhs-stack.yml

+2-6
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,5 @@ jobs:
3232
displayName: Run help of `install.hs`
3333
- bash: |
3434
source .azure/linux.bashrc
35-
stack install.hs stack-install-cabal
36-
displayName: Run stack-install-cabal target of `install.hs`
37-
- bash: |
38-
source .azure/linux.bashrc
39-
stack install.hs build-latest
40-
displayName: Run build-latest target of `install.hs`
35+
stack install.hs latest
36+
displayName: Run latest target of `install.hs`

.azure/windows-installhs-stack.yml

+2-6
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,5 @@ jobs:
3030
displayName: Run help of `install.hs`
3131
- bash: |
3232
source .azure/windows.bashrc
33-
stack install.hs stack-install-cabal
34-
displayName: Run stack-install-cabal target of `install.hs`
35-
- bash: |
36-
source .azure/windows.bashrc
37-
stack install.hs build-latest
38-
displayName: Run build-latest target of `install.hs`
33+
stack install.hs latest
34+
displayName: Run latest target of `install.hs`

README.md

+8-20
Original file line numberDiff line numberDiff line change
@@ -226,47 +226,35 @@ or using the existing alias script
226226

227227
Running the script with cabal on windows requires a cabal version greater or equal to `3.0.0.0`.
228228

229-
Unfortunately, it is still required to have `stack` installed so that the install-script can locate the `local-bin` directory (on Linux `~/.local/bin`) and copy the `hie` binaries to `hie-x.y.z`, which is required for the `hie-wrapper` to function as expected. There are plans to remove this requirement and let users build hie only with one build tool or another.
230-
231229
For brevity, only the `stack`-based commands are presented in the following sections.
232230

233-
##### Install cabal using stack
234-
235-
Although you can use hie for stack based projects (those which have a `stack.yaml` in the project base directory) without having cabal installed, you will need it for cabal based projects (with only a `<projectName>.cabal` file or a `cabal.project` one in the project base directory).
236-
237-
You can install an appropriate cabal version using stack by running:
238-
239-
```bash
240-
stack ./install.hs stack-install-cabal
241-
```
242-
243231
##### Install specific GHC Version
244232

245233
Install hie for the latest available and supported GHC version (and hoogle docs):
246234

247235
```bash
248-
stack ./install.hs build
236+
stack ./install.hs hie
249237
```
250238

251239
Install hie for a specific GHC version (and hoogle docs):
252240

253241
```bash
254242
stack ./install.hs hie-8.6.5
255-
stack ./install.hs build-data
243+
stack ./install.hs data
256244
```
257245

258246
The Haskell IDE Engine can also be built with `cabal v2-build` instead of `stack build`.
259247
This has the advantage that you can decide how the GHC versions have been installed.
260-
To see what GHC versions are available, the command `stack install.hs cabal-ghcs` can be used.
248+
To see what GHC versions are available, the command `cabal-hie-install ghcs` can be used.
261249
It will list all GHC versions that are on the path and their respective installation directory.
262250
If you think, this list is incomplete, you can try to modify the PATH variable, such that the executables can be found.
263-
Note, that the targets `cabal-build` and `cabal-build-data` depend on the found GHC versions.
251+
Note, that the targets `hie` and `data` depend on the found GHC versions.
264252
They install Haskell IDE Engine only for the found GHC versions.
265253

266254
An example output is:
267255

268256
```bash
269-
> stack install.hs cabal-ghcs
257+
> cabal-hie-install ghcs
270258
******************************************************************
271259
Found the following GHC paths:
272260
ghc-8.4.4: /opt/bin/ghc-8.4.4
@@ -278,11 +266,11 @@ ghc-8.6.2: /opt/bin/ghc-8.6.2
278266
If your desired ghc has been found, you use it to install Haskell IDE Engine.
279267

280268
```bash
281-
stack install.hs cabal-hie-8.4.4
282-
stack install.hs cabal-build-data
269+
cabal-hie-install hie-8.4.4
270+
cabal-hie-install data
283271
```
284272

285-
In general, targets that use `cabal` instead of `stack` are prefixed with `cabal-*` and are identical to their counterpart, except they do not install a GHC if it is missing but fail.
273+
In general, executing targets with `cabal` instead of `stack` have the same behaviour, except they do not install a GHC if it is missing but fail.
286274

287275
##### Multiple versions of HIE (optional)
288276

docs/Build.md

+15-11
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,17 @@ See the project's `README` for detailed information about installing `hie`.
2727
The build script `install.hs` defines several targets using the `shake` build system. The targets are roughly:
2828

2929
* `hie-*`: builds and installs the `hie` binaries. Also renames the binaries to contain the correct version-number.
30-
* `build-latest`: builds and installs `hie` for the latest available and supported `ghc` version.
31-
* `build-data`: builds the hoogle-db required by `hie`
32-
* `build`: builds and installs `hie` for the latest supported `ghc` version (like `build-latest`) and the hoogle-db (like `build-data`)
33-
* `cabal-*`: execute the same task as the original target, but with `cabal` instead of `stack`
30+
* `latest`: builds and installs `hie` for the latest available and supported `ghc` version.
31+
* `data`: builds the hoogle-db required by `hie`
32+
* `hie`: builds and installs `hie` for the latest supported `ghc` version (like `latest`) and the hoogle-db (like `data`)
3433

35-
Each `stack-*.yaml` contains references to packages in the submodules. Calling `stack` with one of those causes the build to fail if the submodules have not been initialized already. The file `shake.yaml` solves this issue invoking the `git` binary itself to update the submodules. Moreover, it specifies the correct version of `shake` and is used for installing all run-time dependencies such as `cabal` and `hoogle` if necessary.
34+
Each `stack-*.yaml` contains references to packages in the submodules. Calling `stack` with one of those causes the build to fail if the submodules have not been initialized already. The file `shake.yaml` solves this issue invoking the `git` binary itself to update the submodules. Moreover, it specifies the correct version of `shake` and is used for installing all run-time dependencies such as `hoogle` if necessary.
3635

3736
### Run-time dependencies
3837

3938
`hie` depends on a correct environment in order to function properly:
4039

41-
* `cabal-install`: This dependency is required by `hie` to handle correctly projects that are not `stack` based. You can install an appropriate version using `stack` with the `stack-install-cabal` target.
40+
* `cabal-install`: This dependency is required by `hie` to handle correctly projects that are not `stack` based. You can install it using one of the methods listed here: https://www.haskell.org/cabal/#install-upgrade
4241
* The `hoogle` database: `hoogle generate` needs to be called with the most-recent `hoogle` version.
4342

4443
### Steps to build `hie`
@@ -68,12 +67,21 @@ EOF
6867

6968
Then `hie` can be compiled for a specific GHC version:
7069

70+
* For cabal prior to 3.0.0.0
7171
```bash
7272
export GHCP=<path-to-ghc-binary>
7373
cabal v2-install exe:hie -w $GHCP \
7474
--write-ghc-environment-files=never --symlink-bindir=$HOME/.local/bin \
7575
--overwrite-policy=always --reinstall
7676
```
77+
* For cabal 3.0.0.0 or newer
78+
```bash
79+
export GHCP=<path-to-ghc-binary>
80+
cabal v2-install exe:hie -w $GHCP \
81+
--write-ghc-environment-files=never --installdir=$HOME/.local/bin \
82+
--overwrite-policy=always --reinstall
83+
```
84+
* For windows you will need cabal 3.0.0.0 and add the argument `--install-method=copy`
7785

7886
The final step is to configure the `hie` client to use a custom `hie-wrapper` script that enables the runtime options for profiling. Such a script could look like this:
7987

@@ -88,17 +96,13 @@ The final step is to configure the `hie` client to use a custom `hie-wrapper` sc
8896

8997
The `install.hs` script performs some checks to ensure that a correct installation is possible and provide meaningful error messages for known issues.
9098

91-
* `stack` needs to be up-to-date. Version `1.9.3` is required
99+
* `stack` needs to be up-to-date. Version `2.1.1` is required
92100
* `cabal` needs to be up-to-date. Version `3.0.0.0` is required for windows systems and `2.4.1.0` for other ones.
93101
* `ghc-8.6.3` is broken on windows. Trying to install `hie-8.6.3` on windows is not possible.
94102
* When the build fails, an error message, that suggests to remove `.stack-work` directory, is displayed.
95103

96104
### Tradeoffs
97105

98-
#### `stack` is a build dependency
99-
100-
Currently, `stack` is needed even if you run the script with `cabal` to get the path where install the binaries but there are plans to remove that dependency (see #1380).
101-
102106
#### run `install.hs` with `stack` installs a GHC before running
103107

104108
Before the code in `install.hs` can be executed, `stack` installs a `GHC`, depending on the `resolver` field in `shake.yaml`. This is necessary if `install.hs` should be completely functional right after a fresh `git clone` without further configuration.

install/hie-install.cabal

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ library
3131

3232
if flag(run-from-stack)
3333
cpp-options: -DRUN_FROM_STACK
34+
else
35+
build-depends: cabal-install-parsers
3436

3537
flag run-from-stack
3638
description: Inform the application that it is run from stack

install/src/Cabal.hs

+20-29
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
{-# LANGUAGE CPP #-}
2+
13
module Cabal where
24

35
import Development.Shake
@@ -15,16 +17,26 @@ import System.Directory ( findExecutable
1517
import Version
1618
import Print
1719
import Env
18-
import Stack
20+
import Data.Functor.Identity
21+
#if RUN_FROM_STACK
22+
import Control.Exception ( throwIO )
23+
#else
24+
import Cabal.Config
25+
#endif
26+
27+
getInstallDir :: IO FilePath
28+
#if RUN_FROM_STACK
29+
-- we should never hit this codepath
30+
getInstallDir = throwIO $ userError "Stack and cabal should never be mixed"
31+
#else
32+
getInstallDir = runIdentity . cfgInstallDir <$> readConfig
33+
#endif
1934

2035
execCabal :: CmdResult r => [String] -> Action r
21-
execCabal = execCabalWithOriginalPath
36+
execCabal = command [] "cabal"
2237

2338
execCabal_ :: [String] -> Action ()
24-
execCabal_ = execCabalWithOriginalPath
25-
26-
execCabalWithOriginalPath :: CmdResult r => [String] -> Action r
27-
execCabalWithOriginalPath = withoutStackCachedBinaries . (command [] "cabal")
39+
execCabal_ = command [] "cabal"
2840

2941
cabalBuildData :: Action ()
3042
cabalBuildData = do
@@ -39,19 +51,9 @@ getGhcPathOfOrThrowError versionNumber =
3951
error (ghcVersionNotFoundFailMsg versionNumber)
4052
Just p -> return p
4153

42-
cabalBuildHie :: VersionNumber -> Action ()
43-
cabalBuildHie versionNumber = do
44-
ghcPath <- getGhcPathOfOrThrowError versionNumber
45-
execCabal_
46-
[ "v2-build"
47-
, "-w", ghcPath
48-
, "--write-ghc-environment-files=never"
49-
, "--max-backjumps=5000"
50-
, "--disable-tests"]
51-
5254
cabalInstallHie :: VersionNumber -> Action ()
5355
cabalInstallHie versionNumber = do
54-
localBin <- getLocalBin
56+
localBin <- liftIO $ getInstallDir
5557
cabalVersion <- getCabalVersion
5658
ghcPath <- getGhcPathOfOrThrowError versionNumber
5759

@@ -65,6 +67,7 @@ cabalInstallHie versionNumber = do
6567
, "-w", ghcPath
6668
, "--write-ghc-environment-files=never"
6769
, installDirOpt, localBin
70+
, "--max-backjumps=5000"
6871
, "exe:hie"
6972
, "--overwrite-policy=always"
7073
]
@@ -84,18 +87,6 @@ cabalInstallHie versionNumber = do
8487
++ minorVerExe
8588
++ " to " ++ localBin
8689

87-
installCabalWithStack :: Action ()
88-
installCabalWithStack = do
89-
-- try to find existing `cabal` executable with appropriate version
90-
mbc <- withoutStackCachedBinaries (liftIO (findExecutable "cabal"))
91-
92-
case mbc of
93-
Just c -> do
94-
cabalVersion <- checkCabal
95-
printLine $ "There is already a cabal executable in $PATH with the required minimum version: " ++ cabalVersion
96-
-- install `cabal-install` if not already installed
97-
Nothing -> execStackShake_ ["install", "cabal-install"]
98-
9990
checkCabal_ :: Action ()
10091
checkCabal_ = checkCabal >> return ()
10192

install/src/Help.hs

+5-51
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ helpMessage versions@BuildableVersions {..} = do
7878
[emptyTarget]
7979
[ generalTargets
8080
, defaultTargets
81-
, stackTargets
82-
, cabalTargets
81+
, if isRunFromCabal then [cabalGhcsTarget] else []
8382
, [macosIcuTarget]
8483
]
8584

@@ -89,52 +88,26 @@ helpMessage versions@BuildableVersions {..} = do
8988
defaultTargets = [buildTarget, buildLatestTarget, buildDataTarget]
9089
++ map hieTarget (getDefaultBuildSystemVersions versions)
9190

92-
stackTargets =
93-
[ stackTarget buildTarget
94-
, stackTarget buildLatestTarget
95-
, stackTarget buildDataTarget
96-
]
97-
++ (if isRunFromStack then [stackTarget installCabalTarget] else [])
98-
++ map (stackTarget . hieTarget) stackVersions
99-
100-
cabalTargets =
101-
[ cabalGhcsTarget
102-
, cabalTarget buildTarget
103-
, cabalTarget buildLatestTarget
104-
, cabalTarget buildDataTarget
105-
]
106-
++ map (cabalTarget . hieTarget) cabalVersions
107-
10891
-- | Empty target. Purpose is to introduce a newline between the targets
10992
emptyTarget :: (String, String)
11093
emptyTarget = ("", "")
11194

11295
templateTarget :: (String, String)
11396
templateTarget = ("<target>", "")
11497

115-
targetWithBuildSystem :: String -> TargetDescription -> TargetDescription
116-
targetWithBuildSystem system (target, description) =
117-
(system ++ "-" ++ target, description ++ "; with " ++ system)
118-
119-
stackTarget :: TargetDescription -> TargetDescription
120-
stackTarget = targetWithBuildSystem "stack"
121-
122-
cabalTarget :: TargetDescription -> TargetDescription
123-
cabalTarget = targetWithBuildSystem "cabal"
124-
12598
hieTarget :: String -> TargetDescription
12699
hieTarget version =
127100
("hie-" ++ version, "Builds hie for GHC version " ++ version)
128101

129102
buildTarget :: TargetDescription
130-
buildTarget = ("build", "Build hie with the latest available GHC and the data files")
103+
buildTarget = ("hie", "Build hie with the latest available GHC and the data files")
131104

132105
buildLatestTarget :: TargetDescription
133-
buildLatestTarget = ("build-latest", "Build hie with the latest available GHC")
106+
buildLatestTarget = ("latest", "Build hie with the latest available GHC")
134107

135108
buildDataTarget :: TargetDescription
136109
buildDataTarget =
137-
("build-data", "Get the required data-files for `hie` (Hoogle DB)")
110+
("data", "Get the required data-files for `hie` (Hoogle DB)")
138111

139112
-- special targets
140113

@@ -146,25 +119,6 @@ helpTarget = ("help", "Show help message including all targets")
146119

147120
cabalGhcsTarget :: TargetDescription
148121
cabalGhcsTarget =
149-
( "cabal-ghcs"
122+
( "ghcs"
150123
, "Show all GHC versions that can be installed via `cabal-build`."
151124
)
152-
153-
installCabalTarget :: TargetDescription
154-
installCabalTarget =
155-
( "install-cabal"
156-
, "Install the cabal executable. It will install the required minimum version for hie (currently "
157-
++ versionToString requiredCabalVersion
158-
++ ") if it isn't already present in $PATH"
159-
)
160-
161-
-- | Creates a message of the form "a, b, c and d", where a,b,c,d are GHC versions.
162-
-- If there is no GHC in the list of `hieVersions`
163-
allVersionMessage :: [String] -> String
164-
allVersionMessage wordList = case wordList of
165-
[] -> ""
166-
[a] -> show a
167-
(a : as) ->
168-
let msg = intersperse ", " wordList
169-
lastVersion = last msg
170-
in concat $ init (init msg) ++ [" and ", lastVersion]

0 commit comments

Comments
 (0)