使用Bazel构建Makefile

7

我试图构建Bazel项目中子模块的Makefile。我发现Bazel确实提供了genrule来执行bash命令。当前我面临两个问题 -

1. 如何在执行命令之前进入目录,类似于 -

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

重现步骤:

  1. git clone git@github.com:bazelbuild/examples.git
  2. cd examples/ && git submodule add git@github.com:mucsi96/cpp-hello-world.git cpp-tutorial/stage1/main/hello
  3. 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文件是不可行的。


也许这个是一个半有用的例子--某些东西$(location ...) - Kerrek SB
谢谢,是的,我希望逐步解决这个问题。当我使用cd ./$(location hello)时,会出现$(location) expression is not a declared prerequisite of this rule错误。 - Aditya
你需要引用其中一个已声明的名称 -- 比如如果你有 srcs = ["foo.txt"] + glob(["*.json]), ,那么你可以引用 $(location :foo.txt) 等等。也许列出你的源文件清单,或至少其中一个(Makefile)? - Kerrek SB
1个回答

10

如果您想构建使用一个Makefile的C++项目,不要自己编写genrule,而应该使用rules_foreign_ccrules_foreign_ccenvoy和其他各种大型C++程序用于构建外部基于CMake和Make的依赖项。

参见简单的Makefile示例。在其中,您首先需要创建一个filegroup来收集与要构建的项目相关的所有源代码和文件,包括Makefile本身:

filegroup(
    name = "sources",
    srcs = glob(["**"]),
    visibility = ["//simple_make:__subpackages__"],
)

接下来,调用rules_foreign_ccmake规则,该规则还带有其他make特定属性,如prefixmake_env_vars,甚至一种使用make_commands覆盖整个make命令的方法。在这个例子中,我们只是使用了lib_sourcestatic_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和其他规则不应修改源代码的状态,而只应该生成输出文件。考虑在构建之前运行单独的脚本来更新子模块。


谢谢,这是非常详细和有帮助的答案! :) 假设我没有写入子项目的权限,我正在尝试构建它。在这个例子中,我不能在code目录中有BUILD文件,只能在父目录中。是否有一种方法可以在simple_make/BUILD文件中创建filegroup,而不是在simple_make/code/BUILD中? - Aditya
1
你可以在父目录中拥有BUILD文件 - 没问题。另一种选择是在子项目上创建一个new_local_repository,并像“编写”子项目一样在其上应用自己的BUILD文件,但我建议只在父目录中编写一个BUILD文件。您可以在此处了解更多信息:https://docs.bazel.build/versions/master/be/workspace.html#new_local_repository - Jin
在堆栈帖子中跟进 - https://stackoverflow.com/questions/58211438/output-external-name-repo-lib-lib-so-was-not-created-using-bazel-make - Aditya
关于将此链接到cc_library规则的另一个后续。 - Aditya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接