如何在Bazel genrule中为PATH添加工具路径并获取filegroup顶层绝对路径
Bazel BUILD文件相关问题
给定以下Bazel的BUILD文件,有两个问题需要解决:
- 如何获取
compiler_files文件组的顶层绝对路径?尝试过$(location //X:Y)及其变体,但仅得到大量沙盒相对路径的文件列表。 - 在genrule中使用
tools属性提供的工具路径更新PATH环境变量的惯用方法是什么?
package(default_visibility = ['//visibility:public']) filegroup( name = "script", srcs = ["src/inspect.sh"], ) genrule( name = "inspect", srcs = [":script"], cmd = """ # Instead of /tmp below I need to refer to the path of one of the tools # export PATH=/tmp:$$PATH source $(location :script) cp output.txt $(RULEDIR)/ """, tools = [ "@emsdk//emscripten_toolchain:compiler_files" ], outs = ["generated.txt"] )
问题1:获取compiler_files文件组的顶层绝对路径
filegroup是分散文件的集合,本身没有单一"顶层路径"。如果需要的是这些文件的共同父目录,可以按以下方式处理:
- 优先确认
@emsdk//emscripten_toolchain是否有直接指向目标目录的target(比如compiler_dir),如果有,直接用$(location @emsdk//emscripten_toolchain:compiler_dir)获取路径。 - 没有现成目录target的话,从文件组中任意文件的路径提取父目录:
cmd = """ # 取文件组中第一个文件的父目录作为顶层路径 COMPILER_TOP=$(dirname $(first $(locations @emsdk//emscripten_toolchain:compiler_files))) # 后续可使用$COMPILER_TOP变量 """
注意:Bazel构建在沙盒环境中,所有路径都是沙盒内的相对路径,不存在主机系统的绝对路径——这是构建隔离的设计,建议脚本逻辑适配沙盒环境,不要依赖主机绝对路径。
问题2:在genrule中更新PATH以包含tools路径
方法1:针对单个明确的可执行工具
如果compiler_files中有具体的可执行文件(比如emcc),直接引用该文件并提取目录:
genrule( name = "inspect", srcs = [":script"], cmd = """ EMCC_DIR=$(dirname $(location @emsdk//emscripten_toolchain:emcc)) export PATH=$EMCC_DIR:$$PATH source $(location :script) cp output.txt $(RULEDIR)/ """, tools = [ "@emsdk//emscripten_toolchain:emcc" ], outs = ["generated.txt"] )
方法2:针对文件组中的多个工具
如果工具都在同一目录下,从文件组中取任意文件的目录添加到PATH:
cmd = """ TOOL_DIR=$(dirname $(first $(locations @emsdk//emscripten_toolchain:compiler_files))) export PATH=$TOOL_DIR:$$PATH source $(location :script) cp output.txt $(RULEDIR)/ """
关键注意点
- 用
$$PATH而非$PATH,因为genrule的cmd在shell执行时,$PATH会被Bazel提前解析,需要转义为$$PATH保留给shell处理。 - 如果工具分散在多个目录,需要逐个提取目录并追加到PATH中。
内容的提问来源于stack exchange,提问作者mallwright
相关产品推荐
相关产品推荐

