diff options
author | Vincent Ambo <tazjin@google.com> | 2019-07-04T10·18+0100 |
---|---|---|
committer | Vincent Ambo <tazjin@google.com> | 2019-07-04T10·18+0100 |
commit | f723b8b878a3c4a4687b9e337a875500bebb39b1 (patch) | |
tree | e85204cf042c355e90cff61c111e7d8cd15df311 /third_party/bazel/rules_haskell/haskell/ghc_bindist.bzl | |
parent | 2eb1dc26e42ffbdc168f05ef744bd4b4f3e4c36f (diff) |
feat(third_party/bazel): Check in rules_haskell from Tweag r/17
Diffstat (limited to 'third_party/bazel/rules_haskell/haskell/ghc_bindist.bzl')
-rw-r--r-- | third_party/bazel/rules_haskell/haskell/ghc_bindist.bzl | 408 |
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 000000000000..3a448675e9d0 --- /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, + ) |