bazel 运行 来自 运行ning py_binary

bazel run from a running py_binary

我有一个 py_binary 和另一个可运行的目标。我想 bazel run //:the_inner 第一个目标 bazel run //:the_outer

的第二个目标(也可以是 py_binary)
py_binary(
  name="the_outer",
  srcs=["the_outer.py"]
)

py_binary(
  name="the_inner",
  srcs=["the_inner.py"]
)

简单

rv = subprocess.run( "bazel run //:the_inner".split(), capture_output=True, text=True)

给我一条错误消息,告诉我我不应该这样做,并告诉我我应该使用的工作区。此时我只是解析错误信息并再次调用第二个目标。

workspace = re.search( r"'(\.\w/)+'". rv.stderr ).group(1)
subprocess.run( "bazel run //:the_inner".split(), cwd=workspace)

它有效,但解决方案非常尴尬。有没有一种规范的方法可以 bazel run 从另一个 bazel run 收集东西,特别是 python? 我见过的解决方案包括

不,不应该这样做。不,不在乎 - 如果有那么多简单的解决方法就不会了

更典型的方法是让“外部”二进制文件通过“数据”依赖于“内部”二进制文件,并使用python runfiles 库找到内部二进制文件。

https://github.com/bazelbuild/bazel/blob/master/tools/python/runfiles/runfiles.py

例如:

BUILD:

py_binary(
  name = "a",
  srcs = ["a.py"],
  deps = ["@bazel_tools//tools/python/runfiles:runfiles"],
  data = [":b"],
)

py_binary(
  name = "b",
  srcs = ["b.py"],
)

a.py:

from bazel_tools.tools.python.runfiles import runfiles
import subprocess

r = runfiles.Create()
rv = subprocess.run(r.Rlocation("__main__/b"), capture_output=True, text=True)
print("b says:")
print(rv.stdout)

b.py:

print("hello world")

运行:

$ bazel run a
INFO: Analyzed target //:a (39 packages loaded, 296 targets configured).
INFO: Found 1 target...
Target //:a up-to-date:
  bazel-bin/a
INFO: Elapsed time: 0.791s, Critical Path: 0.01s
INFO: 8 processes: 8 internal.
INFO: Build completed successfully, 8 total actions
INFO: Build completed successfully, 8 total actions
b says:
hello world

我在文档中找到了我要查找的内容: https://docs.bazel.build/versions/main/user-manual.html#run

subprocess.run( "bazel run //:the_inner".split(), cwd=os.environ.get("BUILD_WORKSPACE_DIRECTORY","."))

extra environment variables are also available to the binary:

  • BUILD_WORKSPACE_DIRECTORY: the root of the workspace where the build was run.
  • BUILD_WORKING_DIRECTORY: the current working directory where Bazel was run from.