gpt4 book ai didi

bazel - 从系统包含目录中隔离Bazel C++构建

转载 作者:行者123 更新时间:2023-12-02 16:22:11 27 4
gpt4 key购买 nike

我想使Bazel C ++构建独立于/usr/include/usr/local/include等。默认情况下,如this thread中所述,/usr/include中的所有文件在编译C ++程序时都可用,而不仅仅是标准程序。

实现此目标的最佳方法是什么?

一种选择是将标准头文件放入tarball中,并通过HTTP托管在某个位置,然后添加new_http_repository并使用gcc运行-nostdinc -isysroot

最佳答案

该解决方案包括三个部分:


创建一个自定义C ++工具链定义
说服Bazel使用该工具链
说服编译器忽略其默认系统头并使用您的默认系统头


这是您需要的参考:

https://docs.bazel.build/versions/master/crosstool-reference.html
https://docs.bazel.build/versions/master/tutorial/crosstool.html

这是一个特别好的教程:

https://github.com/bazelbuild/bazel/wiki/Yet-Another-CROSSTOOL-Writing-Tutorial

还有更多教程,我不知道它们是最新的:

https://github.com/bazelbuild/bazel/wiki/About-the-CROSSTOOL
https://github.com/bazelbuild/bazel/wiki/Building-with-a-custom-toolchain



这是我如何在带有GCC的Linux上进行此工作的方法:


创建一个带有虚拟cc_binary规则的新工作区。

mkdir /tmp/bar && cd /tmp/bar
touch WORKSPACE
echo "cc_binary(name='x',srcs=['x.cc'])" > BUILD
echo -e "#include <stdio.h>\nint main(void) { return 0; }" > x.cc

建立虚拟目标。

bazel build //:x


由于这是cc_ *规则,Bazel将初始化C ++工具链。这包括自动生成
CROSSTOOL文件。这是一个描述编译器界面的文本文件,因此Bazel知道如何
与之交谈。
为您的自定义crosstool创建一个程序包,在其中复制自动生成的CROSSTOOL和BUILD文件。

mkdir /tmp/bar/my_toolchain
touch /tmp/bar/my_toolchain/WORKSPACE
cat $(bazel info output_base)/external/local_config_cc/CROSSTOOL > /tmp/bar/my_toolchain/CROSSTOOL
cat $(bazel info output_base)/external/local_config_cc/BUILD > /tmp/bar/my_toolchain/BUILD


我们将使用自动生成的文件作为模板开始。
将外部存储库规则添加到WORKSPACE文件。

echo "local_repository(name='my_toolchain', path='/tmp/bar/my_toolchain')" >> WORKSPACE


这样,您可以通过Bazel构建标签引用自定义工具链。
尝试使用自定义工具。

bazel build --crosstool_top=@my_toolchain//:toolchain //:x


由于它与自动生成的相同,因此构建应该成功。
通过自定义CROSSTOOL中的“本地”工具链编辑系统头文件路径。

注意:如果要选择,则可能需要编辑其他工具链。看到
这里的工具链选择:
https://docs.bazel.build/versions/master/crosstool-reference.html#toolchain-selection

在文本编辑器中,打开 /tmp/bar/my_toolchain/CROSSTOOL,找到“工具链”记录,该记录的
“ toolchain_identifier”是“ local”,并注释掉其“ cxx_builtin_include_directory”条目
(注释字符为“#”)。

然后为您的工具链目录添加新的“ cxx_builtin_include_directory”:

cxx_builtin_include_directory: "/tmp/bar/my_toolchain"


您刚刚告诉Bazel系统标头在哪里,因此当它验证标头包含时,它将知道此路径下的标头是系统标头并且允许包含。
添加一个编译器标志来声明系统头文件的位置。

在刚刚添加的“ cxx_builtin_include_directory”行下,添加以下内容:

compiler_flag: "-isystem=/tmp/bar/my_toolchain"


您刚刚告诉Bazel告诉编译器应该在哪里查找系统头文件。
将标头添加到默认的编译操作输入集中。

在文本编辑器中,打开 /tmp/bar/my_toolchain/BUILD,找到“ compiler_deps”文件组,然后
例如,编辑其“ srcs”属性,如下所示:

srcs = glob(["**/*.h"]),


您刚刚告诉Bazel始终将这些文件包含在C ++编译操作中,因此构建
将可用于沙箱和远程执行,并且Bazel将重新构建C ++规则(如果有
系统标头(您刚刚添加到 srcs的标头)会发生变化。
创建一个模拟 stdc-predef.h

这是编译器始终希望包含的头文件。幸运的是,编译器将首先
请先检查您的“ -isystem”值,然后再返回其默认路径(我不知道是否
您可以将其告诉ingore),因此我们可以像下面这样模拟该文件:

touch /tmp/bar/my_toolchain/std-predef.h

尝试使用自定义Crosstool进行构建。

$ bazel build --crosstool_top=@my_toolchain//:toolchain //:x
INFO: Build options have changed, discarding analysis cache.
INFO: Analysed target //:x (0 packages loaded, 61 targets configured).
INFO: Found 1 target...
ERROR: /tmp/bar/BUILD:1:1: undeclared inclusion(s) in rule '//:x':
this rule is missing dependency declarations for the following files included by 'x.cc':
'/usr/include/stdio.h'
(...)
Target //:x failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 0.332s, Critical Path: 0.09s, Remote (0.00% of the time): [queue: 0.00%, setup: 0.00%, process: 0.00%]
INFO: 0 processes.
FAILED: Build did NOT complete successfully


由于在我们的工具链目录中没有 stdio.h,但是在编译器自身中只有一个
默认目录,它将找到文件并抱怨缺少标题。您可以创建一个
模拟 stdio.h使此静音。

您可以创建一个伪造的 stdio.h来使构建工作进行,也可以删除
#include <stdio.h>中的 x.cc行。
在自定义工具链中创建伪造的系统头。

我们将使用它来验证Bazel是否从自定义工具链中拾取文件。

echo 'int foo_func(int x) { return x*2; }' > /tmp/bar/my_toolchain/foo.h

重写源文件以包含自定义系统头。

echo -e '#include <foo.h>\nint main(int argc, char**) { return foo_func(argc); }' > x.cc

使用自定义工具链再次构建。现在一切正常。

bazel build --crosstool_top=@my_toolchain//:toolchain //:x

尝试使用2个args(so argc=3)运行构建的二进制文件:

bazel-bin/x hello world ; echo $?
6

关于bazel - 从系统包含目录中隔离Bazel C++构建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53715751/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com