bazelbuild / bazelbuild/bazel

Vary unused_inputs_list behavior based on which action produces the file

Open
#14,292 8 comments 11 reactions 0 assignees View on GitHub
P4 team-Rules-API type: feature request
Dominant language
Java
Stars
25.8k
Forks
4.6k
Avg merge
2d 20h
Merged PRs (30d)
72

Description

## Status Quo

`unused_inputs_list` allows inputs to be trimmed after an action executes so that the same action will not be re-executed if only the listed unused inputs are changed.
In some cases it is possible to determine this list of unused inputs prior to running the action, this is known as "input discovery" or "input pruning".
While many rulesets _could_ take advantage of this, it is not exposed to Starlark rules.
The builtin C++ rules do take advantage of this, and there is discussion about allowing a C++ specific version of input pruning for the Starlark version of the rules (see #13871).

## Description of the Feature Request

As described by @bjacklyn in https://github.com/bazelbuild/bazel/pull/13871#issuecomment-948051404, and discussed in the Q&A of the BazelCon21 stream: it seems that it should be possible for `unused_inputs_list` to be extended in a meaningful way to allow all Starlark rules access to input discovery.
If the `File` referenced in a `unused_inputs_list` attribute is also listed in the `outputs` of that action, then the current behavior is maintained: the `inputs` are trimmed after the action executes.
If the `unused_inputs_list` `File` is listed under `inputs`, then the `inputs` are trimmed _before_ the action is scheduled for execution, including not being part of the lookup key for the action cache. If the action does execute, then the listed unused inputs will not be included in the sandbox.
If the `unused_inputs_list` is not listed under `inputs` nor `outputs`, then the build should fail.

#### Example Usage

```
ctx.actions.run(
inputs = source_inputs,
outputs = [unused_inputs_file],
arguments = [discover_args],
executable = ctx.executable.input_discoverer,
unused_inputs_list = unused_inputs_file,
mnemonic = "DiscoverInputs",
)

ctx.actions.run(
inputs = depset([unused_inputs_file], transitive = [source_inputs])
outputs = outputs,
arguments = [args],
executable = ctx.executable.compiler,
unused_inputs_list = unused_inputs_file,
mnemonic = "Compile",
)
```
In this example, both actions use `unused_inputs_list`. The action that produces it uses it to trim its inputs _after_ execution. The `Compile` action uses it to trim its inputs _before_ execution, as a form of input discovery.

Contributor guide

Open the contributing guide

Research direction

Start by reviewing the existing unused_inputs_list behavior and the input-pruning discussion in #13871. Done means actions use the file's presence in inputs or outputs to select pre-execution or post-execution trimming, while invalid placement causes the build to fail.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
build-system
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.