Cabal Haskell build tool

Version 3.13 · source

Start here

cabal init --interactive
New package
cabal build
Compile everything
cabal run <exe> -- <args>
Run an executable
cabal test
Run test suites
cabal repl
GHCi with the project
cabal update
Refresh package index
cabal install <exe>
Install a program
cabal freeze
Pin solved versions

Concepts

Project cabal.project
Package <name>.cabal
Component library, exe, test, bench
Module *.hs

Projects

cabal init --interactive
Create a package with prompts
cabal init --non-interactive
Create a package with defaults
cabal init --minimal
Create a bare .cabal file
cabal check
Lint the .cabal file for Hackage
cabal user-config init
Write the default user config
cabal path
Show where cabal keeps files

Build

cabal build
Build all default targets
cabal build <target>
Build one package or component
cabal build all
Build every package in the project
cabal build --enable-tests --enable-benchmarks
Include tests and benchmarks
cabal build -O2
Optimise (default is -O1)
cabal build --ghc-options=-Wall
Pass flags to GHC
cabal build -w ghc-<version>
Use a specific compiler
cabal build --only-dependencies
Build just the dependencies
cabal build --enable-profiling
Build with profiling
cabal target <pattern>
Show fully qualified target names
cabal clean
Delete dist-newstyle

Run & REPL

cabal run
Run the only executable
cabal run <exe> -- <args>
Run an executable with arguments
Everything after -- goes to your program, not to cabal.
cabal run <script>.hs
Run a standalone script
cabal repl
Open GHCi on the default target
cabal repl <target>
Open GHCi on one component
cabal repl --enable-tests
Load test modules too
cabal repl -b <pkg>
Start a REPL with an extra package
cabal exec -- <cmd>
Run a command in the project environment
cabal list-bin <exe>
Print the path of a built binary

Test & docs

cabal test
Build and run all test suites
cabal test <suite>
Run one test suite
cabal test --test-show-details=direct
Stream test output live
cabal test --test-options="<args>"
Pass arguments to the test program
cabal bench
Run benchmarks
cabal haddock
Build API documentation
cabal haddock-project
Build combined docs for local packages

Dependencies

cabal update
Download the latest package index
cabal list <text>
Search package names
cabal info <pkg>
Show details of a package
cabal outdated
List dependencies with newer versions
cabal freeze
Write cabal.project.freeze
cabal get <pkg>
Unpack a package's source
cabal build --allow-newer
Ignore upper version bounds
Handy to test a bump, but fix the bounds in the .cabal file afterwards.
cabal gen-bounds
Suggest version bounds
cabal build --constraint="<pkg> ==<ver>"
Force a version for one build

Install

cabal install <exe>
Install an executable from Hackage
cabal install --installdir=<dir>
Choose where binaries go
cabal install --overwrite-policy=always
Replace an installed binary
cabal install --install-method=copy
Copy instead of symlink
cabal install --lib <pkg>
Add a library to the global environment
cabal install exe:<name>
Install the executable of this project

Publish

cabal sdist
Make a source tarball
cabal sdist --list-only
List files that would be packed
cabal upload <tarball>
Upload a candidate to Hackage
cabal upload --publish <tarball>
Publish for real
cabal upload --documentation <docs>
Upload haddock docs

Package file

.cabal stanzas
Stanza Use
library Reusable code; list exposed-modules
executable <name> Program; needs main-is
test-suite <name> Tests; type: exitcode-stdio-1.0
benchmark <name> Benchmarks; same form as tests
common <name> Shared fields, pulled in with import:
Common fields
Field Meaning
cabal-version Spec version, e.g. 3.0
build-depends Packages with version bounds
hs-source-dirs Where the .hs files live
default-language GHC2021 or Haskell2010
ghc-options Flags such as -Wall
other-modules Internal, not exported modules
.cabal skeleton
cabal-version: 3.0name:          demoversion:       0.1.0.0build-type:    Simplecommon shared    default-language: GHC2021    ghc-options:      -Wall    build-depends:    base <5library    import:           shared    hs-source-dirs:   src    exposed-modules:  Demoexecutable demo    import:           shared    hs-source-dirs:   app    main-is:          Main.hs    build-depends:    demo

cabal.project

packages: .
List the packages in the project
packages: ./*/*.cabal
Glob over several packages
tests: True
Always enable test suites
constraints: <pkg> ==<ver>
Pin a version for the project
package *
Open a block of options for all packages
with-compiler: ghc-<version>
Fix the compiler
source-repository-package
Depend on a git checkout
cabal configure --enable-tests
Write cabal.project.local
--project-file=<file>
Use another project file

Recipes

New library and executable
cabal init --interactivecabal buildcabal run demo -- --helpcabal repl
Multi-package project
# cabal.projectpackages:  core/  cli/tests: True# thencabal build allcabal test all
Pin a git dependency
# cabal.projectsource-repository-package  type: git  location: https://github.com/<user>/<repo>  tag: <commit>
Reproducible build
cabal updatecabal freezegit add cabal.project.freezecabal build --enable-tests && cabal test