Aaron Bentley
Aaron Bentley

Reputation: 1380

How does Bazel's py_binary stamping work?

The docs say that the "stamp" parameter will "enable link stamping" and that it will "encode build information into the binary" and "stamp the build information into the binary"

But where does that information actually go, and how can I retrieve it?

It does not seem to be a simple search-and-replace, nor variable definition, nor environment variable, nor format-string variable. Test python script:

BUILD_HOST="ASDF"
print("{BUILD_HOST}")
print(BUILD_HOST)

Build rule: py_binary(name="catself", srcs=["catself.py"], stamp=1)

Output:

$ bazel run --stamp catself
INFO: Analyzed target //:catself (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //:catself up-to-date:
  bazel-bin/catself
INFO: Elapsed time: 0.083s, Critical Path: 0.01s
INFO: 0 processes.
INFO: Build completed successfully, 1 total action
INFO: Build completed successfully, 1 total action
{BUILD_HOST}
ASDF

Upvotes: 0

Views: 1780

Answers (1)

ahumesky
ahumesky

Reputation: 5026

It looks like stamping might not be enabled for py_binary. It should work for genrule though, so something simple like this should work:

py_binary(
  name = "foo",
  srcs = ["foo.py"],
  data = [":stable-status.txt"],
)

genrule(
  name = "copy_stable-status.txt",
  outs = ["stable-status.txt"],
  cmd = "cp bazel-out/stable-status.txt $@",
  stamp = 1,
)

foo.py:

build_info = {}
with open("stable-status.txt") as stable_status:
  for line in stable_status.readlines():
    key, val = line.split(" ", 1)
    build_info[key] = val.strip()
print("Build label is:")
print(build_info['BUILD_EMBED_LABEL'])

then:

$ bazel run foo --embed_label=foobar
Starting local Bazel server and connecting to it...
INFO: Analyzed target //:foo (17 packages loaded, 102 targets configured).
INFO: Found 1 target...
Target //:foo up-to-date:
  bazel-bin/foo
INFO: Elapsed time: 2.985s, Critical Path: 0.11s
INFO: 1 process: 1 linux-sandbox.
INFO: Build completed successfully, 6 total actions
INFO: Build completed successfully, 6 total actions
Build label is:
foobar

Or something fancier:

py_binary(
  name = "bar",
  srcs = ["bar.py"],
  deps = [":buildinfo"],
)

py_library(
  name = "buildinfo",
  srcs = [":buildinfo.py"],
)

genrule(
  name = "gen_buildinfo",
  outs = ["buildinfo.py"],
  cmd = r"""sed -E 's/(.*) (.*)/\1 = "\2"/' bazel-out/stable-status.txt > $@""",
  stamp = 1,
)

bar.py:

import buildinfo
print("Build label is:")
print(buildinfo.BUILD_EMBED_LABEL)

Upvotes: 4

Related Questions