13

I'm new to bazel, and I'm getting a failure to build my C++ package with

ERROR: /path/to/package/BUILD:linenumber:1 undeclared inclusion(s) in rule '//path/to/package:name': this rule is missing dependency declarations for the following files included by 'path/to/package/source_file.cpp'

...followed by a list of header files in a different directory. These files are not part of the package that is being built, but are being pulled in from elsewhere.

My question is how to properly add the declaration to the BUILD file to resolve the error?

According to the online Bazel docu here I should add each header to the srcs list. (To be clear, these are headers that are used internally by the library I'm building and not part of the public interface, so they don't belong in hdrs.) But If I try that,

  srcs = [ ..., "path/to/dependent/headers/header.h",]

I get an error message

ERROR: ... crosses boundary of subpackage ... (perhaps you meant to put the colon here: ...?)

because the directory with the headers isn't a Bazel package.

If I try changing the final / to a colon as that error message suggests,

  srcs = [ ..., "path/to/dependent/headers:header.h",]

then

ERROR: ... target names may not contain ':'.

The Bazel C++ tutorial here, in the section "Additonal Include Paths" says that external include directories should be declared via copts:

cc_library(
    name = "some_lib",
    srcs = ["some_lib.cc"],
    hdrs = ["some_lib.h"],
    copts = ["-Ithird_party/some_lib"],
)

But adding that -I flag does not git rid of the "undeclared inclusion(s)" error!

$ bazel version
Build label: 0.4.3
Build target: bazel-out/local-fastbuild/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: Thu Dec 22 12:31:25 2016 (1482409885)
Build timestamp: 1482409885
Build timestamp as int: 1482409885
Die in Sente
  • 9,546
  • 3
  • 35
  • 41

3 Answers3

16

I met a similar problem "undeclared inclusion(s) in rule", I solved it by removing the bazel cache files in "/root/.cache/bazel/".

E_net4
  • 27,810
  • 13
  • 101
  • 139
bidai
  • 211
  • 3
  • 5
  • 2
    Thanks, I haven't used it in a while and it was something in the cache... – Nico Mar 12 '18 at 15:02
  • 1
    Deleting everything from the Bazel cache resolved the issue for me that I had after upgrading Clang on Windows and using in in Bazel with --compiler=clang-cl. – astraujums Feb 03 '21 at 12:22
  • Please keep in mind that removing Bazel's cache has a big timing cost overhead. The whole cache has to be constructed from the beginning (which will take some time to do it). I haven't tried `Elizebeth Kurian`'s answer. It might provide better performance. – mgNobody May 11 '22 at 19:56
6

Bazel wants you to depend on the headers (i.e., put them in deps). Basically, you should create a cc_library for those headers. Putting headers in hdrs doesn't publicly expose them, it just exposes them to rules that depend on that library (which is exactly what you want). So you'll have:

# third_party/some_lib/BUILD
cc_library(
    name = "headers",
    hdrs = glob(["*.h"]),
    visibility = ["//path/to/package:__pkg__"],
)

Note that you should replace //path/to/package with your actual target's package, but the __pkg__ above is literal: that's how you indicate "visible to that package". Then no other packages can access those headers.

Then add //third_party/some_lib:headers in your target's deps.

The copts are just used to modify C++'s header search paths, not Bazel's. Bazel always assumes that you'll do #include "path/relative/to/your/workspace/dir.h", but if you've got a source like:

#include "foo.h"

where foo.h is at third_party/some_lib/includes/foo.h, you could say copts = ["-Ithird_party/some_lib/includes"] to add that to C++'s header search path.

kris
  • 23,024
  • 10
  • 70
  • 79
  • Thanks, @kristina. So, the trick is I have to modify the third_party source tree to add a minimal Bazel BUILD file over there -- whether I "own" that tree or not. It can't be done from inside the source tree for my package. – Die in Sente May 11 '17 at 21:34
  • Sort of, you can add a BUILD file at `//third_party:BUILD` or `//:BUILD`, if you don't want to "pollute" a 3rd party source. – kris May 11 '17 at 21:56
3

try out this, this worked for me

bazel clean --expunge

this command will clean up all disk and memory traces of a Bazel instance. reference : https://docs.bazel.build/versions/main/user-manual.html

desertnaut
  • 57,590
  • 26
  • 140
  • 166