about summary refs log tree commit diff
path: root/third_party/bazel/rules_haskell/haskell/ghc_bindist.bzl
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/bazel/rules_haskell/haskell/ghc_bindist.bzl')
-rw-r--r--third_party/bazel/rules_haskell/haskell/ghc_bindist.bzl408
1 files changed, 408 insertions, 0 deletions
diff --git a/third_party/bazel/rules_haskell/haskell/ghc_bindist.bzl b/third_party/bazel/rules_haskell/haskell/ghc_bindist.bzl
new file mode 100644
index 0000000000..3a448675e9
--- /dev/null
+++ b/third_party/bazel/rules_haskell/haskell/ghc_bindist.bzl
@@ -0,0 +1,408 @@
+"""Workspace rules (GHC binary distributions)"""
+
+_GHC_DEFAULT_VERSION = "8.4.4"
+
+# Generated with `bazel run @io_tweag_rules_haskell//haskell:gen-ghc-bindist`
+# To add a version or architecture, edit the constants in haskell/gen_ghc_bindist.py,
+# regenerate the dict and copy it here.
+# We’d like to put this dict into its own file,
+# but that triggers a bug in Skydoc unfortunately.
+GHC_BINDIST = \
+    {
+        "7.10.3": {
+            "darwin_amd64": (
+                "https://downloads.haskell.org/~ghc/7.10.3/ghc-7.10.3-x86_64-apple-darwin.tar.xz",
+                "b7cad2ea7badb7006621105fbf24b4bd364d2e51c1a75661978d9280d68e83a8",
+            ),
+            "linux_amd64": (
+                "https://downloads.haskell.org/~ghc/7.10.3/ghc-7.10.3-x86_64-deb8-linux.tar.xz",
+                "804c75c4635353bf987c1ca120b8531c7bb4957c5b84d29c7adc4894b6fd579d",
+            ),
+            "windows_amd64": (
+                "https://downloads.haskell.org/~ghc/7.10.3/ghc-7.10.3-x86_64-unknown-mingw32.tar.xz",
+                "cc7987ca7ffcd8fc8b999ed8f7408300cd9fef156032338fd57d63f577532b81",
+            ),
+        },
+        "8.0.2": {
+            "darwin_amd64": (
+                "https://downloads.haskell.org/~ghc/8.0.2/ghc-8.0.2-x86_64-apple-darwin.tar.xz",
+                "ff50a2df9f002f33b9f09717ebf5ec5a47906b9b65cc57b1f9849f8b2e06788d",
+            ),
+            "linux_amd64": (
+                "https://downloads.haskell.org/~ghc/8.0.2/ghc-8.0.2-x86_64-deb8-linux.tar.xz",
+                "5ee68290db00ca0b79d57bc3a5bdce470de9ce9da0b098a7ce6c504605856c8f",
+            ),
+            "windows_amd64": (
+                "https://downloads.haskell.org/~ghc/8.0.2/ghc-8.0.2-x86_64-unknown-mingw32.tar.xz",
+                "8c42c1f4af995205b9816a1e97e2752fe758544c1f5fe77958cdcd319c9c2d53",
+            ),
+        },
+        "8.2.2": {
+            "darwin_amd64": (
+                "https://downloads.haskell.org/~ghc/8.2.2/ghc-8.2.2-x86_64-apple-darwin.tar.xz",
+                "f90fcf62f7e0936a6dfc3601cf663729bfe9bbf85097d2d75f0a16f8c2e95c27",
+            ),
+            "linux_amd64": (
+                "https://downloads.haskell.org/~ghc/8.2.2/ghc-8.2.2-x86_64-deb8-linux.tar.xz",
+                "48e205c62b9dc1ccf6739a4bc15a71e56dde2f891a9d786a1b115f0286111b2a",
+            ),
+            "windows_amd64": (
+                "https://downloads.haskell.org/~ghc/8.2.2/ghc-8.2.2-x86_64-unknown-mingw32.tar.xz",
+                "1e033df2092aa546e763e7be63167720b32df64f76673ea1ce7ae7c9f564b223",
+            ),
+        },
+        "8.4.1": {
+            "darwin_amd64": (
+                "https://downloads.haskell.org/~ghc/8.4.1/ghc-8.4.1-x86_64-apple-darwin.tar.xz",
+                "d774e39f3a0105843efd06709b214ee332c30203e6c5902dd6ed45e36285f9b7",
+            ),
+            "linux_amd64": (
+                "https://downloads.haskell.org/~ghc/8.4.1/ghc-8.4.1-x86_64-deb8-linux.tar.xz",
+                "427c77a934b30c3f1de992c38c072afb4323fe6fb30dbac919ca8cb6ae98fbd9",
+            ),
+            "windows_amd64": (
+                "https://downloads.haskell.org/~ghc/8.4.1/ghc-8.4.1-x86_64-unknown-mingw32.tar.xz",
+                "328b013fc651d34e075019107e58bb6c8a578f0155cf3ad4557e6f2661b03131",
+            ),
+        },
+        "8.4.2": {
+            "darwin_amd64": (
+                "https://downloads.haskell.org/~ghc/8.4.2/ghc-8.4.2-x86_64-apple-darwin.tar.xz",
+                "87469222042b9ac23f9db216a8d4e5107297bdbbb99df71eb4d9e7208455def2",
+            ),
+            "linux_amd64": (
+                "https://downloads.haskell.org/~ghc/8.4.2/ghc-8.4.2-x86_64-deb8-linux.tar.xz",
+                "246f66eb56f4ad0f1c7755502cfc8f9972f2d067dede17e151f6f479c1f76fbd",
+            ),
+            "windows_amd64": (
+                "https://downloads.haskell.org/~ghc/8.4.2/ghc-8.4.2-x86_64-unknown-mingw32.tar.xz",
+                "797634aa9812fc6b2084a24ddb4fde44fa83a2f59daea82e0af81ca3dd323fde",
+            ),
+        },
+        "8.4.3": {
+            "darwin_amd64": (
+                "https://downloads.haskell.org/~ghc/8.4.3/ghc-8.4.3-x86_64-apple-darwin.tar.xz",
+                "af0b455f6c46b9802b4b48dad996619cfa27cc6e2bf2ce5532387b4a8c00aa64",
+            ),
+            "linux_amd64": (
+                "https://downloads.haskell.org/~ghc/8.4.3/ghc-8.4.3-x86_64-deb8-linux.tar.xz",
+                "30a402c6d4754a6c020e0547f19ae3ac42e907e35349aa932d347f73e421a8e2",
+            ),
+            "windows_amd64": (
+                "https://downloads.haskell.org/~ghc/8.4.3/ghc-8.4.3-x86_64-unknown-mingw32.tar.xz",
+                "8a83cfbf9ae84de0443c39c93b931693bdf2a6d4bf163ffb41855f80f4bf883e",
+            ),
+        },
+        "8.4.4": {
+            "darwin_amd64": (
+                "https://downloads.haskell.org/~ghc/8.4.4/ghc-8.4.4-x86_64-apple-darwin.tar.xz",
+                "28dc89ebd231335337c656f4c5ead2ae2a1acc166aafe74a14f084393c5ef03a",
+            ),
+            "linux_amd64": (
+                "https://downloads.haskell.org/~ghc/8.4.4/ghc-8.4.4-x86_64-deb8-linux.tar.xz",
+                "4c2a8857f76b7f3e34ecba0b51015d5cb8b767fe5377a7ec477abde10705ab1a",
+            ),
+            "windows_amd64": (
+                "https://downloads.haskell.org/~ghc/8.4.4/ghc-8.4.4-x86_64-unknown-mingw32.tar.xz",
+                "da29dbb0f1199611c7d5bb7b0dd6a7426ca98f67dfd6da1526b033cd3830dc05",
+            ),
+        },
+        "8.6.2": {
+            "darwin_amd64": (
+                "https://downloads.haskell.org/~ghc/8.6.2/ghc-8.6.2-x86_64-apple-darwin.tar.xz",
+                "8ec46a25872226dd7e5cf7271e3f3450c05f32144b96e6b9cb44cc4079db50dc",
+            ),
+            "linux_amd64": (
+                "https://downloads.haskell.org/~ghc/8.6.2/ghc-8.6.2-x86_64-deb8-linux.tar.xz",
+                "13f96e8b83bb5bb60f955786ff9085744c24927a33be8a17773f84c7c248533a",
+            ),
+            "windows_amd64": (
+                "https://downloads.haskell.org/~ghc/8.6.2/ghc-8.6.2-x86_64-unknown-mingw32.tar.xz",
+                "9a398e133cab09ff2610834337355d4e26c35e0665403fb9ff8db79315f74d3d",
+            ),
+        },
+        "8.6.3": {
+            "darwin_amd64": (
+                "https://downloads.haskell.org/~ghc/8.6.3/ghc-8.6.3-x86_64-apple-darwin.tar.xz",
+                "79d069a1a7d74cfdd7ac2a2711c45d3ddc6265b988a0cefa342714b24f997fc1",
+            ),
+            "linux_amd64": (
+                "https://downloads.haskell.org/~ghc/8.6.3/ghc-8.6.3-x86_64-deb8-linux.tar.xz",
+                "291ca565374f4d51cc311488581f3279d3167a064fabfd4a6722fe2bd4532fd5",
+            ),
+            "windows_amd64": (
+                "https://downloads.haskell.org/~ghc/8.6.3/ghc-8.6.3-x86_64-unknown-mingw32.tar.xz",
+                "2fec383904e5fa79413e9afd328faf9bc700006c8c3d4bcdd8d4f2ccf0f7fa2a",
+            ),
+        },
+        "8.6.4": {
+            "darwin_amd64": (
+                "https://downloads.haskell.org/~ghc/8.6.4/ghc-8.6.4-x86_64-apple-darwin.tar.xz",
+                "cccb58f142fe41b601d73690809f6089f7715b6a50a09aa3d0104176ab4db09e",
+            ),
+            "linux_amd64": (
+                "https://downloads.haskell.org/~ghc/8.6.4/ghc-8.6.4-x86_64-deb8-linux.tar.xz",
+                "34ef5fc8ddf2fc32a027180bea5b1c8a81ea840c87faace2977a572188d4b42d",
+            ),
+            "windows_amd64": (
+                "https://downloads.haskell.org/~ghc/8.6.4/ghc-8.6.4-x86_64-unknown-mingw32.tar.xz",
+                "e8d021b7a90772fc559862079da20538498d991956d7557b468ca19ddda22a08",
+            ),
+        },
+        "8.6.5": {
+            "darwin_amd64": (
+                "https://downloads.haskell.org/~ghc/8.6.5/ghc-8.6.5-x86_64-apple-darwin.tar.xz",
+                "dfc1bdb1d303a87a8552aa17f5b080e61351f2823c2b99071ec23d0837422169",
+            ),
+            "linux_amd64": (
+                "https://downloads.haskell.org/~ghc/8.6.5/ghc-8.6.5-x86_64-deb8-linux.tar.xz",
+                "c419fd0aa9065fe4d2eb9a248e323860c696ddf3859749ca96a84938aee49107",
+            ),
+            "windows_amd64": (
+                "https://downloads.haskell.org/~ghc/8.6.5/ghc-8.6.5-x86_64-unknown-mingw32.tar.xz",
+                "457024c6ea43bdce340af428d86319931f267089398b859b00efdfe2fd4ce93f",
+            ),
+        },
+    }
+
+def _execute_fail_loudly(ctx, args):
+    """Execute a command and fail loudly if it fails.
+
+    Args:
+      ctx: Repository rule context.
+      args: Command and its arguments.
+    """
+    eresult = ctx.execute(args, quiet = False)
+    if eresult.return_code != 0:
+        fail("{0} failed, aborting creation of GHC bindist".format(" ".join(args)))
+
+load("@bazel_tools//tools/build_defs/repo:utils.bzl", "patch")
+
+def _ghc_bindist_impl(ctx):
+    # Avoid rule restart by resolving these labels early. See
+    # https://github.com/bazelbuild/bazel/blob/master/tools/cpp/lib_cc_configure.bzl#L17.
+    ghc_build = ctx.path(Label("//haskell:ghc.BUILD"))
+    crosstool_windows = ctx.path(Label("//haskell:CROSSTOOL.windows"))
+
+    version = ctx.attr.version
+    target = ctx.attr.target
+    os, _, arch = target.partition("_")
+
+    if GHC_BINDIST[version].get(target) == None:
+        fail("Operating system {0} does not have a bindist for GHC version {1}".format(ctx.os.name, ctx.attr.version))
+    else:
+        url, sha256 = GHC_BINDIST[version][target]
+
+    bindist_dir = ctx.path(".")  # repo path
+
+    ctx.download_and_extract(
+        url = url,
+        output = ".",
+        sha256 = sha256,
+        type = "tar.xz",
+        stripPrefix = "ghc-" + version,
+    )
+
+    # We apply some patches, if needed.
+    patch(ctx)
+
+    # As the patches may touch the package DB we regenerate the cache.
+    if len(ctx.attr.patches) > 0:
+        _execute_fail_loudly(ctx, ["./bin/ghc-pkg", "recache"])
+
+    # On Windows the bindist already contains the built executables
+    if os != "windows":
+        _execute_fail_loudly(ctx, ["sed", "-i", "s/RelocatableBuild = NO/RelocatableBuild = YES/", "mk/config.mk.in"])
+        _execute_fail_loudly(ctx, ["./configure", "--prefix", bindist_dir.realpath])
+        _execute_fail_loudly(ctx, ["make", "install"])
+        ctx.file("patch_bins", executable = True, content = """#!/usr/bin/env bash
+grep -lZ {bindist_dir} bin/* | xargs -0 --verbose \\
+    sed -i \\
+        -e '2iDISTDIR="$( dirname "$(resolved="$0"; while tmp="$(readlink "$resolved")"; do resolved="$tmp"; done; echo "$resolved")" )/.."' \\
+        -e 's:{bindist_dir}:$DISTDIR:'
+""".format(
+            bindist_dir = bindist_dir.realpath,
+        ))
+        _execute_fail_loudly(ctx, ["./patch_bins"])
+
+    ctx.template(
+        "BUILD",
+        ghc_build,
+        executable = False,
+    )
+    ctx.template("CROSSTOOL", crosstool_windows, executable = False)
+    ctx.file("WORKSPACE")
+
+_ghc_bindist = repository_rule(
+    _ghc_bindist_impl,
+    local = False,
+    attrs = {
+        "version": attr.string(
+            default = _GHC_DEFAULT_VERSION,
+            values = GHC_BINDIST.keys(),
+            doc = "The desired GHC version",
+        ),
+        "target": attr.string(),
+        "patches": attr.label_list(
+            default = [],
+            doc =
+                "A list of files that are to be applied as patches afer " +
+                "extracting the archive.",
+        ),
+        "patch_tool": attr.string(
+            default = "patch",
+            doc = "The patch(1) utility to use.",
+        ),
+        "patch_args": attr.string_list(
+            default = ["-p0"],
+            doc = "The arguments given to the patch tool",
+        ),
+        "patch_cmds": attr.string_list(
+            default = [],
+            doc = "Sequence of commands to be applied after patches are applied.",
+        ),
+    },
+)
+
+def _ghc_bindist_toolchain_impl(ctx):
+    os, _, arch = ctx.attr.target.partition("_")
+    exec_constraints = [{
+        "darwin": "@bazel_tools//platforms:osx",
+        "linux": "@bazel_tools//platforms:linux",
+        "windows": "@bazel_tools//platforms:windows",
+    }.get(os)]
+    target_constraints = exec_constraints
+    ctx.file(
+        "BUILD",
+        executable = False,
+        content = """
+load("@io_tweag_rules_haskell//haskell:toolchain.bzl", "haskell_toolchain")
+
+haskell_toolchain(
+    name = "toolchain",
+    tools = ["{tools}"],
+    version = "{version}",
+    compiler_flags = {compiler_flags},
+    haddock_flags = {haddock_flags},
+    repl_ghci_args = {repl_ghci_args},
+    exec_compatible_with = {exec_constraints},
+    target_compatible_with = {target_constraints},
+)
+        """.format(
+            tools = "@{}//:bin".format(ctx.attr.bindist_name),
+            version = ctx.attr.version,
+            compiler_flags = ctx.attr.compiler_flags,
+            haddock_flags = ctx.attr.haddock_flags,
+            repl_ghci_args = ctx.attr.repl_ghci_args,
+            exec_constraints = exec_constraints,
+            target_constraints = target_constraints,
+        ),
+    )
+
+_ghc_bindist_toolchain = repository_rule(
+    _ghc_bindist_toolchain_impl,
+    local = False,
+    attrs = {
+        "bindist_name": attr.string(),
+        "version": attr.string(),
+        "compiler_flags": attr.string_list(),
+        "haddock_flags": attr.string_list(),
+        "repl_ghci_args": attr.string_list(),
+        "target": attr.string(),
+    },
+)
+
+def ghc_bindist(
+        name,
+        version,
+        target,
+        compiler_flags = None,
+        haddock_flags = None,
+        repl_ghci_args = None):
+    """Create a new repository from binary distributions of GHC. The
+    repository exports two targets:
+
+    * a `bin` filegroup containing all GHC commands,
+    * a `threaded-rts` CC library.
+
+    These targets are unpacked from a binary distribution specific to your
+    platform. Only the platforms that have a "binary package" on the GHC
+    [download page](https://www.haskell.org/ghc/) are supported.
+
+    Example:
+       In `WORKSPACE` file:
+
+       ```bzl
+       load("@io_tweag_rules_haskell//haskell:haskell.bzl", "ghc_bindist")
+
+       # This repository rule creates @ghc repository.
+       ghc_bindist(
+         name    = "ghc",
+         version = "8.2.2",
+       )
+       ```
+    """
+    bindist_name = name
+    toolchain_name = "{}-toolchain".format(name)
+
+    # Recent GHC versions on Windows contain a bug:
+    # https://gitlab.haskell.org/ghc/ghc/issues/16466
+    # We work around this by patching the base configuration.
+    patches = {
+        "8.6.2": ["@io_tweag_rules_haskell//haskell:assets/ghc_8_6_2_win_base.patch"],
+        "8.6.4": ["@io_tweag_rules_haskell//haskell:assets/ghc_8_6_4_win_base.patch"],
+    }.get(version) if target == "windows_amd64" else None
+
+    extra_attrs = {"patches": patches, "patch_args": ["-p0"]} if patches else {}
+
+    # We want the toolchain definition to be tucked away in a separate
+    # repository, that way `bazel build //...` will not match it (and
+    # e.g. build the Windows toolchain even on Linux). At the same
+    # time, we don't want the definition in the bindist repository,
+    # because then we need to download the bindist first before we can
+    # see the toolchain definition. The solution is to add the
+    # toolchain definition in its own special repository.
+    _ghc_bindist(
+        name = bindist_name,
+        version = version,
+        target = target,
+        **extra_attrs
+    )
+    _ghc_bindist_toolchain(
+        name = toolchain_name,
+        bindist_name = bindist_name,
+        version = version,
+        compiler_flags = compiler_flags,
+        haddock_flags = haddock_flags,
+        repl_ghci_args = repl_ghci_args,
+        target = target,
+    )
+    native.register_toolchains("@{}//:toolchain".format(toolchain_name))
+
+def haskell_register_ghc_bindists(
+        version,
+        compiler_flags = None,
+        haddock_flags = None,
+        repl_ghci_args = None):
+    """Register GHC binary distributions for all platforms as toolchains.
+
+    Toolchains can be used to compile Haskell code. This function
+    registers one toolchain for each known binary distribution on all
+    platforms of the given GHC version. During the build, one
+    toolchain will be selected based on the host and target platforms
+    (See [toolchain resolution][toolchain-resolution]).
+
+    [toolchain-resolution]: https://docs.bazel.build/versions/master/toolchains.html#toolchain-resolution
+
+    """
+    if not GHC_BINDIST.get(version):
+        fail("Binary distribution of GHC {} not available.".format(version))
+    for target in GHC_BINDIST[version]:
+        ghc_bindist(
+            name = "io_tweag_rules_haskell_ghc_{}".format(target),
+            target = target,
+            version = version,
+            compiler_flags = compiler_flags,
+            haddock_flags = haddock_flags,
+            repl_ghci_args = repl_ghci_args,
+        )