Skip to content

rustc: include proc-macro dep transitive rlibs in proc-macro link inputs#29

Open
walter-zeromatter wants to merge 2 commits into
hermeticbuild:mainfrom
ZeromatterOSS:fix/proc-macro-dep-transitive-link-inputs
Open

rustc: include proc-macro dep transitive rlibs in proc-macro link inputs#29
walter-zeromatter wants to merge 2 commits into
hermeticbuild:mainfrom
ZeromatterOSS:fix/proc-macro-dep-transitive-link-inputs

Conversation

@walter-zeromatter

Copy link
Copy Markdown

Problem

When building a proc-macro target, rustc passes all transitively-reachable rlibs to the linker (clang++). This includes rlibs that arrive through proc-macro dependency chains — for example, if proc-macro A depends on proc-macro B which depends on rlib chrono, rustc's linker invocation for A.so includes chrono.rlib.

collect_deps in rustc.bzl skips dep_info.transitive_crate_outputs for proc-macro deps (the if not is_proc_macro guard at line 258). This is correct for non-proc-macro callers — they don't need those rlibs. But it means proc-macro targets don't declare those rlibs as Bazel action inputs.

Under --remote_download_outputs=minimal (remote execution with minimal downloads), Bazel only downloads declared action inputs. Undeclared rlibs are absent from the sandbox, causing:

clang++: error: no such file or directory: 'bazel-out/.../libchrono-2319700776.rlib'

Fix

Add a transitive_proc_macro_dep_outputs field to DepInfo that captures the transitive rlib outputs of proc-macro deps (exactly what the if not is_proc_macro guard was skipping). In collect_inputs, when the target being built is itself a proc-macro, merge this depset into the action inputs.

This is targeted: non-proc-macro callers are unaffected (no change to transitive_crate_outputs semantics for them), and the new inputs are only added for proc-macro link actions where they're actually needed.

Changes

  • rust/private/providers.bzl: new transitive_proc_macro_dep_outputs field on DepInfo
  • rust/private/rustc.bzl (collect_deps): for proc-macro deps, accumulate their transitive_crate_outputs into the new field
  • rust/private/rustc.bzl (collect_inputs): for proc-macro targets, include transitive_proc_macro_dep_outputs in the action inputs depset

🤖 Generated with Claude Code

When building a proc-macro, rustc passes all transitively-reachable rlibs
to the linker (clang++). This includes rlibs that come through proc-macro
dependency chains, even though those rlibs are already embedded in their
parent proc-macro .so files.

Under --remote_download_outputs=minimal, Bazel only downloads declared
action inputs. The missing rlibs cause clang++ to fail with "no such file
or directory" because they weren't declared as action inputs.

Add a new `transitive_proc_macro_dep_outputs` field to DepInfo. Populate
it with the transitive_crate_outputs of proc-macro deps (the ones skipped
by the existing `if not is_proc_macro` guard). In collect_inputs, include
this depset in the action inputs when building a proc-macro target.

Copy link
Copy Markdown

Pushed follow-up 729e90b38 for the nested proc-macro case: proc-macro deps now carry their own transitive_proc_macro_dep_outputs, and there is a regression test for a two-hop proc-macro chain.

Validated with buildifier, targeted proc-macro/transitive-crate-output Bazel tests, bazel build //test/unit/proc_macro:nested_outer_macro, and git diff --check.

@walter-zeromatter walter-zeromatter marked this pull request as ready for review June 24, 2026 23:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants