From 1eead55cba41a733a85a4541291c444ce7a2b6d3 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Wed, 25 Jan 2023 18:18:21 +0100 Subject: [PATCH 01/10] Add simple-binary test for zig_binary rule --- e2e/workspace/simple-binary/BUILD.bazel | 20 ++++++++++++++++++++ e2e/workspace/simple-binary/main.zig | 7 +++++++ e2e/workspace/simple-binary/output.expected | 1 + 3 files changed, 28 insertions(+) create mode 100644 e2e/workspace/simple-binary/BUILD.bazel create mode 100644 e2e/workspace/simple-binary/main.zig create mode 100644 e2e/workspace/simple-binary/output.expected diff --git a/e2e/workspace/simple-binary/BUILD.bazel b/e2e/workspace/simple-binary/BUILD.bazel new file mode 100644 index 00000000..82fd9c70 --- /dev/null +++ b/e2e/workspace/simple-binary/BUILD.bazel @@ -0,0 +1,20 @@ +load("@bazel_skylib//rules:diff_test.bzl", "diff_test") +load("@rules_zig//zig:defs.bzl", "zig_binary") + +zig_binary( + name = "binary", + main = "main.zig", +) + +genrule( + name = "output", + outs = ["output.actual"], + cmd = "$(execpath :binary) > $(OUTS)", + tools = [":binary"], +) + +diff_test( + name = "output_test", + file1 = ":output.expected", + file2 = ":output.actual", +) diff --git a/e2e/workspace/simple-binary/main.zig b/e2e/workspace/simple-binary/main.zig new file mode 100644 index 00000000..a2ce4c02 --- /dev/null +++ b/e2e/workspace/simple-binary/main.zig @@ -0,0 +1,7 @@ +const std = @import("std"); + +pub fn main() void { + std.io.getStdOut().writeAll( + "Hello World!\n", + ) catch unreachable; +} diff --git a/e2e/workspace/simple-binary/output.expected b/e2e/workspace/simple-binary/output.expected new file mode 100644 index 00000000..980a0d5f --- /dev/null +++ b/e2e/workspace/simple-binary/output.expected @@ -0,0 +1 @@ +Hello World! From b0e7b4f5d1b37dd7976d859eb5cdfdc10a561bd2 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Wed, 25 Jan 2023 18:23:20 +0100 Subject: [PATCH 02/10] zig_binary skeleton --- docs/rules.md | 14 ++++++++++---- zig/BUILD.bazel | 1 + zig/defs.bzl | 6 +++--- zig/private/BUILD.bazel | 6 ++++++ zig/private/zig_binary.bzl | 17 +++++++++++++++++ 5 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 zig/private/zig_binary.bzl diff --git a/docs/rules.md b/docs/rules.md index 3a4dda36..8e6a152b 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -2,15 +2,21 @@ Public API re-exports - + -## example +## zig_binary
-example()
+zig_binary(name)
 
