为何Bazel的rules_foreign_cc中make规则无法找到/生成产物?
使用rules_foreign_cc构建Makefile项目时输出文件找不到的问题
问题分析
核心问题是rules_foreign_cc在沙箱环境执行Makefile构建后,Bazel无法在预期路径定位到生成的二进制文件,具体诱因包括:
- 冗余文件干扰:
filegroup用glob(["**"])包含了hello目录下所有文件(包括多余的WORKSPACE),可能打乱沙箱内的文件结构。 - 输出路径不匹配:rules_foreign_cc会在独立沙箱环境构建,默认要求产物输出到指定的
OUT_DIR目录,但你的Makefile直接在当前目录生成hello_binary,导致Bazel无法找到目标文件。 - 无效clean命令:Makefile的clean指令尝试删除
hello,但实际生成的是hello_binary,虽不影响构建,但建议修正。
解决方案
方案1:修改Makefile,输出到Bazel指定目录
rules_foreign_cc执行构建时会自动设置OUT_DIR环境变量,指向Bazel期望的输出目录。修改Makefile,将二进制文件输出到该路径:
all: gcc hello.c -o $(OUT_DIR)/hello_binary clean: rm -f $(OUT_DIR)/hello_binary
方案2:修正BUILD.bazel配置
- 限制
filegroup仅包含必要的构建文件,避免冗余文件干扰 - 移除不必要的
out_bin_dir设置(规则默认会处理输出路径)
修改后的hello/BUILD.bazel:
load("@rules_foreign_cc//foreign_cc:defs.bzl", "make") filegroup( name = "hellosrc", srcs = [ "hello.c", "Makefile", ], ) make( name="hello_build", lib_source=":hellosrc", out_binaries=["hello_binary"], targets=["all"], )
额外优化
删除hello目录下的空WORKSPACE文件,根目录WORKSPACE已通过local_repository引入该子项目,冗余文件可能造成混淆。
验证方法
若仍有问题,添加--verbose_failures参数查看详细执行日志:
bazel build @hello//:hello_build --verbose_failures
通过日志可查看Makefile的执行路径、文件生成位置,进一步排查问题。
内容的提问来源于stack exchange,提问作者theo
相关产品推荐
相关产品推荐

