Cabal packages
Bazel

Cabal packages


haskell_cabal_binary

haskell_cabal_binary(name, cabalopts, compiler_flags, deps, exe_name, flags, setup_deps, srcs,
                     tools, verbose)

Use Cabal to build a binary.

Examples

haskell_cabal_binary(
    name = "happy",
    srcs = glob(["**"]),
)

This rule assumes that the .cabal file defines a single executable with the same name as the package.

This rule does not use cabal-install. It calls the package’s Setup.hs script directly if one exists, or the default one if not. All sources files that would have been part of a Cabal sdist need to be listed in srcs (crucially, including the .cabal file).

Attributes

name Name; required

A unique name for this target.

cabalopts List of strings; optional; default is []

Additional flags to pass to Setup.hs configure. Subject to make variable expansion.

Use --ghc-option=OPT to configure additional compiler flags. Use --haddock-option=--optghc=OPT if these flags are required for haddock generation as well.

compiler_flags List of strings; optional; default is []

DEPRECATED. Use cabalopts with --ghc-option instead.

Flags to pass to Haskell compiler, in addition to those defined the cabal file. Subject to Make variable substitution.

deps List of labels; optional; default is []

Package build dependencies. Note, setup dependencies need to be declared separately using setup_deps.

exe_name String; optional; default is ""

Cabal executable component name. Defaults to the value of the name attribute.

flags List of strings; optional; default is []

List of Cabal flags, will be passed to Setup.hs configure --flags=....

setup_deps List of labels; optional; default is []

Dependencies for custom setup Setup.hs.

srcs List of labels; optional; default is []

All files required to build the package, including the Cabal file.

tools List of labels; optional; default is []

Tool dependencies. They are built using the host configuration, since the tools are executed as part of the build.

verbose Boolean; optional; default is True

Whether to show the output of the build


haskell_cabal_library

haskell_cabal_library(name, cabalopts, compiler_flags, deps, flags, haddock, package_name,
                      setup_deps, srcs, sublibrary_name, tools, unique_name, verbose, version)

Use Cabal to build a library.

Examples

haskell_cabal_library(
    name = "lib-0.1.0.0",
    srcs = ["lib.cabal", "Lib.hs", "Setup.hs"],
)

haskell_toolchain_library(name = "base")

haskell_binary(
    name = "bin",
    deps = [":base", ":lib-0.1.0.0"],
    srcs = ["Main.hs"],
)

This rule does not use cabal-install. It calls the package’s Setup.hs script directly if one exists, or the default one if not. All sources files that would have been part of a Cabal sdist need to be listed in srcs (crucially, including the .cabal file). A haskell_cabal_library can be substituted for any haskell_library. The two are interchangeable in most contexts. However, using a plain haskell_library sometimes leads to better build times, and does not require drafting a .cabal file.

Attributes

name Name; required

A unique name for this target.

cabalopts List of strings; optional; default is []

Additional flags to pass to Setup.hs configure. Subject to make variable expansion.

Use --ghc-option=OPT to configure additional compiler flags. Use --haddock-option=--optghc=OPT if these flags are required for haddock generation as well.

compiler_flags List of strings; optional; default is []

DEPRECATED. Use cabalopts with --ghc-option instead.

Flags to pass to Haskell compiler, in addition to those defined the cabal file. Subject to Make variable substitution.

deps List of labels; optional; default is []

Package build dependencies. Note, setup dependencies need to be declared separately using setup_deps.

flags List of strings; optional; default is []

List of Cabal flags, will be passed to Setup.hs configure --flags=....

haddock Boolean; optional; default is True

Whether to generate haddock documentation.

package_name String; optional; default is ""

Cabal package name. Defaults to name attribute.

setup_deps List of labels; optional; default is []

Dependencies for custom setup Setup.hs.

srcs List of labels; optional; default is []

All files required to build the package, including the Cabal file.

sublibrary_name String; optional; default is ""

sublibrary of the Cabal package to build

tools List of labels; optional; default is []

Tool dependencies. They are built using the host configuration, since the tools are executed as part of the build.

unique_name Boolean; optional; default is False

Whether the library name is known to be unique within the workspace. This is used by stack_snapshot where library names are known to be unique within the snapshot. If true, then the dynamic library symlink underneath _solib_<cpu> will be shortened to avoid exceeding the MACH-O header size limit on MacOS.

verbose Boolean; optional; default is True

Whether to show the output of the build

version String; required

Version of the Cabal package.


stack_snapshot

stack_snapshot(name, stack, extra_deps, vendored_packages, snapshot, local_snapshot,
               stack_snapshot_json, packages, flags, haddock, setup_deps, tools, components,
               stack_update, verbose, netrc, kwargs)

Use Stack to download and extract Cabal source distributions.

This rule will use Stack to compute the transitive closure of the subset of the given snapshot listed in the packages attribute, and generate a dependency graph. If a package in the closure depends on system libraries or other external libraries, use the extra_deps attribute to list them. This attribute works like the --extra-{include,lib}-dirs flags for Stack and cabal-install do. If a package has a custom setup with setup dependencies, use the setup_deps attribute to list them.

Packages that are in the snapshot need not have their versions specified. But any additional packages or version overrides will have to be specified with a package identifier of the form <package>-<version> in the packages attribute. Note that you cannot override the version of any packages built into GHC.

