Bazel构建Go应用时出现"Argument list too long"错误求助
解决Bazel构建Go应用时"Argument list too long"错误的方案
我之前也遇到过Mac上Bazel构建大型Go项目的这个问题,根源就是Mac的sandbox-exec工具对命令行参数长度有严格限制,当你的项目依赖包和源文件太多时,参数列表就会超出阈值。下面是针对你的环境(Bazel 0.11.1 + Go Rules 0.11.0)的具体解决办法:
快速临时解决:构建命令添加标志
直接在构建时加上Bazel的实验性参数文件标志,它会自动把过长的参数写入临时文件,避免命令行溢出:
bazel build //go-app --experimental_action_param_file=auto
这个标志在Bazel 0.11.x版本已经支持,它会自动检测参数长度,超过阈值时自动切换到参数文件模式。
持久化解决方案:配置.bazelrc
如果你不想每次构建都手动加标志,可以在项目根目录创建或修改.bazelrc文件,添加全局配置:
# .bazelrc build --experimental_action_param_file=auto
这样后续所有bazel build命令都会自动启用参数文件功能,一劳永逸。
进阶自定义:用Skylark Args API实现(适合需要精细控制的场景)
如果你想在BUILD文件中直接通过规则配置参数文件,可以写一个简单的自定义规则,利用Args.use_param_file方法强制使用参数文件:
load("@io_bazel_rules_go//go:def.bzl", "go_context") def _param_file_go_binary_impl(ctx): go = go_context(ctx) args = go.actions.args() # 配置Go编译参数 args.add("build") args.add("-o", ctx.outputs.executable) args.add_all(ctx.files.srcs) # 启用参数文件:把参数写入临时文件,用@前缀指定文件路径 args.use_param_file("@%s", use_always = True) # 执行编译动作 go.actions.run( executable = go.go, arguments = [args], inputs = ctx.files.srcs + ctx.files.deps + go.sdk.files, outputs = [ctx.outputs.executable], env = go.env, ) param_file_go_binary = rule( implementation = _param_file_go_binary_impl, executable = True, attrs = { "srcs": attr.label_list(allow_files = [".go"]), "deps": attr.label_list(), "_go_context_data": attr.label(default = "@io_bazel_rules_go//:go_context_data"), }, toolchains = ["@io_bazel_rules_go//go:toolchain"], )
然后在BUILD文件中用这个自定义规则替代官方的go_binary:
param_file_go_binary( name = "go-app", srcs = glob(["*.go"]), deps = [ # 你的依赖列表 ], )
这种方式适合需要对参数传递做更精细控制的场景,不过日常使用前面两种方法就足够了。
内容的提问来源于stack exchange,提问作者Deepak
相关产品推荐
相关产品推荐

