Bazel: Formulation of proper -I flag in copts

Created on 6 May 2015  Â·  14Comments  Â·  Source: bazelbuild/bazel

The documentation for how to properly formulate the path passed to -I is unclear. What is the right make-variable to use in order to get these paths to begin with bazel-out?

Most helpful comment

I think that this issue should be re-opened. Specifying paths from the root of workspace is not always a good solution (e.g. if you wrapped cc_library target creation in a macro and want to add addional -I options in it). Having something like $(CURRENT_SOURCE_DIR) and $(CURRENT_GEN_DIR) would be very helpful. Or, maybe another attribute "non_transitive_includes" should be added - with behavior just like "includes" but without transitive behavior...
Using "includes" attribute is not always possible - as mentioned earlier it have transitive nature, causing weird build failures if some directories have headers with the same name.

All 14 comments

You could use $(location ...), but in general you probably shouldn't need to set -I (you'd add the path to includes=[...]). What are you trying to do?

I'm trying to compile a library that has some private includes. I don't want to add them to includes=[] because of the transitive nature of the parameter. How would I use location in this manner? Can I refer to arbitrary directories (such as $(location include/)) or only labels?

I have the same question too. When I try the $(location ...) method, I get the following error:

in copts attribute of cc_library rule //openssl:openssl: '$location' syntax is not supported; use '$(location)' instead for "Make" variables, or escape the '$' as '$$' if you intended this for the shell.

What is the right way to use it?

There's $(GENDIR), which ought to work for this purpose.

On Thu, May 7, 2015 at 11:23 AM, huahang [email protected] wrote:

I have the same question too. When I try the $(location ...) method, I get
the following error:

in copts attribute of cc_library rule //openssl:openssl: '$location'
syntax is not supported; use '$(location)' instead for "Make" variables, or
escape the '$' as '$$' if you intended this for the shell.

What is the right way to use it?

—
Reply to this email directly or view it on GitHub
https://github.com/google/bazel/issues/181#issuecomment-99790021.

Does bazel-genfiles always contain the relevant source tree files as well? I thought it only contained generated files?

Well, you can set -Ix/y/z -I$(GENFILES)/x/y/z.

On Thu, May 7, 2015 at 3:13 PM, applmak [email protected] wrote:

Does bazel-genfiles always contain the relevant source tree files as well?
I thought it only contained generated files?

—
Reply to this email directly or view it on GitHub
https://github.com/google/bazel/issues/181#issuecomment-99859931.

Oh, duh, I get what you are saying. Bazel runs with the cwd @ the same place as the WORKSPACE file. Gotcha. Thanks.

@ulfjack That works indeed. But it implies that the BUILD file's location has got to be fixed relative to the WORKSPACE root, right?

Yes. It might be nicer to support something like $(location), but we don't
have that at this time.

(We also don't have relative labels, which might be an even bigger obstacle
to relocatable BUILD files.)

On Thu, May 7, 2015 at 3:26 PM, huahang [email protected] wrote:

@ulfjack https://github.com/ulfjack That works indeed. But it implies
that the BUILD file's location has got to be fixed relative to the
WORKSPACE root, right?

—
Reply to this email directly or view it on GitHub
https://github.com/google/bazel/issues/181#issuecomment-99864030.

With the recent changes to the directory layout, $(GENDIR) no longer works, leaving no way of specifying a correct '-I' parameter. The only documented Make variables are BINDIR and GENDIR, neither of which point anywhere.

TBH, that was a bit of a hack in the first place to work around proper $(location) support for copts.

Why can't you use includes?

Because I don't want to transitively infect all of the targets which depend on this one. Specifically, in this case it's a BUILD file for an external dependency (gflags) configured via CMake. Among other artifacts, CMake spits out include/gflags/config.h which is a "private" header (listed in the BUILD srcs) alongside the public headers. Clients should include those headers as <gflags/header.h> but the library source includes config.h as "config.h". We've added includes = ["include"] and an unsightly, but formerly functional, -I$(GENDIR)/repo_name/include/gflags to copts. Given the nature of the problem, adding the nested include/gflags to includes ends up sacrificing correctness for expedience and potentially causing more, harder to debug, problems down the road.

I think that this issue should be re-opened. Specifying paths from the root of workspace is not always a good solution (e.g. if you wrapped cc_library target creation in a macro and want to add addional -I options in it). Having something like $(CURRENT_SOURCE_DIR) and $(CURRENT_GEN_DIR) would be very helpful. Or, maybe another attribute "non_transitive_includes" should be added - with behavior just like "includes" but without transitive behavior...
Using "includes" attribute is not always possible - as mentioned earlier it have transitive nature, causing weird build failures if some directories have headers with the same name.

e.g. if you wrapped cc_library target creation in a macro

I am in exactly this situation and don't see a workaround.

Was this page helpful?
0 / 5 - 0 ratings