I can't properly add external dependency with bazel

Viewed 546

I trying to test "Hello World" C++ project with Bazel.

I have the following project structure:

WORKSPACE
/dependencies
  BUILD
  BUILD.gtest
/test
  BUILD

WORKSPACE has the following structure:

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

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

BUILD.gtest has the following structure:

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 has the following structure:

cc_test(
  name = "unittests",
  srcs = ["scanner_test.cc"],
  copts = ["-Iexternal/gtest/include"],
  deps = [
   "//scanner:scanner",
   "@gtest//:main"
  ]
)

when I execute

bazel build //test:unittests

I get

INFO: Analyzed target //test:unittests (26 packages loaded, 315 targets configured).
INFO: Found 1 target...
ERROR: ../test/BUILD:1:8: Compiling test/scanner_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 argument(s) skipped)

Use --sandbox_debug to see verbose messages from the sandbox
test/scanner_test.cc:1:10: fatal error: gtest/gtest.h: No such file or directory
    1 | #include "gtest/gtest.h"
      |          ^~~~~~~~~~~~~~~
compilation terminated.
Target //test:unittests failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 2.314s, Critical Path: 0.08s
INFO: 2 processes: 2 internal.
FAILED: Build did NOT complete successfully
2 Answers

As the other answer mentions:

The file BUILD.gtest is not needed.

Because gtest repo / release archive already provides one.

The reason why your own didn't behave as you might have expected is you've tried to point to the headers by manipulating copts which is applied only to building that one specific cc_library target (from linked docs):

The flags take effect only for compiling this target, not its dependencies, so be careful about header files included elsewhere.

Whereas to expose these interfaces to other targets consuming it you need to use includes (docs again):

Unlike COPTS, these flags are added for this rule and every rule that depends on it.

The file BUILD.gtest is not needed.

WORKSPACE.bazel:

workspace(name = "GTestDemo")

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

http_archive(
  name = "gtest",
  url = "https://github.com/google/googletest/archive/release-1.10.0.tar.gz",
  sha256 = "9dc9157a9a1551ec7a7e43daea9a694a0bb5fb8bec81235d8a1e6ef64c716dcb",
  strip_prefix = "googletest-release-1.10.0",
)

BUILD.bazel:

cc_test(
    name = "tests",
    srcs = ["test.cpp"],
    deps = [
        "@gtest//:gtest",
        "@gtest//:gtest_main",
    ],
)

test.cpp:

#include <iostream>
#include <fstream>

#include "gtest/gtest.h"

using namespace std;

TEST(sample_test_case, sample_test) {
    EXPECT_EQ(1, 1);
}

Tested with Bazel 4.1.0.

Related