Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ghc version to CI matrix for bindists #1923

Merged
merged 27 commits into from
Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
ca51320
WIP Add ghc version to CI matrix for bindists
avdv Jul 31, 2023
bfa0d00
Use separate stackage snapshot for GHC 9.4.5
avdv Aug 1, 2023
298420e
Fix compilation of tools/worker with GHC 9.4.5
avdv Aug 1, 2023
527c47c
Fix compilation of rule_info_haskell_proto for GHC 9.4.5
avdv Aug 1, 2023
2b745f7
Add stackage snapshot links for GHC 9.2.5
avdv Aug 1, 2023
9c9740b
Add type signatures
avdv Aug 2, 2023
0be971c
Use GHC version in bzlmod
avdv Aug 8, 2023
5539b21
Define default GHC version
avdv Aug 8, 2023
ee26fdc
Make sure GHC_VERSION is used
avdv Aug 8, 2023
634de02
Use protoc-update-bounds branch without submodules
avdv Aug 9, 2023
9172508
Load ghc_version in rules_haskell_tests module too
avdv Aug 9, 2023
f44b13a
Use Cabal 3.8.1 with GHC 9.4
avdv Aug 9, 2023
23789d3
Only use GHC_VERSION variable for rules_haskell modules
avdv Aug 10, 2023
f1acc5d
Do not reverse order of plugins for GHC >= 9.4.1
avdv Aug 14, 2023
fc33fef
Add protoc wrapper on Windows
avdv Aug 14, 2023
9a8e464
Remove `allow_single_file` parameter for `protoc` and `plugin`
avdv Aug 14, 2023
18cbb11
Make the `start` script select the right stack snapshot
avdv Aug 15, 2023
de47ca9
Add missing links
avdv Aug 17, 2023
86c50d3
Make protoc able to be overridden by `--proto_compiler`
avdv Aug 18, 2023
a4271eb
Set `--proto_compiler` to `//tests:protoc.cmd` on Windows
avdv Aug 18, 2023
d2b7117
Pass on runtime manifests for protoc
avdv Aug 22, 2023
466d7ec
Format
avdv Aug 23, 2023
569c7b2
Bump minimal Bazel version to 5.3
avdv Aug 23, 2023
9ced5ed
Pass on runtime manifests for protoc and plugin
avdv Aug 22, 2023
d755fad
README: Add section about protoc errors on Windows to Troubleshooting
avdv Sep 1, 2023
cfbe06a
Simplify determining the root module
avdv Sep 1, 2023
6821989
Clarify semantics of the ghc_default_version module extension
avdv Sep 1, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .bazelrc.common
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ query --deleted_packages=examples,examples/arm,examples/cat_hs,examples/cat_hs/e
# Needed to build @rules_jvm_external//private/tools/java/com/github/bazelbuild/rules_jvm_external/zip (used by //tests/java_classpath)
build:macos-nixpkgs --tool_java_language_version=11

# Needed to run protoc compiled with libc++ / clang on Windows
build:windows-bindist --proto_compiler @rules_haskell//tests:protoc.cmd
avdv marked this conversation as resolved.
Show resolved Hide resolved

# This flag will become the default in bazel 7
# https://github.com/bazelbuild/bazel/issues/17032
build --incompatible_disable_starlark_host_transitions
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ jobs:
os: [ubuntu-latest, macos-11, windows-latest]
module: [rules_haskell, rules_haskell_tests]
bzlmod: [bzlmod, workspace]
ghc:
- 9.2.5
- 9.4.5
env:
GHC_VERSION: ${{ matrix.ghc }}
runs-on: ${{ matrix.os }}
steps:
- if: ${{ matrix.os == 'ubuntu-latest' }}
Expand Down
7 changes: 7 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ bazel_dep(
version = "0.3.0",
)

ghc_version = use_extension("//extensions:ghc_version.bzl", "ghc_default_version")

use_repo(
ghc_version,
"rules_haskell_ghc_version",
)

