about summary refs log tree commit diff
path: root/third_party/bazel/rules_haskell/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/bazel/rules_haskell/README.md')
-rw-r--r--third_party/bazel/rules_haskell/README.md344
1 files changed, 344 insertions, 0 deletions
diff --git a/third_party/bazel/rules_haskell/README.md b/third_party/bazel/rules_haskell/README.md
new file mode 100644
index 0000000000..5357946424
--- /dev/null
+++ b/third_party/bazel/rules_haskell/README.md
@@ -0,0 +1,344 @@
+<p align="left"><img src="logo/horizontal.png" alt="rules_haskell" height="100px"></p>
+
+# Haskell rules for [Bazel][bazel]
+
+[![CircleCI](https://circleci.com/gh/tweag/rules_haskell.svg?style=svg)](https://circleci.com/gh/tweag/rules_haskell)
+[![Build Status](https://dev.azure.com/tweag/rules_haskell/_apis/build/status/tweag.rules_haskell?branchName=master)](https://dev.azure.com/tweag/rules_haskell/_build/latest?definitionId=1?branchName=master)
+
+Bazel automates building and testing software. It scales to very large
+multi-language projects. This project extends Bazel with build rules
+for Haskell. Get started building your own project using these rules
+wih the [setup script below](#setup).
+
+[bazel]: https://bazel.build/
+[bazel-getting-started]: https://docs.bazel.build/versions/master/getting-started.html
+[bazel-cli]: https://docs.bazel.build/versions/master/command-line-reference.html
+[external-repositories]: https://docs.bazel.build/versions/master/external.html
+[nix]: https://nixos.org/nix
+
+## Rule summary
+
+The full reference documentation for rules is at https://haskell.build.
+
+## Setup
+
+You'll need [Bazel >= 0.24][bazel-getting-started] installed.
+
+### The easy way
+
+In a fresh directory, run:
+
+```console
+$ curl https://haskell.build/start | sh
+```
+
+This will generate initial `WORKSPACE` and `BUILD` files for you. See the
+[examples](./tests) and the [API reference](#Rules) below to adapt these for
+you project. Then,
+
+```console
+$ bazel build //...    # Build all targets
+$ bazel test //...     # Run all tests
+```
+
+You can learn more about Bazel's command line
+syntax [here][bazel-cli]. Common [commands][bazel-cli-commands] are
+`build`, `test`, `run` and `coverage`.
+
+### Nixpkgs
+
+This rule set supports [Nixpkgs][nixpkgs]. If you are on NixOS, or if
+you are using Nixpkgs on your project, consider passing the following
+argument on the command-line to select a Nixpkgs-based toolchain for
+the build:
+
+```
+$ bazel build --host_platform=@io_tweag_rules_haskell//haskell/platforms:linux_x86_64_nixpkgs //...
+```
+
+See [below](#saving-common-command-line-flags-to-a-file) to
+permanently set that flag.
+
+[bazel-cli-commands]: https://docs.bazel.build/versions/master/command-line-reference.html#commands
+[nixpkgs]: https://nixos.org/nixpkgs/
+
+### Doing it manually
+
+Add the following to your `WORKSPACE` file, and select a `$VERSION`
+(or even an arbitrary commit hash) accordingly.
+
+```bzl
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+
+http_archive(
+  name = "io_tweag_rules_haskell",
+  strip_prefix = "rules_haskell-$VERSION",
+  urls = ["https://github.com/tweag/rules_haskell/archive/v$VERSION.tar.gz"],
+)
+
+load(
+    "@io_tweag_rules_haskell//haskell:haskell.bzl",
+	"haskell_repositories",
+	"haskell_register_toolchains",
+)
+
+haskell_repositories()
+
+haskell_register_toolchains()
+```
+
+You will then need to write one `BUILD` file for each "package" you
+want to define. See below for examples.
+
+## Tutorial and Examples
+
+We provide a [tutorial for writing your first rules][tutorial].
+The corresponding source code is in [./tutorial](./tutorial).
+
+A collection of example rules is in [./examples](./examples).
+
+[tutorial]: https://rules-haskell.readthedocs.io/en/latest/
+
+## Rules
+
+See https://api.haskell.build for the reference documentation on provided
+rules. Using [./serve-docs.sh](./serve-docs.sh), you can also view
+this documentation locally.
+
+## Language interop
+
+We may be supporting interop with other languages in one way or
+another. Please see languages listed below about how.
+
+### C/C++
+
+C/C++ libraries can be specified as dependencies. Exporting Haskell libraries
+as C/C++ dependencies currently requires the `cc_haskell_import` rule. This is
+a temporary workaround to Bazel limitations.
+
+### Java
+
+You can supply `java_*` rule targets in `deps` of
+[haskell_binary](#haskell_binary) and
+[haskell_library](#haskell_library). This will make jars produced by
+those dependencies available during Haskell source compilation phase
+(i.e. not during linking &c. but it's subject to change) and set the
+CLASSPATH for that phase as well.
+
+## Troubleshooting
+
+### No such file or directory
+
+If you see error messages complaining about missing `as` (`ld` or indeed
+some other executable):
+
+```
+cc: error trying to exec 'as': execvp: No such file or directory
+`cc' failed in phase `Assembler'. (Exit code: 1)
+```
+
+It means that your `gcc` cannot find `as` by itself. This happens only on
+certain operating systems which have `gcc` compiled without `--with-as` and
+`--with-ld` flags. We need to make `as` visible manually in that case:
+
+```bzl
+# Create a symlink to system executable 'as'
+genrule(
+    name = "toolchain_as",
+    outs = ["as"],
+    cmd = "ln -s /usr/bin/as $@",
+)
+
+# Make it visible to rules_haskell rules:
+haskell_toolchain(
+    name = "ghc",
+    tools = ["@ghc//:bin"],
+    version = "8.4.1",
+    extra_binaries = [":toolchain_as"], # <----
+)
+```
+
+### `__STDC_VERSION__` does not advertise C99 or later
+
+If you see an error message like this:
+
+```
+/root/.cache/bazel/_bazel_root/b8b1b1d6144a88c698a010767d2217af/external/ghc/lib/ghc-8.4.1/include/Stg.h:29:3: error:
+     error: #error __STDC_VERSION__ does not advertise C99 or later
+     # error __STDC_VERSION__ does not advertise C99 or later
+       ^
+   |
+29 | # error __STDC_VERSION__ does not advertise C99 or later
+   |   ^
+```
+
+It means that your `gcc` selects incorrect flavor of C by default. We need
+C99 or later, as the error message says, so try this:
+
+```bzl
+haskell_toolchain(
+    name = "ghc",
+    tools = ["@ghc//:bin"],
+    version = "8.4.1",
+    compiler_flags = ["-optc-std=c99"], # <----
+)
+```
+
+### `bazel` fails because some executable cannot be found
+
+Make sure you run your build in a pure nix shell
+(`nix-shell --pure shell.nix`). If it still doesn’t build,
+it is likely a bug.
+
+### A Haskell dependency fails with strange error messages
+
+If you get cabal error messages the likes of:
+
+```
+CallStack (from HasCallStack):
+  dieNoWrap, called at libraries/Cabal/Cabal/Distribution/Utils/LogProgress.hs:61:9 in Cabal-2.0.1.0:Distribution.Utils.LogProgress
+Error:
+    The following packages are broken because other packages they depend on are missing. These broken packages must be rebuilt before they can be used.
+installed package lens-labels-0.2.0.1 is broken due to missing package profunctors-5.2.2-HzcVdviprlKb7Ap1woZu4, tagged-0.8.5-HviTdonkllN1ZD6he1Zn8I
+```
+
+you’ve most likely hit GHC’s
+[infamous non-deterministic library ID bug](https://nixos.org/nixpkgs/manual/#how-to-recover-from-ghcs-infamous-non-deterministic-library-id-bug).
+
+### Warning about home modules during non-sandboxed builds
+
+Say you have a folder that mixes source files for two different
+libraries or for a library and an executable. If you build with
+sandboxing turned off, it is possible that GHC will use the source
+files for one library during the build of the other. The danger in
+this situation is that because GHC used inputs that Bazel didn't know
+about, incremental rebuilds might not be correct. This is why you get
+a warning of the following form if this happens:
+
+```
+<no location info>: warning: [-Wmissing-home-modules]
+    Modules are not listed in command line but needed for compilation: Foo
+```
+
+Turning sandboxing on (this is Bazel's default on Linux and macOS)
+protects against this problem. If sandboxing is not an option, simply
+put the source files for each target in a separate directory (you can
+still use a single `BUILD` file to define all targets).
+
+## For `rules_haskell` developers
+
+### Saving common command-line flags to a file
+
+If you find yourself constantly passing the same flags on the
+command-line for certain commands (such as `--host_platform` or
+`--compiler`), you can augment the [`.bazelrc`](./.bazelrc) file in
+this repository with a `.bazelrc.local` file. This file is ignored by
+Git.
+
+### Reference a local checkout of `rules_haskell`
+
+When you develop on `rules_haskell`, you usually do it in the context
+of a different project that has `rules_haskell` as a `WORKSPACE`
+dependency, like so:
+
+```
+http_archive(
+    name = "io_tweag_rules_haskell",
+    strip_prefix = "rules_haskell-" + version,
+    sha256 = …,
+    urls = …,
+)
+```
+
+To reference a local checkout instead, use the
+[`--override_repository`][override_repository] command line option:
+   
+```
+bazel build/test/run/sync \
+  --override_repository io_tweag_rules_haskell=/path/to/checkout
+```
+   
+If you don’t want to type that every time, [temporarily add it to
+`.bazelrc`][bazelrc].
+
+[override_repository]: https://docs.bazel.build/versions/master/command-line-reference.html#flag--override_repository
+[local_repository]: https://docs.bazel.build/versions/master/be/workspace.html#local_repository
+[bazelrc]: https://docs.bazel.build/versions/master/best-practices.html#bazelrc
+
+### Test Suite
+
+To run the test suite for these rules, you'll need [Nix][nix]
+installed. First, from the project’s folder start a pure nix shell:
+
+```
+$ nix-shell --pure shell.nix
+```
+
+This will make sure that bazel has the exact same environment
+on every development system (`python`, `ghc`, `go`, …).
+
+To build and run tests locally, execute:
+
+```
+$ bazel test //...
+```
+
+Skylark code in this project is formatted according to the output of
+[buildifier]. You can check that the formatting is correct using:
+
+```
+$ bazel run //:buildifier
+```
+
+If tests fail then run the following to fix the formatting:
+
+```
+$ git rebase --exec "bazel run //:buildifier-fix" <first commit>
+```
+
+where `<first commit>` is the first commit in your pull request.
+This fixes formatting for each of your commits separately, to keep
+the history clean.
+
+[buildifier]: https://github.com/bazelbuild/buildtools/tree/master/buildifier
+
+### <a name="nixpkgs-pin" />How to update the nixpkgs pin
+
+You have to find a new git commit where all our `shell.nix`
+dependencies are available from the official NixOS Hydra binary cache.
+
+At least for `x86-linux` this is guaranteed for the `unstable`
+channels. You can find the `nixpkgs` git commit of current `unstable`
+here:
+
+https://nixos.org/channels/nixos-unstable/git-revision
+
+That might be too old for your use-case (because all tests have to
+pass for that channel to be updated), so as a fallback there is:
+
+https://nixos.org/channels/nixos-unstable-small/git-revision
+
+You copy that hash to `url` in
+[`./nixpkgs/default.nix`](./nixpkgs/default.nix). Don’t forget to
+change the `sha256` or it will use the old version. Please update the
+date comment to the date of the `nixpkgs` commit you are pinning to.
+
+### CircleCI
+
+Pull Requests are checked by CircleCI.
+
+If a check fails and you cannot reproduce it locally (e.g. it failed on Darwin
+and you only run Linux), you can [ssh into CircleCI to aid debugging][ci-ssh].
+
+[ci-ssh]: https://circleci.com/docs/2.0/ssh-access-jobs/
+
+#### “unable to start any build”
+
+```
+error: unable to start any build; either increase '--max-jobs' or enable remote builds
+```
+
+We set `--builders ""` and `--max-jobs 0` on CI to be sure all
+dependencies are coming from binary caches. You might need to add an
+exception (TODO: where to add exception) or [switch to a different
+nixpkgs pin](#nixpkgs-pin).