diff --git a/debian/amd64/qemu-system-arm/BUILD.bazel b/debian/amd64/qemu-system-arm/BUILD.bazel index 0a7d8329b47923760377c99a4fd7453c06a69111..184f32df623652d6bc4daa8e6efd51f68af09180 100644 --- a/debian/amd64/qemu-system-arm/BUILD.bazel +++ b/debian/amd64/qemu-system-arm/BUILD.bazel @@ -10,11 +10,17 @@ debian_patchelf( debian_launcher( name = "qemu-system-arm", src = ":patched", + env = { + "TMPDIR": "./tmp", + }, visibility = ["//:__subpackages__"], ) debian_launcher( name = "qemu-system-aarch64", src = ":patched", + env = { + "TMPDIR": "./tmp", + }, visibility = ["//:__subpackages__"], ) diff --git a/debian/amd64/qemu-system-x86/BUILD.bazel b/debian/amd64/qemu-system-x86/BUILD.bazel index 928b882e4629e01ce2eaeccbddce486e4c5282f0..1fda05ff45340c8fef34cea6127567da0e1dd925 100644 --- a/debian/amd64/qemu-system-x86/BUILD.bazel +++ b/debian/amd64/qemu-system-x86/BUILD.bazel @@ -10,11 +10,17 @@ debian_patchelf( debian_launcher( name = "qemu-system-i386", src = ":patched", + env = { + "TMPDIR": "./tmp", + }, visibility = ["//:__subpackages__"], ) debian_launcher( name = "qemu-system-x86_64", src = ":patched", + env = { + "TMPDIR": "./tmp", + }, visibility = ["//:__subpackages__"], ) diff --git a/debian/arm64/qemu-system-arm/BUILD.bazel b/debian/arm64/qemu-system-arm/BUILD.bazel index 0a7d8329b47923760377c99a4fd7453c06a69111..184f32df623652d6bc4daa8e6efd51f68af09180 100644 --- a/debian/arm64/qemu-system-arm/BUILD.bazel +++ b/debian/arm64/qemu-system-arm/BUILD.bazel @@ -10,11 +10,17 @@ debian_patchelf( debian_launcher( name = "qemu-system-arm", src = ":patched", + env = { + "TMPDIR": "./tmp", + }, visibility = ["//:__subpackages__"], ) debian_launcher( name = "qemu-system-aarch64", src = ":patched", + env = { + "TMPDIR": "./tmp", + }, visibility = ["//:__subpackages__"], ) diff --git a/debian/arm64/qemu-system-x86/BUILD.bazel b/debian/arm64/qemu-system-x86/BUILD.bazel index 928b882e4629e01ce2eaeccbddce486e4c5282f0..1fda05ff45340c8fef34cea6127567da0e1dd925 100644 --- a/debian/arm64/qemu-system-x86/BUILD.bazel +++ b/debian/arm64/qemu-system-x86/BUILD.bazel @@ -10,11 +10,17 @@ debian_patchelf( debian_launcher( name = "qemu-system-i386", src = ":patched", + env = { + "TMPDIR": "./tmp", + }, visibility = ["//:__subpackages__"], ) debian_launcher( name = "qemu-system-x86_64", src = ":patched", + env = { + "TMPDIR": "./tmp", + }, visibility = ["//:__subpackages__"], ) diff --git a/debian/launcher/launch.py b/debian/launcher/launch.py index 9011b781e469fa515632046c4073c43dc2950fab..6aa5b7d4cd495ce164b807ad03798243e94f6ce3 100644 --- a/debian/launcher/launch.py +++ b/debian/launcher/launch.py @@ -26,6 +26,17 @@ def runfile(path: Path) -> Path: return resolved +def resolve(value: str) -> str: + runfiles = Runfiles.Create() + try: + resolved = runfiles.Rlocation(value) + except ValueError: + return value + if not Path(resolved).exists(): + return value + return resolved + + def quoted(value: str) -> str: return value.removeprefix("'").removesuffix("'") @@ -60,6 +71,14 @@ def arguments(prsr: ArgumentParser) -> None: help="The root of the unpacked Debian archives.", type=runfile, ) + prsr.add_argument( + "--env", + action="append", + metavar=("NAME", "VALUE"), + nargs=2, + help="A environment variable pairing to enforce into the subprocess.", + default=[], + ) prsr.add_argument( "executable", metavar="EXECUTABLE", @@ -88,14 +107,26 @@ def execute( tmp.symlink_to(interpreter) move(tmp, symlink) + try: + tmpdir = env["TMPDIR"] + except KeyError: + pass + else: + Path(tmpdir).mkdir(parents=True, exist_ok=True) + assert executable.exists() cmd = (f"{executable}", *arguments) process = run(cmd, env=env) return process.returncode +class BazelArgumentParser(ArgumentParser): + def convert_arg_line_to_args(self, line): + return (line.removeprefix("'").removesuffix("'"),) + + def main(exe: Path, *args: str) -> int: - prsr = ArgumentParser( + prsr = BazelArgumentParser( prog=str(exe), description="Launches a Debian ELF interpreter patched executable.", fromfile_prefix_chars="@", @@ -119,7 +150,8 @@ def main(exe: Path, *args: str) -> int: interpreter=parsed.root / parsed.interpreter, symlink=parsed.symlink, env=environ - | {"LD_LIBRARY_PATH": parsed.llp.removeprefix("'").removesuffix("'")}, + | {k: resolve(v) for k, v in parsed.env} + | {"LD_LIBRARY_PATH": parsed.llp}, ) except CalledProcessError as e: return e.returncode diff --git a/debian/launcher/rule.bzl b/debian/launcher/rule.bzl index ad0612411466d35bbe195c9547cd825cf8473e17..b84f50260b80d594ca02c8d5b9f4182c0e0e938b 100644 --- a/debian/launcher/rule.bzl +++ b/debian/launcher/rule.bzl @@ -47,6 +47,10 @@ def _runfile(label, file): return path.removeprefix("../") return "{}/{}".format(label.workspace_name or "_main", path) +def _env(pair): + key, value = pair + return ["--env", key, value] + def implementation(ctx): if not ctx.file.src.is_directory: fail("`src` must be a directory") @@ -64,6 +68,8 @@ def implementation(ctx): args.add("--interpreter", interpreter) args.add("--symlink", symlink) args.add("--root", _runfile(ctx.attr.src.label, ctx.file.src)) + args.add_all(ctx.attr.env.items(), map_each = _env) + args.add("--") args.add(relative) ctx.actions.write(output = arguments, content = args) @@ -82,7 +88,10 @@ def implementation(ctx): runfiles = runfiles.merge(ctx.attr.src.default_runfiles) runfiles = runfiles.merge_all([d.default_runfiles for d in ctx.attr.data]) - return DefaultInfo(executable = executable, files = files, runfiles = runfiles) + default = DefaultInfo(executable = executable, files = files, runfiles = runfiles) + env = RunEnvironmentInfo(environment = ctx.attr.env) + + return default, env debian_launcher = rule( doc = DOC,