Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resolve bazel "undeclared inclusion(s)" error?

Tags:

c++

bazel

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
like image 523
Die in Sente Avatar asked May 11 '17 17:05

Die in Sente


Video Answer


2 Answers

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.

like image 142
kristina Avatar answered Sep 18 '22 01:09

kristina


I met similar prolblem "undeclared inclusion(s) in rule", I solved by removing the bazel cache files in /root/.cache/bazel/. Hope helps

like image 30
bidai Avatar answered Sep 20 '22 01:09

bidai