From b22ed8a446e1495de1340af940b00addaf3f8d09 Mon Sep 17 00:00:00 2001 From: Jacob Shirley Date: Wed, 27 May 2026 18:02:05 +0000 Subject: [PATCH] pkg_install: make callable from a symbolic macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `pkg_install` wires its internal `_pkg_install_script` rule to a `py_binary` via the script's *output filename*: py_binary( name = name, srcs = [":" + name + "_install_script"], main = name + "_install_script.py", # <-- file-name-as-label ... ) `_pkg_install_script` declared that file at analysis time via `ctx.actions.declare_file(...)`, so the file `_install_script.py` existed only as an artifact in the rule's `DefaultInfo` — no loading-time package label was ever registered for it. Legacy macros tolerated the file-name-as-label shortcut, but in a symbolic macro, label references must resolve to real loading-time targets in scope. Bazel errors with: no such target '//pkg:_install_script.py': target '_install_script.py' not declared in package '' (did you mean _install_script?) Promote the script file to a predeclared output via `attr.output()`. The caller passes `out = _install_script.py`, which registers `//pkg:_install_script.py` as a real package label at loading time. `py_binary.main` can then resolve that label in any macro scope, and the rule impl reads the file through `ctx.outputs.out` instead of `ctx.actions.declare_file`. No change to the user-facing `pkg_install` API. --- pkg/install.bzl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/install.bzl b/pkg/install.bzl index 02787ee7..97320f2e 100644 --- a/pkg/install.bzl +++ b/pkg/install.bzl @@ -23,7 +23,7 @@ load("//pkg:providers.bzl", "PackageDirsInfo", "PackageFilegroupInfo", "PackageF load("//pkg/private:pkg_files.bzl", "create_mapping_context_from_ctx", "process_src", "write_manifest") def _pkg_install_script_impl(ctx): - script_file = ctx.actions.declare_file(ctx.attr.name + ".py") + script_file = ctx.outputs.out mapping_context = create_mapping_context_from_ctx(ctx, label = ctx.label, default_mode = "0644") for src in ctx.attr.srcs: @@ -108,6 +108,10 @@ _pkg_install_script = rule( ], doc = "Source mapping/grouping targets", ), + "out": attr.output( + mandatory = True, + doc = "Output path for the generated installer script. Must end in '.py'.", + ), "destdir": attr.string(), "destdir_flag": attr.label(doc = "string flag to obtain destdir from"), # This is private for now -- one could perhaps imagine making this @@ -189,6 +193,7 @@ def pkg_install(name, srcs, destdir = None, destdir_flag = None, **kwargs): _pkg_install_script( name = name + "_install_script", + out = name + "_install_script.py", srcs = srcs, destdir = destdir, destdir_flag = destdir_flag,