You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何调试Bazel分析阶段并解决pkg_tar的remap_paths失效问题?

问题描述

我使用Bazel 3.4和rules_pkg 0.3,手里有一组带多级目录的.so文件,每个子目录对应特定架构的.so文件,现在要把这些文件打包分发。希望去掉架构目录层级,让最终的pkg.tar少一层目录结构(这样加载器更容易指向.so文件)。但因为用的是rules_pkg 0.3,没法用pkg_files。

我写了下面的规则,但remap_paths完全不起作用,输出的tar包里还是有lib/arm64、lib/amd64目录。是不是哪里漏了?

我已经做了这些步骤:

  • 用bazel build --subcommands target查看tar_pkgs动作阶段的参数文件,确认remap没应用到参数文件里,问题肯定出在分析阶段。
  • 尝试调试分析阶段,在本地缓存目录~/.cache/sandox_hash/external/rules_pkg/pkg.bzl里加打印语句,但没效果。就算在pkg.bzl里写语法错误的Python代码,构建也不受影响,好像这个文件没被重新解析。

另外想问下,有哪些工具可以用来打印/调试分析阶段?

对应的规则代码:

pkg_tar(
    name = "my_tar",
    srcs = select({
      "//condition_here" : ["lib/arm64"]
      "//conditions:default" : ["lib/amd64"]
    }),
    remap_paths = {
        "lib/amd64" : "lib",
        "lib/arm64" : "lib",
    }, 
    mode = "0644",
    package_dir = "/package/dir",
    visibility = ["//visibility:public"],
)
解决方案与调试建议

一、remap_paths失效的原因与修复

rules_pkg 0.3的remap_paths是基于文件的原始路径而非目录路径来匹配的,你在srcs里传入的是整个目录(lib/arm64、lib/amd64),规则会把目录本身作为源处理,remap逻辑无法穿透目录匹配到内部的.so文件。

你需要把srcs改成目录下的具体文件,用glob匹配所有.so文件,这样remap才能逐个处理文件路径:

pkg_tar(
    name = "my_tar",
    srcs = select({
      "//condition_here": glob(["lib/arm64/*.so"]),
      "//conditions:default": glob(["lib/amd64/*.so"])
    }),
    remap_paths = {
        "lib/amd64": "lib",
        "lib/arm64": "lib",
    },
    mode = "0644",
    package_dir = "/package/dir",
    visibility = ["//visibility:public"],
)

另外注意,rules_pkg 0.3的remap_paths是前缀匹配,确保键是文件路径的准确前缀,比如lib/arm64/libfoo.so会被替换成lib/libfoo.so。

二、分析阶段调试工具与方法

1. Bazel内置调试参数

  • 生成分析阶段日志:执行bazel build --verbose_failures --subcommands --explain=analysis.log target,analysis.log会记录分析阶段的详细决策,包括规则属性的处理逻辑。
  • 直接打印属性值:在BUILD文件里用print()输出属性内容,比如:
    selected_srcs = select({
        "//condition_here": glob(["lib/arm64/*.so"]),
        "//conditions:default": glob(["lib/amd64/*.so"])
    })
    print("Selected srcs:", selected_srcs)
    
    pkg_tar(
        name = "my_tar",
        srcs = selected_srcs,
        # 其他属性...
    )
    
    执行bazel build target时,控制台会直接输出打印内容。

2. 正确修改rules_pkg源码调试

你修改缓存里的pkg.bzl没生效,是因为Bazel会缓存外部依赖的源码。要让修改生效:

  • 在WORKSPACE里把rules_pkg改成本地依赖:
    local_repository(
        name = "rules_pkg",
        path = "/path/to/your/local/rules_pkg",
    )
    
  • 修改本地rules_pkg/pkg.bzl后,执行bazel clean --expunge清除缓存,再重新构建,修改的代码才会被解析。

3. 用bazel query验证配置

执行bazel query --output=build //path/to:my_tar,查看目标的实际构建配置,确认remap_paths和srcs是否被正确解析。

内容的提问来源于stack exchange,提问作者Dragonsheep

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 22:57:01