From f170fd650fb11bc96bd9fa11aac8397feb1fc321 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 27 Feb 2023 08:29:54 +0100 Subject: [PATCH 01/10] Add a build setting for -fsingle-threaded --- .bazelrc.flags | 1 + zig/config/single_threaded/BUILD.bazel | 13 +++++++++++++ zig/private/providers/zig_settings_info.bzl | 1 + zig/private/settings.bzl | 15 +++++++++++++++ zig/settings/BUILD.bazel | 21 ++++++++++++++------- 5 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 zig/config/single_threaded/BUILD.bazel diff --git a/.bazelrc.flags b/.bazelrc.flags index 8990d30f..d876cfe0 100644 --- a/.bazelrc.flags +++ b/.bazelrc.flags @@ -4,3 +4,4 @@ # the same aliases. build --flag_alias=zig_mode=@rules_zig//zig/settings:mode +build --flag_alias=zig_threaded=@rules_zig//zig/settings:threaded diff --git a/zig/config/single_threaded/BUILD.bazel b/zig/config/single_threaded/BUILD.bazel new file mode 100644 index 00000000..acf8c935 --- /dev/null +++ b/zig/config/single_threaded/BUILD.bazel @@ -0,0 +1,13 @@ +config_setting( + name = "multi_threaded", + flag_values = { + "//zig/settings:threaded": "multi", + }, +) + +config_setting( + name = "single_threaded", + flag_values = { + "//zig/settings:threaded": "single", + }, +) diff --git a/zig/private/providers/zig_settings_info.bzl b/zig/private/providers/zig_settings_info.bzl index 3da9762a..55a6aff6 100644 --- a/zig/private/providers/zig_settings_info.bzl +++ b/zig/private/providers/zig_settings_info.bzl @@ -4,6 +4,7 @@ ZigSettingsInfo = provider( doc = "Collection of all active Zig build settings.", fields = { "mode": "The Zig build mode.", + "threaded": "The Zig multi- or single-threaded setting.", "args": "The collected compiler arguments for all active settings.", }, ) diff --git a/zig/private/settings.bzl b/zig/private/settings.bzl index 4ddef3c1..e780df7d 100644 --- a/zig/private/settings.bzl +++ b/zig/private/settings.bzl @@ -11,6 +11,10 @@ ATTRS = { doc = "The build mode setting.", mandatory = True, ), + "threaded": attr.label( + doc = "The Zig multi- or single-threaded setting.", + mandatory = True, + ), } MODE_ARGS = { @@ -22,14 +26,25 @@ MODE_ARGS = { MODE_VALUES = ["debug", "release_safe", "release_small", "release_fast"] +THREADED_ARGS = { + "multi": ["-fno-single-threaded"], + "single": ["-fsingle-threaded"], +} + +THREADED_VALUES = ["multi", "single"] + def _settings_impl(ctx): args = [] mode = ctx.attr.mode[BuildSettingInfo].value args.extend(MODE_ARGS[mode]) + threaded = ctx.attr.threaded[BuildSettingInfo].value + args.extend(THREADED_ARGS[threaded]) + settings_info = ZigSettingsInfo( mode = mode, + threaded = threaded, args = args, ) diff --git a/zig/settings/BUILD.bazel b/zig/settings/BUILD.bazel index 752e93d5..62c6abb7 100644 --- a/zig/settings/BUILD.bazel +++ b/zig/settings/BUILD.bazel @@ -1,21 +1,28 @@ load("@bazel_skylib//rules:common_settings.bzl", "string_flag") -load("//zig/private:settings.bzl", "settings") +load( + "//zig/private:settings.bzl", + "MODE_VALUES", + "THREADED_VALUES", + "settings", +) settings( name = "settings", mode = ":mode", + threaded = ":threaded", visibility = ["//visibility:public"], ) string_flag( name = "mode", build_setting_default = "debug", - values = [ - "debug", - "release_safe", - "release_small", - "release_fast", - ], + values = MODE_VALUES, +) + +string_flag( + name = "threaded", + build_setting_default = "multi", + values = THREADED_VALUES, ) # Execute `bazel run //util:update_filegroups` to update this target. From 57d4bb34728d018fa2a444a22df0d5630c021d14 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 27 Feb 2023 08:35:26 +0100 Subject: [PATCH 02/10] Factor out assert_find_unique_option --- zig/tests/mode_test.bzl | 18 +++--------------- zig/tests/util.bzl | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 15 deletions(-) create mode 100644 zig/tests/util.bzl diff --git a/zig/tests/mode_test.bzl b/zig/tests/mode_test.bzl index 83f5f570..51e4de57 100644 --- a/zig/tests/mode_test.bzl +++ b/zig/tests/mode_test.bzl @@ -3,25 +3,13 @@ load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts", "unittest") load("@bazel_skylib//lib:partial.bzl", "partial") load("//zig/private/providers:zig_settings_info.bzl", "ZigSettingsInfo") +load(":util.bzl", "assert_find_unique_option") # TODO[AH] Canonicalize this label (`str(Label(...))`) for `bzlmod` support. # Note, that canonicalization is not compatible with Bazel 5.3.2, where it will # strip the requried `@` prefix. _SETTINGS_MODE = "@//zig/settings:mode" -def _assert_find_unique_option(env, name, args): - index = -1 - for i, arg in enumerate(args): - if arg == name: - asserts.equals(env, -1, index, "The option {} should be unique.".format(name)) - index = i - asserts.true(env, index + 1 <= len(args), "The option {} should have an argument.".format(name)) - asserts.false(env, index == -1, "The option {} should be set.".format(name)) - if index != -1: - return args[index + 1] - else: - return None - def _define_settings_mode_test(mode, option): def _test_impl(ctx): env = analysistest.begin(ctx) @@ -29,7 +17,7 @@ def _define_settings_mode_test(mode, option): settings = analysistest.target_under_test(env)[ZigSettingsInfo] asserts.equals(env, mode, settings.mode) - mode_option = _assert_find_unique_option(env, "-O", settings.args) + mode_option = assert_find_unique_option(env, "-O", settings.args) asserts.equals(env, option, mode_option) return analysistest.end(env) @@ -57,7 +45,7 @@ def _define_build_mode_test(mnemonic, mode, option): env = analysistest.begin(ctx) action = _assert_find_action(env, mnemonic) - mode_option = _assert_find_unique_option(env, "-O", action.argv) + mode_option = assert_find_unique_option(env, "-O", action.argv) asserts.equals(env, option, mode_option) return analysistest.end(env) diff --git a/zig/tests/util.bzl b/zig/tests/util.bzl new file mode 100644 index 00000000..8726abd9 --- /dev/null +++ b/zig/tests/util.bzl @@ -0,0 +1,26 @@ +"""Utilities for unit and analysis tests.""" + +load("@bazel_skylib//lib:unittest.bzl", "asserts") + +def assert_find_unique_option(env, name, args): + """Assert that the given option is set and unique and return its value. + + Args: + env: The Skylib unittest environment object. + name: String, The name of the flag, including any `--` prefix. + args: sequence of String, The list of arguments to search in. + + Returns: + The option value of the argument or `None` if unset. + """ + index = -1 + for i, arg in enumerate(args): + if arg == name: + asserts.equals(env, -1, index, "The option {} should be unique.".format(name)) + index = i + asserts.true(env, index + 1 <= len(args), "The option {} should have an argument.".format(name)) + asserts.false(env, index == -1, "The option {} should be set.".format(name)) + if index != -1: + return args[index + 1] + else: + return None From 38aa6632c954a5a6edcf7e07eb522d52899ef7ed Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 27 Feb 2023 08:37:43 +0100 Subject: [PATCH 03/10] Factor out assert_find_action --- zig/tests/mode_test.bzl | 16 ++++++---------- zig/tests/util.bzl | 22 +++++++++++++++++++++- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/zig/tests/mode_test.bzl b/zig/tests/mode_test.bzl index 51e4de57..39fd5992 100644 --- a/zig/tests/mode_test.bzl +++ b/zig/tests/mode_test.bzl @@ -3,7 +3,11 @@ load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts", "unittest") load("@bazel_skylib//lib:partial.bzl", "partial") load("//zig/private/providers:zig_settings_info.bzl", "ZigSettingsInfo") -load(":util.bzl", "assert_find_unique_option") +load( + ":util.bzl", + "assert_find_action", + "assert_find_unique_option", +) # TODO[AH] Canonicalize this label (`str(Label(...))`) for `bzlmod` support. # Note, that canonicalization is not compatible with Bazel 5.3.2, where it will @@ -32,19 +36,11 @@ _settings_mode_release_safe_test = _define_settings_mode_test("release_safe", "R _settings_mode_release_small_test = _define_settings_mode_test("release_small", "ReleaseSmall") _settings_mode_release_fast_test = _define_settings_mode_test("release_fast", "ReleaseFast") -def _assert_find_action(env, mnemonic): - actions = analysistest.target_actions(env) - for action in actions: - if action.mnemonic == mnemonic: - return action - asserts.true(env, False, "Expected an action with mnemonic {}.".format(mnemonic)) - return None - def _define_build_mode_test(mnemonic, mode, option): def _test_impl(ctx): env = analysistest.begin(ctx) - action = _assert_find_action(env, mnemonic) + action = assert_find_action(env, mnemonic) mode_option = assert_find_unique_option(env, "-O", action.argv) asserts.equals(env, option, mode_option) diff --git a/zig/tests/util.bzl b/zig/tests/util.bzl index 8726abd9..09756ed3 100644 --- a/zig/tests/util.bzl +++ b/zig/tests/util.bzl @@ -1,6 +1,6 @@ """Utilities for unit and analysis tests.""" -load("@bazel_skylib//lib:unittest.bzl", "asserts") +load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") def assert_find_unique_option(env, name, args): """Assert that the given option is set and unique and return its value. @@ -24,3 +24,23 @@ def assert_find_unique_option(env, name, args): return args[index + 1] else: return None + +def assert_find_action(env, mnemonic): + """Assert that the given action mnemonic exists and return the first instance. + + Args: + env: The Skylib unittest environment object. + mnemonic: String, The action mnemonic to look for. + + Returns: + The action object or `None` if not found. + """ + actions = analysistest.target_actions(env) + + for action in actions: + if action.mnemonic == mnemonic: + return action + + asserts.true(env, False, "Expected an action with mnemonic {}.".format(mnemonic)) + + return None From 0bc28fbb674c7e91366296a6c4034647de0f09c8 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 27 Feb 2023 08:51:02 +0100 Subject: [PATCH 04/10] Analysis tests for threaded on settings target --- zig/tests/BUILD.bazel | 3 +++ zig/tests/threaded_test.bzl | 43 +++++++++++++++++++++++++++++++++++++ zig/tests/util.bzl | 37 +++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 zig/tests/threaded_test.bzl diff --git a/zig/tests/BUILD.bazel b/zig/tests/BUILD.bazel index 9bf0f4c1..5b8dc15c 100644 --- a/zig/tests/BUILD.bazel +++ b/zig/tests/BUILD.bazel @@ -1,6 +1,7 @@ load(":mode_test.bzl", "mode_test_suite") load(":package_info_test.bzl", "package_info_test_suite") load(":rules_test.bzl", "rules_test_suite") +load(":threaded_test.bzl", "threaded_test_suite") load(":versions_test.bzl", "versions_test_suite") mode_test_suite(name = "mode_test") @@ -9,4 +10,6 @@ package_info_test_suite(name = "package_info_test") rules_test_suite(name = "rules_test") +threaded_test_suite(name = "threaded_test") + versions_test_suite(name = "versions_test") diff --git a/zig/tests/threaded_test.bzl b/zig/tests/threaded_test.bzl new file mode 100644 index 00000000..42f519a7 --- /dev/null +++ b/zig/tests/threaded_test.bzl @@ -0,0 +1,43 @@ +"""Analysis tests for Zig multi- or single-threaded settings.""" + +load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts", "unittest") +load("@bazel_skylib//lib:partial.bzl", "partial") +load("//zig/private/providers:zig_settings_info.bzl", "ZigSettingsInfo") +load( + ":util.bzl", + "assert_flag_set", + "assert_flag_unset", +) + +# TODO[AH] Canonicalize this label (`str(Label(...))`) for `bzlmod` support. +# Note, that canonicalization is not compatible with Bazel 5.3.2, where it will +# strip the requried `@` prefix. +_SETTINGS_THREADED = "@//zig/settings:threaded" + +def _define_settings_threaded_test(threaded, flag_set, flag_not_set): + def _test_impl(ctx): + env = analysistest.begin(ctx) + + settings = analysistest.target_under_test(env)[ZigSettingsInfo] + asserts.equals(env, threaded, settings.threaded) + + assert_flag_set(env, flag_set, settings.args) + assert_flag_unset(env, flag_not_set, settings.args) + + return analysistest.end(env) + + return analysistest.make( + _test_impl, + config_settings = {_SETTINGS_THREADED: threaded}, + ) + +_settings_threaded_single_test = _define_settings_threaded_test("single", "-fsingle-threaded", "-fno-single-threaded") +_settings_threaded_multi_test = _define_settings_threaded_test("multi", "-fno-single-threaded", "-fsingle-threaded") + +def threaded_test_suite(name): + unittest.suite( + name, + # Test Zig threaded setting on the settings target + partial.make(_settings_threaded_single_test, target_under_test = "//zig/settings"), + partial.make(_settings_threaded_multi_test, target_under_test = "//zig/settings"), + ) diff --git a/zig/tests/util.bzl b/zig/tests/util.bzl index 09756ed3..15d469d6 100644 --- a/zig/tests/util.bzl +++ b/zig/tests/util.bzl @@ -2,6 +2,43 @@ load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") +def _is_flag_set(flag, args): + """Check whether the given flag is set. + + Args: + flag: String, The name of the flag, including any `--` prefix. + args: sequence of String, The list of arguments to search in. + + Returns: + True if the flag is set, False otherwise. + """ + for arg in args: + if arg == flag: + return True + return False + +def assert_flag_set(env, flag, args): + """Assert that the given flag is set. + + Args: + env: The Skylib unittest environment object. + flag: String, The name of the flag, including any `--` prefix. + args: sequence of String, The list of arguments to search in. + """ + is_set = _is_flag_set(flag, args) + asserts.true(env, is_set, "The flag {} should have been set.".format(flag)) + +def assert_flag_unset(env, flag, args): + """Assert that the given flag is not set. + + Args: + env: The Skylib unittest environment object. + flag: String, The name of the flag, including any `--` prefix. + args: sequence of String, The list of arguments to search in. + """ + is_set = _is_flag_set(flag, args) + asserts.false(env, is_set, "The flag {} should not have been set.".format(flag)) + def assert_find_unique_option(env, name, args): """Assert that the given option is set and unique and return its value. From e239c7910b817e3a5614e4ff4e928ddd77c798a9 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 27 Feb 2023 08:56:56 +0100 Subject: [PATCH 05/10] Test threaded settings on build actions --- zig/tests/threaded_test.bzl | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/zig/tests/threaded_test.bzl b/zig/tests/threaded_test.bzl index 42f519a7..72c06e71 100644 --- a/zig/tests/threaded_test.bzl +++ b/zig/tests/threaded_test.bzl @@ -5,6 +5,7 @@ load("@bazel_skylib//lib:partial.bzl", "partial") load("//zig/private/providers:zig_settings_info.bzl", "ZigSettingsInfo") load( ":util.bzl", + "assert_find_action", "assert_flag_set", "assert_flag_unset", ) @@ -34,10 +35,44 @@ def _define_settings_threaded_test(threaded, flag_set, flag_not_set): _settings_threaded_single_test = _define_settings_threaded_test("single", "-fsingle-threaded", "-fno-single-threaded") _settings_threaded_multi_test = _define_settings_threaded_test("multi", "-fno-single-threaded", "-fsingle-threaded") +def _define_build_threaded_test(mnemonic, threaded, flag_set, flag_not_set): + def _test_impl(ctx): + env = analysistest.begin(ctx) + + action = assert_find_action(env, mnemonic) + + assert_flag_set(env, flag_set, action.argv) + assert_flag_unset(env, flag_not_set, action.argv) + + return analysistest.end(env) + + return analysistest.make( + _test_impl, + config_settings = {_SETTINGS_THREADED: threaded}, + ) + +_build_exe_threaded_single_test = _define_build_threaded_test("ZigBuildExe", "single", "-fsingle-threaded", "-fno-single-threaded") +_build_exe_threaded_multi_test = _define_build_threaded_test("ZigBuildExe", "multi", "-fno-single-threaded", "-fsingle-threaded") + +_build_lib_threaded_single_test = _define_build_threaded_test("ZigBuildLib", "single", "-fsingle-threaded", "-fno-single-threaded") +_build_lib_threaded_multi_test = _define_build_threaded_test("ZigBuildLib", "multi", "-fno-single-threaded", "-fsingle-threaded") + +_build_test_threaded_single_test = _define_build_threaded_test("ZigBuildTest", "single", "-fsingle-threaded", "-fno-single-threaded") +_build_test_threaded_multi_test = _define_build_threaded_test("ZigBuildTest", "multi", "-fno-single-threaded", "-fsingle-threaded") + def threaded_test_suite(name): unittest.suite( name, # Test Zig threaded setting on the settings target partial.make(_settings_threaded_single_test, target_under_test = "//zig/settings"), partial.make(_settings_threaded_multi_test, target_under_test = "//zig/settings"), + # Test Zig threaded setting on a binary target + partial.make(_build_exe_threaded_single_test, target_under_test = "//zig/tests/simple-binary:binary"), + partial.make(_build_exe_threaded_multi_test, target_under_test = "//zig/tests/simple-binary:binary"), + # Test Zig threaded setting on a library target + partial.make(_build_lib_threaded_single_test, target_under_test = "//zig/tests/simple-library:library"), + partial.make(_build_lib_threaded_multi_test, target_under_test = "//zig/tests/simple-library:library"), + # Test Zig threaded setting on a test target + partial.make(_build_test_threaded_single_test, target_under_test = "//zig/tests/simple-test:test"), + partial.make(_build_test_threaded_multi_test, target_under_test = "//zig/tests/simple-test:test"), ) From 351b0fc4bc0e39a8fa813ea5d66f1b2fc0b840b3 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 27 Feb 2023 20:30:01 +0100 Subject: [PATCH 06/10] rename config/single_threaded to config/threaded --- zig/config/{single_threaded => threaded}/BUILD.bazel | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename zig/config/{single_threaded => threaded}/BUILD.bazel (100%) diff --git a/zig/config/single_threaded/BUILD.bazel b/zig/config/threaded/BUILD.bazel similarity index 100% rename from zig/config/single_threaded/BUILD.bazel rename to zig/config/threaded/BUILD.bazel From 93b100d94eb63fadee64b4056858ec554fe6edcf Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 27 Feb 2023 20:56:41 +0100 Subject: [PATCH 07/10] Add analysis tests for config settings --- zig/config/threaded/BUILD.bazel | 4 +- zig/settings/BUILD.bazel | 2 + zig/tests/BUILD.bazel | 3 ++ zig/tests/config_test.bzl | 83 +++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 zig/tests/config_test.bzl diff --git a/zig/config/threaded/BUILD.bazel b/zig/config/threaded/BUILD.bazel index acf8c935..84bec64e 100644 --- a/zig/config/threaded/BUILD.bazel +++ b/zig/config/threaded/BUILD.bazel @@ -1,12 +1,12 @@ config_setting( - name = "multi_threaded", + name = "multi", flag_values = { "//zig/settings:threaded": "multi", }, ) config_setting( - name = "single_threaded", + name = "single", flag_values = { "//zig/settings:threaded": "single", }, diff --git a/zig/settings/BUILD.bazel b/zig/settings/BUILD.bazel index 62c6abb7..609c3542 100644 --- a/zig/settings/BUILD.bazel +++ b/zig/settings/BUILD.bazel @@ -17,12 +17,14 @@ string_flag( name = "mode", build_setting_default = "debug", values = MODE_VALUES, + visibility = ["//zig/config/mode:__pkg__"], ) string_flag( name = "threaded", build_setting_default = "multi", values = THREADED_VALUES, + visibility = ["//zig/config/threaded:__pkg__"], ) # Execute `bazel run //util:update_filegroups` to update this target. diff --git a/zig/tests/BUILD.bazel b/zig/tests/BUILD.bazel index 5b8dc15c..05b2901c 100644 --- a/zig/tests/BUILD.bazel +++ b/zig/tests/BUILD.bazel @@ -1,9 +1,12 @@ +load(":config_test.bzl", "config_test_suite") load(":mode_test.bzl", "mode_test_suite") load(":package_info_test.bzl", "package_info_test_suite") load(":rules_test.bzl", "rules_test_suite") load(":threaded_test.bzl", "threaded_test_suite") load(":versions_test.bzl", "versions_test_suite") +config_test_suite(name = "config_test") + mode_test_suite(name = "mode_test") package_info_test_suite(name = "package_info_test") diff --git a/zig/tests/config_test.bzl b/zig/tests/config_test.bzl new file mode 100644 index 00000000..b9fbee1e --- /dev/null +++ b/zig/tests/config_test.bzl @@ -0,0 +1,83 @@ +"""Analysis tests for Zig configuration settings.""" + +load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts", "unittest") +load("@bazel_skylib//lib:partial.bzl", "partial") + +_ValueInfo = provider( + doc = "Returns the value attribute of a value rule.", + fields = ["value"], +) + +def _value_impl(ctx): + return [_ValueInfo(value = ctx.attr.value)] + +_string_value = rule( + _value_impl, + attrs = { + "value": attr.string(mandatory = True), + }, +) + +def _define_config_settings_test(*, flag, value): + def _test_impl(ctx): + env = analysistest.begin(ctx) + + actual_value = analysistest.target_under_test(env)[_ValueInfo].value + asserts.equals(env, value, actual_value, "Unexpected value for {}".format(flag)) + + return analysistest.end(env) + + return analysistest.make( + _test_impl, + config_settings = {flag: value}, + ) + +# TODO[AH] Canonicalize this label (`str(Label(...))`) for `bzlmod` support. +# Note, that canonicalization is not compatible with Bazel 5.3.2, where it will +# strip the requried `@` prefix. +_SETTINGS_MODE = "@//zig/settings:mode" +_SETTINGS_THREADED = "@//zig/settings:threaded" + +_mode_debug_test = _define_config_settings_test(flag = _SETTINGS_MODE, value = "debug") +_mode_release_safe_test = _define_config_settings_test(flag = _SETTINGS_MODE, value = "release_safe") +_mode_release_small_test = _define_config_settings_test(flag = _SETTINGS_MODE, value = "release_small") +_mode_release_fast_test = _define_config_settings_test(flag = _SETTINGS_MODE, value = "release_fast") + +_threaded_single_test = _define_config_settings_test(flag = _SETTINGS_THREADED, value = "single") +_threaded_multi_test = _define_config_settings_test(flag = _SETTINGS_THREADED, value = "multi") + +def config_test_suite(name): + """Test suite for configuration settings. + + Args: + name: String, A unique name to assign to the test-suite. + """ + mode_name = "{}_mode".format(name) + _string_value( + name = mode_name, + value = select({ + "//zig/config/mode:debug": "debug", + "//zig/config/mode:release_safe": "release_safe", + "//zig/config/mode:release_small": "release_small", + "//zig/config/mode:release_fast": "release_fast", + }), + ) + threaded_name = "{}_threaded".format(name) + _string_value( + name = threaded_name, + value = select({ + "//zig/config/threaded:single": "single", + "//zig/config/threaded:multi": "multi", + }), + ) + unittest.suite( + name, + # mode + partial.make(_mode_debug_test, target_under_test = mode_name), + partial.make(_mode_release_safe_test, target_under_test = mode_name), + partial.make(_mode_release_small_test, target_under_test = mode_name), + partial.make(_mode_release_fast_test, target_under_test = mode_name), + # threaded + partial.make(_threaded_single_test, target_under_test = threaded_name), + partial.make(_threaded_multi_test, target_under_test = threaded_name), + ) From e4ce983a93448ef6ec63642b7d08b48d24844510 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 27 Feb 2023 21:57:54 +0100 Subject: [PATCH 08/10] e2e test for threaded setting --- e2e/workspace/configure-threaded/BUILD.bazel | 124 ++++++++++++++++++ e2e/workspace/configure-threaded/binary.zig | 9 ++ .../binary_multi_output.expected | 1 + .../binary_single_output.expected | 1 + e2e/workspace/configure-threaded/defs.bzl | 19 +++ e2e/workspace/configure-threaded/library.zig | 8 ++ .../configure-threaded/test_multi.zig | 6 + .../configure-threaded/test_single.zig | 6 + 8 files changed, 174 insertions(+) create mode 100644 e2e/workspace/configure-threaded/BUILD.bazel create mode 100644 e2e/workspace/configure-threaded/binary.zig create mode 100644 e2e/workspace/configure-threaded/binary_multi_output.expected create mode 100644 e2e/workspace/configure-threaded/binary_single_output.expected create mode 100644 e2e/workspace/configure-threaded/defs.bzl create mode 100644 e2e/workspace/configure-threaded/library.zig create mode 100644 e2e/workspace/configure-threaded/test_multi.zig create mode 100644 e2e/workspace/configure-threaded/test_single.zig diff --git a/e2e/workspace/configure-threaded/BUILD.bazel b/e2e/workspace/configure-threaded/BUILD.bazel new file mode 100644 index 00000000..477b0d8e --- /dev/null +++ b/e2e/workspace/configure-threaded/BUILD.bazel @@ -0,0 +1,124 @@ +load("@bazel_skylib//rules:build_test.bzl", "build_test") +load("@bazel_skylib//rules:diff_test.bzl", "diff_test") +load( + "@rules_zig//zig:defs.bzl", + "zig_binary", + "zig_configure", + "zig_configure_binary", + "zig_configure_test", + "zig_library", + "zig_test", +) +load(":defs.bzl", "run") + +zig_library( + name = "library", + main = "library.zig", + tags = ["manual"], +) + +zig_configure( + name = "library_single", + actual = ":library", + threaded = "single", +) + +zig_configure( + name = "library_multi", + actual = ":library", + threaded = "multi", +) + +genrule( + name = "library_single_symbol", + srcs = [":library_single"], + outs = ["library_single_symbol.txt"], + cmd = "$(NM) -j --defined-only $(SRCS) | grep single_threaded > $(OUTS)", + toolchains = ["@bazel_tools//tools/cpp:current_cc_toolchain"], +) + +genrule( + name = "library_multi_symbol", + srcs = [":library_multi"], + outs = ["library_multi_symbol.txt"], + cmd = "$(NM) -j --defined-only $(SRCS) | grep multi_threaded > $(OUTS)", + toolchains = ["@bazel_tools//tools/cpp:current_cc_toolchain"], +) + +build_test( + name = "library_test", + targets = [ + ":library_single_symbol", + ":library_multi_symbol", + ], +) + +zig_binary( + name = "binary", + main = "binary.zig", + tags = ["manual"], +) + +zig_configure_binary( + name = "binary_single", + actual = ":binary", + threaded = "single", +) + +zig_configure_binary( + name = "binary_multi", + actual = ":binary", + threaded = "multi", +) + +# NOTE using genrule instead of run fails with Bazel version 5.3.2. +# It seems that the configuration transition is not handled correctly by +# genrule in Bazel version 5.3.2. + +run( + name = "binary_single_output", + out = "binary_single_output.actual", + tool = ":binary_single", +) + +run( + name = "binary_multi_output", + out = "binary_multi_output.actual", + tool = ":binary_multi", +) + +diff_test( + name = "binary_single_output_test", + file1 = ":binary_single_output.expected", + file2 = ":binary_single_output.actual", +) + +diff_test( + name = "binary_multi_output_test", + file1 = ":binary_multi_output.expected", + file2 = ":binary_multi_output.actual", +) + +zig_test( + name = "_test_single", + main = "test_single.zig", + tags = ["manual"], +) + +zig_configure_test( + name = "test_single", + actual = "_test_single", + threaded = "single", +) + +zig_test( + name = "_test_multi", + main = "test_multi.zig", + tags = ["manual"], +) + +zig_configure_test( + name = "test_multi", + actual = "_test_multi", + threaded = "multi", +) diff --git a/e2e/workspace/configure-threaded/binary.zig b/e2e/workspace/configure-threaded/binary.zig new file mode 100644 index 00000000..8cf0d7dd --- /dev/null +++ b/e2e/workspace/configure-threaded/binary.zig @@ -0,0 +1,9 @@ +const std = @import("std"); +const builtin = @import("builtin"); + +pub fn main() void { + std.io.getStdOut().writer().print( + "{}\n", + .{builtin.single_threaded}, + ) catch unreachable; +} diff --git a/e2e/workspace/configure-threaded/binary_multi_output.expected b/e2e/workspace/configure-threaded/binary_multi_output.expected new file mode 100644 index 00000000..c508d536 --- /dev/null +++ b/e2e/workspace/configure-threaded/binary_multi_output.expected @@ -0,0 +1 @@ +false diff --git a/e2e/workspace/configure-threaded/binary_single_output.expected b/e2e/workspace/configure-threaded/binary_single_output.expected new file mode 100644 index 00000000..27ba77dd --- /dev/null +++ b/e2e/workspace/configure-threaded/binary_single_output.expected @@ -0,0 +1 @@ +true diff --git a/e2e/workspace/configure-threaded/defs.bzl b/e2e/workspace/configure-threaded/defs.bzl new file mode 100644 index 00000000..e6a153d7 --- /dev/null +++ b/e2e/workspace/configure-threaded/defs.bzl @@ -0,0 +1,19 @@ +"""Implements a rule to run a binary and write its output to a file.""" + +def _run_impl(ctx): + ctx.actions.run_shell( + outputs = [ctx.outputs.out], + tools = [ctx.executable.tool], + mnemonic = "RunBinary", + command = "{} > {}".format(ctx.executable.tool.path, ctx.outputs.out.path), + progress_message = "Running binary to create %{output}", + ) + return [DefaultInfo(files = depset([ctx.outputs.out]))] + +run = rule( + _run_impl, + attrs = { + "out": attr.output(), + "tool": attr.label(executable = True, cfg = "exec"), + }, +) diff --git a/e2e/workspace/configure-threaded/library.zig b/e2e/workspace/configure-threaded/library.zig new file mode 100644 index 00000000..b76c02a4 --- /dev/null +++ b/e2e/workspace/configure-threaded/library.zig @@ -0,0 +1,8 @@ +const std = @import("std"); +const builtin = @import("builtin"); + +comptime { + @export(internalName, .{ .name = if (builtin.single_threaded) "single_threaded" else "multi_threaded", .linkage = .Strong }); +} + +fn internalName() callconv(.C) void {} diff --git a/e2e/workspace/configure-threaded/test_multi.zig b/e2e/workspace/configure-threaded/test_multi.zig new file mode 100644 index 00000000..ebecf3b8 --- /dev/null +++ b/e2e/workspace/configure-threaded/test_multi.zig @@ -0,0 +1,6 @@ +const std = @import("std"); +const builtin = @import("builtin"); + +test "single_threaded is false" { + try std.testing.expect(!builtin.single_threaded); +} diff --git a/e2e/workspace/configure-threaded/test_single.zig b/e2e/workspace/configure-threaded/test_single.zig new file mode 100644 index 00000000..63951ffd --- /dev/null +++ b/e2e/workspace/configure-threaded/test_single.zig @@ -0,0 +1,6 @@ +const std = @import("std"); +const builtin = @import("builtin"); + +test "single_threaded is true" { + try std.testing.expect(builtin.single_threaded); +} From a6f7287c996dc7cba9a16521fbb3a56b111c2a30 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 27 Feb 2023 22:02:45 +0100 Subject: [PATCH 09/10] Add threaded attribute to zig_configure --- zig/private/zig_configure.bzl | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/zig/private/zig_configure.bzl b/zig/private/zig_configure.bzl index 5debd504..0501ccee 100644 --- a/zig/private/zig_configure.bzl +++ b/zig/private/zig_configure.bzl @@ -1,21 +1,29 @@ """Implementation of the zig_configure rule.""" load("@bazel_skylib//lib:paths.bzl", "paths") -load("//zig/private:settings.bzl", "MODE_VALUES") +load("//zig/private:settings.bzl", "MODE_VALUES", "THREADED_VALUES") DOC = """\ """ def _zig_transition_impl(settings, attr): - result = {} + result = dict(settings) if attr.mode: result["//zig/settings:mode"] = attr.mode + if attr.threaded: + result["//zig/settings:threaded"] = attr.threaded return result _zig_transition = transition( implementation = _zig_transition_impl, - inputs = [], - outputs = ["//zig/settings:mode"], + inputs = [ + "//zig/settings:mode", + "//zig/settings:threaded", + ], + outputs = [ + "//zig/settings:mode", + "//zig/settings:threaded", + ], ) def _make_attrs(*, executable, test): @@ -31,6 +39,11 @@ def _make_attrs(*, executable, test): mandatory = False, values = MODE_VALUES, ), + "threaded": attr.string( + doc = "The threaded setting", + mandatory = False, + values = THREADED_VALUES, + ), "_whitelist_function_transition": attr.label( default = "@bazel_tools//tools/whitelists/function_transition_whitelist", ), From a9d9f7541dd3fa9914c7e64d70465739f001f0fa Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 27 Feb 2023 22:03:36 +0100 Subject: [PATCH 10/10] Update generated files --- .bazelrc | 4 ++-- docs/rules.md | 9 ++++++--- zig/config/BUILD.bazel | 1 + zig/config/threaded/BUILD.bazel | 7 +++++++ zig/tests/BUILD.bazel | 8 ++++++++ 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/.bazelrc b/.bazelrc index 89dc2064..54d7309b 100644 --- a/.bazelrc +++ b/.bazelrc @@ -7,8 +7,8 @@ import %workspace%/.bazelrc.flags # Deleted packages for integration tests. # To update these lines, execute # `bazel run @contrib_rules_bazel_integration_test//tools:update_deleted_packages` -build --deleted_packages=e2e/workspace,e2e/workspace/configure-mode,e2e/workspace/multiple-sources-and-packages-test,e2e/workspace/multiple-sources-binary,e2e/workspace/simple-binary,e2e/workspace/simple-library,e2e/workspace/simple-test,e2e/workspace/transitive-zig-packages-binary,e2e/workspace/transitive-zig-packages-binary/hello-world,e2e/workspace/transitive-zig-packages-binary/hello-world/data,e2e/workspace/transitive-zig-packages-binary/hello-world/data/hello,e2e/workspace/transitive-zig-packages-binary/hello-world/data/world,e2e/workspace/transitive-zig-packages-binary/hello-world/io,e2e/workspace/zig-package-binary,e2e/workspace/zig-package-binary/data,e2e/workspace/zig-package-binary/io,zig/tests/integration_tests/workspace -query --deleted_packages=e2e/workspace,e2e/workspace/configure-mode,e2e/workspace/multiple-sources-and-packages-test,e2e/workspace/multiple-sources-binary,e2e/workspace/simple-binary,e2e/workspace/simple-library,e2e/workspace/simple-test,e2e/workspace/transitive-zig-packages-binary,e2e/workspace/transitive-zig-packages-binary/hello-world,e2e/workspace/transitive-zig-packages-binary/hello-world/data,e2e/workspace/transitive-zig-packages-binary/hello-world/data/hello,e2e/workspace/transitive-zig-packages-binary/hello-world/data/world,e2e/workspace/transitive-zig-packages-binary/hello-world/io,e2e/workspace/zig-package-binary,e2e/workspace/zig-package-binary/data,e2e/workspace/zig-package-binary/io,zig/tests/integration_tests/workspace +build --deleted_packages=e2e/workspace,e2e/workspace/configure-mode,e2e/workspace/configure-threaded,e2e/workspace/multiple-sources-and-packages-test,e2e/workspace/multiple-sources-binary,e2e/workspace/simple-binary,e2e/workspace/simple-library,e2e/workspace/simple-test,e2e/workspace/transitive-zig-packages-binary,e2e/workspace/transitive-zig-packages-binary/hello-world,e2e/workspace/transitive-zig-packages-binary/hello-world/data,e2e/workspace/transitive-zig-packages-binary/hello-world/data/hello,e2e/workspace/transitive-zig-packages-binary/hello-world/data/world,e2e/workspace/transitive-zig-packages-binary/hello-world/io,e2e/workspace/zig-package-binary,e2e/workspace/zig-package-binary/data,e2e/workspace/zig-package-binary/io,zig/tests/integration_tests/workspace +query --deleted_packages=e2e/workspace,e2e/workspace/configure-mode,e2e/workspace/configure-threaded,e2e/workspace/multiple-sources-and-packages-test,e2e/workspace/multiple-sources-binary,e2e/workspace/simple-binary,e2e/workspace/simple-library,e2e/workspace/simple-test,e2e/workspace/transitive-zig-packages-binary,e2e/workspace/transitive-zig-packages-binary/hello-world,e2e/workspace/transitive-zig-packages-binary/hello-world/data,e2e/workspace/transitive-zig-packages-binary/hello-world/data/hello,e2e/workspace/transitive-zig-packages-binary/hello-world/data/world,e2e/workspace/transitive-zig-packages-binary/hello-world/io,e2e/workspace/zig-package-binary,e2e/workspace/zig-package-binary/data,e2e/workspace/zig-package-binary/io,zig/tests/integration_tests/workspace # Load any settings specific to the current user. # .bazelrc.user should appear in .gitignore so that settings are not shared with team members diff --git a/docs/rules.md b/docs/rules.md index d763052c..409e9bab 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -28,7 +28,7 @@ zig_binary(name, deps< ## zig_configure
-zig_configure(name, actual, mode)
+zig_configure(name, actual, mode, threaded)
 
