diff --git a/docs/rules.md b/docs/rules.md index f53f87ae..1bb41324 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -118,7 +118,7 @@ zig_c_library( load("@rules_zig//zig:defs.bzl", "zig_configure") zig_configure(name, actual, extra_toolchains, mode, target, threaded, use_cc_common_link, - zig_version) + zig_version, zigopt) Transitions a target and its dependencies to a different configuration. @@ -174,6 +174,7 @@ zig_configure( | threaded | The threaded setting, corresponds to the `-fsingle-threaded` Zig compiler flag. | String | optional | `""` | | use_cc_common_link | Whether to use cc_common.link to link zig binaries, tests and shared libraries. | Boolean | optional | `False` | | zig_version | The Zig SDK version, must be registered using the `zig` module extension. | String | optional | `""` | +| zigopt | Additional list of flags passed to the zig compiler for all Zig compile actions.

The flags specified by this setting do not override those specified via the `zigopts` attribute of `zig_*` rules. Instead, they are prepended to the command line before module specific flags.

This is an advanced feature that can conflict with attributes, build settings, and other flags defined by the toolchain itself. Use this at your own risk of hitting undefined behaviors. | List of strings | optional | `[]` | @@ -184,7 +185,7 @@ zig_configure( load("@rules_zig//zig:defs.bzl", "zig_configure_binary") zig_configure_binary(name, actual, extra_toolchains, mode, target, threaded, use_cc_common_link, - zig_version) + zig_version, zigopt) Transitions a target and its dependencies to a different configuration. @@ -240,6 +241,7 @@ zig_configure_binary( | threaded | The threaded setting, corresponds to the `-fsingle-threaded` Zig compiler flag. | String | optional | `""` | | use_cc_common_link | Whether to use cc_common.link to link zig binaries, tests and shared libraries. | Boolean | optional | `False` | | zig_version | The Zig SDK version, must be registered using the `zig` module extension. | String | optional | `""` | +| zigopt | Additional list of flags passed to the zig compiler for all Zig compile actions.

The flags specified by this setting do not override those specified via the `zigopts` attribute of `zig_*` rules. Instead, they are prepended to the command line before module specific flags.

This is an advanced feature that can conflict with attributes, build settings, and other flags defined by the toolchain itself. Use this at your own risk of hitting undefined behaviors. | List of strings | optional | `[]` | @@ -250,7 +252,7 @@ zig_configure_binary( load("@rules_zig//zig:defs.bzl", "zig_configure_test") zig_configure_test(name, actual, extra_toolchains, mode, target, threaded, use_cc_common_link, - zig_version) + zig_version, zigopt) Transitions a target and its dependencies to a different configuration. @@ -306,6 +308,7 @@ zig_configure_test( | threaded | The threaded setting, corresponds to the `-fsingle-threaded` Zig compiler flag. | String | optional | `""` | | use_cc_common_link | Whether to use cc_common.link to link zig binaries, tests and shared libraries. | Boolean | optional | `False` | | zig_version | The Zig SDK version, must be registered using the `zig` module extension. | String | optional | `""` | +| zigopt | Additional list of flags passed to the zig compiler for all Zig compile actions.

The flags specified by this setting do not override those specified via the `zigopts` attribute of `zig_*` rules. Instead, they are prepended to the command line before module specific flags.

This is an advanced feature that can conflict with attributes, build settings, and other flags defined by the toolchain itself. Use this at your own risk of hitting undefined behaviors. | List of strings | optional | `[]` | diff --git a/zig/private/settings.bzl b/zig/private/settings.bzl index 2d751ce0..ddac6375 100644 --- a/zig/private/settings.bzl +++ b/zig/private/settings.bzl @@ -27,6 +27,18 @@ ATTRS = { doc = "The Zig multi- or single-threaded setting.", mandatory = True, ), + "zigopt": attr.label( + doc = """ +Additional list of flags passed to the zig compiler for all Zig compile actions. + +The flags specified by this setting do not override those specified via the `zigopts` attribute of `zig_*` rules. +Instead, they are prepended to the command line before module specific flags. + +This is an advanced feature that can conflict with attributes, build settings, and other flags defined by the toolchain itself. +Use this at your own risk of hitting undefined behaviors. +""", + mandatory = True, + ), } MODE_ARGS = { @@ -56,6 +68,9 @@ def _settings_impl(ctx): threaded = ctx.attr.threaded[BuildSettingInfo].value args.extend(THREADED_ARGS[threaded]) + zigopts = ctx.attr.zigopt[BuildSettingInfo].value + args.extend(zigopts) + settings_info = ZigSettingsInfo( mode = mode, threaded = threaded, diff --git a/zig/private/zig_configure.bzl b/zig/private/zig_configure.bzl index bd1e35b7..38157d0d 100644 --- a/zig/private/zig_configure.bzl +++ b/zig/private/zig_configure.bzl @@ -113,6 +113,8 @@ def _zig_transition_impl(settings, attr): result["//zig/settings:mode"] = attr.mode if attr.threaded: result["//zig/settings:threaded"] = attr.threaded + if attr.zigopt: + result["//zig/settings:zigopt"] = attr.zigopt return result _zig_transition = transition( @@ -124,6 +126,7 @@ _zig_transition = transition( "//zig/settings:use_cc_common_link", "//zig/settings:mode", "//zig/settings:threaded", + "//zig/settings:zigopt", ], outputs = [ "//command_line_option:extra_toolchains", @@ -132,6 +135,7 @@ _zig_transition = transition( "//zig/settings:use_cc_common_link", "//zig/settings:mode", "//zig/settings:threaded", + "//zig/settings:zigopt", ], ) @@ -169,6 +173,18 @@ def _make_attrs(*, executable): mandatory = False, values = THREADED_VALUES, ), + "zigopt": attr.string_list( + doc = """ +Additional list of flags passed to the zig compiler for all Zig compile actions. + +The flags specified by this setting do not override those specified via the `zigopts` attribute of `zig_*` rules. +Instead, they are prepended to the command line before module specific flags. + +This is an advanced feature that can conflict with attributes, build settings, and other flags defined by the toolchain itself. +Use this at your own risk of hitting undefined behaviors. +""", + mandatory = False, + ), "_allowlist_function_transition": attr.label( default = "@bazel_tools//tools/allowlists/function_transition_allowlist", ), diff --git a/zig/settings/BUILD.bazel b/zig/settings/BUILD.bazel index 58fa5b4d..182d03a9 100644 --- a/zig/settings/BUILD.bazel +++ b/zig/settings/BUILD.bazel @@ -1,4 +1,4 @@ -load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "string_flag") +load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "repeatable_string_flag", "string_flag") load( "//zig/private:settings.bzl", "MODE_VALUES", @@ -12,12 +12,13 @@ settings( threaded = ":threaded", use_cc_common_link = ":use_cc_common_link", visibility = ["//visibility:public"], + zigopt = ":zigopt", ) bool_flag( name = "use_cc_common_link", build_setting_default = False, - visibility = ["//zig/config/mode:__pkg__"], + visibility = ["//visibility:private"], ) string_flag( @@ -34,6 +35,12 @@ string_flag( visibility = ["//zig/config/threaded:__pkg__"], ) +repeatable_string_flag( + name = "zigopt", + build_setting_default = [], + visibility = ["//visibility:private"], +) + # Execute `bazel run //util:update_filegroups` to update this target. filegroup( name = "all_files", diff --git a/zig/tests/BUILD.bazel b/zig/tests/BUILD.bazel index fd3015dc..98a96a9d 100644 --- a/zig/tests/BUILD.bazel +++ b/zig/tests/BUILD.bazel @@ -12,6 +12,7 @@ load(":threaded_test.bzl", "threaded_test_suite") load(":toolchain_header_test.bzl", "toolchain_header_test_suite") load(":use_cc_common_link_test.bzl", "use_cc_common_link_test_suite") load(":versions_test.bzl", "versions_test_suite") +load(":zigopt_test.bzl", "zigopt_test_suite") bzlmod_zig_test_suite(name = "bzlmod_zig_test") @@ -39,6 +40,8 @@ toolchain_header_test_suite(name = "toolchain_header_test") versions_test_suite(name = "versions_test") +zigopt_test_suite(name = "zigopt_test") + bzl_library( name = "util", srcs = ["util.bzl"], diff --git a/zig/tests/zigopt_test.bzl b/zig/tests/zigopt_test.bzl new file mode 100644 index 00000000..063d9240 --- /dev/null +++ b/zig/tests/zigopt_test.bzl @@ -0,0 +1,70 @@ +"""Analysis tests for Zig multi- or single-zigopt settings.""" + +load("@bazel_skylib//lib:partial.bzl", "partial") +load("@bazel_skylib//lib:unittest.bzl", "analysistest", "unittest") +load("//zig/private/providers:zig_settings_info.bzl", "ZigSettingsInfo") +load( + ":util.bzl", + "assert_find_action", + "assert_flag_set", + "canonical_label", +) + +_SETTINGS_ZIGOPT = canonical_label("@//zig/settings:zigopt") + +def _define_settings_zigopt_test(zigopts): + def _test_impl(ctx): + env = analysistest.begin(ctx) + + settings = analysistest.target_under_test(env)[ZigSettingsInfo] + + for zigopt in zigopts: + assert_flag_set(env, zigopt, settings.args) + + return analysistest.end(env) + + return analysistest.make( + _test_impl, + config_settings = {_SETTINGS_ZIGOPT: zigopts}, + ) + +_settings_zigopt_test = _define_settings_zigopt_test(["-mcpu=native", "-flto"]) + +def _define_build_zigopt_test(mnemonic, zigopts): + def _test_impl(ctx): + env = analysistest.begin(ctx) + + action = assert_find_action(env, mnemonic) + + for zigopt in zigopts: + assert_flag_set(env, zigopt, action.argv) + + return analysistest.end(env) + + return analysistest.make( + _test_impl, + config_settings = {_SETTINGS_ZIGOPT: zigopts}, + ) + +_build_exe_zigopt_test = _define_build_zigopt_test("ZigBuildExe", ["-mcpu-native", "-flto"]) + +_build_static_lib_zigopt_test = _define_build_zigopt_test("ZigBuildStaticLib", ["-mcpu-native", "-flto"]) + +_build_shared_lib_zigopt_test = _define_build_zigopt_test("ZigBuildSharedLib", ["-mcpu-native", "-flto"]) + +_build_test_zigopt_test = _define_build_zigopt_test("ZigBuildTest", ["-mcpu-native", "-flto"]) + +def zigopt_test_suite(name): + unittest.suite( + name, + # Test Zig zigopt setting on the settings target + partial.make(_settings_zigopt_test, target_under_test = "//zig/settings", size = "small"), + # Test Zig zigopt setting on a binary target + partial.make(_build_exe_zigopt_test, target_under_test = "//zig/tests/simple-binary:binary", size = "small"), + # Test Zig zigopt setting on a library target + partial.make(_build_static_lib_zigopt_test, target_under_test = "//zig/tests/simple-library:library", size = "small"), + # Test Zig zigopt setting on a shared library target + partial.make(_build_shared_lib_zigopt_test, target_under_test = "//zig/tests/simple-shared-library:shared", size = "small"), + # Test Zig zigopt setting on a test target + partial.make(_build_test_zigopt_test, target_under_test = "//zig/tests/simple-test:test", size = "small"), + )