Home > Back-end >  How can I avoid relative paths in #includes when building with Bazel
How can I avoid relative paths in #includes when building with Bazel

Time:11-10

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.

  • Related