From 16b98a065944372b3c1ccae04ae7991fd34bf145 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Wed, 3 Apr 2024 08:23:00 +0200 Subject: [PATCH 01/10] Configure Zig cache directory from environment The `zig_repositories` repository rule inspects the environment and configures the Zig cache directory based on it and the toolchain's execution platform. --- zig/repositories.bzl | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/zig/repositories.bzl b/zig/repositories.bzl index 32ffff98..17665c53 100644 --- a/zig/repositories.bzl +++ b/zig/repositories.bzl @@ -47,6 +47,35 @@ _ATTRS = { "platform": attr.string(mandatory = True, values = PLATFORMS.keys()), } +_VAR_CACHE_PREFIX = "RULES_ZIG_CACHE_PREFIX" +_VAR_CACHE_PREFIX_LINUX = "RULES_ZIG_CACHE_PREFIX_LINUX" +_VAR_CACHE_PREFIX_MACOS = "RULES_ZIG_CACHE_PREFIX_MACOS" +_VAR_CACHE_PREFIX_WINDOWS = "RULES_ZIG_CACHE_PREFIX_WINDOWS" + +_ENV = [ + _VAR_CACHE_PREFIX, + _VAR_CACHE_PREFIX_LINUX, + _VAR_CACHE_PREFIX_MACOS, + _VAR_CACHE_PREFIX_WINDOWS, +] + +_DEFAULT_CACHE_PREFIX = "/tmp/zig-cache" +_DEFAULT_CACHE_PREFIX_LINUX = "/tmp/zig-cache" +_DEFAULT_CACHE_PREFIX_MACOS = "/var/tmp/zig-cache" +_DEFAULT_CACHE_PREFIX_WINDOWS = "C:\\Temp\\zig-cache" + +def _env_zig_cache_prefix(environ, platform): + if platform.find("linux") != -1: + cache_prefix = environ.get(_VAR_CACHE_PREFIX_LINUX, environ.get(_VAR_CACHE_PREFIX, _DEFAULT_CACHE_PREFIX_LINUX)) + elif platform.find("macos") != -1: + cache_prefix = environ.get(_VAR_CACHE_PREFIX_MACOS, environ.get(_VAR_CACHE_PREFIX, _DEFAULT_CACHE_PREFIX_MACOS)) + elif platform.find("windows") != -1: + cache_prefix = environ.get(_VAR_CACHE_PREFIX_WINDOWS, environ.get(_VAR_CACHE_PREFIX, _DEFAULT_CACHE_PREFIX_WINDOWS)) + else: + cache_prefix = environ.get(_VAR_CACHE_PREFIX, _DEFAULT_CACHE_PREFIX) + + return cache_prefix + def _zig_repo_impl(repository_ctx): url = TOOL_VERSIONS[repository_ctx.attr.zig_version][repository_ctx.attr.platform].url integrity = TOOL_VERSIONS[repository_ctx.attr.zig_version][repository_ctx.attr.platform].integrity @@ -63,6 +92,8 @@ def _zig_repo_impl(repository_ctx): stripPrefix = prefix, ) + cache_prefix = _env_zig_cache_prefix(repository_ctx.os.environ, repository_ctx.attr.platform) + build_content = """#Generated by zig/repositories.bzl load("@rules_zig//zig:toolchain.bzl", "zig_toolchain") zig_toolchain( @@ -74,9 +105,11 @@ zig_toolchain( zig_lib = glob(["lib/**"]), zig_lib_path = "lib", zig_version = "{zig_version}", + zig_cache = {zig_cache}, ) """.format( zig_version = repository_ctx.attr.zig_version, + zig_cache = repr(cache_prefix), ) # Base BUILD file for this repository @@ -86,6 +119,7 @@ zig_repositories = repository_rule( _zig_repo_impl, doc = _DOC, attrs = _ATTRS, + environ = _ENV, ) # Wrapper macro around everything above, this is the primary API From eb4a4dd432ff62ac855e9570102f5931096d9aea Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Wed, 3 Apr 2024 08:28:27 +0200 Subject: [PATCH 02/10] Track Zig cache directory in toolchain info --- zig/private/providers/zig_toolchain_info.bzl | 1 + zig/private/zig_toolchain.bzl | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/zig/private/providers/zig_toolchain_info.bzl b/zig/private/providers/zig_toolchain_info.bzl index 45c24c6d..e8ff84ae 100644 --- a/zig/private/providers/zig_toolchain_info.bzl +++ b/zig/private/providers/zig_toolchain_info.bzl @@ -13,6 +13,7 @@ Files required in runfiles to make the Zig executable available. May be empty if the zig_exe_path points to a locally installed Zig executable. """, "zig_version": "String, The Zig toolchain's version.", + "zig_cache": "String, The Zig cache directory prefix used for the global and local cache.", } ZigToolchainInfo = provider( diff --git a/zig/private/zig_toolchain.bzl b/zig/private/zig_toolchain.bzl index 3e0905fb..ffc016d9 100644 --- a/zig/private/zig_toolchain.bzl +++ b/zig/private/zig_toolchain.bzl @@ -51,6 +51,10 @@ ATTRS = { doc = "The Zig toolchain's version.", mandatory = True, ), + "zig_cache": attr.string( + doc = "The Zig cache directory prefix. Used for both the global and local cache.", + mandatory = True, + ), } # Avoid using non-normalized paths (workspace/../other_workspace/path) @@ -101,6 +105,7 @@ def _zig_toolchain_impl(ctx): zig_exe_path = ctx.attr.zig_exe_path zig_lib_path = ctx.attr.zig_lib_path zig_version = ctx.attr.zig_version + zig_cache = ctx.attr.zig_cache if ctx.attr.zig_exe: zig_files = ctx.attr.zig_exe.files.to_list() + ctx.files.zig_lib @@ -135,6 +140,7 @@ def _zig_toolchain_impl(ctx): zig_lib_path = zig_lib_path, zig_files = zig_files, zig_version = zig_version, + zig_cache = zig_cache, ) # Export all the providers inside our ToolchainInfo From 1ba4f46d180ec33d235056a039d9bb89dcdda298 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Wed, 3 Apr 2024 08:34:43 +0200 Subject: [PATCH 03/10] Configure Zig cache command line options --- zig/private/common/zig_build.bzl | 4 +--- zig/private/common/zig_cache.bzl | 24 ++++++------------------ zig/private/common/zig_docs.bzl | 4 +--- 3 files changed, 8 insertions(+), 24 deletions(-) diff --git a/zig/private/common/zig_build.bzl b/zig/private/common/zig_build.bzl index cb221b4f..e56fd009 100644 --- a/zig/private/common/zig_build.bzl +++ b/zig/private/common/zig_build.bzl @@ -251,9 +251,7 @@ def zig_build_impl(ctx, *, kind): ) zig_cache_output( - actions = ctx.actions, - name = ctx.label.name, - outputs = outputs, + zigtoolchaininfo = zigtoolchaininfo, args = args, ) diff --git a/zig/private/common/zig_cache.bzl b/zig/private/common/zig_cache.bzl index 44cbdced..8e7d2b9e 100644 --- a/zig/private/common/zig_cache.bzl +++ b/zig/private/common/zig_cache.bzl @@ -1,26 +1,14 @@ """Defines utilities to handle the Zig compiler cache.""" -load("@bazel_skylib//lib:paths.bzl", "paths") - -def zig_cache_output(*, actions, name, outputs, args): +def zig_cache_output(*, zigtoolchaininfo, args): """Handle the Zig compiler cache. - Declares directory outputs for the local and global Zig compiler cache. - Appends both to the given outputs list, and arguments object. + Configures the local and global cache based on the given cache prefix path. + The cache is not a Bazel managed input or output of the build action. Args: - actions: `ctx.actions`. - name: String, A unique name to distinguish this cache from others. - outputs: List; mutable, Append the declared outputs to this list. + zigtoolchaininfo: ZigToolchainInfo. args: Args; mutable, Append the Zig cache flags to this object. """ - - # TODO[AH] Persist or share at least the global cache somehow. - local_cache = actions.declare_directory(paths.join(".zig-cache", "local", name)) - global_cache = actions.declare_directory(paths.join(".zig-cache", "global", name)) - - outputs.append(local_cache) - outputs.append(global_cache) - - args.add_all(["--cache-dir", local_cache.path]) - args.add_all(["--global-cache-dir", global_cache.path]) + args.add_all(["--cache-dir", zigtoolchaininfo.zig_cache]) + args.add_all(["--global-cache-dir", zigtoolchaininfo.zig_cache]) diff --git a/zig/private/common/zig_docs.bzl b/zig/private/common/zig_docs.bzl index 45e909fd..d39d5753 100644 --- a/zig/private/common/zig_docs.bzl +++ b/zig/private/common/zig_docs.bzl @@ -114,9 +114,7 @@ def zig_docs_impl(ctx, *, kind): ) zig_cache_output( - actions = ctx.actions, - name = ctx.label.name + "-docs", - outputs = outputs, + zigtoolchaininfo = zigtoolchaininfo, args = args, ) From 931da1e32197a6d74e521232e9b80be154aeeb60 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Wed, 3 Apr 2024 08:45:21 +0200 Subject: [PATCH 04/10] Configure sandbox mount path for Zig cache --- .bazelrc.common | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.bazelrc.common b/.bazelrc.common index 118f1b3b..3fa351d2 100644 --- a/.bazelrc.common +++ b/.bazelrc.common @@ -30,3 +30,13 @@ test --test_output=errors test --test_verbose_timeout_warnings # docs: https://bazel.build/reference/command-line-reference#flag--incompatible_exclusive_test_sandboxed test --incompatible_exclusive_test_sandboxed + +# docs: https://bazel.build/reference/command-line-reference#flag--enable_platform_specific_config +common --enable_platform_specific_config +# Enable persistent Zig cache directory within the sandbox, +# see https://github.com/aherrmann/rules_zig/issues/87, +# and https://github.com/uber/hermetic_cc_toolchain/issues/83. +# docs: https://bazel.build/reference/command-line-reference#flag--sandbox_add_mount_pair +build:linux --sandbox_add_mount_pair=/tmp +build:macos --sandbox_add_mount_pair=/var/tmp +build:windows --sandbox_add_mount_pair=C:\Temp From 2c4da5e1ff9799899a8a56419e4fd534ca467aaa Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Wed, 3 Apr 2024 08:53:37 +0200 Subject: [PATCH 05/10] update generated files --- docs/repositories.md | 8 ++++++++ docs/toolchains.md | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/repositories.md b/docs/repositories.md index 01c429bf..abaaa03e 100644 --- a/docs/repositories.md +++ b/docs/repositories.md @@ -66,4 +66,12 @@ Fetch and install a Zig toolchain. | repo_mapping | In `WORKSPACE` context only: a dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository.

