Why does bazel not see includes defined in bazelrc?

882 Views Asked by At

I am migrating large legacy makefiles project to Bazel. Project used to copy all sources and headers into single "build dir" before build, and because of this all source and header files use single level includes, without any prefix (#include "1.hpp").

Bazel requires that modules (libraries) use relative path to header starting at WORKSPACE file, however my goal is to introduce Bazel build files, which require 0 modifications of a source code.

I use bazelrc to globally set paths to includes as if structure was flat: .bazelrc:

build --copt=-Ia/b/c

/a/b/BUILD

cc_library(
  name = "lib",
  srcs = ["c/1.cpp"],
  hdrs = ["c/1.hpp"],
  visibility = ["//visibility:public"]
)

When I build this target, I see my -I flag in compiler invocation, but compilation fails because bazel can not find header 1.hpp:

$ bazel build -s //a/b:lib
...
a/b/c/1.cpp:13:10: fatal error: 1.hpp: No such file or directory
   13 | #include "1.hpp"
      |

Interestingly enough, it prints me gcc command that it invokes during build and if I run this command, compiler is able to find 1.hpp and 1.cpp compiles.

How to make bazel "see" this includes? Do I really need to additionally specify copts for every target in addition to global -I flags?

1

There are 1 best solutions below

2
slsy On BEST ANSWER

Bazel use sandboxing: for each action (compile a C++ file, link a library) the specific build directory is prepared. That directory contains only files (using symlinks and other Linux sorcery), which are explicitly defined as dependency/source/header for given target.

That trick with --copt=-Ia/b/c is a bad idea, because that option will work only for targets, which depend on //a/b:lib.

Use includes or strip_include_prefix attribute instead:

cc_library(
  name = "lib",
  srcs = ["c/1.cpp"],
  hdrs = ["c/1.hpp"],
  strip_include_prefix = "c",
  visibility = ["//visibility:public"]
)

and add the lib as a dependency of every target, which need to access these headers:

cc_binary(
  name = "some bin",
  srcs = ["foo.cpp"],
  deps = ["//a/b:lib"],
)