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
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.
I met similar prolblem "undeclared inclusion(s) in rule", I solved by removing the bazel cache files in /root/.cache/bazel/. Hope helps
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With