使用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
原因与解决方案
问题原因
- 输出路径不匹配:Bazel的genrule在沙箱环境的execroot目录下执行命令,ANTLR默认会在当前工作目录(execroot根目录)生成文件,但Bazel期望输出文件出现在对应包的指定路径下,导致Bazel找不到声明的
hello_lexer.go。 - 输出文件未完全声明:ANTLR实际生成多个文件,但配置中仅声明了
hello_lexer.go,后续可能引发其他构建问题。
修复步骤
修改BUILD.bazel配置,做两处调整:
- 添加
-o $(RULEDIR)参数,指定ANTLR输出到Bazel提供的genrule专属输出目录($(RULEDIR)是Bazel内置变量)。 - 将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
相关产品推荐
相关产品推荐