-This is an example +**ATTRIBUTES** + + +| Name | Description | Type | Mandatory | Default | +| :------------- | :------------- | :------------- | :------------- | :------------- | +| name | A unique name for this target. | Name | required | | + diff --git a/zig/BUILD.bazel b/zig/BUILD.bazel index d441b635..7432787b 100644 --- a/zig/BUILD.bazel +++ b/zig/BUILD.bazel @@ -27,6 +27,7 @@ bzl_library( name = "defs", srcs = ["defs.bzl"], visibility = ["//visibility:public"], + deps = ["//zig/private:zig_binary"], ) bzl_library( diff --git a/zig/defs.bzl b/zig/defs.bzl index b48c6fcb..9a9a3fdb 100644 --- a/zig/defs.bzl +++ b/zig/defs.bzl @@ -1,5 +1,5 @@ "Public API re-exports" -def example(): - """This is an example""" - pass +load("//zig/private:zig_binary.bzl", _zig_binary = "zig_binary") + +zig_binary = _zig_binary diff --git a/zig/private/BUILD.bazel b/zig/private/BUILD.bazel index 2f07e8d1..ec40c4f0 100644 --- a/zig/private/BUILD.bazel +++ b/zig/private/BUILD.bazel @@ -11,3 +11,9 @@ bzl_library( srcs = ["versions.bzl"], visibility = ["//zig:__subpackages__"], ) + +bzl_library( + name = "zig_binary", + srcs = ["zig_binary.bzl"], + visibility = ["//zig:__subpackages__"], +) diff --git a/zig/private/zig_binary.bzl b/zig/private/zig_binary.bzl new file mode 100644 index 00000000..b291d241 --- /dev/null +++ b/zig/private/zig_binary.bzl @@ -0,0 +1,17 @@ +"""Implementation of the zig_binary rule.""" + +DOC = """\ +""" + +ATTRS = { +} + +def _zig_binary_impl(ctx): + return [DefaultInfo()] + +zig_binary = rule( + _zig_binary_impl, + attrs = ATTRS, + doc = DOC, + toolchains = ["//zig:toolchain_type"], +) From c9c6b3bf108987af4a6739e72af952475c95f34c Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Wed, 25 Jan 2023 21:48:05 +0100 Subject: [PATCH 03/10] Implement basic zig_binary --- docs/rules.md | 3 ++- zig/private/BUILD.bazel | 1 + zig/private/zig_binary.bzl | 43 +++++++++++++++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/docs/rules.md b/docs/rules.md index 8e6a152b..1200840a 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -7,7 +7,7 @@ Public API re-exports ## zig_binary
-zig_binary(name)
+zig_binary(name, main)
 
@@ -18,5 +18,6 @@ zig_binary(name) | Name | Description | Type | Mandatory | Default | | :------------- | :------------- | :------------- | :------------- | :------------- | | name | A unique name for this target. | Name | required | | +| main | The main source file. | Label | required | | diff --git a/zig/private/BUILD.bazel b/zig/private/BUILD.bazel index ec40c4f0..3d0b18e5 100644 --- a/zig/private/BUILD.bazel +++ b/zig/private/BUILD.bazel @@ -16,4 +16,5 @@ bzl_library( name = "zig_binary", srcs = ["zig_binary.bzl"], visibility = ["//zig:__subpackages__"], + deps = ["@bazel_skylib//lib:paths"], ) diff --git a/zig/private/zig_binary.bzl b/zig/private/zig_binary.bzl index b291d241..0d4afeb5 100644 --- a/zig/private/zig_binary.bzl +++ b/zig/private/zig_binary.bzl @@ -1,13 +1,54 @@ """Implementation of the zig_binary rule.""" +load("@bazel_skylib//lib:paths.bzl", "paths") + DOC = """\ """ ATTRS = { + "main": attr.label( + allow_single_file = [".zig"], + doc = "The main source file.", + mandatory = True, + ), } def _zig_binary_impl(ctx): - return [DefaultInfo()] + ziginfo = ctx.toolchains["//zig:toolchain_type"].ziginfo + + # TODO[AH] Append `.exe` extension on Windows. + output = ctx.actions.declare_file(ctx.label.name) + + local_cache = ctx.actions.declare_directory(paths.join(".zig-cache", "local", ctx.label.name)) + global_cache = ctx.actions.declare_directory(paths.join(".zig-cache", "global", ctx.label.name)) + + args = ctx.actions.args() + args.use_param_file("@%s") + + args.add(output, format = "-femit-bin=%s") + args.add(ctx.file.main) + + # TODO[AH] Persist or share at least the global cache somehow. + args.add_all(["--cache-dir", local_cache.path]) + args.add_all(["--global-cache-dir", global_cache.path]) + + ctx.actions.run( + outputs = [output, local_cache, global_cache], + inputs = [ctx.file.main], + executable = ziginfo.target_tool_path, + tools = ziginfo.tool_files, + arguments = ["build-exe", args], + mnemonic = "ZigBuildExe", + progress_message = "Building Zig binary %{output} from %{input}", + ) + + default = DefaultInfo( + executable = output, + files = depset([output]), + runfiles = ctx.runfiles(files = [output]), + ) + + return [default] zig_binary = rule( _zig_binary_impl, From 8a3c5fbb6cdfb97f9b47571659eb44b940cc867f Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 26 Jan 2023 08:18:26 +0100 Subject: [PATCH 04/10] todo notes --- zig/private/zig_binary.bzl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/zig/private/zig_binary.bzl b/zig/private/zig_binary.bzl index 0d4afeb5..9a8ee392 100644 --- a/zig/private/zig_binary.bzl +++ b/zig/private/zig_binary.bzl @@ -41,7 +41,9 @@ def _zig_binary_impl(ctx): mnemonic = "ZigBuildExe", progress_message = "Building Zig binary %{output} from %{input}", ) + # TODO[AH] Forward tags as execution constraints + # TODO[AH] analysis test to ensure that default output, files to run executable, and runfiles contain the binary. default = DefaultInfo( executable = output, files = depset([output]), From a3154f402230600efd26d44dc10a85b1bf9af1cc Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 26 Jan 2023 08:34:38 +0100 Subject: [PATCH 05/10] analysis test skeleton --- zig/tests/BUILD.bazel | 3 +++ zig/tests/rules_test.bzl | 27 +++++++++++++++++++++++++++ zig/tests/simple-binary/BUILD.bazel | 7 +++++++ zig/tests/simple-binary/main.zig | 7 +++++++ 4 files changed, 44 insertions(+) create mode 100644 zig/tests/rules_test.bzl create mode 100644 zig/tests/simple-binary/BUILD.bazel create mode 100644 zig/tests/simple-binary/main.zig diff --git a/zig/tests/BUILD.bazel b/zig/tests/BUILD.bazel index 93eae3c5..40b2b2a3 100644 --- a/zig/tests/BUILD.bazel +++ b/zig/tests/BUILD.bazel @@ -1,3 +1,6 @@ +load(":rules_test.bzl", "rules_test_suite") load(":versions_test.bzl", "versions_test_suite") +rules_test_suite(name = "rules_test") + versions_test_suite(name = "versions_test") diff --git a/zig/tests/rules_test.bzl b/zig/tests/rules_test.bzl new file mode 100644 index 00000000..c429c72b --- /dev/null +++ b/zig/tests/rules_test.bzl @@ -0,0 +1,27 @@ +"""Analysis tests for rules +See https://bazel.build/rules/testing#testing-rules +""" + +load("@bazel_skylib//lib:unittest.bzl", "analysistest") + +def _simple_binary_test_impl(ctx): + env = analysistest.begin(ctx) + target = analysistest.target_under_test(env) + return analysistest.end(env) + +_simple_binary_test = analysistest.make(_simple_binary_test_impl) + +def _test_simple_binary(name): + _simple_binary_test( + name = name, + target_under_test = "//zig/tests/simple-binary:binary", + ) + +def rules_test_suite(name): + _test_simple_binary(name = "simple_binary_test") + native.test_suite( + name = name, + tests = [ + ":simple_binary_test", + ], + ) diff --git a/zig/tests/simple-binary/BUILD.bazel b/zig/tests/simple-binary/BUILD.bazel new file mode 100644 index 00000000..7419cb57 --- /dev/null +++ b/zig/tests/simple-binary/BUILD.bazel @@ -0,0 +1,7 @@ +load("@rules_zig//zig:defs.bzl", "zig_binary") + +zig_binary( + name = "binary", + main = "main.zig", + visibility = ["//zig/tests:__pkg__"], +) diff --git a/zig/tests/simple-binary/main.zig b/zig/tests/simple-binary/main.zig new file mode 100644 index 00000000..a2ce4c02 --- /dev/null +++ b/zig/tests/simple-binary/main.zig @@ -0,0 +1,7 @@ +const std = @import("std"); + +pub fn main() void { + std.io.getStdOut().writeAll( + "Hello World!\n", + ) catch unreachable; +} From bb3dbd6ab7b6d07f7ce64361e7fe068fe7a2c993 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 26 Jan 2023 08:41:53 +0100 Subject: [PATCH 06/10] Analysis test for zig_binary outputs --- zig/tests/rules_test.bzl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/zig/tests/rules_test.bzl b/zig/tests/rules_test.bzl index c429c72b..1f7f064a 100644 --- a/zig/tests/rules_test.bzl +++ b/zig/tests/rules_test.bzl @@ -2,11 +2,19 @@ See https://bazel.build/rules/testing#testing-rules """ -load("@bazel_skylib//lib:unittest.bzl", "analysistest") +load("@bazel_skylib//lib:sets.bzl", "sets") +load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") def _simple_binary_test_impl(ctx): env = analysistest.begin(ctx) target = analysistest.target_under_test(env) + default = target[DefaultInfo] + + executable = default.files_to_run.executable + asserts.true(executable != None, "zig_binary should produce an executable.") + asserts.true(sets.contains(sets.make(default.files.to_list()), executable), "zig_binary should return the executable as an output.") + asserts.true(sets.contains(sets.make(default.default_runfiles.files.to_list()), executable), "zig_binary should return the executable in the runfiles.") + return analysistest.end(env) _simple_binary_test = analysistest.make(_simple_binary_test_impl) From f144a87490c6876307b74519c4ebc66b8cfaebd0 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 26 Jan 2023 08:44:40 +0100 Subject: [PATCH 07/10] progress message --- zig/private/zig_binary.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zig/private/zig_binary.bzl b/zig/private/zig_binary.bzl index 9a8ee392..a5407472 100644 --- a/zig/private/zig_binary.bzl +++ b/zig/private/zig_binary.bzl @@ -39,7 +39,7 @@ def _zig_binary_impl(ctx): tools = ziginfo.tool_files, arguments = ["build-exe", args], mnemonic = "ZigBuildExe", - progress_message = "Building Zig binary %{output} from %{input}", + progress_message = "Building %{input} as Zig binary %{output}", ) # TODO[AH] Forward tags as execution constraints From b92cbc2b096f9223bfbe614861112bd53c67fefe Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 26 Jan 2023 08:48:32 +0100 Subject: [PATCH 08/10] Analysis test on action output --- zig/tests/rules_test.bzl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/zig/tests/rules_test.bzl b/zig/tests/rules_test.bzl index 1f7f064a..d2ab9161 100644 --- a/zig/tests/rules_test.bzl +++ b/zig/tests/rules_test.bzl @@ -15,6 +15,15 @@ def _simple_binary_test_impl(ctx): asserts.true(sets.contains(sets.make(default.files.to_list()), executable), "zig_binary should return the executable as an output.") asserts.true(sets.contains(sets.make(default.default_runfiles.files.to_list()), executable), "zig_binary should return the executable in the runfiles.") + build = [ + action + for action in analysistest.target_actions(env) + if action.mnemonic == "ZigBuildExe" + ] + asserts.equals(env, 1, len(build), "zig_binary should generate one ZigBuildExe action.") + build = build[0] + asserts.true(sets.contains(sets.make(build.outputs.to_list()), executable), "zig_binary should generate a ZigBuildExe action that generates the binary.") + return analysistest.end(env) _simple_binary_test = analysistest.make(_simple_binary_test_impl) From 94b7663c867a034a6afbbf6cdaa396eaa1153824 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 26 Jan 2023 08:50:09 +0100 Subject: [PATCH 09/10] Forward tags as execution requirements --- zig/private/zig_binary.bzl | 1 + 1 file changed, 1 insertion(+) diff --git a/zig/private/zig_binary.bzl b/zig/private/zig_binary.bzl index a5407472..2e5ec2ae 100644 --- a/zig/private/zig_binary.bzl +++ b/zig/private/zig_binary.bzl @@ -40,6 +40,7 @@ def _zig_binary_impl(ctx): arguments = ["build-exe", args], mnemonic = "ZigBuildExe", progress_message = "Building %{input} as Zig binary %{output}", + execution_requirements = {tag: "" for tag in ctx.attr.tags}, ) # TODO[AH] Forward tags as execution constraints From dabf7efcfe38f7b5d1a5928a58ad48adaea250cc Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 26 Jan 2023 08:50:38 +0100 Subject: [PATCH 10/10] todo notes done --- zig/private/zig_binary.bzl | 2 -- 1 file changed, 2 deletions(-) diff --git a/zig/private/zig_binary.bzl b/zig/private/zig_binary.bzl index 2e5ec2ae..1190ddc0 100644 --- a/zig/private/zig_binary.bzl +++ b/zig/private/zig_binary.bzl @@ -42,9 +42,7 @@ def _zig_binary_impl(ctx): progress_message = "Building %{input} as Zig binary %{output}", execution_requirements = {tag: "" for tag in ctx.attr.tags}, ) - # TODO[AH] Forward tags as execution constraints - # TODO[AH] analysis test to ensure that default output, files to run executable, and runfiles contain the binary. default = DefaultInfo( executable = output, files = depset([output]),