Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ You'll need [Bazel >= 6.0][bazel-getting-started] installed.

If you are on NixOS, skip to the [Nixpkgs](#Nixpkgs) section.

> [!NOTE]
> Bazel 8 users will need to add
> `common --noincompatible_disallow_ctx_resolve_tools` to `.bazelrc`

### System dependencies

Refer to the "Before you begin" section in [the documentation](docs/haskell.rst).
Expand Down
24 changes: 8 additions & 16 deletions haskell/c2hs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ def _c2hs_library_impl(ctx):
)
args = hs.actions.args()
c2hs = ctx.toolchains["@rules_haskell//haskell/c2hs:toolchain"].c2hs
c2hs_exe = ctx.toolchains["@rules_haskell//haskell/c2hs:toolchain"].c2hs_exe

if len(ctx.files.srcs) != 1:
fail("srcs field should contain exactly one file.")
Expand All @@ -44,7 +43,7 @@ def _c2hs_library_impl(ctx):
args.add_all([chs_file.path, "-o", hs_file.path])

args.add("-C-E")
args.add_all(["--cpp", cc.tools.cc])
args.add_all(["--cpp", cc.tools.cc.executable.path])
args.add("-C-includeghcplatform.h")
args.add("-C-includeghcversion.h")
args.add_all(["-C" + x for x in cc.cpp_flags])
Expand All @@ -70,29 +69,24 @@ def _c2hs_library_impl(ctx):
(version_macro_headers, version_macro_flags) = version_macro_includes(dep_info)
args.add_all(["-C" + x for x in version_macro_flags])

(inputs, input_manifests) = ctx.resolve_tools(tools = [c2hs])

