Bazel: Bazel can't build .c files including other .c files

Created on 4 Dec 2015  Â·  13Comments  Â·  Source: bazelbuild/bazel

I have a project which happens to #include .c files from other .c files. When sandboxing is disabled, undeclared inclusion errors will be thrown for .c files which are, in fact, declared.

As it happens, this particular project does not build with sandboxing enabled, either (whereas it did in prior versions of Bazel), but the cause is not readily discernable.

P4 team-Rules-CPP feature request

Most helpful comment

textual_hdrs is what we're using internally, and we'll make a broad announcement if this is going to change.

All 13 comments

Do you have a reproducible case you can share?

Sure. The real-world example is libunwind (see http://git.savannah.gnu.org/cgit/libunwind.git/tree/src/elf32.c, among many others) but here's a toy example:

$ cd src/bazel/test

$ cat BUILD
cc_library(
  name = "foo",
  srcs = [
    "bar.c",
    "baz.c",
    "someheader.h",
  ],
)
$ cat bar.c
#include "someheader.h"
#include "baz.c"

int main(void) {
  return 0;
}

$ cat baz.c [empty]
$ cat someheader.h [empty]

Failure case, sandboxing disabled:

$ ../output/bazel build --genrule_strategy=standalone --spawn_strategy=standalone ...                                                                                                                                                    
INFO: Found 1 target...
ERROR: /home/kbekirog/src/bazel/test/BUILD:1:1: undeclared inclusion(s) in rule '//test:foo':
this rule is missing dependency declarations for the following files included by 'test/bar.c':
  '/home/kbekirog/src/bazel/test/baz.c'.
Target //test:foo failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 0.069s, Critical Path: 0.01s

Failure case, sandboxing enabled:

$ ../output/bazel build ...                                                                                                                                                                                                            
INFO: Found 1 target...
INFO: From Compiling test/bar.c:
test/bar.c:2:17: fatal error: baz.c: No such file or directory
compilation terminated.
ERROR: /home/kbekirog/src/bazel/test/BUILD:1:1: C++ compilation of rule '//test:foo' failed: gcc failed: error executing command /usr/bin/gcc -U_FORTIFY_SOURCE '-D_FORTIFY_SOURCE=1' -fstack-protector -Wall -Wunused-but-set-parameter -Wno-free-nonheap-object -fno-omit-frame-pointer -iquote . -iquote ... (remaining 21 argument(s) skipped).
Target //test:foo failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 0.138s, Critical Path: 0.05s

So it appears that this example is broken in both modes on Ubuntu 15.10.

Have you tried textual_hdrs?

I'm a bit confused as to how I would apply textual_hdrs here, as the problematic included files are not headers, nor public. They are internal to the library.

I think files in textual_hdrs are allowed to be included by srcs from the rule itself, so if you put the #included .c files in there it should work.

It does technically make them "public", but I don't think Bazel currently distinguishes between .h files in hdrs vs srcs anyways.

I think even just putting the other files in hdrs should work. However, I
think this is still a valid issue. We should either clarify that only .h
files can be included from srcs, or relax the restriction.

On Mon, Dec 7, 2015 at 1:13 PM, bsilver8192 [email protected]
wrote:

I think files in textual_hdrs are allowed to be included by srcs from the
rule itself, so if you put the #included .c files in there it should work.

It does technically make them "public", but I don't think Bazel currently
distinguishes between .h files in hdrs vs srcs anyways.

—
Reply to this email directly or view it on GitHub
https://github.com/bazelbuild/bazel/issues/680#issuecomment-162611808.

We can't easily 'relax the restriction' - if we add all source files to the set of includable headers, downstream actions get a _lot_ larger. Internally, we haven't seen much of a problem with mostly requiring the naming convention to apply. There are a few third party projects that don't follow the naming convention, and using textual_hdrs as a workaround seems reasonable to me. If we were to redesign cc_library, we might do it differently - using explicit attributes instead of filtering by extension.

We're still working on C++ modules support, which actually makes use of the distinction between srcs, hdrs, and textual_hdrs. When that is more stable, we could consider updating the attribute names to match the C++ module settings.

Wow, got bitten by that today (trying to compile freeimage). Luckily the textual_hdrs workaround is working. Really deferring until 1.0?

My intent for setting it to the 1.0 milestone was for this issue to block a 1.0 release, not to indicate that it'll only be fixed in 1.0. That said, nobody is working on this right now. I'm not even sure what the right solution is.

This prevents boost from building in bazel. boost::container has a c file that includes another c file. I can't change the code because it's an external repo. Is there any way for me to work around this?

Using textual_hdrs worked for me :). Is that a workaround, or is that the recommended long-term approach for this situation?

textual_hdrs is what we're using internally, and we'll make a broad announcement if this is going to change.

The textual_hdrs workaround isn't available for cc_binary, only cc_library.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

damienmg picture damienmg  Â·  67Comments

laurentlb picture laurentlb  Â·  76Comments

laurentlb picture laurentlb  Â·  111Comments

dslomov picture dslomov  Â·  61Comments

laurentlb picture laurentlb  Â·  101Comments