Skip to content

Commit

Permalink
Merge branch 'stable'
Browse files Browse the repository at this point in the history
  • Loading branch information
mpilgrem committed Sep 16, 2022
2 parents 3b73b7a + 720bf7a commit 3b142eb
Showing 1 changed file with 106 additions and 83 deletions.
189 changes: 106 additions & 83 deletions doc/build_command.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,117 +4,118 @@

## Overview

The primary command you use in Stack is `build`. This page describes the `build`
command's interface. The goal of the interface is to do the right thing for
simple input, and allow a lot of flexibility for more complicated goals.
Stack's primary command is `build`. This page describes its interface. The goal
of the interface is to do the right thing for simple input, and allow
flexibility for more complicated goals.

See the introductory part of Stack's
[user's guide](GUIDE.md#the-stack-build-command) for an introduction to the
command.

## Synonyms

One potential point of confusion is the synonym commands for `build`. These are
provided to match commonly expected command line interfaces, and to make common
workflows shorter. The important thing to note is that all of these are just
the `build` command in disguise. Each of these commands are called out as
synonyms in the `--help` output. These commands are:
The synonym commands for `build` are:

* `stack test` is the same as `stack build --test`
* `stack bench` is the same as `stack build --bench`
* `stack haddock` is the same as `stack build --haddock`
* `stack install` is the same as `stack build --copy-bins`
|Synonym command|Equivalent `build` command flag|
|---------------|-------------------------------|
|`stack test` |`stack build --test` |
|`stack bench` |`stack build --bench` |
|`stack haddock`|`stack build --haddock` |
|`stack install`|`stack build --copy-bins` |

The advantage of the synonym commands is that they're convenient and short. The
advantage of the options is that they compose. For example,
The advantage of the synonym commands is that they are convenient and short. The
advantage of the flags is that they compose. For example,
`stack build --test --copy-bins` will build libraries, executables, and test
suites, run the test suites, and then copy the executables to your local bin
path (more on this below).

## Components

Components are a subtle yet important point to how build operates under the
surface. Every cabal package is made up of one or more components. It can have
0 or 1 libraries, and then 0 or more of executable, test, and benchmark
components. Stack allows you to call out a specific component to be built, e.g.
`stack build mypackage:test:mytests` will build the `mytests` component of the
`mypackage` package. `mytests` must be a test suite component.

We'll get into the details of the target syntax for how to select components in
the next section. In this section, the important point is: whenever you target
a test suite or a benchmark, it's built __and also run__, unless you explicitly
disable running via `--no-run-tests` or `--no-run-benchmarks`. Case in point:
the previous command will in fact build the `mytests` test suite *and* run it,
even though you haven't used the `stack test` command or the `--test` option.
(We'll get to what exactly `--test` does below.)

This gives you a lot of flexibility in choosing what you want Stack to do. You
can run a single test component from a package, run a test component from one
package and a benchmark from another package, etc.

One final note on components: you can only control components for local
packages, not dependencies. With dependencies, Stack will *always* build the
library (if present) and all executables, and ignore test suites and
benchmarks. If you want more control over a package, you must add it to your
`packages` setting in your project-level configuration file (`stack.yaml`).
Every Cabal package is made up of one or more components. It can have an
optional library component, one or more optional executable components, one or
more optional test suite components, and one or more optional benchmark
components.

Stack allows you to identify a specific component to be built. For example,
`stack build mypackage:test:mytests` will build (and run - see further below)
the `mytests` component of the `mypackage` package. `mytests` must be a test
suite component.

By default, if a test suite component is targeted, the component is built and
run. The running behaviour can be disabled with the `--no-run-tests` flag.
Similarly, if a benchmark component is targeted, it is built and run unless the
running behaviour is disabled with the `--no-run-benchmarks` flag.

This ability to specify a component applies only to a local package. With
dependencies, Stack will *always* build the library (if present) and all
executables (if any), and ignore test suites and benchmarks. If you want more
control over a package, you must add it to your `packages` setting in your
project-level configuration file (`stack.yaml`).

## Target syntax

In addition to a number of options (like the aforementioned `--test`),
`stack build` takes a list of zero or more *targets* to be built. There are a
number of different syntaxes supported for this list:
`stack build` takes a list of one or more optional *targets* to be built. The
supported syntaxes for targets are:

* *package*, e.g. `stack build foobar`, is the most commonly used target. It
will try to find the package in the following locations: local packages,
extra dependencies, snapshots, and package index (e.g. Hackage). If it's
found in the package index, then the latest version of that package from
the index is implicitly added to your extra dependencies.
extra deps, snapshots, and package index (e.g. Hackage). If it's found in
the package index, then the latest version of that package from the index is
implicitly added to your extra dependencies.

This is where the `--test` and `--bench` flags come into play. If the
package is a local package, then all of the test suite and benchmark
components are selected to be built, respectively. In any event, the
library and executable components are also selected to be built.
If the package is a local package, the library and executable components are
selected to be built. If the `--test` and `--bench` flags are set, then all
of the test suite and benchmark components, respectively, are selected to be
built.

* *package identifier*, e.g. `stack build foobar-1.2.3`, is usually used to
include specific package versions from the index. If the version selected
conflicts with an existing local package or extra dep, then stack fails
with an error. Otherwise, this is the same as calling `stack build foobar`,
except instead of using the latest version from the index, the version
specified is used.
include specific package versions from the package index. If the version
selected conflicts with an existing local package or extra dep, then Stack
fails with an error. Otherwise, this is the same as using
`stack build foobar`, except instead of using the latest version from the
package index, the version specified is used.

* *component*. Instead of referring to an entire package and letting Stack
decide which components to build, you select individual components from
inside a package. This can be done for more fine-grained control over which
test suites to run, or to have a faster compilation cycle. There are
multiple ways to refer to a specific component (provided for convenience):

* `packagename:comptype:compname` is the most explicit. The available
comptypes are `exe`, `test`, and `bench`.
* Side note: When any `exe` component is specified, all of the package's
executable components will be built. This is due to limitations in all
currently released versions of Cabal. See
[issue#1046](https://github.com/commercialhaskell/stack/issues/1406)
* `packagename:compname` allows you to leave off the component type, as
that will (almost?) always be redundant with the component name. For
example, `stack build mypackage:mytestsuite`.
* `:compname` is a useful shortcut, saying "find the component in all of
the local packages." This will result in an error if multiple packages
have a component with the same name. To continue the above example,
`stack build :mytestsuite`.

* *directory*, e.g. `stack build foo/bar`, will find all local packages that
exist in the given directory hierarchy and then follow the same procedure as
passing in package names as mentioned above. There's an important caveat
here: if your directory name is parsed as one of the above target types, it
will be treated as that. Explicitly starting your target with `./` can be a
good way to avoid that, e.g. `stack build ./foo`

Finally: if you provide no targets (e.g., running `stack build`), Stack will
implicitly pass in all of your local packages. If you only want to target
packages in the current directory or deeper, you can pass in `.`, e.g.
`stack build .`.

To get a list of the available targets in your project, use `stack ide targets`.
* `packagename:comptype:compname` is the most explicit. The available
comptypes are `exe`, `test`, and `bench`.

!!! note

When any `exe` component is specified, all of the package's
executable components will be built. This is due to limitations in
all currently released versions of Cabal. See
[issue#1046](https://github.com/commercialhaskell/stack/issues/1406)

* `packagename:compname` allows you to leave out the component type, as
that will (almost?) always be redundant with the component name. For
example, `stack build mypackage:mytestsuite`.

* `:compname` is a useful shortcut, saying "find the component in all of
the local packages." This will result in an error if multiple packages
have a component with the same name. To continue the above example,
`stack build :mytestsuite`.

* *directory*, e.g. `stack build foo/bar`, will find all local packages that
exist in the given directory hierarchy and then follow the same procedure as
passing in package names as mentioned above. There's an important caveat
here: if your directory name is parsed as one of the above target types, it
will be treated as that. Explicitly starting your target with `./` can be a
good way to avoid that, e.g. `stack build ./foo`.

!!! note

`stack build .` will target local packages in the current working
directory or its subdirectories.

`stack build` with no targets specified will build all local packages.

Command `stack ide targets` to get a list of the available targets in your
project.

## Controlling what gets built

Expand All @@ -125,6 +126,11 @@ about how these dependencies get specified.
In addition to specifying targets, you can also control what gets built, or
retained, with the following flags:

### The `stack build --bench` flag

Pass the flag to add benchmark components to the targets, if specific components
are not identified.

### The `stack build --dependencies-only` flag

Pass the flag to skip building the targets. The flag `--only-dependencies` has
Expand Down Expand Up @@ -189,11 +195,28 @@ Set the flag to keep intermediate files and build directories that would
otherwise be considered temporary and deleted. It may be useful to inspect
these, if a build fails. By default, they are not kept.

### The `stack build --only-configure` flag

[:octicons-tag-24: 0.1.4.0](https://github.com/commercialhaskell/stack/releases/tag/v0.1.4.0)

Pass the flag to perform only the configure step, not any builds. This is
intended for tool usage. It may break when used on multiple packages at once.

!!! note

If there are downstream actions that require a package to be built then a
full build will occur, even if the flag is passed.

### The `stack build --only-dependencies` flag

Pass the flag to skip building the targets. The flag `--dependencies-only` has
the same effect.

### The `stack build --only-snapshot` flag

Pass the flag to build only snapshot dependencies, which are cached and shared
with other projects.

### The `stack build --[no-]reconfigure` flag

Default: Disabled
Expand All @@ -213,10 +236,10 @@ executables won't work the first time the package is built due to an issue in

This option can be specified multiple times to skip multiple components.

### The `stack build --only-snapshot` flag
### The `stack build --test` flag

Pass the flag to build only snapshot dependencies, which are cached and shared
with other projects.
Pass the flag to add test suite components to the targets, if specific
components are not identified.

## Other flags and options

Expand Down

0 comments on commit 3b142eb

Please sign in to comment.