This rule invokes the stack tool for version and dependency resolution based on the specified snapshot. You can generate a stack_snapshot.json file to avoid invoking stack on every fetch and instead pin the outcome in a file that can be checked into revision control. Execute the following command:

bazel run @stackage-unpinned//:pin

Then specify the stack_snapshot_json attribute to point to the generated file:

stack_snapshot(
    ...
    stack_snapshot_json = "//:stackage_snapshot.json",
)

By default stack_snapshot defines a library target for each package. If a package does not contain a library component or contains executable components, then you need to declare so yourself using the components attribute. Library targets are exposed as @stackage//:<package-name> and executables are exposed as @stackage-exe//<package-name>:<executable-name>, assuming that you invoked stack_snapshot with name = "stackage".

In the external repository defined by the rule, all given packages are available as top-level targets named after each package. Additionally, the dependency graph is made available within packages.bzl as the dict packages mapping unversioned package names to structs holding the fields

  • name: The unversioned package name.
  • version: The package version.
  • library: Whether the package has a declared library component.
  • executables: List of declared executable components.
  • deps: The list of library dependencies according to stack.
  • tools: The list of tool dependencies according to stack.
  • flags: The list of Cabal flags.

NOTE: Make sure your GHC version matches the version expected by the snapshot. E.g. if you pass snapshot = "lts-13.15", make sure you use GHC 8.6.4 (e.g. by invoking rules_haskell_toolchains(version="8.6.4")). Sadly, rules_haskell cannot maintain this correspondence for you. You will need to manage it yourself. If you have a version mismatch, you will end up with versions of core GHC packages which do not match the versions listed in the snapshot, and potentially other problems.

Examples

stack_snapshot(
    name = "stackage",
    packages = ["conduit", "doctest", "lens", "zlib-0.6.2"],
    vendored_packages = {"split": "//split:split"},
    tools = ["@happy//:happy"],  # Use externally provided `happy`
    components = {
        "doctest": ["lib", "exe"],  # Optional since doctest is known to have an exe component.
        "happy": [],  # Override happy's default exe component.
    },
    snapshot = "lts-13.15",
    extra_deps = {"zlib": ["@zlib.dev//:zlib"]},
)

defines @stackage//:conduit, @stackage//:doctest, @stackage//:lens, @stackage//:zlib library targets and a @stackage-exe//doctest executable target. It also uses an externally provided happy rather than the one provided by the snapshot.

Alternatively

stack_snapshot(
    name = "stackage",
    packages = ["conduit", "doctest", "lens", "zlib"],
    flags = {"zlib": ["-non-blocking-ffi"]},
    tools = ["@happy//:happy"],  # Use externally provided `happy`
    components = {
        "doctest": ["lib", "exe"],  # Optional since doctest is known to have an exe component.
        "happy": [],  # Override happy's default exe component.
    },
    local_snapshot = "//:snapshot.yaml",
    extra_deps = {"zlib": ["@zlib.dev//:zlib"]},

Does the same as the previous example, provided there is a snapshot.yaml, at the root of the repository with content

resolver: lts-13.15

packages:
  - zlib-0.6.2

Attributes

name required

The name of the Bazel workspace.

stack optional; default is None

The stack binary to use to enumerate package dependencies.

extra_deps optional; default is {}

Extra dependencies of packages, e.g. system libraries or C/C++ libraries. Dict of stackage package names to a list of targets. The list of targets is given as input to the named stackage package. { "postgresql-libpq": ["@postgresql//:include"], "zlib": ["@zlib.dev//:zlib"] } means @postgresql//:include is passed to the stackage package postgresql-libpq while @zlib.dev//:zlib is passed to the stackage package zlib.

vendored_packages optional; default is {}

Add or override a package to the snapshot with a custom unpacked source distribution. Each package must contain a Cabal file named <package-name>.cabal in the package root.

snapshot optional; default is ""

The name of a Stackage snapshot. Incompatible with local_snapshot.

local_snapshot optional; default is None

A custom Stack snapshot file, as per the Stack documentation. Incompatible with snapshot.

stack_snapshot_json optional; default is None

A label to a stack_snapshot.json file, e.g. //:stack_snapshot.json. Specify this to use pinned artifacts for generating build targets.

packages optional; default is []

A set of package identifiers. For packages in the snapshot, version numbers can be omitted.

flags optional; default is {}

A dict from package name to list of flags.

haddock optional; default is True

Whether to generate haddock documentation.

setup_deps optional; default is {}

Setup dependencies of packages, e.g. cabal-doctest. Dict of stackage package names to a list of targets in the same format as for extra_deps.

tools optional; default is []

Tool dependencies. They are built using the host configuration, since the tools are executed as part of the build.

components optional; default is {}

Defines which Cabal components to build for each package. A dict from package name to list of components. Use lib for the library component and exe:<exe-name> for an executable component, exe is a short-cut for exe:<package-name>. The library component will have the label @<workspace>//:<package> and an executable component will have the label @<workspace>-exe//<package>:<exe-name>, where <workspace> is the name given to the stack_snapshot invocation.

stack_update optional; default is None

A meta repository that is used to avoid multiple concurrent invocations of stack update which could fail due to a race on the hackage security lock.

verbose optional; default is False

Whether to show the output of the build.

netrc optional; default is ""

Location of the .netrc file to use for authentication. Defaults to ~/.netrc if present.

kwargs optional