如何为Bazel的go_test编写包装器替换Linux动态加载器
解决rules_go中go_test的Fedora ld执行包装问题
核心思路
通过自定义Shell包装脚本替换go_test的默认执行入口,调用runfiles中自带的Fedora ld-linux-x86-64.so.2来加载Go测试二进制,绕过主机系统(如Ubuntu)的ld解释器,解决glibc版本不匹配导致的段错误。
具体实现步骤
1. 编写Fedora ld包装脚本
在项目中创建一个Shell脚本(比如//scripts/fedora_ld_wrapper.sh),内容如下:
#!/bin/bash # 从Bazel自动设置的RUNFILES_DIR中找到Fedora ld路径 FEDORA_LD="${RUNFILES_DIR}/fedora_sysroot/usr/lib64/ld-linux-x86-64.so.2" # 提取测试二进制路径(Bazel会将其作为第一个参数传给wrapper) TEST_BINARY="$1" # 移除第一个参数,保留后续测试参数 shift # 用Fedora ld加载测试二进制并传入剩余参数 exec "$FEDORA_LD" "$TEST_BINARY" "$@"
注意:如果你的Fedora ld在runfiles中的路径不同,需要调整
FEDORA_LD的路径(比如依赖标签是@your_fedora_libs//:ld-linux-x86-64.so.2,路径要对应)。
2. 在BUILD文件中配置go_test
在你的BUILD文件中,添加对Fedora ld和包装脚本的依赖,并设置test_wrapper字段:
load("@io_bazel_rules_go//go:def.bzl", "go_test") # 声明Fedora ld的依赖(根据你的实际依赖标签调整) filegroup( name = "fedora_ld", srcs = ["@fedora_sysroot//:usr/lib64/ld-linux-x86-64.so.2"], visibility = ["//visibility:private"], ) go_test( name = "my_test", srcs = ["my_test.go"], # 你的常规依赖(包括cgo链接的Fedora库) deps = [ "//your/package/deps", "@fedora_sysroot//:your_libs", ], # 将Fedora ld和包装脚本加入测试的runfiles data = [ ":fedora_ld", "//scripts:fedora_ld_wrapper.sh", ], # 指定包装脚本作为测试的执行入口 test_wrapper = "//scripts:fedora_ld_wrapper.sh", # 确保RUNFILES_DIR环境变量可在脚本中使用 env = { "RUNFILES_DIR": "${RUNFILES_DIR}", }, )
3. 确保脚本权限
给包装脚本添加可执行权限:
chmod +x scripts/fedora_ld_wrapper.sh
或者在BUILD文件中用genrule处理权限:
genrule( name = "fedora_ld_wrapper_exec", srcs = ["fedora_ld_wrapper.sh"], outs = ["fedora_ld_wrapper_exec.sh"], cmd = "cp $< $@ && chmod +x $@", )
然后在go_test的data和test_wrapper中引用//scripts:fedora_ld_wrapper_exec.sh。
关键细节说明
RUNFILES_DIR是Bazel自动设置的环境变量,指向当前测试的runfiles目录,确保脚本能准确定位到Fedora ld。- 使用
exec命令替换脚本进程为ld的进程,避免额外的shell进程影响测试执行。 - 包装脚本会保留原测试的所有参数,确保测试逻辑不受影响。
内容的提问来源于stack exchange,提问作者Malt3
相关产品推荐
相关产品推荐

