我正在尝试在bazel项目中构建子模块的Makefile。我看到bazel确实提供了执行bash命令的规则。我目前面临两个问题-
1。如何在执行命令之前将CD插入目录,例如-
genrule(
name = "hello-make",
srcs = ["hello"] + glob(["hello/**"]),
outs = ["hello/main"],
cmd = "(cd $(location :hello) && make)",
)
2。在执行genrule之前如何更新更新子模块?
添加cmd = "(git submodule init && git submodule update)"
会得到fatal: Not a git repository (or any of the parent directories): .git
复制步骤:
git clone git@github.com:bazelbuild/examples.git
cd examples/ && git submodule add git@github.com:mucsi96/cpp-hello-world.git cpp-tutorial/stage1/main/hello
cd cpp-tutorial/stage1/ && bazel build //main:hello-world
此步骤之后,我想添加一条规则,该规则允许我进行初始化,更新并制作hello子模块。
是否有比将其创建为git@github.com:mucsi96/cpp-hello-world.git
的子模块更好的方法来构建git clone git@github.com:bazelbuild/examples.git
?
实际项目更加复杂,并且无法为cpp-hello-world.git创建BUILD文件。
答案 0 :(得分:5)
与其滚动自己的genrule
来构建一个使用Makefile
的(大概是C ++)项目,而是签出rules_foreign_cc
。 rules_foreign_cc
和其他各种大型C ++程序使用envoy
来构建外部CMake和基于Make的依赖项。
请参见simple_make
示例。在其中,您首先要制作一个filegroup
来收集与要构建的项目相关的所有源和文件,包括Makefile
本身:
filegroup(
name = "sources",
srcs = glob(["**"]),
visibility = ["//simple_make:__subpackages__"],
)
然后,调用rules_foreign_cc
的{{3}},它还带有其他make
特定的属性,例如prefix
,make_env_vars
,甚至还有一种使用make
覆盖整个make_commands
命令。在此示例中,我们仅使用lib_source
和static_libraries
属性:
load("@rules_foreign_cc//tools/build_defs:make.bzl", "make")
make(
name = "make_lib",
lib_source = "//simple_make/code:sources",
static_libraries = ["liba.a"],
)
最后,运行bazel build //package/to:make_lib
来调用make
规则。
在执行genrule之前如何更新更新子模块?
不要尝试执行此操作,尤其是当它更新就地项目源时。 genrules
和其他规则不应在构建期间修改源的状态,而应仅构建输出文件。考虑在构建之前运行单独的脚本来更新子模块。