diff --git a/haskell/cabal.bzl b/haskell/cabal.bzl index a03a6d21bf..cb19759b96 100644 --- a/haskell/cabal.bzl +++ b/haskell/cabal.bzl @@ -531,7 +531,7 @@ def _haskell_cabal_library_impl(ctx): arguments = [json_args.path], inputs = depset([json_args], transitive = [c.inputs]), input_manifests = c.input_manifests, - tools = [c.cabal_wrapper], + tools = [c.cabal_wrapper, ctx.executable._runghc], outputs = outputs, env = c.env, mnemonic = "HaskellCabalLibrary", @@ -814,7 +814,7 @@ def _haskell_cabal_binary_impl(ctx): binary, data_dir, ], - tools = [c.cabal_wrapper], + tools = [c.cabal_wrapper, ctx.executable._runghc], env = c.env, mnemonic = "HaskellCabalBinary", progress_message = "HaskellCabalBinary {}".format(hs.label), diff --git a/haskell/private/runghc.bzl b/haskell/private/runghc.bzl index 1cb21b2ea8..dcd4fe9939 100644 --- a/haskell/private/runghc.bzl +++ b/haskell/private/runghc.bzl @@ -7,32 +7,60 @@ load("@bazel_skylib//lib:paths.bzl", "paths") # platform. In order to achieve this, we provide a runghc of a # toolchain targeting the execution platform. # -# Producing runghc with a custom rule, as defined here, allows to use -# it in rules which are using a Haskell toolchain for the target -# platform. +# Producing a runghc wrapper with a custom rule, as defined here, +# allows to use it in rules which are using a Haskell toolchain for +# the target platform. # -def _runghc_impl(ctx): +def _runghc_wrapper_impl(ctx): hs_toolchain = ctx.toolchains["@rules_haskell//haskell:toolchain"] - (_, extension) = paths.split_extension(hs_toolchain.tools.runghc.path) - runghc_file = ctx.actions.declare_file(ctx.label.name + extension) - ctx.actions.symlink( - output = runghc_file, - target_file = hs_toolchain.tools.runghc, + f = hs_toolchain.tools.runghc + runghc_runfile_path = paths.join(f.owner.workspace_name, f.owner.package, f.owner.name) + runghc_wrapper_file = ctx.actions.declare_file(ctx.label.name) + ctx.actions.write( + output = runghc_wrapper_file, + content = """\ +#!/usr/bin/env bash + +# --- begin runfiles.bash initialization v2 --- +# Copy-pasted from the Bazel Bash runfiles library v2. +set -uo pipefail; f=bazel_tools/tools/bash/runfiles/runfiles.bash +source "${{RUNFILES_DIR:-/dev/null}}/$f" 2>/dev/null || \ +source "$(grep -sm1 "^$f " "${{RUNFILES_MANIFEST_FILE:-/dev/null}}" | cut -f2- -d' ')" 2>/dev/null || \ +source "$0.runfiles/$f" 2>/dev/null || \ +source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ +source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ +{{ echo>&2 "ERROR: cannot find $f"; exit 1; }}; f=; set -e +# --- end runfiles.bash initialization v2 --- + +$(rlocation "{runghc}") "$@" +""".format(runghc = runghc_runfile_path), is_executable = True, ) return [DefaultInfo( - executable = runghc_file, + executable = runghc_wrapper_file, runfiles = hs_toolchain.cc_wrapper.runfiles.merge( - ctx.runfiles(files = [runghc_file, hs_toolchain.tools.runghc]), + ctx.runfiles(files = [runghc_wrapper_file, hs_toolchain.tools.runghc]), ), )] -runghc = rule( +_runghc_wrapper = rule( executable = True, - implementation = _runghc_impl, + implementation = _runghc_wrapper_impl, toolchains = ["@rules_haskell//haskell:toolchain"], - doc = """Produces the runghc program.""", + doc = """Produces the runghc wrapper script.""", ) + +def runghc(name, visibility): + _runghc_wrapper(name = name + ".sh") + native.sh_binary( + name = name, + srcs = [name + ".sh"], + data = [name + ".sh"], + deps = [ + "@bazel_tools//tools/bash/runfiles", + ], + visibility = visibility, + )