gpt4 book ai didi

bazel - 用 bazel 构建一个简单的库,修复包含路径

转载 作者:行者123 更新时间:2023-12-04 10:13:56 34 4
gpt4 key购买 nike

我有一个非常简单的目录结构:

.
├── libs
│   └── foo
│   ├── BUILD
│   ├── include
│   │   └── foo
│   │   └── func.h
│   └── src
│   └── func.cxx
└── WORKSPACE

func.h :
#pragma once

int square(int );

func.cxx :
#include <foo/func.h>

int square(int i) { return i * i; }

BUILD :
cc_library(
name = "foo",
srcs = ["src/func.cxx"],
hdrs = ["include/foo/func.h"],
visibility = ["//visibility:public"],
)

这无法构建:
$ bazel build //libs/foo
INFO: Analysed target //libs/foo:foo (0 packages loaded).
INFO: Found 1 target...
ERROR: /home/brevzin/sandbox/bazel/libs/foo/BUILD:1:1: C++ compilation of rule '//libs/foo:foo' failed (Exit 1)
libs/foo/src/func.cxx:1:22: fatal error: foo/func.h: No such file or directory
#include <foo/func.h>
^
compilation terminated.
Target //libs/foo:foo failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 0.299s, Critical Path: 0.02s
FAILED: Build did NOT complete successfully

如何正确设置包含路径?我尝试使用 include_prefix (无论是 include 还是 include/foo )但这并没有改变行为。

最佳答案

嗯,包含来自其他地方的头文件的棘手部分是您必须根据工作空间(WORKSPACE 文件所在的位置)从其相对位置指定头文件。

此外,您不应该使用尖括号,包括样式 #include <a/b.h>除非您包含系统头文件。
#include的相关规范可以在这里找到:https://docs.bazel.build/versions/master/bazel-and-cpp.html#include-paths

TL;博士 您需要对 func.cxx 进行的唯一更改文件就是,把第一行改成#include "libs/foo/include/foo/func.h" .

然后,当你运行 bazel build //... (在此工作区中构建所有目标,类似于 make 生成 all )从工作区的根目录,您将不会遇到错误。

但是,这并不是解决您问题的唯一方法。

解决此问题的另一种方法(不涉及更改源代码包含语句)是在规则 cc_library 的属性中指定包含路径。 .

这意味着,您可以更改您的 BUILD在路径中 libs/foo使它看起来像这样:

cc_library(
name = "foo",
srcs = ["src/func.cxx"],
hdrs = ["include/foo/func.h"],
copts = ["-Ilibs/foo/include"], # This is the key part
visibility = ["//visibility:public"],
)

在此更改之后,编译器将能够找出在哪里可以找到头文件,并且您不必更改源代码,是的。

相关信息可以在这里找到: https://docs.bazel.build/versions/master/cpp-use-cases.html#adding-include-paths



尽管如此,还有另一种解决问题的hacky方法,但是,它涉及对代码进行更多更改。

它利用了规则 cc_inc_library .

规则 cc_inc_library将带 prefixhdrs 中指定的头文件的相对路径传递给此规则的属性属性。

网站上的示例有点困惑,您的代码和目录结构将产生更好的演示目的。

在您的情况下,您必须修改您的 BUILD文件下 libs/foo看起来像这样的东西:
cc_library(
name = "foo",
srcs = ["src/func.cxx"],
deps = [":lib"],
copts = ["-Ilibs/foo/include"],
visibility = ["//visibility:public"],
)

cc_inc_library(
name = "lib",
hdrs = ["include/foo/func.h"],
prefix = "include/foo",
)

在您的情况下,头文件 func.h它具有来自包 libs/foo 的相对路径如 include/foo/func.h ,这是在 hdrs 中指定的属性。
因为它有一个到工作区根目录的相对路径为 libs/foo/include/foo/func.h ,以及 prefix cc_inc_library 中的属性指定为 include/foo :值 include/foo将被剥离形式 lib/foo/include/foo/func.h ,制作 libs/foo/func.h .

所以,现在你可以在你的 func.cxx 中包含这个头文件。如 #include "libs/foo/func.h" .
现在,bazel 不会报错说找不到头文件了。

您可以在以下位置找到有关此规则的信息: https://docs.bazel.build/versions/master/be/c-cpp.html#cc_inc_library .
然而,如上所述,解释充其量是令人困惑的,可能是因为它的文档已经过时了。

我被 bazel.build上的office解释搞糊涂了很长一段时间,直到我阅读了这条规则的源代码: https://github.com/bazelbuild/bazel/blob/f20ae6b20816df6a393c6e8352befba9b158fdf4/src/main/java/com/google/devtools/build/lib/rules/cpp/CcIncLibrary.java#L36-L50

实现该函数的实际代码的注释在解释该规则的实际作用方面做得更好。
cc_inc_library自 Bazel 0.12 版以来,规则已被弃用。

使用 cc_library方法代替。

见: https://blog.bazel.build/2018/04/11/bazel-0.12.html

关于bazel - 用 bazel 构建一个简单的库,修复包含路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47915433/

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