I'm struggling to understand the logic of how includes
work in Bazel targets. I want my code to be modular, so I am trying to avoid #include
statements with relative or long absolute paths.
Suppose I have the following workspace structure:
tree .
.
├── BUILD
├── is_binary_tree
│ ├── BUILD
│ └── is_binary_tree.cpp
├── lib
│ ├── BUILD
│ ├── graphs.cpp
│ └── graphs.h
└── WORKSPACE
I'm getting the following warning when trying to bazel build //is_binary_tree:is_binary_tree
and I don't understand what it means :
WARNING: /is_binary_tree/BUILD:1:10: in includes attribute of cc_binary rule //is_binary_tree:is_binary_tree: '../lib' resolves to 'lib' not below the relative path of its package 'is_binary_tree'. This will be an error in the future
Why would ../lib
resolve to lib
. Lib should be in the parent directory of is_binary_tree, so from the standpoint of is_binary_tree it can be found at ../lib, isn't this right?
To get rid of the relative path and avoid having something like #include ../lib/graphs.h
in is_binary_tree/is_binary_tree.cpp
I added an includes attribute to my is_binary_tree
target like so:
is_binary_tree/is_binary_tree.cpp
#include "graphs.h"
int main(){
return 0;
}
is_binary_tree/BUILD
cc_binary(
name="is_binary_tree",
srcs=["is_binary_tree.cpp"],
includes=["../lib"],
deps=["//lib:graphs"],
)
And I'm getting the aforementioned WARNING. What am I missing?
And more broadly, what is the best way to include dependencies without having long relative paths in #include statements ? (I want my code to be modular and not specific to a given Bazel workspace folder organization)
Thanks
CodePudding user response:
That includes
should go in //lib:graphs
, so that anything which depends on it (has it in deps
) uses it. lib/BUILD
should look like this:
cc_library(
name = "graphs",
hdrs = ["graphs.h"],
srcs = ["graphs.cpp"],
includes = ["."],
visibility = ["//visibility:public"],
)
Then you drop includes
from is_binary_tree
and it should work.
In general, each Bazel target contains information about its files. It depends on other targets to use their files.
More broadly, Bazel defaults to #include paths relative to the base of the repository. That means you'd write #include "lib/graphs.h"
in any file, whether that's is_binary_tree/is_binary_tree.cpp
or x/y/z/foobar.cpp
. That avoids collisions between graphics/constants.h
and audio/constants.h
, without using absolute paths.