Generate native Bazel platforms instead of requiring tint_build_is flags Currently, people who use the Bazel rules for tint and dawn need to specify os flags like --//src/tint:os=win when running *every* bazel command. This is not very idiomatic (unlike GN where build flags are the standard) and Skia has found this cumbersome. This change replaces those hand-specified flags with the built-in "platforms" attributes. These automatically get set based on the target OS (which defaults to the host os). These will be easier for clients (such as Skia) to use. This also cleans up bazel labels - for labels defined in the same file (such as the tint_build_wgsl_writer aliases) they are prefixed with a colon which is better stylistically. Turns out the mac rules were broken - you can't put a .mm file in a cc_library. I've temporarily removed those and plan to have a follow-on CL that creates objc_library targets that work with Bazel. Suggested review order: - src/tint/utils/command/BUILD.bazel to see examples where conditions involving one platform (windows) are a direct swap and also cases where it's a "platforms *except* for these" are handled with a more idiomatic structure. - All the rest of the BUILD.bazel files to see the changes are equivalent - build.go and expr.go (probably start with the tests) to see the new helper functions - tools/src/cmd/gen/build/BUILD.bazel.tmpl which uses the new helper functions - Anything else Change-Id: I61ae06a3f56f0f4ade65c43d6813a3448e0ccdcd Bug: b/256859233 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/324475 Commit-Queue: Kai Ninomiya <kainino@chromium.org> Reviewed-by: dan sinclair <dsinclair@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
diff --git a/src/tint/BUILD.bazel b/src/tint/BUILD.bazel index 7293f559..46b43e6 100644 --- a/src/tint/BUILD.bazel +++ b/src/tint/BUILD.bazel
@@ -27,7 +27,8 @@ # GEN_BUILD:DO_NOT_GENERATE - This is a hand-crafted file. -load(":flags.bzl", "declare_bool_flag", "declare_os_flag") +load(":flags.bzl", "declare_bool_flag") +load("@bazel_skylib//lib:selects.bzl", "selects") load("//src/tint:generated_sources.bzl", "tint_generated_sources", "tint_generation_dependencies") # Declares the 'tint_build_*' flags that control what parts of Tint get built @@ -66,8 +67,7 @@ visibility = ["//visibility:public"], ) -# Declares the 'os' flag that control what OS-specific Tint code gets built -declare_os_flag() + genrule( name = "generate_sources",
diff --git a/src/tint/api/BUILD.bazel b/src/tint/api/BUILD.bazel index df48433..30610d2 100644 --- a/src/tint/api/BUILD.bazel +++ b/src/tint/api/BUILD.bazel
@@ -197,8 +197,8 @@ selects.config_setting_group( name = "tint_build_spv_reader_or_tint_build_spv_writer", match_any = [ - "tint_build_spv_reader", - "tint_build_spv_writer", + ":tint_build_spv_reader", + ":tint_build_spv_writer", ], )
diff --git a/src/tint/cmd/common/BUILD.bazel b/src/tint/cmd/common/BUILD.bazel index 4d9774c..9f345a3 100644 --- a/src/tint/cmd/common/BUILD.bazel +++ b/src/tint/cmd/common/BUILD.bazel
@@ -121,8 +121,8 @@ selects.config_setting_group( name = "tint_build_spv_reader_or_tint_build_spv_writer", match_any = [ - "tint_build_spv_reader", - "tint_build_spv_writer", + ":tint_build_spv_reader", + ":tint_build_spv_writer", ], )
diff --git a/src/tint/cmd/test/BUILD.bazel b/src/tint/cmd/test/BUILD.bazel index 106768d..2eb910d 100644 --- a/src/tint/cmd/test/BUILD.bazel +++ b/src/tint/cmd/test/BUILD.bazel
@@ -232,8 +232,8 @@ selects.config_setting_group( name = "tint_build_spv_reader_or_tint_build_spv_writer", match_any = [ - "tint_build_spv_reader", - "tint_build_spv_writer", + ":tint_build_spv_reader", + ":tint_build_spv_writer", ], )
diff --git a/src/tint/cmd/tint/BUILD.bazel b/src/tint/cmd/tint/BUILD.bazel index c74ad23..fded2d4 100644 --- a/src/tint/cmd/tint/BUILD.bazel +++ b/src/tint/cmd/tint/BUILD.bazel
@@ -177,8 +177,8 @@ selects.config_setting_group( name = "tint_build_spv_reader_or_tint_build_spv_writer", match_any = [ - "tint_build_spv_reader", - "tint_build_spv_writer", + ":tint_build_spv_reader", + ":tint_build_spv_writer", ], )
diff --git a/src/tint/flags.bzl b/src/tint/flags.bzl index ad2314b..25104c9 100644 --- a/src/tint/flags.bzl +++ b/src/tint/flags.bzl
@@ -1,5 +1,4 @@ load("@bazel_skylib//rules:common_settings.bzl", "string_flag", "bool_flag") -load("@bazel_skylib//lib:selects.bzl", "selects") def declare_bool_flag(name, default): """Create a boolean flag and two config_settings with the names: <name>_true, <name>_false. @@ -33,38 +32,6 @@ visibility = ["//visibility:public"], ) -def declare_os_flag(): - """Creates the 'os' string flag that specifies the OS to target, and a pair of - 'tint_build_is_<os>_true' and 'tint_build_is_<os>_false' targets. - - The OS flag can be specified on the command line with '--//src/tint:os=<os>' - """ - - OSes = [ - "win", - "linux", - "mac", - "other" - ] - - string_flag( - name = "os", - build_setting_default = "other", - values = OSes, - ) - - for os in OSes: - native.config_setting( - name = "tint_build_is_{}_true".format(os), - flag_values = { ":os": os }, - visibility = ["//visibility:public"], - ) - selects.config_setting_group( - name = "tint_build_is_{}_false".format(os), - match_any = [ "tint_build_is_{}_true".format(other) for other in OSes if other != os], - visibility = ["//visibility:public"], - ) - COPTS = [ "-fno-rtti", "-fno-exceptions",
diff --git a/src/tint/lang/msl/validate/BUILD.bazel b/src/tint/lang/msl/validate/BUILD.bazel index 60318e2..b8e0820 100644 --- a/src/tint/lang/msl/validate/BUILD.bazel +++ b/src/tint/lang/msl/validate/BUILD.bazel
@@ -45,8 +45,7 @@ srcs = [ "validate.cc", ] + select({ - ":tint_build_is_mac": [ - "validate_metal.mm", + "@platforms//os:macos": [ ], "//conditions:default": [], }), @@ -63,7 +62,7 @@ "//src/tint/utils/text", "//src/utils", ] + select({ - ":tint_build_is_mac": [ + "@platforms//os:macos": [ ], "//conditions:default": [], }), @@ -72,11 +71,6 @@ ) alias( - name = "tint_build_is_mac", - actual = "//src/tint:tint_build_is_mac_true", -) - -alias( name = "tint_build_msl_writer", actual = "//src/tint:tint_build_msl_writer_true", )
diff --git a/src/tint/lang/spirv/validate/BUILD.bazel b/src/tint/lang/spirv/validate/BUILD.bazel index 7b547a6..1d9c9ee 100644 --- a/src/tint/lang/spirv/validate/BUILD.bazel +++ b/src/tint/lang/spirv/validate/BUILD.bazel
@@ -97,8 +97,8 @@ selects.config_setting_group( name = "tint_build_spv_reader_or_tint_build_spv_writer", match_any = [ - "tint_build_spv_reader", - "tint_build_spv_writer", + ":tint_build_spv_reader", + ":tint_build_spv_writer", ], )
diff --git a/src/tint/utils/command/BUILD.bazel b/src/tint/utils/command/BUILD.bazel index 2e8bb06..aa5cef1 100644 --- a/src/tint/utils/command/BUILD.bazel +++ b/src/tint/utils/command/BUILD.bazel
@@ -46,17 +46,19 @@ "args.cc", "cli.cc", ] + select({ - ":_not_tint_build_is_linux__and__not_tint_build_is_mac__and__not_tint_build_is_win_": [ + "@platforms//os:linux": [], + "@platforms//os:macos": [], + "@platforms//os:windows": [], + "//conditions:default": [ "command_other.cc", ], - "//conditions:default": [], }) + select({ ":tint_build_is_linux_or_tint_build_is_mac": [ "command_posix.cc", ], "//conditions:default": [], }) + select({ - ":tint_build_is_win": [ + "@platforms//os:windows": [ "command_windows.cc", ], "//conditions:default": [], @@ -107,50 +109,12 @@ visibility = ["//visibility:public"], ) -alias( - name = "tint_build_is_linux", - actual = "//src/tint:tint_build_is_linux_true", -) - -alias( - name = "_not_tint_build_is_linux_", - actual = "//src/tint:tint_build_is_linux_false", -) - -alias( - name = "tint_build_is_mac", - actual = "//src/tint:tint_build_is_mac_true", -) - -alias( - name = "_not_tint_build_is_mac_", - actual = "//src/tint:tint_build_is_mac_false", -) - -alias( - name = "tint_build_is_win", - actual = "//src/tint:tint_build_is_win_true", -) - -alias( - name = "_not_tint_build_is_win_", - actual = "//src/tint:tint_build_is_win_false", -) - selects.config_setting_group( name = "tint_build_is_linux_or_tint_build_is_mac", match_any = [ - "tint_build_is_linux", - "tint_build_is_mac", + "@platforms//os:linux", + "@platforms//os:macos", ], ) -selects.config_setting_group( - name = "_not_tint_build_is_linux__and__not_tint_build_is_mac__and__not_tint_build_is_win_", - match_all = [ - ":_not_tint_build_is_linux_", - ":_not_tint_build_is_mac_", - ":_not_tint_build_is_win_", - ], -)
diff --git a/src/tint/utils/file/BUILD.bazel b/src/tint/utils/file/BUILD.bazel index cec6429..2c8f4fc 100644 --- a/src/tint/utils/file/BUILD.bazel +++ b/src/tint/utils/file/BUILD.bazel
@@ -44,17 +44,19 @@ name = "file", srcs = [ ] + select({ - ":_not_tint_build_is_linux__and__not_tint_build_is_mac__and__not_tint_build_is_win_": [ + "@platforms//os:linux": [], + "@platforms//os:macos": [], + "@platforms//os:windows": [], + "//conditions:default": [ "tmpfile_other.cc", ], - "//conditions:default": [], }) + select({ ":tint_build_is_linux_or_tint_build_is_mac": [ "tmpfile_posix.cc", ], "//conditions:default": [], }) + select({ - ":tint_build_is_win": [ + "@platforms//os:windows": [ "tmpfile_windows.cc", ], "//conditions:default": [], @@ -86,50 +88,12 @@ visibility = ["//visibility:public"], ) -alias( - name = "tint_build_is_linux", - actual = "//src/tint:tint_build_is_linux_true", -) - -alias( - name = "_not_tint_build_is_linux_", - actual = "//src/tint:tint_build_is_linux_false", -) - -alias( - name = "tint_build_is_mac", - actual = "//src/tint:tint_build_is_mac_true", -) - -alias( - name = "_not_tint_build_is_mac_", - actual = "//src/tint:tint_build_is_mac_false", -) - -alias( - name = "tint_build_is_win", - actual = "//src/tint:tint_build_is_win_true", -) - -alias( - name = "_not_tint_build_is_win_", - actual = "//src/tint:tint_build_is_win_false", -) - selects.config_setting_group( name = "tint_build_is_linux_or_tint_build_is_mac", match_any = [ - "tint_build_is_linux", - "tint_build_is_mac", + "@platforms//os:linux", + "@platforms//os:macos", ], ) -selects.config_setting_group( - name = "_not_tint_build_is_linux__and__not_tint_build_is_mac__and__not_tint_build_is_win_", - match_all = [ - ":_not_tint_build_is_linux_", - ":_not_tint_build_is_mac_", - ":_not_tint_build_is_win_", - ], -)
diff --git a/src/tint/utils/system/BUILD.bazel b/src/tint/utils/system/BUILD.bazel index adafa32..d7fa3e5 100644 --- a/src/tint/utils/system/BUILD.bazel +++ b/src/tint/utils/system/BUILD.bazel
@@ -44,17 +44,19 @@ name = "system", srcs = [ ] + select({ - ":_not_tint_build_is_linux__and__not_tint_build_is_mac__and__not_tint_build_is_win_": [ + "@platforms//os:linux": [], + "@platforms//os:macos": [], + "@platforms//os:windows": [], + "//conditions:default": [ "terminal_other.cc", ], - "//conditions:default": [], }) + select({ - ":_not_tint_build_is_win_": [ + "@platforms//os:windows": [], + "//conditions:default": [ "env_other.cc", ], - "//conditions:default": [], }) + select({ - ":tint_build_is_linux": [ + "@platforms//os:linux": [ "executable_path_linux.cc", ], "//conditions:default": [], @@ -64,12 +66,12 @@ ], "//conditions:default": [], }) + select({ - ":tint_build_is_mac": [ + "@platforms//os:macos": [ "executable_file_mac.cc", ], "//conditions:default": [], }) + select({ - ":tint_build_is_win": [ + "@platforms//os:windows": [ "env_windows.cc", "executable_path_windows.cc", "terminal_windows.cc", @@ -94,50 +96,12 @@ visibility = ["//visibility:public"], ) -alias( - name = "tint_build_is_linux", - actual = "//src/tint:tint_build_is_linux_true", -) - -alias( - name = "_not_tint_build_is_linux_", - actual = "//src/tint:tint_build_is_linux_false", -) - -alias( - name = "tint_build_is_mac", - actual = "//src/tint:tint_build_is_mac_true", -) - -alias( - name = "_not_tint_build_is_mac_", - actual = "//src/tint:tint_build_is_mac_false", -) - -alias( - name = "tint_build_is_win", - actual = "//src/tint:tint_build_is_win_true", -) - -alias( - name = "_not_tint_build_is_win_", - actual = "//src/tint:tint_build_is_win_false", -) - selects.config_setting_group( name = "tint_build_is_linux_or_tint_build_is_mac", match_any = [ - "tint_build_is_linux", - "tint_build_is_mac", + "@platforms//os:linux", + "@platforms//os:macos", ], ) -selects.config_setting_group( - name = "_not_tint_build_is_linux__and__not_tint_build_is_mac__and__not_tint_build_is_win_", - match_all = [ - ":_not_tint_build_is_linux_", - ":_not_tint_build_is_mac_", - ":_not_tint_build_is_win_", - ], -)
diff --git a/src/tint/utils/text/BUILD.bazel b/src/tint/utils/text/BUILD.bazel index 3d14c0e..1d2abfe 100644 --- a/src/tint/utils/text/BUILD.bazel +++ b/src/tint/utils/text/BUILD.bazel
@@ -53,17 +53,19 @@ "styled_text_theme.cc", "unicode.cc", ] + select({ - ":_not_tint_build_is_linux__and__not_tint_build_is_mac__and__not_tint_build_is_win_": [ + "@platforms//os:linux": [], + "@platforms//os:macos": [], + "@platforms//os:windows": [], + "//conditions:default": [ "styled_text_printer_other.cc", ], - "//conditions:default": [], }) + select({ ":tint_build_is_linux_or_tint_build_is_mac": [ "styled_text_printer_posix.cc", ], "//conditions:default": [], }) + select({ - ":tint_build_is_win": [ + "@platforms//os:windows": [ "styled_text_printer_windows.cc", ], "//conditions:default": [], @@ -120,50 +122,12 @@ visibility = ["//visibility:public"], ) -alias( - name = "tint_build_is_linux", - actual = "//src/tint:tint_build_is_linux_true", -) - -alias( - name = "_not_tint_build_is_linux_", - actual = "//src/tint:tint_build_is_linux_false", -) - -alias( - name = "tint_build_is_mac", - actual = "//src/tint:tint_build_is_mac_true", -) - -alias( - name = "_not_tint_build_is_mac_", - actual = "//src/tint:tint_build_is_mac_false", -) - -alias( - name = "tint_build_is_win", - actual = "//src/tint:tint_build_is_win_true", -) - -alias( - name = "_not_tint_build_is_win_", - actual = "//src/tint:tint_build_is_win_false", -) - selects.config_setting_group( name = "tint_build_is_linux_or_tint_build_is_mac", match_any = [ - "tint_build_is_linux", - "tint_build_is_mac", + "@platforms//os:linux", + "@platforms//os:macos", ], ) -selects.config_setting_group( - name = "_not_tint_build_is_linux__and__not_tint_build_is_mac__and__not_tint_build_is_win_", - match_all = [ - ":_not_tint_build_is_linux_", - ":_not_tint_build_is_mac_", - ":_not_tint_build_is_win_", - ], -)
diff --git a/src/utils/BUILD.bazel b/src/utils/BUILD.bazel index 6f5ec91..b92ed74 100644 --- a/src/utils/BUILD.bazel +++ b/src/utils/BUILD.bazel
@@ -26,9 +26,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. load("@rules_cc//cc:defs.bzl", "cc_library") -load("//src/utils:flags.bzl", "COPTS", "declare_os_flag") - -declare_os_flag() +load("//src/utils:flags.bzl", "COPTS") cc_library( name = "utils", @@ -47,7 +45,7 @@ "typed_integer.h", "underlying_type.h", ] + select({ - "//src/utils:dawn_build_is_win_true": [ + "@platforms//os:windows": [ "windows_with_undefs.h", ], "//conditions:default": [],
diff --git a/src/utils/flags.bzl b/src/utils/flags.bzl index 33e40c9..e057122 100644 --- a/src/utils/flags.bzl +++ b/src/utils/flags.bzl
@@ -1,38 +1,3 @@ -load("@bazel_skylib//lib:selects.bzl", "selects") -load("@bazel_skylib//rules:common_settings.bzl", "string_flag") - -def declare_os_flag(): - """Creates the 'os' string flag that specifies the OS to target, and a pair of - 'dawn_build_is_<os>_true' and 'dawn_build_is_<os>_false' targets. - - The OS flag can be specified on the command line with '--//src/tint:os=<os>' - """ - - OSes = [ - "win", - "linux", - "mac", - "other", - ] - - string_flag( - name = "os", - build_setting_default = "other", - values = OSes, - ) - - for os in OSes: - native.config_setting( - name = "dawn_build_is_{}_true".format(os), - flag_values = {":os": os}, - visibility = ["//visibility:public"], - ) - selects.config_setting_group( - name = "dawn_build_is_{}_false".format(os), - match_any = ["dawn_build_is_{}_true".format(other) for other in OSes if other != os], - visibility = ["//visibility:public"], - ) - COPTS = [ "-fno-rtti", "-fno-exceptions",
diff --git a/tools/src/cmd/gen/build/BUILD.bazel.tmpl b/tools/src/cmd/gen/build/BUILD.bazel.tmpl index 21b3226..53b9e7b 100644 --- a/tools/src/cmd/gen/build/BUILD.bazel.tmpl +++ b/tools/src/cmd/gen/build/BUILD.bazel.tmpl
@@ -109,9 +109,11 @@ {{- end}} {{- else}} {{- range $File := $.UnconditionalSourceFiles}} -{{- if or (not $.Kind.IsLib) (HasSuffix $File.Name ".cc")}} -{{- if not ($.IsGeneratedSource $File.Path)}} +{{- if not (HasSuffix $File.Name ".mm")}} +{{- if or (not $.Kind.IsLib) (HasSuffix $File.Name ".cc")}} +{{- if not ($.IsGeneratedSource $File.Path)}} "{{TrimPrefix $File.Name $.Directory.Path}}", +{{- end}} {{- end}} {{- end}} {{- end}} @@ -122,14 +124,29 @@ ] {{- if $Conditionals.HasSourceFiles}} {{- range $Cond := $Conditionals}} + select({ -{{- if $Cond.SourceFiles}} - ":{{Eval "ConditionTarget" $Cond.Condition}}": [ +{{- if $Cond.Condition.IsNegative}} +{{- range $Var := $Cond.Condition.PositiveVarsOfNegative}} + "{{$Label := PlatformLabel $Var}}{{if $Label}}{{$Label}}{{else}}//src/tint:{{$Var}}_true{{end}}": [], +{{- end}} + "//conditions:default": [ {{- range $File := $Cond.SourceFiles}} +{{- if not (HasSuffix $File.Name ".mm")}} "{{TrimPrefix $File.Name $.Directory.Path}}", +{{- end}} {{- end}} ], -{{- end}} +{{- else}} +{{- if $Cond.SourceFiles}} + "{{$Label := PlatformLabel $Cond.Condition.String}}{{if $Label}}{{$Label}}{{else}}:{{Eval "ConditionTarget" $Cond.Condition}}{{end}}": [ +{{- range $File := $Cond.SourceFiles}} +{{- if not (HasSuffix $File.Name ".mm")}} + "{{TrimPrefix $File.Name $.Directory.Path}}", +{{- end}} +{{- end}} + ], +{{- end}} "//conditions:default": [], +{{- end}} }) {{- end}} {{- end}}, @@ -144,8 +161,10 @@ {{- else}} {{- range $File := $.UnconditionalSourceFiles}} {{- if not (HasSuffix $File.Name ".cc")}} -{{- if not ($.IsGeneratedSource $File.Path)}} +{{- if not (HasSuffix $File.Name ".mm")}} +{{- if not ($.IsGeneratedSource $File.Path)}} "{{TrimPrefix $File.Name $.Directory.Path}}", +{{- end}} {{- end}} {{- end}} {{- end}} @@ -176,8 +195,11 @@ ] {{- if $Conditionals.HasDependencies}} {{- range $Cond := $Conditionals}} + select({ -{{- if or $Cond.InternalDependencies $Cond.ExternalDependencies}} - ":{{Eval "ConditionTarget" $Cond.Condition}}": [ +{{- if $Cond.Condition.IsNegative}} +{{- range $Var := $Cond.Condition.PositiveVarsOfNegative}} + "{{$Label := PlatformLabel $Var}}{{if $Label}}{{$Label}}{{else}}//src/tint:{{$Var}}_true{{end}}": [], +{{- end}} + "//conditions:default": [ {{- range $Dep := $Cond.InternalDependencies}} "{{Eval "Dependency" $Dep}}", {{- end}} @@ -188,8 +210,22 @@ {{- end}} {{- end}} ], -{{- end}} +{{- else}} +{{- if or $Cond.InternalDependencies $Cond.ExternalDependencies}} + "{{$Label := PlatformLabel $Cond.Condition.String}}{{if $Label}}{{$Label}}{{else}}:{{Eval "ConditionTarget" $Cond.Condition}}{{end}}": [ +{{- range $Dep := $Cond.InternalDependencies}} + "{{Eval "Dependency" $Dep}}", +{{- end}} +{{- range $Dep := $Cond.ExternalDependencies}} +{{- $Target := Eval "ExternalDependencyTarget" $Dep}} +{{- if $Target}} + {{$Target}} +{{- end}} +{{- end}} + ], +{{- end}} "//conditions:default": [], +{{- end}} }) {{- end}} {{- end}}, @@ -261,28 +297,33 @@ {{- define "ConditionalRules"}} {{- if $.Unarys}} {{- range $Unary := $.Unarys}} +{{- if not (ShouldSkipUnary $Unary)}} alias( name = "{{Eval "ConditionTarget" $Unary}}", - actual = "//src/tint:{{$Unary.Var}}_{{not $Unary.Negate}}", + actual = "{{ConditionTargetLabel $Unary.Var $Unary.Negate}}", ) {{/* newline */}} +{{- end}} {{- end}} {{- end}} {{- if $.Ors}} {{- range $Ors := $.Ors}} +{{- if not (ShouldSkipOrs $Ors)}} selects.config_setting_group( name = "{{Eval "ConditionTarget" $Ors}}", match_any = [ {{- range $Unary := $Ors}} - "{{Eval "ConditionTarget" $Unary}}", + "{{$Label := PlatformLabel $Unary.Var}}{{if $Label}}{{$Label}}{{else}}:{{Eval "ConditionTarget" $Unary}}{{end}}", {{- end}} ], ) {{/* newline */}} +{{- end}} {{- end}} {{- end}} {{- if $.Ands}} {{- range $Ands := $.Ands}} +{{- if not (ShouldSkipAnds $Ands)}} selects.config_setting_group( name = "{{Eval "ConditionTarget" $Ands}}", match_all = [ @@ -291,6 +332,7 @@ {{- end}} ], ) +{{- end}} {{- end}} {{/* newline */}} {{- end}}
diff --git a/tools/src/cmd/gen/build/build.go b/tools/src/cmd/gen/build/build.go index f520ecb..63a0c09 100644 --- a/tools/src/cmd/gen/build/build.go +++ b/tools/src/cmd/gen/build/build.go
@@ -658,6 +658,61 @@ return nil } +// platformOSMap maps Tint's build-flag variables to standard Bazel platform constraints. +// This makes it easier for clients to build w/o needing to set too many flags. +var platformOSMap = map[string]string{ + "tint_build_is_win": "@platforms//os:windows", + "tint_build_is_linux": "@platforms//os:linux", + "tint_build_is_mac": "@platforms//os:macos", +} + +// ConditionTargetLabel returns a Bazel target label for a build variable and optional negation. +// For platform constraints, it returns the standard @platforms//os target. +// For custom flags, it returns the global //src/tint config settings. +// +// Examples: +// +// ConditionTargetLabel("tint_build_is_win", false) => "@platforms//os:windows" +// ConditionTargetLabel("tint_build_glsl_writer", true) => "//src/tint:tint_build_glsl_writer_false" +func ConditionTargetLabel(variable string, isNegated bool) string { + if label, ok := platformOSMap[variable]; ok { + return label + } + suffix := "_true" + if isNegated { + suffix = "_false" + } + return "//src/tint:" + variable + suffix +} + +// ShouldSkipOrs returns true if the OR expression consists entirely of negated platform variables. +func ShouldSkipOrs(ors cnf.Ors) bool { + for _, unary := range ors { + if !unary.Negate { + return false + } + if _, ok := platformOSMap[unary.Var]; !ok { + return false + } + } + return true +} + +// ShouldSkipAnds returns true if the AND expression consists entirely of negated platform variables. +func ShouldSkipAnds(ands cnf.Ands) bool { + for _, ors := range ands { + for _, unary := range ors { + if !unary.Negate { + return false + } + if _, ok := platformOSMap[unary.Var]; !ok { + return false + } + } + } + return true +} + // TODO(crbug.com/344014313): Add unittests once fileutils and template are // converted to support dependency injection // emitBuildFiles emits a 'BUILD.*' file in each source directory for each @@ -713,7 +768,18 @@ w.WriteString(common.Header(string(existing), CanonicalizePath(relTmplPath), "#")) // Write the template output - err = templates[tmplPath].Run(w, dir, map[string]any{}) + err = templates[tmplPath].Run(w, dir, map[string]any{ + "ShouldSkipUnary": func(unary cnf.Unary) bool { + _, ok := platformOSMap[unary.Var] + return ok + }, + "ShouldSkipOrs": ShouldSkipOrs, + "ShouldSkipAnds": ShouldSkipAnds, + "PlatformLabel": func(variable string) string { + return platformOSMap[variable] + }, + "ConditionTargetLabel": ConditionTargetLabel, + }) if err != nil { return nil, err }
diff --git a/tools/src/cmd/gen/build/build_test.go b/tools/src/cmd/gen/build/build_test.go index 45c4b11e..b908f69 100644 --- a/tools/src/cmd/gen/build/build_test.go +++ b/tools/src/cmd/gen/build/build_test.go
@@ -1137,3 +1137,72 @@ ` require.Equal(t, expectedContents, string(bytes[:])) } + +func TestConditionTargetLabel(t *testing.T) { + test := func(variable string, isNegated bool, expected string) { + name := fmt.Sprintf("%v_%v", variable, isNegated) + t.Run(name, func(t *testing.T) { + got := ConditionTargetLabel(variable, isNegated) + require.Equal(t, expected, got) + }) + } + + test("tint_build_is_win", false, "@platforms//os:windows") + test("tint_build_is_linux", false, "@platforms//os:linux") + test("tint_build_is_mac", false, "@platforms//os:macos") + // We should never get a negated platform case due to ShouldSkipUnary + test("tint_build_is_mac", true, "@platforms//os:macos") + + test("tint_build_glsl_writer", false, "//src/tint:tint_build_glsl_writer_true") + test("tint_build_glsl_writer", true, "//src/tint:tint_build_glsl_writer_false") +} + +func TestShouldSkipOrs(t *testing.T) { + test := func(name string, unaries []cnf.Unary, expected bool) { + t.Run(name, func(t *testing.T) { + got := ShouldSkipOrs(cnf.Ors(unaries)) + require.Equal(t, expected, got) + }) + } + + test("Negated platform variables", []cnf.Unary{ + {Var: "tint_build_is_win", Negate: true}, + {Var: "tint_build_is_mac", Negate: true}, + }, true) + + test("Positive platform variable", []cnf.Unary{ + {Var: "tint_build_is_win", Negate: false}, + }, false) + + test("Negated non-platform variable", []cnf.Unary{ + {Var: "tint_build_glsl_writer", Negate: true}, + }, false) + + test("Mixed platform and non-platform", []cnf.Unary{ + {Var: "tint_build_is_win", Negate: true}, + {Var: "tint_build_glsl_writer", Negate: true}, + }, false) +} + +func TestShouldSkipAnds(t *testing.T) { + test := func(name string, ands cnf.Ands, expected bool) { + t.Run(name, func(t *testing.T) { + got := ShouldSkipAnds(ands) + require.Equal(t, expected, got) + }) + } + + test("Negated platform variables", cnf.Ands{ + cnf.Ors{{Var: "tint_build_is_win", Negate: true}}, + cnf.Ors{{Var: "tint_build_is_mac", Negate: true}}, + }, true) + + test("Positive platform variable", cnf.Ands{ + cnf.Ors{{Var: "tint_build_is_win", Negate: false}}, + }, false) + + test("Mixed negated platform and non-platform", cnf.Ands{ + cnf.Ors{{Var: "tint_build_is_win", Negate: true}}, + cnf.Ors{{Var: "tint_build_glsl_writer", Negate: true}}, + }, false) +}
diff --git a/tools/src/cnf/expr.go b/tools/src/cnf/expr.go index 79e7ec5..81ac4de 100644 --- a/tools/src/cnf/expr.go +++ b/tools/src/cnf/expr.go
@@ -28,6 +28,8 @@ package cnf import ( + "sort" + "dawn.googlesource.com/dawn/tools/src/container" ) @@ -78,3 +80,48 @@ } return out } + +// IsNegative returns true if the expression consists entirely of negated variables. +// This is used by the build generator templates to natively map purely negative +// platform-specific build expressions (e.g. !win) to Bazel's inline +// '//conditions:default' branch (Bazel lacks negation natively). +// +// Example: +// +// !tint_build_is_win && !tint_build_is_mac => true +// tint_build_is_win => false +func (e Expr) IsNegative() bool { + if len(e) == 0 { + return false + } + for _, ors := range e { + for _, unary := range ors { + if !unary.Negate { + return false + } + } + } + return true +} + +// PositiveVarsOfNegative returns the unique, sorted variable names of negated variables in the expression. +// This is used to query the corresponding positive platform targets that must match an empty list [] +// inside the generated negative conditional select statements. +// +// Example: +// +// !tint_build_is_win && !tint_build_is_mac => []string{"tint_build_is_mac", "tint_build_is_win"} +func (e Expr) PositiveVarsOfNegative() []string { + vars := []string{} + seen := map[string]bool{} + for _, ors := range e { + for _, unary := range ors { + if unary.Negate && !seen[unary.Var] { + seen[unary.Var] = true + vars = append(vars, unary.Var) + } + } + } + sort.Strings(vars) + return vars +}
diff --git a/tools/src/cnf/expr_test.go b/tools/src/cnf/expr_test.go index 5e5a015..9e82d89 100644 --- a/tools/src/cnf/expr_test.go +++ b/tools/src/cnf/expr_test.go
@@ -28,6 +28,7 @@ package cnf_test import ( + "reflect" "testing" "dawn.googlesource.com/dawn/tools/src/cnf" @@ -88,3 +89,43 @@ } } } + +func TestIsNegative(t *testing.T) { + test := func(expression string, expected bool) { + t.Run(expression, func(t *testing.T) { + expr, err := cnf.Parse(expression) + if err != nil { + t.Fatalf("unexpected error Parse('%v'): %v", expression, err) + } + got := expr.IsNegative() + if got != expected { + t.Errorf("IsNegative() returned %v, expected %v", got, expected) + } + }) + } + + test("!a", true) + test("!a && !b", true) + test("a", false) + test("!a && b", false) +} + +func TestPositiveVarsOfNegative(t *testing.T) { + test := func(expression string, expected []string) { + t.Run(expression, func(t *testing.T) { + expr, err := cnf.Parse(expression) + if err != nil { + t.Fatalf("unexpected error Parse('%v'): %v", expression, err) + } + got := expr.PositiveVarsOfNegative() + if !reflect.DeepEqual(got, expected) { + t.Errorf("PositiveVarsOfNegative() returned %v, expected %v", got, expected) + } + }) + } + + test("!a", []string{"a"}) + test("!a && !b", []string{"a", "b"}) + test("a", []string{}) + test("!a && b", []string{"a"}) +}