Design: Symbolic Macros #19921
Replies: 7 comments 9 replies
-
Feature request: I often use a macro to permit users to supply an "attribute" that accepts multiple types. The polymorphism makes a nicer developer experience: for example you can provide a label of a file, or give a list of strings or a dictionary that the macro automatically serializes with a |
Beta Was this translation helpful? Give feedback.
-
Side comment: can we get |
Beta Was this translation helpful? Give feedback.
-
This might be a scope increase / different problem, but one challenge I've seen is that macros as they exist today always "leak" their internal state. For example: def my_binary(name):
native.genrule(
name = "%s_genrule" % name,
outs = ["%s.sh" % name],
# ...
)
native.sh_binary(
name = name,
srcs = ["%s.sh" % name],
deps = ["//some:deps"],
) my_binary(name = "bin")
sh_binary(
name = "other_bin",
srcs = ["bin.sh"],
deps = ["//other:deps"],
) In this example, a user is calling Personally I have a habit of accepting Related concern, what about passing through # //pkg/BUILD
load(“//lib:my_macros.bzl”, “my_validated_binary”)
my_validated_binary(
name = "foo",
testonly = True, # Can this implicitly mark `:main` and `:check` targets `testonly`?
) If a submacro target is explicitly given a def _my_validated_binary_impl(name, srcs, deps, create_test, test_runner):
my_binary(
name = "main",
# No `testonly` set, defaults to `my_validated_binary`'s `testonly` value.
)
my_validation_test(
name = "check",
testonly = True, # Always `testonly = True`.
) Feel free to call this out of scope or not the problem at hand, but just a few thoughts of how we can solve some related macro problems with this approach. |
Beta Was this translation helpful? Give feedback.
-
This might be too specific at this stage of feedback but I'll point out that symbolic macro implementation function in the example my_validated_binary = macro(
# Syntax aligns with `rule`, makes sense.
attrs = {
"srcs": attr.label_list(selectable=True),
"deps": attr.label_list(selectable=True),
"create_test": attr.bool(selectable=False),
"test_runner": attr.label(
selectable=False, default="//lib:default_runner"),
},
# ...
)
# How is this order defined? Is it the source order of the `attrs` dictionary? What about when using tricks like
# `dict.update` or `**` expansion?
def _impl(name, srcs, deps, create_test, test_runner):
# ... Similar, what happens when I define a keyword value with a default? def _impl(name, srcs, deps, create_test, test_runner = Label("//lib:default_runner")):
# ... That could be an error, but I think the fact that there's two reasonable-looking approaches to setting a default is inherently a design smell. Since we're trying to follow existing def _impl(loading_ctx):
my_binary(name = “main”, srcs = loading_ctx.attr.srcs, deps = loading_ctx.attr.deps)
if loading_ctx.attr.create_test:
if loading_ctx.attr.test_runner in BANNED_RUNNERS:
fail(“Please avoid banned test runners”)
my_validation_test(name = “check”, srcs = loading_ctx.attr.srcs, deps = loading_ctx.attr.deps,
test_runner = loading_ctx.attr.test_runner) It doesn't look great, and I do wish we could use arguments in |
Beta Was this translation helpful? Give feedback.
-
Macros and queries (and maybe visibility): If the visibility separates public from private targets within a macro, possible future extension is a query operator, that would only display public targets of a macro - to reduce the complexity of the results. (proposal by @murali42) |
Beta Was this translation helpful? Give feedback.
-
@dgp1130 FWIW I completely agree with macros and leaking their internal rules. There is an internal proposal around that (e.g. supporting things like //visibility:macro_internal). There are several nuances though
All that said... coming up with a solution for visibility could be done later? |
Beta Was this translation helpful? Give feedback.
-
FWIW, I think we should add
|
Beta Was this translation helpful? Give feedback.
-
Status update, Oct 2024: This is implemented and will be released with Bazel 8.0.
Symbolic Macros are a proposed new feature to make macros easier to write and less brittle. I wrote a 2-page* doc summarizing their main properties. A formal design review will come in the future, after we are further along in the prototype.
* (If you don't count the appendix)
Beta Was this translation helpful? Give feedback.
All reactions