rules_haskell_dependencies = use_extension(
"//extensions:rules_haskell_dependencies.bzl",
"rules_haskell_dependencies",
Expand Down
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,20 @@ This could be caused by a dependency on the `ghc-paths` package which bakes the

You can use `@rules_haskell//tools/ghc-paths` as a drop-in replacement to work around this issue. See `tools/ghc-paths/README.md` for further details.

### Windows: protoc.exe exits with an error

If you see
```
protoc.exe: error while loading shared libraries: api-ms-win-crt-filesystem-l1-1-0.dll: cannot open shared object file: No such file or directory
```
or
```
Process finished with exit code -1073741515 (0xC0000135)
```
this usually means the executable cannot find a DLL it depends on (not necessarily the DLL that is mentioned in the error message).

Newer Windows GHC distributions (>= 9.4), come with clang as the C/C++ compiler, and executables produced using that toolchain depend on the libc++ DLL, which is found in the `mingw\bin` directory of the bindist. You can pass `--proto_compiler @rules_haskell//tests:protoc` as a build flag to bazel as a workaround (see [tests/protoc.bzl]).

## For `rules_haskell` developers

### Configuring your platform
Expand Down
16 changes: 13 additions & 3 deletions WORKSPACE
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
workspace(name = "rules_haskell")

load("//haskell:private/ghc_ci.bzl", "ghc_version")

ghc_version(name = "rules_haskell_ghc_version")

load("//haskell:repositories.bzl", "rules_haskell_dependencies")

rules_haskell_dependencies()
Expand Down Expand Up @@ -54,12 +58,14 @@ load("//extensions:rules_haskell_dependencies.bzl", _repositories_3 = "repositor

_repositories_3(bzlmod = False)

load("@rules_haskell_ghc_version//:ghc_version.bzl", "GHC_VERSION")

load(
"@rules_haskell//haskell:ghc_bindist.bzl",
"haskell_register_ghc_bindists",
)

haskell_register_ghc_bindists()
haskell_register_ghc_bindists(version = GHC_VERSION)

load(
"@rules_haskell//haskell/asterius:repositories.bzl",
Expand Down Expand Up @@ -149,7 +155,9 @@ stack_snapshot(
"exe",
],
},
local_snapshot = "//:stackage_snapshot.yaml",
local_snapshot = "//:stackage_snapshot{}.yaml".format(
"_" + str(GHC_VERSION) if GHC_VERSION else ""
),
packages = [
# Core libraries
"base",
Expand Down Expand Up @@ -182,7 +190,9 @@ stack_snapshot(
"typed-process": ["@Cabal//:Cabal"],
"unliftio-core": ["@Cabal//:Cabal"],
},
stack_snapshot_json = "//:stackage_snapshot.json" if not is_windows else None,
stack_snapshot_json = ("//:stackage_snapshot{}.json".format(
"_" + str(GHC_VERSION) if GHC_VERSION else ""
)) if not is_windows else None,
vendored_packages = {
"ghc-paths": "@rules_haskell//tools/ghc-paths",
},
Expand Down
27 changes: 27 additions & 0 deletions extensions/ghc_version.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""Module extension which configures the default GHC version for rules_haskell and rules_haskell_tests

If used from rules_haskell or rules_haskell_tests, this will change the default
GHC version to the value of the `GHC_VERSION` environment variable (if set).

When used from other modules than rules_haskell and rules_haskell_tests, the
default GHC version is given by the `DEFAULT_GHC_VERSION` constant (see [`//haskell:ghc.bzl`](haskell/ghc.bzl).
"""

load(
"@rules_haskell//haskell:private/ghc_ci.bzl",
_ghc_version = "ghc_version",
_ghc_default_version = "ghc_default_version",
)

def _ghc_default_version_impl(mctx):
root_module = mctx.modules[0].name

if root_module in ['rules_haskell', 'rules_haskell_tests']:
_ghc_version(name = "rules_haskell_ghc_version")
else:
_ghc_default_version(name = "rules_haskell_ghc_version")

ghc_default_version = module_extension(
implementation = _ghc_default_version_impl,
#environ = ["GHC_VERSION"], # Bazel >= 6.3.2
)
31 changes: 25 additions & 6 deletions extensions/rules_haskell_dependencies.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ load("@rules_haskell//tools:repositories.bzl", "rules_haskell_worker_dependencie
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
load("@rules_haskell//tools:os_info.bzl", "os_info")
load("@rules_haskell_ghc_version//:ghc_version.bzl", "GHC_VERSION")

def repositories(*, bzlmod):
rules_haskell_dependencies_bzlmod()
Expand All @@ -23,9 +24,27 @@ def repositories(*, bzlmod):

# TODO: Remove when tests are run with a ghc version containing Cabal >= 3.10
# See https://github.com/tweag/rules_haskell/issues/1871
http_archive(
name = "Cabal",
build_file_content = """
if GHC_VERSION and GHC_VERSION.startswith("9.4."):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So long as it's only for our CI, I'm fine with this approach. Generally speaking, a better route would be if we could figure out how to select based on resolved GHC version and then use select to switch to the correct versions. But, that seems quite difficult in this case.

http_archive(
name = "Cabal",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is @Cabal all used? From what I can tell it's mostly used for test dependencies and for the worker. So, it shouldn't directly affect users of rules_haskell, correct?

Side note, I noticed that some test-dependencies in rules_haskell's MODULE.bazel, e.g. some stack_snapshots, are not marked as dev-dependencies. It's out of scope for this PR, but something we should fix.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is @Cabal all used? From what I can tell it's mostly used for test dependencies and for the worker. So, it shouldn't directly affect users of rules_haskell, correct?

Yes.

Side note, I noticed that some test-dependencies in rules_haskell's MODULE.bazel, e.g. some stack_snapshots, are not marked as dev-dependencies. It's out of scope for this PR, but something we should fix.

Agreed, and I already tried that (setting dev_dependency = True) but that failed with some wild error later, since rules_haskell_tests depended on it.

build_file_content = """
load("@rules_haskell//haskell:cabal.bzl", "haskell_cabal_library")
haskell_cabal_library(
name = "Cabal",
srcs = glob(["Cabal/**"]),
verbose = False,
version = "3.8.1.0",
visibility = ["//visibility:public"],
)
""",
sha256 = "b697b558558f351d2704e520e7dcb1f300cd77fea5677d4b2ee71d0b965a4fe9",
strip_prefix = "cabal-ghc-9.4-paths-module-relocatable",
urls = ["https://github.com/tweag/cabal/archive/refs/heads/ghc-9.4-paths-module-relocatable.zip"],
)
else:
http_archive(
name = "Cabal",
build_file_content = """
load("@rules_haskell//haskell:cabal.bzl", "haskell_cabal_library")
haskell_cabal_library(
name = "Cabal",
Expand All @@ -35,9 +54,9 @@ haskell_cabal_library(
visibility = ["//visibility:public"],
)
""",
sha256 = "f69b46cb897edab3aa8d5a4bd7b8690b76cd6f0b320521afd01ddd20601d1356",
strip_prefix = "cabal-gg-8220-with-3630",
urls = ["https://github.com/tweag/cabal/archive/refs/heads/gg/8220-with-3630.zip"],
sha256 = "f69b46cb897edab3aa8d5a4bd7b8690b76cd6f0b320521afd01ddd20601d1356",
strip_prefix = "cabal-gg-8220-with-3630",
urls = ["https://github.com/tweag/cabal/archive/refs/heads/gg/8220-with-3630.zip"],
)

def _rules_haskell_dependencies_impl(_mctx):
Expand Down
6 changes: 6 additions & 0 deletions haskell/ghc.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

# If you change this, change stackage's version in the start script
# (see stackage.org).

# Currently, we are using GHC 9.2.x as default.
DEFAULT_GHC_VERSION = "9.2.5"
5 changes: 2 additions & 3 deletions haskell/ghc_bindist.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@ load(
"resolve_labels",
)
load(":private/validate_attrs.bzl", "check_deprecated_attribute_usage")
load("//haskell:ghc.bzl", "DEFAULT_GHC_VERSION")

# If you change this, change stackage's version in the start script
# (see stackage.org).
_GHC_DEFAULT_VERSION = "9.2.5"
_GHC_DEFAULT_VERSION = DEFAULT_GHC_VERSION

GHC_BINDIST_STRIP_PREFIX = \
{
Expand Down
7 changes: 4 additions & 3 deletions haskell/private/actions/info.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@ def write_proto_file(hs, output_name, proto_type, content):

hs.actions.run_shell(
outputs = [proto_pb],
inputs = depset([proto_txt] + rule_info_protos),
tools = [protoc],
inputs = depset([proto_txt] + rule_info_protos, transitive = [protoc.inputs]),
input_manifests = protoc.input_manifests,
tools = [protoc.executable],
command =
"{protoc} {rule_info_proto} --encode {proto_type} < {proto_txt} > {proto_pb}"
.format(
protoc = protoc.path,
protoc = protoc.executable.path,
proto_type = proto_type,
proto_txt = proto_txt.path,
proto_pb = proto_pb.path,
Expand Down
27 changes: 27 additions & 0 deletions haskell/private/ghc_ci.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
load("@rules_haskell//haskell:ghc.bzl", "DEFAULT_GHC_VERSION")

def _init_ghc_version_repository(repository_ctx, GHC_VERSION):
repository_ctx.file("BUILD")
repository_ctx.file("ghc_version.bzl", content = "GHC_VERSION = {}".format(repr(GHC_VERSION)))

def _ghc_version_impl(repository_ctx):
GHC_VERSION = repository_ctx.os.environ.get("GHC_VERSION")

if GHC_VERSION:
print("Using GHC version {} from env variable `GHC_VERSION`".format(GHC_VERSION))

_init_ghc_version_repository(repository_ctx, GHC_VERSION)

ghc_version = repository_rule(
implementation = _ghc_version_impl,
environ = ["GHC_VERSION"],
configure = True,
)


def _ghc_default_version_impl(repository_ctx):
_init_ghc_version_repository(repository_ctx, DEFAULT_GHC_VERSION)

ghc_default_version = repository_rule(
implementation = _ghc_default_version_impl,
)
avdv marked this conversation as resolved.
Show resolved Hide resolved
5 changes: 4 additions & 1 deletion haskell/private/haskell_impl.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,10 @@ def _haskell_binary_common_impl(ctx, is_test):
fail("""The attribute "narrowed_deps" can only be used if "modules" is specified in {}""".format(ctx.label))

# Note [Plugin order]
plugin_decl = reversed(ctx.attr.plugins)
plugins = ctx.attr.plugins

plugin_decl = reversed(plugins) if hs.toolchain.numeric_version < [9, 4, 1] else plugins

non_default_plugin_decl = reversed(ctx.attr.non_default_plugins)
all_plugin_decls = plugin_decl + non_default_plugin_decl

Expand Down
2 changes: 1 addition & 1 deletion haskell/private/versions.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# because every bazel version tested requires a lot of space on CI
# See https://github.com/tweag/rules_haskell/pull/1781#issuecomment-1187640454
SUPPORTED_BAZEL_VERSIONS = [
"5.2.0",
"5.3.0",
"5.4.1",
"6.2.0",
]
Expand Down
22 changes: 15 additions & 7 deletions haskell/protobuf.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def _haskell_proto_aspect_impl(target, ctx):
ctx.label.package,
)

args.add("--plugin=protoc-gen-haskell=" + pb.plugin.path)
args.add("--plugin=protoc-gen-haskell=" + pb.plugin.executable.path)

hs_files = []
inputs = []
Expand Down Expand Up @@ -149,11 +149,13 @@ def _haskell_proto_aspect_impl(target, ctx):
])

ctx.actions.run(
inputs = depset([pb.protoc, pb.plugin] + inputs),
inputs = depset(inputs, transitive = [pb.plugin.inputs, pb.protoc.inputs]),
input_manifests = pb.protoc.input_manifests + pb.plugin.input_manifests,
outputs = hs_files,
mnemonic = "HaskellProtoc",
executable = pb.protoc,
executable = pb.protoc.executable,
arguments = [args],
tools = [pb.plugin.executable],
env = {
"RULES_HASKELL_GHC_PATH": hs.tools.ghc.path,
"RULES_HASKELL_GHC_PKG_PATH": hs.tools.ghc_pkg.path,
Expand Down Expand Up @@ -350,13 +352,21 @@ registered.
""",
)

def _wrap_tool(ctx, exe, tool):
inputs, input_manifests = ctx.resolve_tools(tools = [tool])
return struct(
executable = exe,
inputs = inputs,
input_manifests = input_manifests
)

def _protobuf_toolchain_impl(ctx):
return [
platform_common.ToolchainInfo(
name = ctx.label.name,
tools = struct(
plugin = ctx.executable.plugin,
protoc = ctx.executable.protoc,
plugin = _wrap_tool(ctx, ctx.executable.plugin, ctx.attr.plugin),
protoc = _wrap_tool(ctx, ctx.executable.protoc, ctx.attr.protoc),
),
deps = ctx.attr.deps,
),
Expand All @@ -368,13 +378,11 @@ _protobuf_toolchain = rule(
"protoc": attr.label(
executable = True,
cfg = "exec",
allow_single_file = True,
mandatory = True,
),
"plugin": attr.label(
executable = True,
cfg = "exec",
allow_single_file = True,
mandatory = True,
),
"deps": attr.label_list(
Expand Down
6 changes: 6 additions & 0 deletions haskell/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ load(
":private/versions.bzl",
"check_bazel_version_compatible",
)
load(":private/ghc_ci.bzl", "ghc_default_version")

_rules_nixpkgs_version = "0c1f8f5470c7f292b7620762e224f53d837929d3"
_rules_nixpkgs_sha256 = "9e3898a33c5f21f634aa9e2d45620e7c4b6d54d16d473571a891193bbd4725ca"
Expand All @@ -17,6 +18,11 @@ _rules_sh_sha256 = "d668bb32f112ead69c58bde2cae62f6b8acefe759a8c95a2d80ff6a85af5
def rules_haskell_dependencies_bzlmod():
"""Provide rules_haskell dependencies which are not available as bzlmod modules."""

maybe(
ghc_default_version,
name = "rules_haskell_ghc_version"
)

# Dependency of com_google_protobuf.
# TODO(judahjacobson): this is a bit of a hack.
# We can't call that repository's protobuf_deps() function
Expand Down
11 changes: 9 additions & 2 deletions haskell/toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,8 @@ def _haskell_toolchain_impl(ctx):
supports_haddock = default_tools_config.supports_haddock,
)

(protoc_inputs, protoc_input_manifests) = ctx.resolve_tools(tools = [ctx.attr._protoc])

return [
platform_common.ToolchainInfo(
name = ctx.label.name,
Expand Down Expand Up @@ -319,7 +321,11 @@ def _haskell_toolchain_impl(ctx):
version = ctx.attr.version,
numeric_version = numeric_version,
global_pkg_db = pkgdb_file,
protoc = ctx.executable._protoc,
protoc = struct(
executable = ctx.executable._protoc,
inputs = protoc_inputs,
input_manifests = protoc_input_manifests,
),
rule_info_proto = ctx.attr._rule_info_proto,
tools_config = tools_config,
),
Expand Down Expand Up @@ -377,7 +383,8 @@ common_attrs = {
"_protoc": attr.label(
executable = True,
cfg = "exec",
default = Label("@com_google_protobuf//:protoc"),
# N.B. can be overridden by `--proto_compiler` flag
default = configuration_field("proto", "proto_compiler"),
),
"_rule_info_proto": attr.label(
allow_single_file = True,
Expand Down
2 changes: 1 addition & 1 deletion rules_haskell_tests/MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ use_repo(
"toolchains_libraries",
"zlib.dev",
"bazel_5",
"build_bazel_bazel_5_2_0",
"build_bazel_bazel_5_3_0",
"build_bazel_bazel_5_4_1",
"build_bazel_bazel_6_2_0",
"bazel_6",
Expand Down
1 change: 1 addition & 0 deletions rules_haskell_tests/stackage_snapshot_9.2.5.json
Loading