Looks like there is a relation between creating a cc_library
on a BUILD
file using hdrs
and includes
to generate the gcc
command with -isystem
, -iquote
and -I
.
To explain my problem better, I have this example.
I have a Bazel
project with the following files:
The dependencies are:
main.cpp
needs foo.hpp
foo.hpp
needs access to #include "bar.h"
, so a library hdrs-bar
is providedbar.h
needs access to #include <system_bar.h>
, so a library hdrs-system-bar
is provided. (Note that <>
on the include is needed.)demo
is created with all these dependenciesAs described on (1), the main.cpp
contains:
#include "foo.hpp"
int main()
{
// ...something which uses foo.hpp
return 0;
}
As described on (2), to be able to access foo.hpp
from main.cpp
I need to create a Bazel project out of a git repository and create a BUILD
file for for it using the build_file_content
where it contains a library that will expose all the *.h
files I need (including the bar.h
).
Therefore the WORKSPACE file contains:
load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository")
new_git_repository(
name = "bar-utils",
remote = "https://github.com/someGitRepo/bar-utils.git",
branch = "master",
build_file_content = """
package(default_visibility = ["//visibility:public"])
cc_library(
name = "hdrs-bar",
hdrs = glob(["bar/*.h"], allow_empty=False),
strip_include_prefix = "bar",
)
""",
)
As described on (3), the WORKSPACE
file also contains a creation of a library called hdrs-system-bar
which contains the system headers needed from bar.h
:
new_local_repository(
name = "bar-system",
path = "/usr/local/bar/include",
build_file_content = """
cc_library(
name = "hdrs-system-bar",
hdrs = glob(["*.h"], allow_empty=False),
visibility = ["//visibility:public"],
)
""",
)
As described in (4), the BUILD file contains a binary which gets all the dependencies in deps
:
cc_binary(
name = "demo",
srcs = ["main.cpp"],
deps = ["@bar-utils//:hdrs-bar", "@bar-system//:hdrs-system-bar"],
)
If I compile:
$ bazel build //... --sandbox_debug
I get the following build ERROR:
bazel-out/aarch64-fastbuild/bin/external/bar-utils/_virtual_includes/hdrs-bar/barUtils.h:7:10: fatal error: bar_runtime.h: No such file or directory #include <bar_runtime.h>
The file bar_runtime.h
should be inside the library hdrs-system-bar
.
So if I see my sandbox folder on .../sandbox/linux-sandbox/4/execroot/__main__/
I get the following directories:
On the external
, I have these two folder, where each contains all the header files I need:
On the bazel-out
, I have the following:
aarch64-fastbuild/bin/external/bar-utils/_virtual_includes/hdrs-bar/bar.h
I was expecting inside this bazel-out
external
to have also the bar-system
, but there is only bar-utils
. Why is that?
To add more info the gcc command generated was like this (removed all the non-necessary arguments for sake of simplicity):
/usr/bin/gcc -iquote external/bar-utils -iquote external/bar-system -c main.cpp
If I simply use includes instead of hdrs on all the libraries creation, I get a lot of -isystem
instead of the -iquote
. But what I need is actually the -I<folder where the headers are>
.
If I manually change my gcc command to:
/usr/bin/gcc -iquote external/bar-utils -Iexternal/bar-system -c main.cpp
Then it works.
How can I force it to use -I
? Changing the cc_libraries
to srcs
or includes
instead of hdrs
is not working.
Solution is to also use the includes
flag, besides the hdrs. This way it will show up on the sandbox and be accessible by adding the -isystem
argument for gcc with the folder you need.
cc_library(
name = "hdrs-system-bar",
hdrs = glob(["*.h"], allow_empty=False),
includes = ["."],
visibility = ["//visibility:public"],
)