1- <div class =" hidden-warning " ><a href =" https://docs.haskellstack.org/ " ><img src =" https://cdn.jsdelivr.net/gh/commercialhaskell/stack/doc/img/hidden-warning.svg " ></a ></div >
1+ <div class =" hidden-warning " ><a href =" https://docs.haskellstack.org/ " ><img src =" https://cdn.jsdelivr.net/gh/commercialhaskell/stack/doc/img/hidden-warning.svg " ></a ></div >
22
33# 2. Building your project
44
5- The ` build ` command is the heart and soul of Stack. It is the engine that powers
6- building your code, testing it, getting dependencies, and more. Quite a bit of
7- the remainder of this guide will cover more advanced ` build ` functions and
8- features, such as building test and Haddocks at the same time, or constantly
9- rebuilding blocking on file changes.
5+ The [ ` stack build ` ] ( ../commands/build_command.md ) command is the heart of Stack.
6+ It is the engine that powers building your code, testing it, getting
7+ dependencies, and more. Much of the remainder of this getting started guide will
8+ cover its features.
109
1110!!! note
1211
@@ -16,61 +15,95 @@ rebuilding blocking on file changes.
1615
1716## Adding dependencies
1817
19- Let's say we decide to modify our ` helloworld ` source a bit to use a new
20- library, perhaps the ubiquitous ` text ` package. In ` src/Lib.hs ` , we can, for
21- example add:
18+ A Haskell package often depends on code exposed by other Haskell packages.
19+
20+ Let's say we decide to modify our existing ` helloworld ` package source code to
21+ use a new library, the one provided by the
22+ [ ` text ` ] ( https://hackage.haskell.org/package/text ) package.
23+
24+ We can modify ` src/Lib.hs ` so that its contents are as follows (click
25+ :material-plus-circle: to learn more):
2226
2327~~~ haskell
24- {-# LANGUAGE OverloadedStrings #-}
28+ {-# LANGUAGE OverloadedStrings #-} -- (1)!
29+
2530module Lib
2631 ( someFunc
2732 ) where
2833
29- import qualified Data.Text.IO as T
34+ import qualified Data.Text.IO as T -- (2)!
3035
3136someFunc :: IO ()
32- someFunc = T. putStrLn " someFunc"
37+ someFunc = T. putStrLn " someFunc" -- (3)!
3338~~~
3439
35- When we try to build this, things don't go as expected:
40+ 1 . Enables overloaded string literals. String literals now have type
41+ ` (IsString a) => a ` .
42+
43+ 2 . The module is exposed by the library of the ` text ` package.
44+
45+ 3 . ` Data.Text.IO.putStrLn :: Text -> IO () ` .
46+
47+ If we command:
3648
3749~~~ text
3850stack build
39- # build failure output (abridged for clarity) ...
40- src\Lib.hs:6:1: error:
51+ ~~~
52+
53+ Stack will report error [ S-7282] during the build:
54+
55+ ~~~ text
56+ ...
57+ Building library for helloworld-0.1.0.0..
58+ [1 of 2] Compiling Lib [Source file changed]
59+
60+ src\Lib.hs:7:1: error:
4161 Could not load module ‘Data.Text.IO’
42- It is a member of the hidden package ‘text-1.2.5.0 ’.
62+ It is a member of the hidden package ‘text-2.0.2 ’.
4363 Perhaps you need to add ‘text’ to the build-depends in your .cabal file.
4464 Use -v (or `:set -v` in ghci) to see a list of the files searched for.
4565 |
46- 6 | import qualified Data.Text.IO as T
66+ 7 | import qualified Data.Text.IO as T
4767 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
68+
69+ Error: [S-7282]
70+ Stack failed to execute the build plan.
71+
72+ While executing the build plan, Stack encountered the error:
73+
74+ [S-7011]
75+ While building package helloworld-0.1.0.0 (scroll up to its section to see the error) using:
76+ ...
77+ Process exited with code: ExitFailure 1
4878~~~
4979
50- This means that the package containing the module in question is not available.
51- To tell Stack to use [ text] ( https://hackage.haskell.org/package/text ) , you need
52- to add it to your ` package.yaml ` file — specifically in your ` dependencies `
53- section, like this:
80+ The error ` Could not load module ... ` means that the package exposing the module
81+ in question is not available.
82+
83+ To tell Stack that the ` text ` package is a dependency of the ` helloworld `
84+ package, you need to update the package description file (` package.yaml ` ).
85+ Specifically, you need to add ` text ` under the ` dependencies ` key, like this:
5486
5587~~~ yaml
5688dependencies :
5789- base >= 4.7 && < 5
58- - text # added here
90+ - text # added
5991~~~
6092
61- Now if we rerun `stack build`, we should get a successful result. Command :
93+ Now, if we command again :
6294
6395~~~text
6496stack build
65- # build output ...
6697~~~
6798
68- This output means that the ` text ` package was downloaded, configured, built, and
99+ we should get a successful result.
100+
101+ The output means that the ` text ` package was downloaded, configured, built, and
69102locally installed. Once that was done, we moved on to building our project
70103package (` helloworld ` ). At no point did we need to ask Stack to build
71104dependencies — it does so automatically.
72105
73- ### Listing Dependencies
106+ ## Listing dependencies
74107
75108Let's have Stack add a few more dependencies to our project. First, we'll
76109include two new packages in the ` dependencies ` section for our library in our
@@ -80,44 +113,48 @@ include two new packages in the `dependencies` section for our library in our
80113dependencies :
81114- base >= 4.7 && < 5
82115- text
83- - filepath
84- - containers
116+ - filepath # added
117+ - containers # added
85118~~~
86119
87- After adding these two dependencies, we can again run `stack build` to have them
88- installed. Command :
120+ After adding these two dependencies, we can again command :
89121
90122~~~text
91123stack build
92- # build output ...
93124~~~
94125
95- Finally, to find out which versions of these libraries Stack installed, we can
96- ask Stack to ` ls dependencies ` . Command:
126+ to have them downloaded, configured, built, and locally installed.
127+
128+ To find out which versions of these packages Stack installed, we can command:
97129
98130~~~ text
99131stack ls dependencies
100- # dependency output ...
101132~~~
102133
103- ### extra-deps
134+ ## Packages not in the snapshot
135+
136+ The packages ` text ` , ` filepath ` and ` containers ` have something in common: they
137+ are all provided with GHC (referred to as GHC boot packages).
104138
105- Let's try a more off-the-beaten-track package: the joke
106- [ acme-missiles] ( http://www.stackage.org/package/acme-missiles ) package. Our
107- source code is simple:
139+ Let's try a dependency on a more off-the-beaten-track package: the joke
140+ [ acme-missiles] ( http://www.stackage.org/package/acme-missiles ) package.
141+
142+ We can further modify ` src/Lib.hs ` so that its contents are as follows:
108143
109144~~~ haskell
110145module Lib
111146 ( someFunc
112147 ) where
113148
114- import Acme.Missiles
149+ import Acme.Missiles ( launchMissiles )
115150
116151someFunc :: IO ()
117152someFunc = launchMissiles
118153~~~
119154
120- Again, we add this new dependency to the ` package.yaml ` file like this:
155+ As before, to tell Stack that the ` acme-missiles ` package is a dependency of the
156+ ` helloworld ` package, we can update the package description file
157+ (` package.yaml ` ). The relevant part of the file now looks like this:
121158
122159~~~ yaml
123160dependencies :
@@ -128,47 +165,80 @@ dependencies:
128165- acme-missiles # added
129166~~~
130167
131- However, rerunning `stack build` shows us the following error message. Command :
168+ If we command :
132169
133170~~~text
134171stack build
135- # build failure output ...
136172~~~
137173
138- It says that it was unable to construct the build plan.
174+ Stack will report error [ S-4804] :
175+
176+ ~~~ text
177+ Error: [S-4804]
178+ Stack failed to construct a build plan.
179+
180+ While constructing the build plan, Stack encountered the following errors. The
181+ 'Stack configuration' refers to the set of package versions specified by the
182+ snapshot (after any dropped packages, or pruned GHC boot packages; if a boot
183+ package is replaced, Stack prunes all other such packages that depend on it) and
184+ any extra-deps:
185+
186+ In the dependencies for helloworld-0.1.0.0:
187+ * acme-missiles needed, but no version is in the Stack configuration (latest
188+ matching version is 0.3).
189+ The above is/are needed since helloworld is a build target.
190+
191+ Some different approaches to resolving some or all of this:
192+
193+ * Recommended action: try adding the following to your extra-deps in
194+ ...\helloworld\stack.yaml (project-level configuration):
195+
196+ - acme-missiles-0.3@sha256:2ba66a092a32593880a87fb00f3213762d7bca65a687d45965778deb8694c5d1,613
197+ ~~~
198+
199+ It says that Stack was unable to construct the build plan.
139200
140201This brings us to the next major topic in using Stack.
141202
142- ## Curated package sets
203+ ## Extending snapshots
204+
205+ A snapshot specifies a version of GHC and a set of package versions.
143206
144207Remember above when ` stack new ` selected some
145208[ LTS snapshot] ( https://github.com/commercialhaskell/lts-haskell#readme ) for us?
146209That defined our build plan and available packages. When we tried using the
147210` text ` package, it just worked, because it was part of the LTS * package set* .
148211
149- We've specified the ` acme-missiles ` package in the ` package.yaml ` file (see
150- above), but ` acme-missiles ` is not part of that LTS package set, so building
212+ We have updated the description of the ` helloworld ` package (in ` package.yaml ` )
213+ to specify that it depends on the ` acme-missiles ` package, but ` acme-missiles `
214+ is not a member of the set of packages specified by the snapshot. So building
151215failed.
152216
153- To add ` acme-missiles ` to the available packages, we'll use the ` extra-deps ` key
154- in the ` stack.yaml ` file. That key defines extra packages, not present in the
155- snapshot, that will be needed as dependencies. You can add this like so:
217+ To add a version of ` acme-missiles ` to the available package versions, we'll use
218+ the ` extra-deps ` key in Stack's project-level configuration file (` stack.yaml ` ).
219+ That key defines extra package versions, not present in the snapshot, that will
220+ be needed as dependencies. You can add this like so:
156221
157222~~~ yaml
158223extra-deps :
159224- acme-missiles-0.3 # not in the LTS snapshot
160225~~~
161226
162- Now `stack build` will succeed.
227+ Now, if we command again :
228+
229+ ~~~text
230+ stack build
231+ ~~~
232+
233+ we should get a successful result.
163234
164- With that out of the way, let's dig a little bit more into these package sets,
165- also known as *snapshots*. We mentioned the LTS snapshots, and you can get quite
166- a bit of information about it at
235+ With that out of the way, let's dig a little bit more into these snapshots. We
236+ mentioned the LTS snapshots, and you can get information about it at
167237[ https://www.stackage.org/lts ] ( https://www.stackage.org/lts ) , including:
168238
169- * The appropriate value (`lts-22.13 `, as is currently the latest LTS)
239+ * The appropriate value (` lts-22.30 ` , as is currently the latest LTS)
170240* The GHC version used
171- * A full list of all packages available in this snapshot
241+ * A full list of all packages versions available in this snapshot
172242* The ability to perform a Hoogle search on the packages in this snapshot
173243* A [ list of all modules] ( https://www.stackage.org/lts/docs ) in a snapshot,
174244 which can be useful when trying to determine which package to add to your
@@ -182,7 +252,7 @@ about them on the
182252If you're not sure which to use, start with LTS Haskell (which Stack will lean
183253towards by default as well).
184254
185- # # Snapshots and changing your compiler version
255+ ## Available snapshots
186256
187257Let's explore package sets a bit further. Instead of ` lts-22.13 ` , let's change
188258our ` stack.yaml ` file to use the
@@ -217,22 +287,6 @@ on the command line and not in your `stack.yaml` file is that using them:
2172872 . Produces unreliable results (since a build run today may proceed differently
218288 tomorrow because of changes outside of your control)
219289
220- ### Changing GHC versions
221-
222- Finally, let's try using an older LTS snapshot. We'll use the newest 21.x
223- snapshot with the command:
224-
225- ~~~ text
226- stack --snapshot lts-21 build
227- # build output ...
228- ~~~
229-
230- This succeeds, automatically installing the necessary GHC along the way. So, we
231- see that different LTS versions use different GHC versions and Stack can handle
232- that.
233-
234- ### Other snapshot values
235-
236290We've mentioned ` nightly-YYYY-MM-DD ` and ` lts-X.Y ` values for the snapshot.
237291There are actually other options available, and the list will grow over time.
238292At the time of writing:
@@ -243,6 +297,22 @@ At the time of writing:
243297The most up-to-date information can always be found in the
244298[ stack.yaml documentation] ( ../configure/yaml/project.md#snapshot ) .
245299
300+ ## Snapshots and GHC versions
301+
302+ As mentioned, a snapshot specifies a version of GHC as well as a set of package
303+ versions.
304+
305+ Let's try using an older LTS snapshot. We'll use the newest 21.x snapshot with
306+ the command:
307+
308+ ~~~ text
309+ stack --snapshot lts-21 build
310+ ~~~
311+
312+ This succeeds, automatically installing the necessary GHC along the way. So, we
313+ see that different LTS versions use different GHC versions and Stack can handle
314+ that.
315+
246316## Cleaning your project
247317
248318You can clean up build artifacts for your project using the ` stack clean ` and
0 commit comments