From e7e7995735a3fc9a72ffe359883c369d20c0529c Mon Sep 17 00:00:00 2001 From: Matt Clarkson Date: Wed, 5 Feb 2025 17:32:50 +0000 Subject: [PATCH 01/12] ci: test on MacOS runner --- .gitlab-ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b9d0edff..39b25133 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,10 @@ include: - component: "${CI_SERVER_HOST}/ci/component/bazelisk/ruleset@v1.2.0" inputs: + oses: + - linux + - windows + - macos versions: - 7.4.0 - 7.x -- GitLab From 49b4de9613a9540d4f11c3fef13c813811f975bc Mon Sep 17 00:00:00 2001 From: Matt Clarkson Date: Thu, 6 Feb 2025 16:25:24 +0000 Subject: [PATCH 02/12] ci: default to Linux runner --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 39b25133..955dc756 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -14,3 +14,4 @@ include: default: tags: - arm64 + - linux -- GitLab From 90747dd993141fa5300498a0b993b662087edaf6 Mon Sep 17 00:00:00 2001 From: Matt Clarkson Date: Thu, 6 Feb 2025 16:29:52 +0000 Subject: [PATCH 03/12] fix: bump to `toolchain_utils@1.0.2` for Bash 3.2 support --- .bazelrc | 2 +- MODULE.bazel | 2 +- MODULE.bazel.lock | 10 +++++----- e2e/.bazelrc | 2 +- e2e/MODULE.bazel | 2 +- e2e/MODULE.bazel.lock | 10 +++++----- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.bazelrc b/.bazelrc index 78a0c5f3..2d2d6a42 100644 --- a/.bazelrc +++ b/.bazelrc @@ -1,6 +1,6 @@ # Use pre-release registry. Remove when available in BCR common --registry https://bcr.bazel.build -common --registry=https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.1/downloads +common --registry=https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads common --registry=https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads # Enable hermetic `rules_python` diff --git a/MODULE.bazel b/MODULE.bazel index 6e899cb6..4c7117db 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -7,7 +7,7 @@ module( bazel_dep(name = "bazel_skylib", version = "1.7.1") bazel_dep(name = "platforms", version = "0.0.10") -bazel_dep(name = "toolchain_utils", version = "1.0.1") +bazel_dep(name = "toolchain_utils", version = "1.0.2") bazel_dep(name = "download_utils", version = "1.0.0") bazel_dep(name = "rules_license", version = "1.0.0") bazel_dep(name = "rules_python", version = "1.0.0") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 47ef2062..82979d52 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -135,7 +135,7 @@ "https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7", "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", - "https://bcr.bazel.build/modules/toolchain_utils/1.0.1/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/toolchain_utils/1.0.2/MODULE.bazel": "not found", "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/MODULE.bazel": "af322bc08976524477c79d1e45e241b6efbeb918c497e8840b8ab116802dda79", @@ -144,10 +144,10 @@ "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads/bazel_registry.json": "not found", "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads/modules/download_utils/1.0.0/MODULE.bazel": "d4715447bb11903353fdc2483b7d7b13c9872d39fb8b852c2510665ca6eee22c", "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads/modules/download_utils/1.0.0/source.json": "653b08947e894656b6d515992fd55272cdc9456a1bd26bdfbd4c523acaa21be2", - "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.1/downloads/bazel_registry.json": "not found", - "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.1/downloads/modules/download_utils/1.0.0/MODULE.bazel": "not found", - "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.1/downloads/modules/toolchain_utils/1.0.1/MODULE.bazel": "e490baaaa201408bcb3757f3827f1d9f096fad10af26a12c74897a5550246110", - "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.1/downloads/modules/toolchain_utils/1.0.1/source.json": "afe923f3f5f0b93ba3928ee5150065103418eae05757846595840e5bb9a1a400" + "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/bazel_registry.json": "not found", + "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/modules/download_utils/1.0.0/MODULE.bazel": "not found", + "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/modules/toolchain_utils/1.0.2/MODULE.bazel": "9b8be503a4fcfd3b8b952525bff0869177a5234d5c35dc3e566b9f5ca2f755a1", + "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/modules/toolchain_utils/1.0.2/source.json": "f70c533c9f1c9e27d4f6be8e985dbd2e9ddfe50b59953ff02c38568b3fa16729" }, "selectedYankedVersions": {}, "moduleExtensions": { diff --git a/e2e/.bazelrc b/e2e/.bazelrc index 78a0c5f3..2d2d6a42 100644 --- a/e2e/.bazelrc +++ b/e2e/.bazelrc @@ -1,6 +1,6 @@ # Use pre-release registry. Remove when available in BCR common --registry https://bcr.bazel.build -common --registry=https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.1/downloads +common --registry=https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads common --registry=https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads # Enable hermetic `rules_python` diff --git a/e2e/MODULE.bazel b/e2e/MODULE.bazel index 596aa35d..ecfd0b16 100644 --- a/e2e/MODULE.bazel +++ b/e2e/MODULE.bazel @@ -36,7 +36,7 @@ pip.parse( ) use_repo(pip, pytest = "ape-e2e-pytest") -bazel_dep(name = "toolchain_utils", version = "1.0.1") +bazel_dep(name = "toolchain_utils", version = "1.0.2") bazel_dep(name = "ape", version = "0.0.0") local_path_override( module_name = "ape", diff --git a/e2e/MODULE.bazel.lock b/e2e/MODULE.bazel.lock index 64572707..8116f8be 100644 --- a/e2e/MODULE.bazel.lock +++ b/e2e/MODULE.bazel.lock @@ -152,7 +152,7 @@ "https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7", "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", - "https://bcr.bazel.build/modules/toolchain_utils/1.0.1/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/toolchain_utils/1.0.2/MODULE.bazel": "not found", "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel": "c0df5e35ad55e264160417fd0875932ee3c9dda63d9fccace35ac62f45e1b6f9", "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", @@ -162,10 +162,10 @@ "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads/bazel_registry.json": "not found", "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads/modules/download_utils/1.0.0/MODULE.bazel": "d4715447bb11903353fdc2483b7d7b13c9872d39fb8b852c2510665ca6eee22c", "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads/modules/download_utils/1.0.0/source.json": "653b08947e894656b6d515992fd55272cdc9456a1bd26bdfbd4c523acaa21be2", - "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.1/downloads/bazel_registry.json": "not found", - "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.1/downloads/modules/download_utils/1.0.0/MODULE.bazel": "not found", - "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.1/downloads/modules/toolchain_utils/1.0.1/MODULE.bazel": "e490baaaa201408bcb3757f3827f1d9f096fad10af26a12c74897a5550246110", - "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.1/downloads/modules/toolchain_utils/1.0.1/source.json": "afe923f3f5f0b93ba3928ee5150065103418eae05757846595840e5bb9a1a400" + "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/bazel_registry.json": "not found", + "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/modules/download_utils/1.0.0/MODULE.bazel": "not found", + "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/modules/toolchain_utils/1.0.2/MODULE.bazel": "9b8be503a4fcfd3b8b952525bff0869177a5234d5c35dc3e566b9f5ca2f755a1", + "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/modules/toolchain_utils/1.0.2/source.json": "f70c533c9f1c9e27d4f6be8e985dbd2e9ddfe50b59953ff02c38568b3fa16729" }, "selectedYankedVersions": {}, "moduleExtensions": { -- GitLab From 48aa278682b56045e6bfa3ddcbbd1fde3ec33ea0 Mon Sep 17 00:00:00 2001 From: Matt Clarkson Date: Tue, 11 Feb 2025 15:37:38 +0000 Subject: [PATCH 04/12] fix: watch `zig`/`srcs` in `compile` repository rule Bazel does not invalidate downstream repository rules unless explicitly watched. --- ape/compile/repository.bzl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ape/compile/repository.bzl b/ape/compile/repository.bzl index dc9530ee..a8c3902b 100644 --- a/ape/compile/repository.bzl +++ b/ape/compile/repository.bzl @@ -35,6 +35,10 @@ def implementation(rctx): ] cmd.extend(rctx.attr.srcs) + rctx.watch(rctx.attr.zig) + for src in rctx.attr.srcs: + rctx.watch(src) + result = rctx.execute(cmd) if result.return_code != 0: fail("Failed to compile: {}".format(result.stderr)) -- GitLab From 45d9c1fe2ff27b380a1a2cff5b53deac966cde91 Mon Sep 17 00:00:00 2001 From: Matt Clarkson Date: Thu, 6 Feb 2025 16:35:32 +0000 Subject: [PATCH 05/12] fix: correct MacOS Apple Silicon launcher name --- MODULE.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MODULE.bazel b/MODULE.bazel index 4c7117db..96dd586f 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -68,7 +68,7 @@ compile = use_repo_rule("//ape/compile:repository.bzl", "compile") compile( name = "ape-arm64.macho", srcs = ["@ape-m1.c"], - output = "ape", + output = "binary", zig = "@zig//:entrypoint", ) -- GitLab From e39624186db7b8ee8c7a377a12e6480400158260 Mon Sep 17 00:00:00 2001 From: Matt Clarkson Date: Thu, 6 Feb 2025 16:40:41 +0000 Subject: [PATCH 06/12] refactor: expose `output`/`links` on `compile` repository Helps make `MODULE.bazel` more consistent and explicit --- MODULE.bazel | 8 +++++++- ape/pe/repository.bzl | 15 +++++++++++---- e2e/binary/curl/head.py | 1 + 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 96dd586f..74969ed7 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -74,7 +74,13 @@ compile( pe = use_repo_rule("//ape/pe:repository.bzl", "pe") -pe(name = "ape.pe") +pe( + name = "ape.pe", + links = { + "entrypoint": "binary", + }, + output = "binary", +) select( name = "launcher", diff --git a/ape/pe/repository.bzl b/ape/pe/repository.bzl index 05795ca0..7b7a422e 100644 --- a/ape/pe/repository.bzl +++ b/ape/pe/repository.bzl @@ -8,6 +8,13 @@ The repository is used to make the APE host select consistent. """ ATTRS = { + "output": attr.string( + doc = "The output file to create", + mandatory = True, + ), + "links": attr.string_dict( + doc = 'Creates links in the downloaded repository as `{" < target > ": " < link > "}`. Depending on the platform, either symbolic or hard links are created.', + ), "build": attr.label( doc = "The `BUILD.bazel` template.", allow_single_file = True, @@ -56,12 +63,12 @@ def implementation(rctx): if result.return_code != 0: fail("Failed to compile C# APE: {}".format(result.stdout)) - rctx.symlink("ape.exe", "ape") - rctx.symlink("ape.exe", "binary") - rctx.symlink("ape.exe", "entrypoint") + rctx.symlink("ape.exe", rctx.attr.output) + for target, linkname in rctx.attr.links.items(): + rctx.symlink(linkname, target) rctx.template("BUILD.bazel", rctx.attr.build, { - "{{exports}}": repr(["ape", "binary", "entrypoint"]), + "{{exports}}": repr([rctx.attr.output] + rctx.attr.links.keys()), }) pe = repository_rule( diff --git a/e2e/binary/curl/head.py b/e2e/binary/curl/head.py index 937d8587..cc195b6e 100644 --- a/e2e/binary/curl/head.py +++ b/e2e/binary/curl/head.py @@ -17,6 +17,7 @@ def ping(url: str) -> bool: # FIXME: remove this when the CI image works with Python SSL verification import ssl + context = ssl._create_unverified_context() try: -- GitLab From 1e5219fc15c640adc571546af38b8336c3fb44a8 Mon Sep 17 00:00:00 2001 From: Matt Clarkson Date: Thu, 6 Feb 2025 16:45:50 +0000 Subject: [PATCH 07/12] build: add `links` to `compile` repository Keeps the consistency and explicitness for `MODULE.bazel` --- MODULE.bazel | 3 +++ ape/compile/BUILD.tmpl.bazel | 2 +- ape/compile/repository.bzl | 8 +++++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 74969ed7..c5f04bc2 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -68,6 +68,9 @@ compile = use_repo_rule("//ape/compile:repository.bzl", "compile") compile( name = "ape-arm64.macho", srcs = ["@ape-m1.c"], + links = { + "entrypoint": "binary", + }, output = "binary", zig = "@zig//:entrypoint", ) diff --git a/ape/compile/BUILD.tmpl.bazel b/ape/compile/BUILD.tmpl.bazel index 74f43591..b65b0ad5 100644 --- a/ape/compile/BUILD.tmpl.bazel +++ b/ape/compile/BUILD.tmpl.bazel @@ -1 +1 @@ -exports_files([{{output}}]) +exports_files({{exports}}) diff --git a/ape/compile/repository.bzl b/ape/compile/repository.bzl index a8c3902b..da5b19be 100644 --- a/ape/compile/repository.bzl +++ b/ape/compile/repository.bzl @@ -17,6 +17,9 @@ ATTRS = { doc = "The compiled output file.", mandatory = True, ), + "links": attr.string_dict( + doc = 'Creates links in the downloaded repository as `{" < target > ": " < link > "}`. Depending on the platform, either symbolic or hard links are created.', + ), "zig": attr.label( doc = "The `zig` compiler to use.", allow_single_file = True, @@ -43,8 +46,11 @@ def implementation(rctx): if result.return_code != 0: fail("Failed to compile: {}".format(result.stderr)) + for target, linkname in rctx.attr.links.items(): + rctx.symlink(linkname, target) + rctx.template("BUILD.bazel", rctx.attr.build, { - "{{output}}": repr(rctx.attr.output), + "{{exports}}": repr([rctx.attr.output] + rctx.attr.links.keys()), }) compile = repository_rule( -- GitLab From d247cc5af020d6fc32885c6680e2a32f372cb557 Mon Sep 17 00:00:00 2001 From: Matt Clarkson Date: Thu, 6 Feb 2025 17:33:05 +0000 Subject: [PATCH 08/12] fix: use `zig` target to build APE launcher Removes the need to have the MacOS SDK installed --- MODULE.bazel | 1 + ape/compile/repository.bzl | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/MODULE.bazel b/MODULE.bazel index c5f04bc2..c6192c0c 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -72,6 +72,7 @@ compile( "entrypoint": "binary", }, output = "binary", + target = "{cpu}-macos-none", zig = "@zig//:entrypoint", ) diff --git a/ape/compile/repository.bzl b/ape/compile/repository.bzl index da5b19be..ea8ce19d 100644 --- a/ape/compile/repository.bzl +++ b/ape/compile/repository.bzl @@ -1,3 +1,5 @@ +load("@toolchain_utils//toolchain/triplet:local.bzl", "TRIPLET") + visibility("//ape/...") DOC = """Performs repository time compilation of source files.""" @@ -13,6 +15,10 @@ ATTRS = { allow_files = [".c"], allow_empty = False, ), + "target": attr.string( + doc = "`zig` target triplet to build for. Can use `{cpu}`/`{os}`/`{libc}` replacements", + default = "{cpu}-{os}-{libc}", + ), "output": attr.string( doc = "The compiled output file.", mandatory = True, @@ -30,9 +36,22 @@ ATTRS = { } def implementation(rctx): + map = { + "amd64": "x86_64", + "arm64": "aarch64", + } + + triplet = rctx.attr.target.format( + cpu = map.get(TRIPLET.cpu, TRIPLET.cpu), + os = TRIPLET.os.kind, + libc = TRIPLET.libc.kind, + ) + cmd = [ rctx.attr.zig, "cc", + "-target", + triplet, "-o", rctx.attr.output, ] -- GitLab From bb5c7af3bb6f28f8693602d926803298fefd52c5 Mon Sep 17 00:00:00 2001 From: Matt Clarkson Date: Thu, 6 Feb 2025 22:01:52 +0000 Subject: [PATCH 09/12] test(conftest): add new `env` fixture for passing runfile environment As per the runfiles specification, runfile environment variables should be passed down to subprocesses. --- e2e/binary/__init__.py | 3 ++- e2e/binary/conftest.py | 26 +++++++++++++++++++++++--- e2e/binary/runfile.py | 24 +++++++++++++++++++----- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/e2e/binary/__init__.py b/e2e/binary/__init__.py index 1798572f..0c485f0b 100644 --- a/e2e/binary/__init__.py +++ b/e2e/binary/__init__.py @@ -2,7 +2,8 @@ from __future__ import annotations from binary.difference import Diff from binary.relative import Relative +from binary.runfile import Env from binary.sniff import sniff from binary.tool import Tool -__all__ = ("sniff", "Diff", "Tool", "Relative") +__all__ = ("sniff", "Diff", "Tool", "Relative", "Env") diff --git a/e2e/binary/conftest.py b/e2e/binary/conftest.py index b83c6382..b645b614 100644 --- a/e2e/binary/conftest.py +++ b/e2e/binary/conftest.py @@ -1,17 +1,27 @@ from __future__ import annotations +from os import environ + from pytest import fixture from .difference import repr as diff from .relative import Relative -from .runfile import Runfile, SupportsRlocation, create +from .runfile import ( + Env, + EnvVars, + Runfile, + Runfiles, + SupportsEnvVars, + SupportsRlocation, + create, +) from .tool import Tool -__all__ = ("Relative", "Tool", "Runfile") +__all__ = ("Relative", "Tool", "Runfile", "Env") @fixture -def runfiles() -> SupportsRlocation: +def runfiles() -> Runfiles: return create() @@ -20,6 +30,16 @@ def runfile(runfiles: SupportsRlocation) -> Runfile: return Runfile(runfiles) +@fixture +def env_vars(runfiles: SupportsEnvVars) -> EnvVars: + return runfiles.EnvVars() + + +@fixture +def env(env_vars: EnvVars) -> Env: + return environ | env_vars + + @fixture def tool(runfile: Runfile) -> Tool: return Tool(runfile) diff --git a/e2e/binary/runfile.py b/e2e/binary/runfile.py index 1f6033f0..e25f0284 100644 --- a/e2e/binary/runfile.py +++ b/e2e/binary/runfile.py @@ -1,9 +1,13 @@ from __future__ import annotations +from collections.abc import Mapping from pathlib import Path, PurePath -from typing import Protocol, runtime_checkable +from typing import Protocol, TypeAlias, runtime_checkable -from python.runfiles import Runfiles +from python.runfiles import Runfiles as runfiles + +EnvVars: TypeAlias = Mapping[str, str] +Env: TypeAlias = EnvVars @runtime_checkable @@ -11,13 +15,23 @@ class SupportsRlocation(Protocol): def Rlocation(self, path: str) -> str | None: ... +@runtime_checkable +class SupportsEnvVars(Protocol): + def EnvVars(self) -> EnvVars: ... + + +@runtime_checkable +class Runfiles(SupportsRlocation, SupportsEnvVars, Protocol): + pass + + class RunfilesError(RuntimeError): pass -def create() -> SupportsRlocation: - created = Runfiles.Create() - if not isinstance(created, SupportsRlocation): +def create() -> Runfiles: + created = runfiles.Create() + if not isinstance(created, Runfiles): raise RunfilesError("failed to create runfiles object") return created -- GitLab From c53415d60c45e7dc3ee732817d1abacbb297b0da Mon Sep 17 00:00:00 2001 From: Matt Clarkson Date: Fri, 7 Feb 2025 10:33:21 +0000 Subject: [PATCH 10/12] fix: use indirect symlink on Apple Silicon Makes the execution of the symlink entirely hermetic. Previously, a direct symlink was used which required the APE binary to unpack and compile the embedded APE launcher. This requires a `cc` on the system. This patch shifts to use the already compiled APE launcher and a "indirect" symlink. The [indirect] symlink feature works by having a `.ape` extension to a symlink that points at the APE launcher. The launcher then removes the `.ape` extension and uses that as the path to the binary to launch. The crucial point is that assimilating an APE binary on MacOS is not natively launchable, unlike all other platforms: ```console $ cd /tmp $ curl -sfSL https://cosmo.zip/pub/cosmos/v/4.0.2/bin/assimilate > assimilate $ curl -sfSL https://cosmo.zip/pub/cosmos/v/4.0.2/bin/awk > awk $ chmod +x assimilate $ chmod +x awk $ ./ape # Already compiled from the patched `ape-m1.c` usage: ape PROG [ARGV1,ARGV2,...] ape - PROG [ARGV0,ARGV1,...] PROG.ape [ARGV1,ARGV2,...] actually portable executable loader silicon 1.10 copyrights 2023 justine alexandra roberts tunney https://justine.lol/ape.html $ ./ape ./awk awk version 20240311 $ ./awk xcode-select: note: No developer tools were found, requesting install. If developer tools are located at a non-default location on disk, use `sudo xcode-select --switch path/to/Xcode.app` to specify the Xcode that you wish to use for command line developer tools, and cancel the installation dialog. See `man xcode-select` for more details. $ ./ape ./assimilate -o awk.assimilated awk awk: ape macho dd command for arm64 not found; by convention ape executables are run on apple silicon only as elf binaries, which are loaded by the ape-m1.c ape loader program; thus consider passing the -ae flags to assimilate to arm64 elf (the host os uses macho natively) $ ./ape ./assimilate -ae -o awk.assimilated awk $ chmod +x awk.assimilated $ ./awk.assimilated zsh: exec format error: ./awk.assimilated $ ./ape ./awk.assimilated awk version 20240311 $ ln -s ape awk.ape # indirect symlink $ ./awk.ape awk version 20240311 $ ln -s awk.ape abc # symlink chain (does not work without the patch) awk version 20240311 ``` [indirect]: https://github.com/jart/cosmopolitan/blob/9f6bf6ea71e1385cc34dab0c492773f428d62869/ape/ape-m1.c#L1043-L1055 --- ape/assimilate/rule.bzl | 55 ++++++++++++++++++++++++++++++--------- e2e/binary/tool.py | 11 +++++--- e2e/symlink/test/rule.bzl | 8 ++---- 3 files changed, 51 insertions(+), 23 deletions(-) diff --git a/ape/assimilate/rule.bzl b/ape/assimilate/rule.bzl index 3dd14a47..aea60c8a 100644 --- a/ape/assimilate/rule.bzl +++ b/ape/assimilate/rule.bzl @@ -50,16 +50,12 @@ def implementation(ctx): if ctx.target_platform_has_constraint(windows) and not basename.endswith(".exe"): basename += ".exe" - executable = ctx.actions.declare_file("{}.ape/{}".format(ctx.label.name, basename)) - if ctx.target_platform_has_constraint(windows): - runfiles = _symlink(ctx, executable) + executable, files, runfiles = _direct(ctx, basename) elif ctx.target_platform_has_constraint(macos) and ctx.target_platform_has_constraint(arm64): - runfiles = _symlink(ctx, executable) + executable, files, runfiles = _indirect(ctx, basename) else: - runfiles = _assimilate(ctx, executable) - - files = depset([executable]) + executable, files, runfiles = _assimilate(ctx, basename) return DefaultInfo( executable = executable, @@ -67,7 +63,8 @@ def implementation(ctx): runfiles = runfiles, ) -def _assimilate(ctx, executable): +def _assimilate(ctx, basename): + executable = ctx.actions.declare_file("{}/{}".format(ctx.label.name, basename)) ape = ctx.toolchains["//ape/toolchain/ape:type"] windows = ctx.attr._windows[platform_common.ConstraintValueInfo] @@ -81,9 +78,9 @@ def _assimilate(ctx, executable): # Executable format if ctx.target_platform_has_constraint(windows): - fail("Cannot assimilate on Windows, APE are already PE format. Symlink instead.") + fail("Cannot assimilate on Windows, APE are already PE format. Use direct symlink instead.") elif ctx.target_platform_has_constraint(macos) and ctx.target_platform_has_constraint(arm64): - fail("Cannot assimilate on Apple Silicon, assimilate binaries are not runnable without APE loader. Symlink instead.") + fail("Cannot assimilate on Apple Silicon, assimilate binaries are not runnable without APE loader. Use indirect symlink instead.") elif ctx.target_platform_has_constraint(macos): args.add("-m") # MachO else: @@ -112,19 +109,51 @@ def _assimilate(ctx, executable): toolchain = "//ape/toolchain/ape:type", ) - return ctx.runfiles([executable]) + files = depset([executable]) + runfiles = None + + return executable, files, runfiles + +def _direct(ctx, basename): + executable = ctx.actions.declare_file("{}/{}".format(ctx.label.name, basename)) -def _symlink(ctx, executable): ctx.actions.symlink( output = executable, target_file = ctx.file.src, is_executable = True, ) + files = depset([executable]) runfiles = ctx.runfiles([executable, ctx.file.src]) runfiles.merge(ctx.attr.src.default_runfiles) - return runfiles + return executable, files, runfiles + +def _indirect(ctx, basename): + indirect = ctx.actions.declare_file("{}/{}.ape".format(ctx.label.name, basename)) + ape = ctx.toolchains["//ape/toolchain/ape:type"] + + ctx.actions.symlink( + output = indirect, + target_file = ape.executable, + is_executable = True, + ) + + direct = ctx.actions.declare_file(basename, sibling = indirect) + + ctx.actions.symlink( + output = direct, + target_file = ctx.file.src, + is_executable = True, + ) + + files = depset([indirect, direct]) + + runfiles = ctx.runfiles([indirect, direct, ctx.file.src, ape.executable]) + runfiles.merge(ctx.attr.src.default_runfiles) + runfiles.merge(ape.default.default_runfiles) + + return indirect, files, runfiles ape_assimilate = rule( doc = DOC, diff --git a/e2e/binary/tool.py b/e2e/binary/tool.py index e9af2b7c..ff7fdfa7 100644 --- a/e2e/binary/tool.py +++ b/e2e/binary/tool.py @@ -1,7 +1,7 @@ from __future__ import annotations from pathlib import Path -from sys import platform +from platform import uname from .runfile import Runfile @@ -11,6 +11,9 @@ class Tool: self.__runfile = runfile def __call__(self, name: str) -> Path: - if platform == "win32": - return self.__runfile(f"ape/ape/assimilate/{name}.ape/{name}.exe") - return self.__runfile(f"ape/ape/assimilate/{name}.ape/{name}") + u = uname() + if u.system == "Windows": + return self.__runfile(f"ape/ape/assimilate/{name}/{name}.exe") + if u.system == "Darwin" and u.machine in {"aarch64", "arm64"}: + return self.__runfile(f"ape/ape/assimilate/{name}/{name}.ape") + return self.__runfile(f"ape/ape/assimilate/{name}/{name}") diff --git a/e2e/symlink/test/rule.bzl b/e2e/symlink/test/rule.bzl index 6b0af5e7..34beb889 100644 --- a/e2e/symlink/test/rule.bzl +++ b/e2e/symlink/test/rule.bzl @@ -6,7 +6,6 @@ ATTRS = { "_test": attr.label( executable = True, cfg = "exec", - allow_single_file = True, default = "@ape//ape:true", ), } @@ -16,17 +15,14 @@ def implementation(ctx): ctx.actions.symlink( output = output, - target_file = ctx.file._test, + target_file = ctx.executable._test, is_executable = True, ) - runfiles = ctx.runfiles((ctx.file._test, output)) - runfiles.merge(ctx.attr._test.default_runfiles) - return DefaultInfo( executable = output, files = depset([output]), - runfiles = runfiles, + runfiles = ctx.attr._test.default_runfiles, ) e2e_symlink_test = rule( -- GitLab From e626a39d8b87954e390919b71ce98e072d3742a2 Mon Sep 17 00:00:00 2001 From: Matt Clarkson Date: Tue, 11 Feb 2025 14:01:30 +0000 Subject: [PATCH 11/12] fix: walk symlinks on Apple Silicon We are now using a feature of the APE launcher to use indirect symlinks. This allows the APE launcher to be symlinked with an `.ape` extension. The APE launcher will remove the `.ape` extension and then launch the binary at that path. This works really well under Bazel because it can handle creating the indirect and direct symlink for a APE binary. For example: ``` $ ls -l ape-arm64.macho awk $ ape-arm64.macho awk --version awk version 20240311 $ ln -s ape-arm64.macho awk.ape $ ./awk.ape # APE launcher removes the `.ape` and executes the `awk` APE binary awk version 20240311 ``` However, Bazel requires that a rule _must_ return files that it has declared and created. A common pattern is to simply symlink to a previously generated file and return that through the `DefaultInfo`. This breaks the indirect symlink because the downstream symlink can remove the `.ape` extension. Even if the symlink includes the `.ape` extension, unless it also generates a direct symlink for the APE launcher to find, it will fail to launch. This patches the APE launcher to walk symlink chains back to the final symlink. It adds a new function to the APE launcher binary: `WalkToIndirect`. The function uses two buffers to walk the symlinks until it finds a path that is not a symlink. The previous path _must_ be the indirect symlink. It needs to use an additional buffer to read the linkname. It will return zero if the new path can be stored in the provided buffer. If not, it will return the number of bytes to allocate. We use this functionality to store the path in the same character buffer used by the system provided environment. If there is not enough space, we then allocate on the stack and store it there. An alternative option is to build a launcher binary that uses runfiles to find both the APE launcher and binary. The preference was to avoid this to be resilient against subprocess calls that do not forward on runfiles information. It would also require a programming language that is hermetic, which would likely be `rules_go`. This is a heavy dependency for users just wanting to launch APE binaries on Apple Silicon. We are _already_ requiring the download of a hermetic C toolchain on Apple Silicon so it makes sense to reuse this download to provide the functionality needed for hermetic launching on Apple Silicon. This is an inperfect solution: all other platforms assimilate a single binary that can be launched on the system. Unfortunately, due to the limitations of the APE format on Apple Silicon, the APE launcher always needs to be in the loop as native binaries are assimilated to ELF. The downstream user now needs to be aware that on Apple Silicon, there are runfiles that need to be forwarded which limits the simple message that an `ape_assimilate` generates a native binary that can be launched. If APE learns how to generate launchable binaries on Apple Silicon, we can switch to `_direct` from `_indirect` and drop the `ape-m1.patch`. --- MODULE.bazel | 3 ++ ape-m1.patch | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 ape-m1.patch diff --git a/MODULE.bazel b/MODULE.bazel index c6192c0c..4b5c43af 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -57,6 +57,9 @@ download_file( executable = False, integrity = "sha256-eK954gq7s/malzVZWbWb1YlJVkBkrbdU8DAuurtL96M=", output = "ape-m1.c", + patches = [ + "//:ape-m1.patch", + ], urls = [ "https://gitlab.arm.com/api/v4/projects/bazel%2Fape/packages/generic/cosmos.zip/4.0.2/ape-m1.c", "https://raw.githubusercontent.com/jart/cosmopolitan/4.0.2/ape/ape-m1.c", diff --git a/ape-m1.patch b/ape-m1.patch new file mode 100644 index 00000000..a73435e3 --- /dev/null +++ b/ape-m1.patch @@ -0,0 +1,97 @@ +--- a/ape-m1.c 2025-02-10 16:59:25 ++++ b/ape-m1.c 2025-02-11 13:48:53 +@@ -325,6 +325,66 @@ + return tail - arg0; + } + return 0; ++} ++ ++static ssize_t WalkToIndirect(const char *restrict path, char *restrict const buf, size_t bufsiz) { ++ char linkname[MAXPATHLEN + 1], a[MAXPATHLEN + 1], b[MAXPATHLEN + 1]; ++ size_t s; ++ ssize_t ss; ++ const char *filepath = path; ++ char *p, *buffer = a; ++ a[0] = '\0'; ++ b[0] = '\0'; ++ do { ++ s = readlink(filepath, linkname, sizeof(linkname)); ++ if (s == -1) { ++ if (errno != EINVAL) ++ return -errno; ++ ++ filepath = filepath == a ? b : a; ++ ++ if (filepath[0] == '\0') ++ return 0; ++ ++ s = StrLen(filepath); ++ if (s >= bufsiz) ++ return s + 1; ++ ++ if(strlcpy(buf, filepath, bufsiz) >= bufsiz) ++ return -EOVERFLOW; ++ ++ return 0; ++ } ++ linkname[s] = '\0'; ++ ++ if (linkname[0] == '/') { ++ if (strlcpy(buffer, linkname, sizeof(a)) >= sizeof(a)) ++ return -EOVERFLOW; ++ goto flip; ++ } ++ ++ s = strlcpy(buffer, filepath, sizeof(a)); ++ if (s >= sizeof(a)) ++ return -EOVERFLOW; ++ ++ for (p = &buffer[s]; p != buffer; --p) { ++ if (*p == '/') { ++ *(++p) = '\0'; ++ break; ++ } ++ } ++ ++ if (strlcat(buffer, linkname, sizeof(a)) >= sizeof(a)) ++ return -EOVERFLOW; ++ ++flip: ++ filepath = buffer; ++ buffer = buffer == a ? b : a; ++ } while (true); ++ ++ return -ENOSYS; + } + + static void Perror(const char *thing, long rc, const char *reason) { +@@ -941,7 +997,8 @@ + struct ApeLoader *M; + long *sp, *sp2, *auxv; + union ElfEhdrBuf *ebuf; +- char *p, *pe, *exe, *prog, *execfn; ++ char *p, *pe, *exe, *prog, *execfn, *buffer; ++ ssize_t s; + + /* allocate loader memory in program's arg block */ + n = sizeof(struct ApeLoader); +@@ -1019,6 +1076,19 @@ + execfn = prog; + } + ++ /* walk symlink chain to possible indirect */ ++ if ((s = WalkToIndirect(prog, prog, StrLen(prog) + 1))) { ++ if (s < 0) ++ Pexit(prog, s, "failed to walk symlinks"); ++ ++ buffer = __builtin_alloca(s); ++ ++ if ((s = WalkToIndirect(prog, buffer, s))) ++ Pexit(prog, s, "failed to perform allocated symlink walk"); ++ ++ prog = buffer; ++ } ++ + /* sneak the system five abi back out of args */ + sp = (long *)(argv - 1); + auxv = (long *)(envp + i + 1); -- GitLab From 9957f0283242d332c8b80d3d5ae9693648a33d1e Mon Sep 17 00:00:00 2001 From: Matt Clarkson Date: Wed, 12 Feb 2025 11:08:26 +0000 Subject: [PATCH 12/12] fix: upgrade to `download_utils@1.0.1` Ensures we get `toolchain_utils@1.0.2` across the graph. We are not intending to upstream `toolchain_utils@1.0.1`. --- .bazelrc | 2 +- MODULE.bazel | 2 +- MODULE.bazel.lock | 10 +++++----- e2e/.bazelrc | 2 +- e2e/MODULE.bazel.lock | 10 +++++----- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.bazelrc b/.bazelrc index 2d2d6a42..290ce56f 100644 --- a/.bazelrc +++ b/.bazelrc @@ -1,7 +1,7 @@ # Use pre-release registry. Remove when available in BCR common --registry https://bcr.bazel.build common --registry=https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads -common --registry=https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads +common --registry=https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.1/downloads # Enable hermetic `rules_python` common --@rules_python//python/config_settings:bootstrap_impl=script diff --git a/MODULE.bazel b/MODULE.bazel index 4b5c43af..a9031fc5 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -8,7 +8,7 @@ module( bazel_dep(name = "bazel_skylib", version = "1.7.1") bazel_dep(name = "platforms", version = "0.0.10") bazel_dep(name = "toolchain_utils", version = "1.0.2") -bazel_dep(name = "download_utils", version = "1.0.0") +bazel_dep(name = "download_utils", version = "1.0.1") bazel_dep(name = "rules_license", version = "1.0.0") bazel_dep(name = "rules_python", version = "1.0.0") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 82979d52..3b47ba49 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -35,7 +35,7 @@ "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/source.json": "f121b43eeefc7c29efbd51b83d08631e2347297c95aac9764a701f2a6a2bb953", "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84", "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8", - "https://bcr.bazel.build/modules/download_utils/1.0.0/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/download_utils/1.0.1/MODULE.bazel": "not found", "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", @@ -141,11 +141,11 @@ "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/MODULE.bazel": "af322bc08976524477c79d1e45e241b6efbeb918c497e8840b8ab116802dda79", "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/source.json": "2be409ac3c7601245958cd4fcdff4288be79ed23bd690b4b951f500d54ee6e7d", "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198", - "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads/bazel_registry.json": "not found", - "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads/modules/download_utils/1.0.0/MODULE.bazel": "d4715447bb11903353fdc2483b7d7b13c9872d39fb8b852c2510665ca6eee22c", - "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads/modules/download_utils/1.0.0/source.json": "653b08947e894656b6d515992fd55272cdc9456a1bd26bdfbd4c523acaa21be2", + "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.1/downloads/bazel_registry.json": "not found", + "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.1/downloads/modules/download_utils/1.0.1/MODULE.bazel": "f1d0afade59e37de978506d6bbf08d7fe5f94964e86944aaf58efcead827b41b", + "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.1/downloads/modules/download_utils/1.0.1/source.json": "9f871ab1f82c8867c19e0224dc411288ababb578fe5c67d7e4a54fb6968d6ba1", "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/bazel_registry.json": "not found", - "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/modules/download_utils/1.0.0/MODULE.bazel": "not found", + "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/modules/download_utils/1.0.1/MODULE.bazel": "not found", "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/modules/toolchain_utils/1.0.2/MODULE.bazel": "9b8be503a4fcfd3b8b952525bff0869177a5234d5c35dc3e566b9f5ca2f755a1", "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/modules/toolchain_utils/1.0.2/source.json": "f70c533c9f1c9e27d4f6be8e985dbd2e9ddfe50b59953ff02c38568b3fa16729" }, diff --git a/e2e/.bazelrc b/e2e/.bazelrc index 2d2d6a42..290ce56f 100644 --- a/e2e/.bazelrc +++ b/e2e/.bazelrc @@ -1,7 +1,7 @@ # Use pre-release registry. Remove when available in BCR common --registry https://bcr.bazel.build common --registry=https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads -common --registry=https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads +common --registry=https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.1/downloads # Enable hermetic `rules_python` common --@rules_python//python/config_settings:bootstrap_impl=script diff --git a/e2e/MODULE.bazel.lock b/e2e/MODULE.bazel.lock index 8116f8be..5308d037 100644 --- a/e2e/MODULE.bazel.lock +++ b/e2e/MODULE.bazel.lock @@ -40,7 +40,7 @@ "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8", "https://bcr.bazel.build/modules/caseyduquettesc_rules_python_pytest/1.1.1/MODULE.bazel": "6e5383ad5f0b4a28829f811683a3dd64a655209b9f6620a0fe68cd6321b7e174", "https://bcr.bazel.build/modules/caseyduquettesc_rules_python_pytest/1.1.1/source.json": "cfa8011e462d3f3eb42ea1ce6aa7f945b944d0499ffd6747789cd87dc64fe015", - "https://bcr.bazel.build/modules/download_utils/1.0.0/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/download_utils/1.0.1/MODULE.bazel": "not found", "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", @@ -159,11 +159,11 @@ "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/MODULE.bazel": "af322bc08976524477c79d1e45e241b6efbeb918c497e8840b8ab116802dda79", "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/source.json": "2be409ac3c7601245958cd4fcdff4288be79ed23bd690b4b951f500d54ee6e7d", "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198", - "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads/bazel_registry.json": "not found", - "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads/modules/download_utils/1.0.0/MODULE.bazel": "d4715447bb11903353fdc2483b7d7b13c9872d39fb8b852c2510665ca6eee22c", - "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads/modules/download_utils/1.0.0/source.json": "653b08947e894656b6d515992fd55272cdc9456a1bd26bdfbd4c523acaa21be2", + "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.1/downloads/bazel_registry.json": "not found", + "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.1/downloads/modules/download_utils/1.0.1/MODULE.bazel": "f1d0afade59e37de978506d6bbf08d7fe5f94964e86944aaf58efcead827b41b", + "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.1/downloads/modules/download_utils/1.0.1/source.json": "9f871ab1f82c8867c19e0224dc411288ababb578fe5c67d7e4a54fb6968d6ba1", "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/bazel_registry.json": "not found", - "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/modules/download_utils/1.0.0/MODULE.bazel": "not found", + "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/modules/download_utils/1.0.1/MODULE.bazel": "not found", "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/modules/toolchain_utils/1.0.2/MODULE.bazel": "9b8be503a4fcfd3b8b952525bff0869177a5234d5c35dc3e566b9f5ca2f755a1", "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/modules/toolchain_utils/1.0.2/source.json": "f70c533c9f1c9e27d4f6be8e985dbd2e9ddfe50b59953ff02c38568b3fa16729" }, -- GitLab