The external_include_paths feature is intended to include external headers as system headers, with the goal of silencing compiler warnings from external headers included in the project's .cpp files.
This works by appending -isystem <path> to the compile command. This works with GCC, but not with Clang. Please find attached a minimal example.
The reason this doesn't work is that the compile command has 2 lines for including the same header:
-iquote <path> (added by Bazel)
-isystem <path> (added by external_include_paths)
When the header is #included with quotes, Clang picks the -iquote line, and the header is not treated as a system header, and the warnings remain. If only the -isystem line exists, then Clang treats the header as a system header, even if it's included with quotes.
Note: this behavior is different from GCC. In GCC, the last line prevails, in this case the -isystem one, regardless of the previous ones. That's why the header is always treated as a system header regardless of whether it's included with quotes or angle brackets.
Solutions:
- Ensure all external headers are
#included with angle brackets instead of quotes. Then the -isystem line is chosen.
- This is hard to remember and hard to enforce repo-wide.
- Remove the relevant
-iquote lines from the command line, and keep only the -isystem ones.
- This would be preferred, since we don't need to change any source code or remember a rule about including with angle brackets.
What do you think? Let me know if I can provide more information. Thank you!
repro.tar.gz
The
external_include_pathsfeature is intended to include external headers as system headers, with the goal of silencing compiler warnings from external headers included in the project's .cpp files.This works by appending
-isystem <path>to the compile command. This works with GCC, but not with Clang. Please find attached a minimal example.The reason this doesn't work is that the compile command has 2 lines for including the same header:
-iquote <path>(added by Bazel)-isystem <path>(added byexternal_include_paths)When the header is
#includedwith quotes, Clang picks the-iquoteline, and the header is not treated as a system header, and the warnings remain. If only the-isystemline exists, then Clang treats the header as a system header, even if it's included with quotes.Note: this behavior is different from GCC. In GCC, the last line prevails, in this case the
-isystemone, regardless of the previous ones. That's why the header is always treated as a system header regardless of whether it's included with quotes or angle brackets.Solutions:
#includedwith angle brackets instead of quotes. Then the-isystemline is chosen.-iquotelines from the command line, and keep only the-isystemones.What do you think? Let me know if I can provide more information. Thank you!
repro.tar.gz