【问题标题】:how to include header file for each file compiled via bazel如何为通过 bazel 编译的每个文件包含头文件
【发布时间】:2022-01-04 05:18:16
【问题描述】:

我有一个正在使用 bazel 构建的项目。我的应用程序在其 BUILD 文件中引用了另一个 bazel 存储库作为依赖项,我们称之为 @dep。我无法对@dep 中的代码进行任何更改,但我需要覆盖在@dep 的一个头文件中定义的C 宏。

我考虑过使用编译器选项 -D 来定义在我要替换的头文件顶部定义的符号,其中包含 C 宏,然后使用 -include 在我的宏中包含不同的头文件,对于通过 bazel 编译的 @dep 中的所有文件。但是在 cc_binary 中,没有 -include 选项,copt = [] 只会对正在编译的目标起作用,而对其依赖项不起作用。

我看到了这篇文章,但不幸的是没有发布解决方案 - How to specify preprocessor includes in Bazel? (-include common_header.h)

【问题讨论】:

  • 我认为feature 可以完成这项工作,也许您可​​以自己弄清楚细节:docs.bazel.build/versions/main/…
  • @Andreas 似乎这需要我定义一个新的工具链,这对于像我需要的那样简单的东西来说似乎有点矫枉过正?文档也很难理解。我不明白为什么他们没有通过 cc_binary 构建规则在编译器命令行上为每个编译的文件提供使用 -include 的方法。毕竟他们已经定义了 = []。
  • 亲爱的 OP,这是 C 还是 C++ 的?
  • @user426 C++ 但我认为这并不重要。

标签: c++ c bazel


【解决方案1】:

我不明白为什么他们没有通过 cc_binary 构建规则在编译器命令行上为每个编译的文件提供使用 -include 的方法。毕竟他们已经定义了 = []。

一般来说,bazel 并没有提供很多这样的机制,因为它可能会导致大型存储库中出现扩展问题。例如。说 project1 和 project2 依赖于 1000 个 cc_library 目标的同一棵树。将它们一起构建会导致构建 1000 个 cc_library 目标。但是如果 cc_binary 有办法改变其依赖项的编译方式,并且 project2 做了类似的事情,那么现在一起构建两个项目需要构建 2000 个 cc_library 目标,这会增加一倍内存需求、远程缓存需求、远程执行需求,增加分析时间。

对于defines 属性,它会影响依赖于defines 目标的事物,但不会影响该目标的依赖关系(它会“向上”构建图,而不是“向下”,如果cc_binary 位于顶部)。

也就是说,有一些方法可以改变目标的依赖关系的编译方式,这些被称为“配置转换”。 (例如 android_binary 使用一个在单个应用程序中编译多个 cpu 架构,但从 [x86] 到 [x86, arm64] 〜双倍如上)。不过,配置转换很少涉及。

在命令行上有更简单的选项,例如--copt,它们会影响整个构建,这可能会起作用。下面的示例可能会满足您的需要。它依赖于被“#ifndef”包围的宏。如果没有#ifndef,它似乎不起作用,一些粗略的搜索说源代码中的宏无法在命令行上替换(我自己不是 c/c++ 专家)。如果重写宏确实需要它位于源文件中,这很棘手,因为没有直接的方法可以将文件添加到每个 cc 操作(或某个子集)的输入中。如果它确实有效,您可以将build --copt=... 添加到工作区根目录下的.bazelrc 文件中,这样您就不必将其添加到命令行。否则,我能想到的唯一其他事情就是自定义工具链,正如其他人提到的那样。

repo1$ bazel run foo
INFO: Analyzed target //:foo (1 packages loaded, 160 targets configured).
INFO: Found 1 target...
Target //:foo up-to-date:
  bazel-bin/foo
INFO: Elapsed time: 0.318s, Critical Path: 0.09s
INFO: 5 processes: 1 internal, 4 linux-sandbox.
INFO: Build completed successfully, 5 total actions
INFO: Build completed successfully, 5 total actions
bar is 16

repo1$ bazel run foo --copt=-DBAZ=15
INFO: Build option --copt has changed, discarding analysis cache.
INFO: Analyzed target //:foo (0 packages loaded, 160 targets configured).
INFO: Found 1 target...
Target //:foo up-to-date:
  bazel-bin/foo
INFO: Elapsed time: 0.252s, Critical Path: 0.09s
INFO: 5 processes: 1 internal, 4 linux-sandbox.
INFO: Build completed successfully, 5 total actions
INFO: Build completed successfully, 5 total actions
bar is 38

repo1/BUILD:

cc_binary(
  name = "foo",
  srcs = ["foo.c", "foo.h"],
  deps = ["@repo2//:bar"],
)

repo1/WORKSPACE:

local_repository(
  name = "repo2",
  path = "../repo2",
)

repo1/foo.c:

#include "foo.h"
#include "bar.h"
#include "stdio.h"

int main() {
  printf("bar is %d\n", bar());
  return 0;
}

repo1/foo.h:


repo2/BUILD:

cc_library(
  name = "bar",
  srcs = ["bar.c"],
  hdrs = ["bar.h"],
  deps = [":baz"],
  visibility = ["//visibility:public"],
)

cc_library(
  name = "baz",
  srcs = ["baz.c"],
  hdrs = ["baz.h"],
  visibility = ["//visibility:public"],
)

repo2/WORKSPACE:


repo2/bar.c:

#include "bar.h"
#include "baz.h"

int bar() {
  return baz() + BAR;
}

repo2/bar.h:

#define BAR 8

int bar();

repo2/baz.c:

#include "baz.h"

int baz() {
  return BAZ * 2;
}

repo2/baz.h:

#ifndef BAZ
#define BAZ 4
#endif

int baz();

【讨论】:

    猜你喜欢
    • 2018-06-24
    • 1970-01-01
    • 2018-10-26
    • 2012-07-06
    • 1970-01-01
    • 2021-12-15
    • 2020-05-17
    • 1970-01-01
    • 2016-04-13
    相关资源
    最近更新 更多