For example, an entry `"@foo": "@bar"` declares that, for any time this repository depends on `@foo` (such as a dependency on `@foo//some:target`, it should actually resolve that dependency within globally-declared `@bar` (`@bar//some:target`).

This attribute is _not_ supported in `MODULE.bazel` context (when invoking a repository rule inside a module extension's implementation function). | Dictionary: String -> String | optional | | | zig_version | - | String | required | | +**ENVIRONMENT VARIABLES** + +This repository rule depends on the following environment variables: +* `RULES_ZIG_CACHE_PREFIX` +* `RULES_ZIG_CACHE_PREFIX_LINUX` +* `RULES_ZIG_CACHE_PREFIX_MACOS` +* `RULES_ZIG_CACHE_PREFIX_WINDOWS` + diff --git a/docs/toolchains.md b/docs/toolchains.md index 447d3eaf..e3113175 100644 --- a/docs/toolchains.md +++ b/docs/toolchains.md @@ -65,7 +65,7 @@ toolchain( ## zig_toolchain
-zig_toolchain(name, zig_exe, zig_exe_path, zig_lib, zig_lib_path, zig_version)
+zig_toolchain(name, zig_cache, zig_exe, zig_exe_path, zig_lib, zig_lib_path, zig_version)
 
Defines a Zig compiler toolchain. @@ -97,6 +97,7 @@ See https://bazel.build/extending/toolchains#defining-toolchains. | Name | Description | Type | Mandatory | Default | | :------------- | :------------- | :------------- | :------------- | :------------- | | name | A unique name for this target. | Name | required | | +| zig_cache | The Zig cache directory prefix. Used for both the global and local cache. | String | required | | | zig_exe | A hermetically downloaded Zig executable for the target platform. | Label | optional | `None` | | zig_exe_path | Path to an existing Zig executable for the target platform. | String | optional | `""` | | zig_lib | Files of a hermetically downloaded Zig library for the target platform. | List of labels | optional | `[]` | From bd1b9652a9a187828ad8db76433167ebe8ad177f Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 4 Apr 2024 08:02:06 +0200 Subject: [PATCH 06/10] Move env_zig_cache_prefix into zig_cache.bzl --- zig/BUILD.bazel | 1 + zig/private/common/zig_cache.bzl | 31 ++++++++++++++++++++++++ zig/repositories.bzl | 41 ++++++++++---------------------- 3 files changed, 45 insertions(+), 28 deletions(-) diff --git a/zig/BUILD.bazel b/zig/BUILD.bazel index 75952d0b..25487e73 100644 --- a/zig/BUILD.bazel +++ b/zig/BUILD.bazel @@ -43,6 +43,7 @@ bzl_library( ":bazel_tools", "//zig/private:toolchains_repo", "//zig/private:versions", + "//zig/private/common:zig_cache", ], ) diff --git a/zig/private/common/zig_cache.bzl b/zig/private/common/zig_cache.bzl index 8e7d2b9e..526884f6 100644 --- a/zig/private/common/zig_cache.bzl +++ b/zig/private/common/zig_cache.bzl @@ -1,5 +1,36 @@ """Defines utilities to handle the Zig compiler cache.""" +VAR_CACHE_PREFIX = "RULES_ZIG_CACHE_PREFIX" +VAR_CACHE_PREFIX_LINUX = "RULES_ZIG_CACHE_PREFIX_LINUX" +VAR_CACHE_PREFIX_MACOS = "RULES_ZIG_CACHE_PREFIX_MACOS" +VAR_CACHE_PREFIX_WINDOWS = "RULES_ZIG_CACHE_PREFIX_WINDOWS" + +DEFAULT_CACHE_PREFIX = "/tmp/zig-cache" +DEFAULT_CACHE_PREFIX_LINUX = "/tmp/zig-cache" +DEFAULT_CACHE_PREFIX_MACOS = "/var/tmp/zig-cache" +DEFAULT_CACHE_PREFIX_WINDOWS = "C:\\Temp\\zig-cache" + +def env_zig_cache_prefix(environ, platform): + """Determine the appropriate Zig cache prefix for the given platform. + + Args: + environ: dict, The environment variables. + platform: string, The name of the toolchain execution platform. + + Returns: + The Zig cache prefix path. + """ + if platform.find("linux") != -1: + cache_prefix = environ.get(VAR_CACHE_PREFIX_LINUX, environ.get(VAR_CACHE_PREFIX, DEFAULT_CACHE_PREFIX_LINUX)) + elif platform.find("macos") != -1: + cache_prefix = environ.get(VAR_CACHE_PREFIX_MACOS, environ.get(VAR_CACHE_PREFIX, DEFAULT_CACHE_PREFIX_MACOS)) + elif platform.find("windows") != -1: + cache_prefix = environ.get(VAR_CACHE_PREFIX_WINDOWS, environ.get(VAR_CACHE_PREFIX, DEFAULT_CACHE_PREFIX_WINDOWS)) + else: + cache_prefix = environ.get(VAR_CACHE_PREFIX, DEFAULT_CACHE_PREFIX) + + return cache_prefix + def zig_cache_output(*, zigtoolchaininfo, args): """Handle the Zig compiler cache. diff --git a/zig/repositories.bzl b/zig/repositories.bzl index 17665c53..d3f0f817 100644 --- a/zig/repositories.bzl +++ b/zig/repositories.bzl @@ -8,6 +8,14 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", __http_archive = "http_arch load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") load("//zig/private:toolchains_repo.bzl", "PLATFORMS", "toolchains_repo") load("//zig/private:versions.bzl", "TOOL_VERSIONS") +load( + "//zig/private/common:zig_cache.bzl", + "VAR_CACHE_PREFIX", + "VAR_CACHE_PREFIX_LINUX", + "VAR_CACHE_PREFIX_MACOS", + "VAR_CACHE_PREFIX_WINDOWS", + "env_zig_cache_prefix", +) def _http_archive(name, **kwargs): maybe(__http_archive, name = name, **kwargs) @@ -46,36 +54,13 @@ _ATTRS = { "zig_version": attr.string(mandatory = True, values = TOOL_VERSIONS.keys()), "platform": attr.string(mandatory = True, values = PLATFORMS.keys()), } - -_VAR_CACHE_PREFIX = "RULES_ZIG_CACHE_PREFIX" -_VAR_CACHE_PREFIX_LINUX = "RULES_ZIG_CACHE_PREFIX_LINUX" -_VAR_CACHE_PREFIX_MACOS = "RULES_ZIG_CACHE_PREFIX_MACOS" -_VAR_CACHE_PREFIX_WINDOWS = "RULES_ZIG_CACHE_PREFIX_WINDOWS" - _ENV = [ - _VAR_CACHE_PREFIX, - _VAR_CACHE_PREFIX_LINUX, - _VAR_CACHE_PREFIX_MACOS, - _VAR_CACHE_PREFIX_WINDOWS, + VAR_CACHE_PREFIX, + VAR_CACHE_PREFIX_LINUX, + VAR_CACHE_PREFIX_MACOS, + VAR_CACHE_PREFIX_WINDOWS, ] -_DEFAULT_CACHE_PREFIX = "/tmp/zig-cache" -_DEFAULT_CACHE_PREFIX_LINUX = "/tmp/zig-cache" -_DEFAULT_CACHE_PREFIX_MACOS = "/var/tmp/zig-cache" -_DEFAULT_CACHE_PREFIX_WINDOWS = "C:\\Temp\\zig-cache" - -def _env_zig_cache_prefix(environ, platform): - if platform.find("linux") != -1: - cache_prefix = environ.get(_VAR_CACHE_PREFIX_LINUX, environ.get(_VAR_CACHE_PREFIX, _DEFAULT_CACHE_PREFIX_LINUX)) - elif platform.find("macos") != -1: - cache_prefix = environ.get(_VAR_CACHE_PREFIX_MACOS, environ.get(_VAR_CACHE_PREFIX, _DEFAULT_CACHE_PREFIX_MACOS)) - elif platform.find("windows") != -1: - cache_prefix = environ.get(_VAR_CACHE_PREFIX_WINDOWS, environ.get(_VAR_CACHE_PREFIX, _DEFAULT_CACHE_PREFIX_WINDOWS)) - else: - cache_prefix = environ.get(_VAR_CACHE_PREFIX, _DEFAULT_CACHE_PREFIX) - - return cache_prefix - def _zig_repo_impl(repository_ctx): url = TOOL_VERSIONS[repository_ctx.attr.zig_version][repository_ctx.attr.platform].url integrity = TOOL_VERSIONS[repository_ctx.attr.zig_version][repository_ctx.attr.platform].integrity @@ -92,7 +77,7 @@ def _zig_repo_impl(repository_ctx): stripPrefix = prefix, ) - cache_prefix = _env_zig_cache_prefix(repository_ctx.os.environ, repository_ctx.attr.platform) + cache_prefix = env_zig_cache_prefix(repository_ctx.os.environ, repository_ctx.attr.platform) build_content = """#Generated by zig/repositories.bzl load("@rules_zig//zig:toolchain.bzl", "zig_toolchain") From f909eac453fa314db07bd037a381b64160971525 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 4 Apr 2024 08:18:37 +0200 Subject: [PATCH 07/10] Unit test for the Zig cache configuration logic --- zig/tests/BUILD.bazel | 3 ++ zig/tests/cache_test.bzl | 114 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 zig/tests/cache_test.bzl diff --git a/zig/tests/BUILD.bazel b/zig/tests/BUILD.bazel index 82074695..eeee260e 100644 --- a/zig/tests/BUILD.bazel +++ b/zig/tests/BUILD.bazel @@ -1,4 +1,5 @@ load("@bazel_skylib//:bzl_library.bzl", "bzl_library") +load(":cache_test.bzl", "cache_test_suite") load(":config_test.bzl", "config_test_suite") load(":mode_test.bzl", "mode_test_suite") load(":module_info_test.bzl", "module_info_test_suite") @@ -8,6 +9,8 @@ load(":target_triple_test.bzl", "target_triple_test_suite") load(":threaded_test.bzl", "threaded_test_suite") load(":versions_test.bzl", "versions_test_suite") +cache_test_suite(name = "cache_test") + config_test_suite(name = "config_test") mode_test_suite(name = "mode_test") diff --git a/zig/tests/cache_test.bzl b/zig/tests/cache_test.bzl new file mode 100644 index 00000000..cc756247 --- /dev/null +++ b/zig/tests/cache_test.bzl @@ -0,0 +1,114 @@ +"""Unit tests for Zig cache handling.""" + +load("@bazel_skylib//lib:partial.bzl", "partial") +load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") +load( + "//zig/private/common:zig_cache.bzl", + "DEFAULT_CACHE_PREFIX", + "DEFAULT_CACHE_PREFIX_LINUX", + "DEFAULT_CACHE_PREFIX_MACOS", + "DEFAULT_CACHE_PREFIX_WINDOWS", + "VAR_CACHE_PREFIX", + "VAR_CACHE_PREFIX_LINUX", + "VAR_CACHE_PREFIX_MACOS", + "VAR_CACHE_PREFIX_WINDOWS", + "env_zig_cache_prefix", +) + +def _env_zig_cache_prefix_test_impl(ctx): + env = unittest.begin(ctx) + + asserts.equals( + env, + DEFAULT_CACHE_PREFIX_LINUX, + env_zig_cache_prefix({}, "x86_64-linux"), + ) + + asserts.equals( + env, + DEFAULT_CACHE_PREFIX_MACOS, + env_zig_cache_prefix({}, "aarch64-macos"), + ) + + asserts.equals( + env, + DEFAULT_CACHE_PREFIX_WINDOWS, + env_zig_cache_prefix({}, "x86_64-windows"), + ) + + asserts.equals( + env, + DEFAULT_CACHE_PREFIX, + env_zig_cache_prefix({}, "x86_64-freebsd"), + ) + + default_env = { + VAR_CACHE_PREFIX: "DEFAULT", + } + + asserts.equals( + env, + "DEFAULT", + env_zig_cache_prefix(default_env, "aarch64-linux"), + ) + + asserts.equals( + env, + "DEFAULT", + env_zig_cache_prefix(default_env, "x86_64-macos"), + ) + + asserts.equals( + env, + "DEFAULT", + env_zig_cache_prefix(default_env, "aarch64-windows"), + ) + + asserts.equals( + env, + "DEFAULT", + env_zig_cache_prefix(default_env, "aarch64-freebsd"), + ) + + overrides_env = { + VAR_CACHE_PREFIX_LINUX: "LINUX", + VAR_CACHE_PREFIX_MACOS: "MACOS", + VAR_CACHE_PREFIX_WINDOWS: "WINDOWS", + VAR_CACHE_PREFIX: "DEFAULT", + } + + asserts.equals( + env, + "LINUX", + env_zig_cache_prefix(overrides_env, "aarch64-linux"), + ) + + asserts.equals( + env, + "MACOS", + env_zig_cache_prefix(overrides_env, "x86_64-macos"), + ) + + asserts.equals( + env, + "WINDOWS", + env_zig_cache_prefix(overrides_env, "aarch64-windows"), + ) + + asserts.equals( + env, + "DEFAULT", + env_zig_cache_prefix(overrides_env, "aarch64-freebsd"), + ) + + return unittest.end(env) + +_env_zig_cache_prefix_test = unittest.make( + _env_zig_cache_prefix_test_impl, +) + +def cache_test_suite(name): + unittest.suite( + name, + partial.make(_env_zig_cache_prefix_test, size = "small"), + ) From ab4d27a0731a1fe6e7e1c0b4f425be3aa73df219 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 4 Apr 2024 08:38:51 +0200 Subject: [PATCH 08/10] Test match toolchain and build cache configuration --- zig/tests/cache_test.bzl | 42 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/zig/tests/cache_test.bzl b/zig/tests/cache_test.bzl index cc756247..288b9116 100644 --- a/zig/tests/cache_test.bzl +++ b/zig/tests/cache_test.bzl @@ -1,7 +1,7 @@ """Unit tests for Zig cache handling.""" load("@bazel_skylib//lib:partial.bzl", "partial") -load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") +load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts", "unittest") load( "//zig/private/common:zig_cache.bzl", "DEFAULT_CACHE_PREFIX", @@ -14,6 +14,12 @@ load( "VAR_CACHE_PREFIX_WINDOWS", "env_zig_cache_prefix", ) +load("//zig/private/providers:zig_toolchain_info.bzl", "ZigToolchainInfo") +load( + ":util.bzl", + "assert_find_action", + "assert_find_unique_option", +) def _env_zig_cache_prefix_test_impl(ctx): env = unittest.begin(ctx) @@ -107,8 +113,42 @@ _env_zig_cache_prefix_test = unittest.make( _env_zig_cache_prefix_test_impl, ) +def _simple_binary_test_impl(ctx): + env = analysistest.begin(ctx) + toolchain = ctx.attr._zig_toolchain[ZigToolchainInfo] + + build = assert_find_action(env, "ZigBuildExe") + + local_cache = assert_find_unique_option(env, "--cache-dir", build.argv) + asserts.equals(env, toolchain.zig_cache, local_cache) + + global_cache = assert_find_unique_option(env, "--global-cache-dir", build.argv) + asserts.equals(env, toolchain.zig_cache, global_cache) + + docs = assert_find_action(env, "ZigBuildDocs") + + local_cache = assert_find_unique_option(env, "--cache-dir", docs.argv) + asserts.equals(env, toolchain.zig_cache, local_cache) + + global_cache = assert_find_unique_option(env, "--global-cache-dir", docs.argv) + asserts.equals(env, toolchain.zig_cache, global_cache) + + return analysistest.end(env) + +_simple_binary_test = analysistest.make( + _simple_binary_test_impl, + attrs = { + "_zig_toolchain": attr.label(default = "//zig:resolved_toolchain"), + }, +) + def cache_test_suite(name): unittest.suite( name, partial.make(_env_zig_cache_prefix_test, size = "small"), + partial.make( + _simple_binary_test, + target_under_test = "//zig/tests/simple-binary:binary", + size = "small", + ), ) From a32261e321d91f104dd132af86a8c29962a04815 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 4 Apr 2024 08:51:59 +0200 Subject: [PATCH 09/10] Integration test that Zig cache can be configured --- .../integration_tests_runner.zig | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/zig/tests/integration_tests/integration_tests_runner.zig b/zig/tests/integration_tests/integration_tests_runner.zig index 846fd650..7fde3ea9 100644 --- a/zig/tests/integration_tests/integration_tests_runner.zig +++ b/zig/tests/integration_tests/integration_tests_runner.zig @@ -39,6 +39,24 @@ test "failing zig_test fails" { try std.testing.expectEqual(std.ChildProcess.Term{ .Exited = 3 }, result.term); } +test "Zig cache directory can be configured" { + const ctx = try BitContext.init(); + + const result = try ctx.exec_bazel(.{ + .argv = &[_][]const u8{ + "cquery", + "--repo_env=RULES_ZIG_CACHE_PREFIX=/CACHE_OVERRIDE", + "--output=starlark", + "--starlark:expr=providers(target)['ToolchainInfo'].zigtoolchaininfo.zig_cache", + "@rules_zig//zig:resolved_toolchain", + }, + }); + defer result.deinit(); + + try std.testing.expect(result.success); + try std.testing.expectEqualStrings("/CACHE_OVERRIDE\n", result.stdout); +} + test "target build mode defaults to Debug" { const ctx = try BitContext.init(); From 5cf8a134a33c5d31707522417414ca70081f7144 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Fri, 5 Apr 2024 08:50:10 +0200 Subject: [PATCH 10/10] Document Zig cache configuration --- README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README.md b/README.md index 0000a099..c06b8341 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,8 @@ and build configuration features well. The instructions assume basic familiarity with the Bazel build system. Take a look at [Bazel's documentation][bazel-intro] if you are unfamiliar. +Consider the [_Additional Setup_](#additional-setup) section as well. + [bazel-intro]: https://bazel.build/about/intro ### Using Bzlmod with Bazel >=6 @@ -135,6 +137,34 @@ information. --> +### Additional Setup + +#### Zig Cache + +The Zig compiler caches intermediate outputs on disk. This cache is shared and +persisted between Bazel builds and build actions. You can configure the cache +directory using the following set of environment variables, you can configure +them through Bazel by using the `--repo_env` flag. + +- `RULES_ZIG_CACHE_PREFIX_LINUX`: Cache directory on Linux, default `/tmp/zig-cache`. +- `RULES_ZIG_CACHE_PREFIX_MACOS`: Cache directory on MacOS, default `/var/tmp/zig-cache`. +- `RULES_ZIG_CACHE_PREFIX_WINDOWS`: Cache directory on Windows, default `C:\Temp\zig-cache`. +- `RULES_ZIG_CACHE_PREFIX`: Cache directory fall-back for all platforms, default `/tmp/zig-cache`. + +> [!Note] +> On Bazel 7 and above you need to explicitly allow persistence in the sandbox. +> You can use the following `.bazelrc` snippet, adjust the paths depending on +> your cache configuration. +> +> ``` +> common --enable_platform_specific_config +> # You can configure `/tmp/zig-cache`, or similar, specifically, +> # if you can ensure that the directory exists before the build. +> build:linux --sandbox_add_mount_pair=/tmp +> build:macos --sandbox_add_mount_pair=/var/tmp +> build:windows --sandbox_add_mount_pair=C:\Temp +> ``` + ## Usage Examples