feat: basic build data with stamping (#3484)

This makes build data accessible to binaries. By default, some basic
information
is always available: target name and if stamping was enabled.

When `--stamp` is enabled, the full `workspace_status_command` output is
included in the
build information.

Build information is made available through a special
`bazel_binary_info` module. This
module is created by the bootstrap and injected into sys.modules. It
provides an API
for gettting the raw build information that was written. Exposing a
module, instead
of a file, is done insulate from the Bazel-ism of runfiles.

When stamping is enabled, the way stamped data works is a bit round
about to get
the desired semantics: that the build data reflects the most recent
build of a
binary, not the last cached value of the build information (e.g., if I
build
a binary, then modify a file in the binary, then build again, the build
data
should reflect the timestamp of the second build). Normal Bazel caching,
however,
makes that somewhat difficult (the build data file has to take the full
transitive
set of files as inputs to properly detect changes, otherwise it'll get
cached
on first build of the binary; plus actions can't take runfiles objects
as inputs).

To work around this, we use some special APIs to get `ctx.version_file`
information
into the output without entirely destroying caching.

* Because `ctx.version_file` doesn't trigger cache invalidation, a
special helper,
`py_internal.copy_without_caching()`, is used to make it _always_
invalidate
caching. Now we can ensure we have a copy of the most recent invocation
data.
* To prevent the above from _always_ rebuilding a binary, another
special api,
`py_internal.declare_constant_metadata_file()` is used to restore the
behavior
  of a file never invalidating caching (even if it changes).

This dance is necessary because actions can't take runfiles as direct
inputs. It
also avoids having to pass the entire program's transitive set of files
as an input
just to do input change tracking.

Note the above only applies when stamping is enabled. Unstamped binaries
don't
do any of this.

Along the way...

* The `stamp` attribute now transitions the `--stamp` flag. This was
necessary so that
  the dependency on version_info was conditional on stamping.
* Remove a defunct helper from the stage2 bootstrap code.
13 files changed
tree: b4107784d5a9aa4df45f70e2eaf6d83d7062a3b0
  1. .bazelci/
  2. .bcr/
  3. .ci/
  4. .github/
  5. docs/
  6. examples/
  7. gazelle/
  8. private/
  9. python/
  10. sphinxdocs/
  11. tests/
  12. tools/
  13. .bazelignore
  14. .bazelrc
  15. .bazelrc.deleted_packages
  16. .bazelversion
  17. .editorconfig
  18. .git-blame-ignore-revs
  19. .gitattributes
  20. .gitignore
  21. .pre-commit-config.yaml
  22. .python-version
  23. .readthedocs.yml
  24. addlicense.sh
  25. AGENTS.md
  26. AUTHORS
  27. BUILD.bazel
  28. BZLMOD_SUPPORT.md
  29. CHANGELOG.md
  30. CONTRIBUTING.md
  31. CONTRIBUTORS
  32. GEMINI.md
  33. internal_dev_deps.bzl
  34. internal_dev_setup.bzl
  35. LICENSE
  36. MODULE.bazel
  37. README.md
  38. RELEASING.md
  39. version.bzl
  40. WORKSPACE
  41. WORKSPACE.bzlmod
README.md

Python Rules for Bazel

Build status

Overview

This repository is the home of the core Python rules -- py_library, py_binary, py_test, py_proto_library, and related symbols that provide the basis for Python support in Bazel. It also contains package installation rules for integrating with PyPI and other indices.

Documentation for rules_python is at https://rules-python.readthedocs.io and in the Bazel Build Encyclopedia.

Examples live in the examples directory.

The core rules are stable. Their implementation is subject to Bazel's backward compatibility policy. This repository aims to follow semantic versioning.

The Bazel community maintains this repository. Neither Google nor the Bazel team provides support for the code. However, this repository is part of the test suite used to vet new Bazel releases. See How to contribute page for information on our development workflow.

Documentation

For detailed documentation, see https://rules-python.readthedocs.io

Bzlmod support

See Bzlmod support for more details.