为什么 Bazel http_archive 规则不下载存档?

Why does Bazel http_archive rule not download archive?

我是 Bazel 新手,正在阅读此处的 C++ 指南,尝试包含外部测试库 (gtest):https://bazel.build/tutorials/cpp-use-cases#include-external-libraries

这是我的文件结构以及 WORKSPACE 和 BUILD 文件内容:

$ tree
.
├── gtest.BUILD
├── lib
│   ├── BUILD
│   ├── hello-time.cc
│   └── hello-time.h
├── main
│   ├── BUILD
│   ├── hello-greet.cc
│   ├── hello-greet.h
│   └── hello-world.cc
├── README.md
├── test
│   ├── BUILD
│   └── hello-test.cc
└── WORKSPACE

工作空间的内容:

$ cat WORKSPACE 
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "gtest",
    build_file = "@//:gtest.BUILD",
    url = "https://github.com/google/googletest/archive/release-1.10.0.zip",
    sha256 = "94c634d499558a76fa649edb13721dce6e98fb1e7018dfaeba3cd7a083945e91",
)

gtest.BUILD 的内容:

$ cat gtest.BUILD 
cc_library(
    name = "main",
    srcs = glob(
        ["src/*.cc"],
        exclude = ["src/gtest-all.cc"]
    ),
    hdrs = glob([
        "include/**/*.h",
        "src/*.h"
    ]),
    copts = ["-Iexternal/gtest/include"],
    linkopts = ["-pthread"],
    visibility = ["//visibility:public"],
)

test/BUILD 的内容:

$ cat test/BUILD 
cc_test(
    name = "hello-test",
    srcs = ["hello-test.cc"],
    copts = ["-Iexternal/gtest/include"],
    deps = [
        "@gtest//:main",
        "//main:hello-greet",
    ],
)

然后我尝试 运行“bazel 测试 test:hello-test”,但它引发了一个问题,抱怨缺少“BUILD”文件:

ERROR: An error occurred during the fetch of repository 'gtest':
   Traceback (most recent call last):
    ...
Error in read: Unable to load package for //:gtest.BUILD: BUILD file not found in any of the following directories. Add a BUILD file to a directory to mark it as a package.
 - /home/user/code/bazelbuild_examples/cpp-tutorial/stage4

然后我 运行 在顶级目录中“touch BUILD”,在发现 GitHub 问题和类似的错误消息后,它消除了那个错误。

Bazel 现在正在下载 gtest 库(可以在“bazel-stage4/external/gtest”下看到它,但它似乎无法提供给测试目标:

ERROR: /home/user/code/bazelbuild_examples/cpp-tutorial/stage4/test/BUILD:1:8: Compiling test/hello-test.cc failed: (Exit 1): gcc failed: error executing command /usr/bin/gcc -U_FORTIFY_SOURCE -fstack-protector -Wall -Wunused-but-set-parameter -Wno-free-nonheap-object -fno-omit-frame-pointer '-std=c++0x' -MD -MF ... (remaining 25 arguments skipped)

Use --sandbox_debug to see verbose messages from the sandbox
test/hello-test.cc:1:10: fatal error: gtest/gtest.h: No such file or directory
    1 | #include "gtest/gtest.h"
      |          ^~~~~~~~~~~~~~~
compilation terminated.

为什么找不到 gtest headers/library? 运行进行“bazel 测试”时,目录布局如何工作? (即相对于第 3 方库目录的测试代码目录在哪里?)

我认为问题与您的 gtest 构建文件有关。首先,google test 已经带有受支持的 Bazel BUILD 文件,那么为什么要自己编写而不是使用他们的呢?

第二个:

cc_library(
    name = "main",
    srcs = glob(
        ["src/*.cc"],
        exclude = ["src/gtest-all.cc"]
    ),
    hdrs = glob([
        "include/**/*.h",
        "src/*.h"
    ]),
    copts = ["-Iexternal/gtest/include"],
    linkopts = ["-pthread"],
    visibility = ["//visibility:public"],
)

在此规则中,c++ 源代码必须为 headers #include 的路径是“include/.../*.h”。那是不合适的。首先,copts 影响 this 规则,但不影响依赖它的其他目标。一般来说,编译器选项应该是工具链的一部分,而不是像这样的规则。其次,cc_library 规则有一个 includes = [] 参数专门用于修复包含路径以去除前导前缀。而不是 copts 你应该使用 includes 来修复路径--------但是你应该使用官方的 google 测试构建文件而不是自己编写并且不必处理有这样的问题。