bazel: cxx_builtin_include_directory doesn't work with non-absolute path
Description of the problem / feature request:
I’m trying to use gcc cross-compiler as external dependency, when I’m specifying cxx_builtin_include_directory as external/cross_toolchain/...
or %package(@cross_toolchain//...)
I’m getting error:
'/private/var/tmp/_bazel_ilya/d86e0e7cfe53385dc3edff3c0d9662b6/external/cross_toolchain/lib/gcc/x86_64-unknown-linux-gnu/7.3.0/include/stddef.h'
'/private/var/tmp/_bazel_ilya/d86e0e7cfe53385dc3edff3c0d9662b6/external/cross_toolchain/lib/gcc/x86_64-unknown-linux-gnu/7.3.0/include/stdarg.h'
It works only if you specify absolute path to include directory.
Bugs: what’s the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.
You can find minimal example here: https://github.com/ipolyakovskiy/bazel-crosscompile-example
To build:
bazel build --config=docker //:hello
INFO: Analysed target //:hello (0 packages loaded).
INFO: Found 1 target...
ERROR: /Users/ilya/hello-bazel-docker/BUILD:1:1: undeclared inclusion(s) in rule '//:hello':
this rule is missing dependency declarations for the following files included by 'hello.c':
'/private/var/tmp/_bazel_ilya/d86e0e7cfe53385dc3edff3c0d9662b6/external/cross_toolchain/lib/gcc/x86_64-unknown-linux-gnu/7.3.0/include/stddef.h'
'/private/var/tmp/_bazel_ilya/d86e0e7cfe53385dc3edff3c0d9662b6/external/cross_toolchain/lib/gcc/x86_64-unknown-linux-gnu/7.3.0/include/stdarg.h'
Target //:hello failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 0.723s, Critical Path: 0.58s
FAILED: Build did NOT complete successfully
What operating system are you running Bazel on?
macOS 10.12.6
What’s the output of bazel info release
?
Tried with release 0.10.0-homebrew
and development version
also
If bazel info release
returns “development version” or “(@non-git)”, tell us how you built Bazel.
development version was build form sources by bazel build //src:bazel
What’s the output of git remote get-url origin ; git rev-parse master ; git rev-parse HEAD
?
https://bazel.googlesource.com/bazel
e7541262293977598ad96d9eb7a83b439eedd634
e7541262293977598ad96d9eb7a83b439eedd634
Have you found anything relevant by searching the web?
Nothing
Any other information, logs, or outputs that you want to share?
AFAIU problem is here: https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java#L1233
Paths which are not absolute just discarded. So is it a bug or intentional behavior? If it is intentional, how I should specify include path in such example?
If it is a bug I can create pull-request with merging execRoot and includePath, which is absolute path to include directory in such case.
About this issue
- Original URL
- State: open
- Created 6 years ago
- Reactions: 2
- Comments: 15 (3 by maintainers)
Commits related to this issue
- Pass -no-canonical-prefixes and -fno-canonical-system-headers to GCC See: https://github.com/bazelbuild/bazel/issues/4605 for motivation. — committed to tweag/rules_haskell by deleted user 5 years ago
- Pass -no-canonical-prefixes and -fno-canonical-system-headers to GCC See: https://github.com/bazelbuild/bazel/issues/4605 for motivation. — committed to tweag/rules_haskell by deleted user 5 years ago
- Adding working around for https://github.com/bazelbuild/bazel/issues/4605 — committed to bazelembedded/bazel-embedded by deleted user 4 years ago
- kleaf: Rename kleaf-common-cflags to kleaf-no-canonical-prefixes. This feature is enabled by default on regular cc_* rules to work around https://github.com/bazelbuild/bazel/issues/4605 However, ... — committed to msft-mirror-aosp/platform.prebuilts.clang.host.linux-x86 by deleted user a year ago
It’s usually quite important to pass
-no-canonical-prefixes
and-fno-canonical-system-headers
to prevent GCC from “helpfully” normalizing system header paths into something Bazel doesn’t know about.For us, building compiler from source was the easiest way around this problem. As a bonus we could use GCC trunk instead of an older version. But yes, annoying.
The advice in this issue will not work for non-standard compilers. GIven today’s crosstool documentation, it’s really not clear how to overcome
this rule is missing dependency declarations for the following files included by ...
errors.This is also an issue with clang, which does not support
-fno-canonical-system-headers
, and-no-canonical-prefixes
does not seem to help.I’ve played a bit more with GCC and indeed the blame falls on Ubuntu maintainers. They build GCC with some configuration flag (not sure which, maybe
enable-multilib
orenable-multiarch
) that effectively renders the-no-canonical-headers
useless.What works for us is to:
-nostdinc++ -isystem path/to/include
(relative to the external workspace root) to the default compiler flags.cxx_builtin_include_directories
.A bit dirty with these extra flags in the compile line though.
With this, the include checker doesn’t complain. Not sure if it’s a bug or a feature 😅
This still seems to be an issue. I have defined a custom cc toolchain and have set cxx_builtin_include_directories as:
undeclared inclusion(s) in rule ‘//main:hello-greet’: this rule is missing dependency declarations for the following files included by ‘main/hello-greet.cc’: ‘/home/jheaff1/.cache/bazel/_bazel_jheaff1/0ac7dd591c66afb95b2d2d0ded26378b/external/x86_64_linux_musl/include/stdc-predef.h’
The documentation is a tad confusing. It states that
cxx_builtin_include_directories should
be “the exact paths used by the compiler, and are generally relative to the exec root.”. It then states that “Relative paths are resolved relative to the configuration file directory.”If indeed the paths are relative to the toolchain configuration file directory, is there any way I can derive the <exec root>/external directory from the toolchain configuration file directory?