我有一个py_binary和另一个可运行的目标。我想从第一个目标bazel run //:the_outer
中bazel run //:the_inner
第二个目标(也可以是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?我看到的解决方案包括
- 解析沙箱中的符号链接并希望您最终进入工作区
find / -name WORKSPACE
,希望只有一个- 将所有内容包装在shell脚本中并将
bazel info workspace
作为参数传递
不,不应该这么做。不,不在乎-如果有这么多简单的解决方案
更典型的方法是;外部";二进制取决于";内部";二进制通路";数据";,并使用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","."))
额外的环境变量也可用于二进制:
- BUILD_WORKSPACE_DIRECTORY:运行构建的工作区的根
- BUILD_WORKING_DIRECTORY:Bazel运行的当前工作目录