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

使用Bazel genrule生成ANTLR Go代码失败:声明输出未创建

问题

使用Bazel的genrule工具基于ANTLR语法生成Go语言词法/语法分析器时,执行bazel build报错:

declared output 'grammar/hello_lexer.go' was not created by genrule

但在Shell中手动运行相同ANTLR命令,能成功生成包括hello_lexer.go在内的目标文件。

文件结构

ls grammar 
BUILD.bazel         Hello.g4            antlr-4.13.1-complete.jar

BUILD.bazel配置

load("@rules_java//java:defs.bzl", "java_library", "java_import")

java_import(
    name = "antlr_jar",
    jars = ["antlr-4.13.1-complete.jar"],
)

genrule(
    name = "generate_parser",
    srcs = glob(["Hello.g4"]),

    tools = [":antlr_jar"],
    cmd = "java -Xmx500M -cp $(location :antlr_jar) org.antlr.v4.Tool -Dlanguage=Go -no-visitor -package parsing  $(SRCS)",
    outs = ["hello_lexer.go"],
)

错误日志

bazel build --subcommands --verbose_failures --sandbox_debug //grammar:generate_parser
INFO: Analyzed target //grammar:generate_parser (0 packages loaded, 0 targets configured).
SUBCOMMAND: # //grammar:generate_parser [action 'Executing genrule //grammar:generate_parser', configuration: 7baf2462b8dc082d7868aad895e80c01f6d9dba247a3296e4fd6dd318f4433c1, execution platform: @@local_config_platform//:host, mnemonic: Genrule]
(cd /private/var/tmp/_bazel_jp/64463e3d7652188cb285edbcf54b686c/execroot/_main && \
  exec env - \
    PATH=/Users/jp/Library/Caches/bazelisk/downloads/sha256/b1cf1c5783fa3eac60942bf2ec6169cfccecd2fa5a355587d8d35983bc1e1310/bin:/opt/homebrew/opt/openjdk/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/Library/Frameworks/Python.framework/Versions/3.12/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/opt/homebrew/opt/coreutils/libexec/gnubin:/usr/local/go/bin:/Applications/GoLand.app/Contents/MacOS:/Users/jp/go/bin/ \
  /bin/bash -c 'source external/bazel_tools/tools/genrule/genrule-setup.sh; java -Xmx500M -cp grammar/antlr-4.13.1-complete.jar org.antlr.v4.Tool -Dlanguage=Go -no-visitor -package parsing  grammar/Hello.g4')
# Configuration: 7baf2462b8dc082d7868aad895e80c01f6d9dba247a3296e4fd6dd318f4433c1
# Execution platform: @@local_config_platform//:host
ERROR: /Users/jp/src/fizzbee/grammar/BUILD.bazel:8:8: declared output 'grammar/hello_lexer.go' was not created by genrule. This is probably because the genrule actually didn't create this output, or because the output was a directory and the genrule was run remotely (note that only the contents of declared file outputs are copied from genrules run remotely)
ERROR: /Users/jp/src/fizzbee/grammar/BUILD.bazel:8:8: Executing genrule //grammar:generate_parser failed: not all outputs were created or valid
Target //grammar:generate_parser failed to build
INFO: Elapsed time: 0.481s, Critical Path: 0.35s
INFO: 2 processes: 1 internal, 1 darwin-sandbox.
ERROR: Build did NOT complete successfully

手动执行命令后生成的文件

ls grammar/ 
BUILD.bazel         Hello.tokens            antlr-4.13.1-complete.jar   hello_listener.go
Hello.g4            HelloLexer.interp       hello_base_listener.go      hello_parser.go
Hello.interp            HelloLexer.tokens       hello_lexer.go

原因与解决方案

问题原因

  1. 输出路径不匹配:Bazel的genrule在沙箱环境的execroot目录下执行命令,ANTLR默认会在当前工作目录(execroot根目录)生成文件,但Bazel期望输出文件出现在对应包的指定路径下,导致Bazel找不到声明的hello_lexer.go。
  2. 输出文件未完全声明:ANTLR实际生成多个文件,但配置中仅声明了hello_lexer.go,后续可能引发其他构建问题。

修复步骤

修改BUILD.bazel配置,做两处调整:

  1. 添加-o $(RULEDIR)参数,指定ANTLR输出到Bazel提供的genrule专属输出目录($(RULEDIR)是Bazel内置变量)。
  2. 将ANTLR生成的所有文件都添加到outs列表中,确保Bazel能捕获所有预期输出。

修改后的配置:

load("@rules_java//java:defs.bzl", "java_import")

java_import(
    name = "antlr_jar",
    jars = ["antlr-4.13.1-complete.jar"],
)

genrule(
    name = "generate_parser",
    srcs = ["Hello.g4"],
    tools = [":antlr_jar"],
    cmd = "java -Xmx500M -cp $(location :antlr_jar) org.antlr.v4.Tool -Dlanguage=Go -no-visitor -package parsing -o $(RULEDIR) $(SRCS)",
    outs = [
        "hello_lexer.go",
        "hello_parser.go",
        "hello_base_listener.go",
        "hello_listener.go",
        "Hello.tokens",
        "HelloLexer.tokens",
        "Hello.interp",
        "HelloLexer.interp",
    ],
)

验证

重新执行bazel build //grammar:generate_parser,ANTLR会将所有文件生成到Bazel指定的输出目录,Bazel能正确识别所有声明的输出,构建即可成功。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 12:45:55