daml/bazel-haskell-deps.bzl
Moritz Kiefer 668373ca85
Embed shake data-files via TH (#4584)
This is a bit ugly but after spending some time digging into the
issues in rules_haskell around data-files, this seems like the most
sensible option especially given that we also want to ship them in the
SDK which woud require additional work even if we do fix it in
rules_haskell.

fixes #4457

changelog_begin
changelog_end
2020-02-18 17:53:27 +01:00

657 lines
20 KiB
Python

# Copyright (c) 2020 The DAML Authors. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# Defines external Haskell dependencies.
#
# Add Stackage dependencies to the `packages` attribute of the `@stackage`
# `stack_snapshot` in the very bottom of this file. If a package or version is
# not available on Stackage, add it to the custom stack snapshot in
# `stack-snapshot.yaml`. If a library requires patching, then add it as an
# `http_archive` and add it to the `vendored_packages` attribute of
# `stack_snapshot`. Executables are defined in an `http_archive` using
# `haskell_cabal_binary`.
load("@bazel_skylib//lib:dicts.bzl", "dicts")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@os_info//:os_info.bzl", "is_windows")
load("@dadew//:dadew.bzl", "dadew_tool_home")
load("@rules_haskell//haskell:cabal.bzl", "stack_snapshot")
GHCIDE_REV = "4e89d4574d538d663bd37f074ef6ef973d14a0f1"
GHCIDE_SHA256 = "0a31e5d7250c0ce18709152c64cea0cc949c84c47cc40396893e5256b587f7ef"
GHCIDE_VERSION = "0.1.0"
JS_JQUERY_VERSION = "3.3.1"
JS_DGTABLE_VERSION = "0.5.2"
JS_FLOT_VERSION = "0.8.3"
SHAKE_VERSION = "0.18.5"
def daml_haskell_deps():
"""Load all Haskell dependencies of the DAML repository."""
# XXX: We do not have access to an integer-simple version of GHC on Windows.
# For the time being we build with GMP. See https://github.com/digital-asset/daml/issues/106
use_integer_simple = not is_windows
#
# Executables
#
http_archive(
name = "alex",
build_file_content = """
load("@rules_haskell//haskell:cabal.bzl", "haskell_cabal_binary")
haskell_cabal_binary(
name = "alex",
srcs = glob(["**"]),
verbose = False,
visibility = ["//visibility:public"],
)
""",
sha256 = "d58e4d708b14ff332a8a8edad4fa8989cb6a9f518a7c6834e96281ac5f8ff232",
strip_prefix = "alex-3.2.4",
urls = ["http://hackage.haskell.org/package/alex-3.2.4/alex-3.2.4.tar.gz"],
)
http_archive(
name = "c2hs",
build_file_content = """
load("@rules_haskell//haskell:cabal.bzl", "haskell_cabal_binary")
haskell_cabal_binary(
name = "c2hs",
srcs = glob(["**"]),
deps = [
"@c2hs_deps//:base",
"@c2hs_deps//:bytestring",
"@c2hs_deps//:language-c",
"@c2hs_deps//:filepath",
"@c2hs_deps//:dlist",
],
verbose = False,
visibility = ["//visibility:public"],
)
""",
sha256 = "91dd121ac565009f2fc215c50f3365ed66705071a698a545e869041b5d7ff4da",
strip_prefix = "c2hs-0.28.6",
urls = ["http://hackage.haskell.org/package/c2hs-0.28.6/c2hs-0.28.6.tar.gz"],
)
http_archive(
name = "happy",
build_file_content = """
load("@rules_haskell//haskell:cabal.bzl", "haskell_cabal_binary")
haskell_cabal_binary(
name = "happy",
srcs = glob(["**"]),
verbose = False,
visibility = ["//visibility:public"],
)
""",
sha256 = "9094d19ed0db980a34f1ffd58e64c7df9b4ecb3beed22fd9b9739044a8d45f77",
strip_prefix = "happy-1.19.11",
urls = ["http://hackage.haskell.org/package/happy-1.19.11/happy-1.19.11.tar.gz"],
)
# Standard ghcide (not ghc-lib based) - used on daml's Haskell sources.
http_archive(
name = "ghcide",
build_file_content = """
load("@rules_haskell//haskell:cabal.bzl", "haskell_cabal_binary", "haskell_cabal_library")
deps = [
"@stackage//:aeson",
"@stackage//:async",
"@stackage//:base",
"@stackage//:binary",
"@stackage//:bytestring",
"@stackage//:containers",
"@stackage//:data-default",
"@stackage//:deepseq",
"@stackage//:directory",
"@stackage//:extra",
"@stackage//:filepath",
"@stackage//:fuzzy",
"@stackage//:ghc",
"@stackage//:ghc-boot",
"@stackage//:ghc-boot-th",
"@stackage//:haddock-library",
"@stackage//:hashable",
"@stackage//:haskell-lsp",
"@stackage//:haskell-lsp-types",
"@stackage//:mtl",
"@stackage//:network-uri",
"@stackage//:prettyprinter",
"@stackage//:prettyprinter-ansi-terminal",
"@stackage//:regex-tdfa",
"@stackage//:rope-utf16-splay",
"@stackage//:safe-exceptions",
"@stackage//:shake",
"@stackage//:sorted-list",
"@stackage//:stm",
"@stackage//:syb",
"@stackage//:text",
"@stackage//:time",
"@stackage//:transformers",
"@stackage//:unordered-containers",
"@stackage//:utf8-string",
]
haskell_cabal_library(
name = "ghcide-lib",
package_name = "ghcide",
version = "{version}",
haddock = False,
srcs = glob(["**"]),
deps = deps,
visibility = ["//visibility:public"],
)
haskell_cabal_binary(
name = "ghcide",
srcs = glob(["**"]),
deps = deps + [
":ghcide-lib",
"@stackage//:gitrev",
"@stackage//:ghc-paths",
"@stackage//:hie-bios",
"@stackage//:optparse-applicative",
],
visibility = ["//visibility:public"],
)
""".format(version = GHCIDE_VERSION),
sha256 = GHCIDE_SHA256,
strip_prefix = "ghcide-%s" % GHCIDE_REV,
urls = ["https://github.com/digital-asset/ghcide/archive/%s.tar.gz" % GHCIDE_REV],
)
http_archive(
name = "hpp",
build_file_content = """
load("@rules_haskell//haskell:cabal.bzl", "haskell_cabal_binary")
haskell_cabal_binary(
name = "hpp",
srcs = glob(["**"]),
deps = [
"@stackage//:base",
"@stackage//:directory",
"@stackage//:filepath",
"@stackage//:hpp",
"@stackage//:time",
],
verbose = False,
visibility = ["//visibility:public"],
)
""",
sha256 = "d1a843f4383223f85de4d91759545966f33a139d0019ab30a2f766bf9a7d62bf",
strip_prefix = "hpp-0.6.1",
urls = ["http://hackage.haskell.org/package/hpp-0.6.1/hpp-0.6.1.tar.gz"],
)
http_archive(
name = "proto3_suite",
build_file_content = """
# XXX: haskell_cabal_binary inexplicably fails with
# realgcc.exe: error: CreateProcess: No such file or directory
# So we use haskell_binary instead.
load("@rules_haskell//haskell:defs.bzl", "haskell_binary")
haskell_binary(
name = "compile-proto-file",
srcs = ["tools/compile-proto-file/Main.hs"],
compiler_flags = ["-w", "-optF=-w"],
deps = [
"@stackage//:base",
"@stackage//:optparse-applicative",
"@stackage//:proto3-suite",
"@stackage//:system-filepath",
"@stackage//:text",
"@stackage//:turtle",
],
visibility = ["//visibility:public"],
)
""",
sha256 = "216fb8b5d92afc9df70512da2331e098e926239efd55e770802079c2a13bad5e",
strip_prefix = "proto3-suite-0.4.0.0",
urls = ["http://hackage.haskell.org/package/proto3-suite-0.4.0.0/proto3-suite-0.4.0.0.tar.gz"],
)
#
# Vendored Libraries
#
# ghc-lib based ghcide - injected into `@stackage` and used for DAML IDE.
http_archive(
name = "ghcide_ghc_lib",
build_file_content = """
load("@rules_haskell//haskell:cabal.bzl", "haskell_cabal_library")
load("@rules_haskell//haskell:defs.bzl", "haskell_library")
load("@stackage//:packages.bzl", "packages")
haskell_cabal_library(
name = "ghcide",
version = "{version}",
srcs = glob(["**"]),
haddock = False,
flags = packages["ghcide"].flags,
deps = packages["ghcide"].deps,
visibility = ["//visibility:public"],
)
haskell_library(
name = "testing",
srcs = glob(["test/src/**/*.hs"]),
src_strip_prefix = "test/src",
deps = [
"@stackage//:base",
"@stackage//:extra",
"@stackage//:containers",
"@stackage//:haskell-lsp-types",
"@stackage//:lens",
"@stackage//:lsp-test",
"@stackage//:parser-combinators",
"@stackage//:tasty-hunit",
"@stackage//:text",
],
compiler_flags = [
"-XBangPatterns",
"-XDeriveFunctor",
"-XDeriveGeneric",
"-XGeneralizedNewtypeDeriving",
"-XLambdaCase",
"-XNamedFieldPuns",
"-XOverloadedStrings",
"-XRecordWildCards",
"-XScopedTypeVariables",
"-XStandaloneDeriving",
"-XTupleSections",
"-XTypeApplications",
"-XViewPatterns",
],
visibility = ["//visibility:public"],
)
""".format(version = GHCIDE_VERSION),
patch_args = ["-p1"],
patches = ["@com_github_digital_asset_daml//bazel_tools:haskell-ghcide-expose-compat.patch"],
sha256 = GHCIDE_SHA256,
strip_prefix = "ghcide-%s" % GHCIDE_REV,
urls = ["https://github.com/digital-asset/ghcide/archive/%s.tar.gz" % GHCIDE_REV],
)
# The Bazel-provided grpc libs cause issues in GHCi so we get them from Nix on Linux and MacOS.
deps = '[":grpc", ":libgpr"]' if is_windows else '["@grpc_nix//:grpc_lib"]'
extra_targets = """
fat_cc_library(
name = "grpc",
input_lib = "@com_github_grpc_grpc//:grpc",
)
# Cabal requires libgpr next to libgrpc. However, fat_cc_library of grpc
# already contains gpr and providing a second copy would cause duplicate symbol
# errors. Instead, we define an empty dummy libgpr.
genrule(name = "gpr-source", outs = ["gpr.c"], cmd = "touch $(OUTS)")
cc_library(name = "gpr", srcs = [":gpr-source"])
cc_library(name = "libgpr", linkstatic = 1, srcs = [":gpr"])
""" if is_windows else ""
http_archive(
name = "grpc_haskell_core",
build_file_content = """
load("@com_github_digital_asset_daml//bazel_tools:fat_cc_library.bzl", "fat_cc_library")
load("@rules_haskell//haskell:cabal.bzl", "haskell_cabal_library")
load("@stackage//:packages.bzl", "packages")
haskell_cabal_library(
name = "grpc-haskell-core",
version = "0.0.0.0",
srcs = glob(["**"]),
haddock = False,
deps = packages["grpc-haskell-core"].deps + {deps},
tools = ["@c2hs//:c2hs"],
verbose = False,
visibility = ["//visibility:public"],
)
{extra_targets}
""".format(deps = deps, extra_targets = extra_targets),
patch_args = ["-p1"],
patches = [
"@com_github_digital_asset_daml//bazel_tools:grpc-haskell-core-cpp-options.patch",
],
sha256 = "087527ec3841330b5328d123ca410901905d111529956821b724d92c436e6cdf",
strip_prefix = "grpc-haskell-core-0.0.0.0",
urls = ["http://hackage.haskell.org/package/grpc-haskell-core-0.0.0.0/grpc-haskell-core-0.0.0.0.tar.gz"],
)
# Note (MK)
# We vendor Shake and its JS dependencies
# so that we can replace the data-files with file-embed.
# This is both to workaround bugs in rules_haskell where data-files
# are not propagated correctly to non-cabal targets and to
# make sure that they are shipped in the SDK.
http_archive(
name = "js_jquery",
build_file_content = """
load("@rules_haskell//haskell:cabal.bzl", "haskell_cabal_library")
load("@stackage//:packages.bzl", "packages")
haskell_cabal_library(
name = "js-jquery",
version = "{version}",
srcs = glob(["**"]),
haddock = False,
deps = packages["js-jquery"].deps,
verbose = False,
visibility = ["//visibility:public"],
)
""".format(version = JS_JQUERY_VERSION),
patch_args = ["-p1"],
patches = [
"@com_github_digital_asset_daml//bazel_tools:haskell-js-jquery.patch",
],
sha256 = "e0e0681f0da1130ede4e03a051630ea439c458cb97216cdb01771ebdbe44069b",
strip_prefix = "js-jquery-{}".format(JS_JQUERY_VERSION),
urls = ["http://hackage.haskell.org/package/js-jquery-{version}/js-jquery-{version}.tar.gz".format(version = JS_JQUERY_VERSION)],
)
http_archive(
name = "js_dgtable",
build_file_content = """
load("@rules_haskell//haskell:cabal.bzl", "haskell_cabal_library")
load("@stackage//:packages.bzl", "packages")
haskell_cabal_library(
name = "js-dgtable",
version = "{version}",
srcs = glob(["**"]),
haddock = False,
deps = packages["js-dgtable"].deps,
verbose = False,
visibility = ["//visibility:public"],
)
""".format(version = JS_DGTABLE_VERSION),
patch_args = ["-p1"],
patches = [
"@com_github_digital_asset_daml//bazel_tools:haskell-js-dgtable.patch",
],
sha256 = "e28dd65bee8083b17210134e22e01c6349dc33c3b7bd17705973cd014e9f20ac",
strip_prefix = "js-dgtable-{}".format(JS_DGTABLE_VERSION),
urls = ["http://hackage.haskell.org/package/js-dgtable-{version}/js-dgtable-{version}.tar.gz".format(version = JS_DGTABLE_VERSION)],
)
http_archive(
name = "js_flot",
build_file_content = """
load("@rules_haskell//haskell:cabal.bzl", "haskell_cabal_library")
load("@stackage//:packages.bzl", "packages")
haskell_cabal_library(
name = "js-flot",
version = "{version}",
srcs = glob(["**"]),
haddock = False,
deps = packages["js-flot"].deps,
verbose = False,
visibility = ["//visibility:public"],
)
""".format(version = JS_FLOT_VERSION),
patch_args = ["-p1"],
patches = [
"@com_github_digital_asset_daml//bazel_tools:haskell-js-flot.patch",
],
sha256 = "1ba2f2a6b8d85da76c41f526c98903cbb107f8642e506c072c1e7e3c20fe5e7a",
strip_prefix = "js-flot-{}".format(JS_FLOT_VERSION),
urls = ["http://hackage.haskell.org/package/js-flot-{version}/js-flot-{version}.tar.gz".format(version = JS_FLOT_VERSION)],
)
http_archive(
name = "shake",
build_file_content = """
load("@rules_haskell//haskell:cabal.bzl", "haskell_cabal_library")
load("@stackage//:packages.bzl", "packages")
haskell_cabal_library(
name = "shake",
version = "{version}",
srcs = glob(["**"]),
haddock = False,
deps = packages["shake"].deps,
verbose = False,
visibility = ["//visibility:public"],
flags = ["embed-files"],
)
""".format(version = SHAKE_VERSION),
patch_args = ["-p1"],
patches = [
"@com_github_digital_asset_daml//bazel_tools:haskell-shake.patch",
],
sha256 = "576ab57f53b8051f67ceeb97bd9abf2e0926f592334a7a1c27c07b36afca240f",
strip_prefix = "shake-{}".format(SHAKE_VERSION),
urls = ["http://hackage.haskell.org/package/shake-{version}/shake-{version}.tar.gz".format(version = SHAKE_VERSION)],
)
#
# Stack binary
#
# On Windows the stack binary is provisioned using dadew.
if is_windows:
native.new_local_repository(
name = "stack_windows",
build_file_content = """
exports_files(["stack.exe"], visibility = ["//visibility:public"])
""",
path = dadew_tool_home("stack"),
)
#
# Stack Snapshots
#
# Used to bootstrap `@c2hs` for `@stackage`.
# Some packages in the `@stackage` snapshot require `c2hs` as a build tool.
# But `c2hs` requires some Stackage packages to builld itself. So, we
# define this separate `stack_snapshot` to bootstrap `c2hs`.
stack_snapshot(
name = "c2hs_deps",
haddock = False,
local_snapshot = "//:stack-snapshot.yaml",
packages = [
"base",
"bytestring",
"dlist",
"filepath",
"language-c",
],
stack = "@stack_windows//:stack.exe" if is_windows else None,
tools = [
"@alex",
"@happy",
],
)
stack_snapshot(
name = "stackage",
extra_deps = {
"bzlib-conduit": ["@bzip2//:libbz2"],
"digest": ["@com_github_madler_zlib//:libz"],
"zlib": ["@com_github_madler_zlib//:libz"],
},
flags = dicts.add(
{
"ghcide": ["ghc-lib"],
"hlint": ["ghc-lib"],
"ghc-lib-parser-ex": ["ghc-lib"],
},
{
"blaze-textual": ["integer-simple"],
"cryptonite": ["-integer-gmp"],
"hashable": ["-integer-gmp"],
"integer-logarithms": ["-integer-gmp"],
"text": ["integer-simple"],
"scientific": ["integer-simple"],
} if use_integer_simple else {},
),
haddock = False,
local_snapshot = "//:stack-snapshot.yaml",
packages = [
"aeson",
"aeson-pretty",
"ansi-terminal",
"ansi-wl-pprint",
"array",
"async",
"attoparsec",
"base",
"base16-bytestring",
"base64-bytestring",
"binary",
"blaze-html",
"bytestring",
"Cabal",
"case-insensitive",
"cereal",
"clock",
"cmark-gfm",
"conduit",
"conduit-extra",
"connection",
"containers",
"contravariant",
"cryptohash",
"cryptonite",
"data-default",
"Decimal",
"deepseq",
"directory",
"dlist",
"either",
"exceptions",
"extra",
"fast-logger",
"file-embed",
"filepath",
"filepattern",
"foldl",
"fuzzy",
"ghc",
"ghc-boot",
"ghc-boot-th",
"ghc-lib",
"ghc-lib-parser",
"ghc-lib-parser-ex",
"ghc-paths",
"ghc-prim",
"gitrev",
"grpc-haskell",
"haddock-library",
"hashable",
"haskeline",
"haskell-lsp",
"haskell-lsp-types",
"haskell-src",
"haskell-src-exts",
"heaps",
"hie-bios",
"hlint",
"hpc",
"hpp",
"hslogger",
"http-client",
"http-client-tls",
"http-conduit",
"http-types",
"insert-ordered-containers",
"jwt",
"lens",
"lens-aeson",
"lifted-async",
"lifted-base",
"lsp-test",
"main-tester",
"managed",
"megaparsec",
"memory",
"monad-control",
"monad-logger",
"monad-loops",
"mtl",
"neat-interpolation",
"network",
"network-uri",
"nsis",
"open-browser",
"optparse-applicative",
"optparse-generic",
"parsec",
"parser-combinators",
"parsers",
"path",
"path-io",
"pipes",
"pretty",
"prettyprinter",
"prettyprinter-ansi-terminal",
"pretty-show",
"primitive",
"process",
"proto3-suite",
"proto3-wire",
"QuickCheck",
"quickcheck-instances",
"random",
"range-set-list",
"recursion-schemes",
"regex-tdfa",
"resourcet",
"retry",
"rope-utf16-splay",
"safe",
"safe-exceptions",
"scientific",
"semigroups",
"semver",
"sorted-list",
"split",
"stache",
"stm",
"swagger2",
"syb",
"system-filepath",
"tagged",
"tar",
"tar-conduit",
"tasty",
"tasty-ant-xml",
"tasty-golden",
"tasty-hunit",
"tasty-quickcheck",
"template-haskell",
"temporary",
"terminal-progress-bar",
"text",
"time",
"tls",
"transformers",
"transformers-base",
"turtle",
"typed-process",
"uniplate",
"unix-compat",
"unliftio",
"unliftio-core",
"unordered-containers",
"uri-encode",
"utf8-string",
"uuid",
"vector",
"xml",
"xml-conduit",
"yaml",
"zip",
"zip-archive",
"zlib",
"zlib-bindings",
] + (["unix"] if not is_windows else ["Win32"]),
stack = "@stack_windows//:stack.exe" if is_windows else None,
tools = [
"@alex",
"@c2hs",
"@happy",
],
vendored_packages = {
"ghcide": "@ghcide_ghc_lib//:ghcide",
"grpc-haskell-core": "@grpc_haskell_core//:grpc-haskell-core",
"js-jquery": "@js_jquery//:js-jquery",
"js-dgtable": "@js_dgtable//:js-dgtable",
"js-flot": "@js_flot//:js-flot",
"shake": "@shake//:shake",
},
)