hs.actions.run_shell(
inputs = depset(transitive = [
depset(cc.hdrs),
depset([chs_file]),
depset(dep_chi_files),
depset(cc.files),
depset(hs.toolchain.bindir),
depset(hs.toolchain.libdir),
set.to_depset(version_macro_headers),
inputs,
]),
input_manifests = input_manifests,
tools = [hs.tools.ghc_pkg, c2hs_exe],
tools = [hs.tools.ghc_pkg, c2hs, cc.tools.cc.as_tool],
outputs = [hs_file, chi_file],
command =
# cpp (called via c2hs) gets very unhappy if the mingw bin dir is
# not in PATH so we add it to PATH explicitly.
(
"""
export PATH=$PATH:{mingw_bin}
""".format(mingw_bin = paths.dirname(cc.tools.cc)) if hs.toolchain.is_windows else ""
""".format(mingw_bin = paths.dirname(cc.tools.cc.executable.path)) if hs.toolchain.is_windows else ""
) +
"""
# Include libdir in include path just like hsc2hs does.
Expand All @@ -103,7 +97,7 @@ def _c2hs_library_impl(ctx):
{c2hs} "${{include_dirs_args[@]}}" "$@"
""".format(
ghc_pkg = hs.tools.ghc_pkg.path,
c2hs = c2hs_exe.path,
c2hs = c2hs.executable.path,
),
mnemonic = "HaskellC2Hs",
arguments = [args],
Expand Down Expand Up @@ -159,12 +153,10 @@ def _c2hs_toolchain_impl(ctx):
return [
platform_common.ToolchainInfo(
name = ctx.label.name,
# We have both c2hs which points to the target and c2hs_exe
# which points to the file. The former is used to collect
# runfiles while the latter is used to get the path to
# c2hs.
c2hs = ctx.attr.c2hs,
c2hs_exe = ctx.executable.c2hs,
# Get a FilesToRunProvider which can be used to insert all the
# necessary files for the tool into the environment of an action
# run.
c2hs = ctx.attr.c2hs[DefaultInfo].files_to_run,
),
]

Expand Down
51 changes: 18 additions & 33 deletions haskell/cabal.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -125,17 +125,6 @@ main = defaultMain
)
return setup

_CABAL_TOOLS = ["alex", "c2hs", "cpphs", "doctest", "happy"]

def _cabal_tool_flag(tool):
"""Return a --with-PROG=PATH flag if input is a recognized Cabal tool. None otherwise."""
if tool.basename in _CABAL_TOOLS:
return "--with-{}={}".format(tool.basename, tool.path)
return None

def _binary_paths(binaries):
return [binary.dirname for binary in binaries.to_list()]

def _concat(sequences):
return [item for sequence in sequences for item in sequence]

Expand All @@ -161,7 +150,7 @@ def _cabal_toolchain_info(hs, cc, workspace_name, runghc):
hsc2hs = hs.tools.hsc2hs.path,
runghc = runghc.path,
ar = ar,
cc = cc.tools.cc,
cc = cc.tools.cc.executable.path,
ld = cc.tools.ld,
strip = cc.tools.strip,
is_windows = hs.toolchain.is_windows,
Expand All @@ -179,8 +168,6 @@ def _prepare_cabal_inputs(
direct_cc_info,
component,
package_id,
tool_inputs,
tool_input_manifests,
cabal,
setup,
setup_deps,
Expand Down Expand Up @@ -252,7 +239,7 @@ def _prepare_cabal_inputs(
env = dicts.add(hs.env, cc.env)
env["PATH"] = join_path_list(
hs.toolchain.is_windows,
_binary_paths(tool_inputs) + posix.paths + hs.tools_config.path_for_cabal,
posix.paths + hs.tools_config.path_for_cabal,
)
if hs.toolchain.is_darwin:
env["SDKROOT"] = "macosx" # See haskell/private/actions/link.bzl
Expand Down Expand Up @@ -348,7 +335,6 @@ def _prepare_cabal_inputs(
extra_ldflags_file = darwin_flags_for_linking_indirect_cc_deps(hs, cc, posix, hs.name, dynamic = True)

# Redundant with _binary_paths() above, but better be explicit when we can.
path_args.extend([_cabal_tool_flag(tool_flag) for tool_flag in tool_inputs.to_list() if _cabal_tool_flag(tool_flag)])

repo_name = "_main"
if generate_paths_module and label and label.repo_name:
Expand Down Expand Up @@ -389,7 +375,6 @@ def _prepare_cabal_inputs(
input_files,
transitive = [
depset(srcs),
depset(cc.files),
depset(ghc_files),
package_databases,
setup_dep_info.package_databases,
Expand All @@ -402,18 +387,14 @@ def _prepare_cabal_inputs(
setup_dep_info.hs_libraries,
dep_info.interface_dirs,
dep_info.hs_libraries,
tool_inputs,
],
)
input_manifests = tool_input_manifests + hs.toolchain.cc_wrapper.manifests

runfiles_direct = runfiles_libs if static_binary else dynamic_libs

return struct(
cabal_wrapper = cabal_wrapper,
args = args,
inputs = inputs,
input_manifests = input_manifests,
env = env,
runfiles = depset(direct = runfiles_direct),
)
Expand Down Expand Up @@ -575,7 +556,7 @@ def _haskell_cabal_library_impl(ctx):
),
sibling = cabal,
)
(tool_inputs, tool_input_manifests) = ctx.resolve_tools(tools = ctx.attr.tools)
attr_tools = [tool[DefaultInfo].files_to_run for tool in ctx.attr.tools]
c = _prepare_cabal_inputs(
hs,
cc,
Expand All @@ -586,8 +567,6 @@ def _haskell_cabal_library_impl(ctx):
direct_cc_info,
component = "lib:{}".format(ctx.attr.sublibrary_name or ctx.attr.package_name or hs.label.name),
package_id = package_id,
tool_inputs = tool_inputs,
tool_input_manifests = tool_input_manifests,
cabal = cabal,
setup = setup,
setup_deps = setup_deps,
Expand Down Expand Up @@ -620,15 +599,23 @@ def _haskell_cabal_library_impl(ctx):
if with_profiling:
outputs.append(profiling_library)

(_, runghc_manifest) = ctx.resolve_tools(tools = [ctx.attr._runghc])
json_args = ctx.actions.declare_file("{}_cabal_wrapper_args.json".format(ctx.label.name))
ctx.actions.write(json_args, json.encode(c.args))

# Ensure that dependent tools can be found.
paths = []
if "PATH" in c.env:
paths.append(c.env["PATH"])
paths.extend([t.executable.dirname for t in attr_tools])
c.env["PATH"] = ":".join(paths)

ctx.actions.run(
executable = c.cabal_wrapper,
arguments = [json_args.path],
inputs = depset([json_args], transitive = [c.inputs]),
input_manifests = c.input_manifests + runghc_manifest,
tools = [c.cabal_wrapper, ctx.executable._runghc] + hs.tools_config.tools_for_ghc,
tools = attr_tools +
[c.cabal_wrapper, ctx.executable._runghc, hs.toolchain.cc_wrapper.as_tool] +
hs.tools_config.tools_for_ghc,
outputs = outputs,
env = c.env,
mnemonic = "HaskellCabalLibrary",
Expand Down Expand Up @@ -911,7 +898,7 @@ def _haskell_cabal_binary_impl(ctx):
"_install/{}_data".format(hs.label.name),
sibling = cabal,
)
(tool_inputs, tool_input_manifests) = ctx.resolve_tools(tools = ctx.attr.tools)
attr_tools = [tool[DefaultInfo].files_to_run for tool in ctx.attr.tools]
c = _prepare_cabal_inputs(
hs,
cc,
Expand All @@ -922,8 +909,6 @@ def _haskell_cabal_binary_impl(ctx):
direct_cc_info,
component = "exe:{}".format(exe_name),
package_id = hs.label.name,
tool_inputs = tool_inputs,
tool_input_manifests = tool_input_manifests,
cabal = cabal,
setup = setup,
setup_deps = setup_deps,
Expand All @@ -942,20 +927,20 @@ def _haskell_cabal_binary_impl(ctx):
static_binary = static_binary,
label = ctx.label,
)
(_, runghc_manifest) = ctx.resolve_tools(tools = [ctx.attr._runghc])
json_args = ctx.actions.declare_file("{}_cabal_wrapper_args.json".format(ctx.label.name))
ctx.actions.write(json_args, json.encode(c.args))
ctx.actions.run(
executable = c.cabal_wrapper,
arguments = [json_args.path],
inputs = depset([json_args], transitive = [c.inputs]),
input_manifests = c.input_manifests + runghc_manifest,
outputs = [
package_database,
binary,
data_dir,
],
tools = [c.cabal_wrapper, ctx.executable._runghc] + hs.tools_config.tools_for_ghc,
tools = attr_tools +
[c.cabal_wrapper, ctx.executable._runghc, hs.toolchain.cc_wrapper.as_tool] +
hs.tools_config.tools_for_ghc,
env = c.env,
mnemonic = "HaskellCabalBinary",
progress_message = "HaskellCabalBinary {}".format(hs.label),
Expand Down
11 changes: 5 additions & 6 deletions haskell/cc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,10 @@ def cc_interop_info(ctx, override_cc_toolchain = None):
# Generate cc wrapper script on Darwin that adjusts load commands.
hs_toolchain = ctx.toolchains["@rules_haskell//haskell:toolchain"]
cc_wrapper = hs_toolchain.cc_wrapper
cc = cc_wrapper.executable.path
cc_files = depset(transitive = [cc_toolchain.all_files, cc_wrapper.inputs])
cc_manifests = cc_wrapper.manifests

tools = {
"ar": cc_toolchain.ar_executable,
"cc": cc,
"cc": cc_wrapper,
"ld": cc_toolchain.ld_executable,
"cpp": cc_toolchain.preprocessor_executable,
"nm": cc_toolchain.nm_executable,
Expand All @@ -150,8 +147,12 @@ def cc_interop_info(ctx, override_cc_toolchain = None):
env["CC_WRAPPER_PLATFORM"] = "linux"

env["CC_WRAPPER_CC_PATH"] = real_cc_path
env["CC_WRAPPER_PATH"] = cc_wrapper.executable.path
env["CC_WRAPPER_CPU"] = cc_toolchain.cpu

if cc_wrapper.as_tool.runfiles_manifest:
env["CC_WRAPPER_MANIFEST"] = cc_wrapper.as_tool.runfiles_manifest.path

cc_libraries_info = deps_HaskellCcLibrariesInfo(
ctx.attr.deps + getattr(ctx.attr, "plugins", []) + getattr(ctx.attr, "setup_deps", []),
)
Expand All @@ -163,8 +164,6 @@ def cc_interop_info(ctx, override_cc_toolchain = None):
return CcInteropInfo(
tools = struct(**tools),
env = env,
files = cc_files.to_list(),
manifests = cc_manifests,
hdrs = hdrs.to_list(),
cpp_flags = cpp_flags,
include_args = include_args,
Expand Down
4 changes: 2 additions & 2 deletions haskell/doctest.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def _haskell_doctest_single(target, ctx):
ctx,
override_cc_toolchain = hs.tools_config.maybe_exec_cc_toolchain,
)
args.add_all(ghc_cc_program_args(hs, cc.tools.cc, cc.tools.ld))
args.add_all(ghc_cc_program_args(hs, cc.tools.cc.executable.path, cc.tools.ld))

doctest_log = ctx.actions.declare_file(
"doctest-log-" + ctx.label.name + "-" + target.label.name,
Expand Down Expand Up @@ -137,7 +137,6 @@ def _haskell_doctest_single(target, ctx):
depset(get_ghci_library_files(hs, cc_libraries_info, cc.transitive_libraries)),
depset(
toolchain.doctest +
cc.files +
[hs.tools.ghc],
),
]),
Expand Down Expand Up @@ -173,6 +172,7 @@ def _haskell_doctest_single(target, ctx):
# sandboxing altogether for doctest tests.
"no-sandbox": "1",
},
tools = [cc.tools.cc.as_tool],
)
return doctest_log

Expand Down
Loading
Loading