@@ -41,6 +41,7 @@ zig_configure(name, name | A unique name for this target. | Name | required | | | actual | The target to transition. | Label | required | | | mode | The build mode setting | String | optional | "" | +| threaded | The threaded setting | String | optional | "" | @@ -48,7 +49,7 @@ zig_configure(name, name, actual, mode) +zig_configure_binary(name, actual, mode, threaded) @@ -61,6 +62,7 @@ zig_configure_binary(name, name | A unique name for this target. | Name | required | | | actual | The target to transition. | Label | required | | | mode | The build mode setting | String | optional | "" | +| threaded | The threaded setting | String | optional | "" | @@ -68,7 +70,7 @@ zig_configure_binary(name, name, actual, mode) +zig_configure_test(name, actual, mode, threaded) @@ -81,6 +83,7 @@ zig_configure_test(name, name | A unique name for this target. | Name | required | | | actual | The target to transition. | Label | required | | | mode | The build mode setting | String | optional | "" | +| threaded | The threaded setting | String | optional | "" | diff --git a/zig/config/BUILD.bazel b/zig/config/BUILD.bazel index b6fabcc6..a694dccb 100644 --- a/zig/config/BUILD.bazel +++ b/zig/config/BUILD.bazel @@ -4,6 +4,7 @@ filegroup( srcs = [ ":BUILD.bazel", "//zig/config/mode:all_files", + "//zig/config/threaded:all_files", ], visibility = ["//zig:__pkg__"], ) diff --git a/zig/config/threaded/BUILD.bazel b/zig/config/threaded/BUILD.bazel index 84bec64e..e69dc8dc 100644 --- a/zig/config/threaded/BUILD.bazel +++ b/zig/config/threaded/BUILD.bazel @@ -11,3 +11,10 @@ config_setting( "//zig/settings:threaded": "single", }, ) + +# Execute `bazel run //util:update_filegroups` to update this target. +filegroup( + name = "all_files", + srcs = [":BUILD.bazel"], + visibility = ["//zig/config:__pkg__"], +) diff --git a/zig/tests/BUILD.bazel b/zig/tests/BUILD.bazel index 05b2901c..b539fe77 100644 --- a/zig/tests/BUILD.bazel +++ b/zig/tests/BUILD.bazel @@ -1,3 +1,4 @@ +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") load(":config_test.bzl", "config_test_suite") load(":mode_test.bzl", "mode_test_suite") load(":package_info_test.bzl", "package_info_test_suite") @@ -16,3 +17,10 @@ rules_test_suite(name = "rules_test") threaded_test_suite(name = "threaded_test") versions_test_suite(name = "versions_test") + +bzl_library( + name = "util", + srcs = ["util.bzl"], + visibility = ["//visibility:public"], + deps = ["@bazel_skylib//lib:unittest"], +)