How to have clang ignore gch directories?

How can I get clang to stop caring about gch directories for
precompiled headers that were created by GCC?

Currently my main build uses GCC and it generates .gch directories:

  $ ls -1d foo_pch*
  foo_pch.h
  foo_pch.h.gch/

When I compile my code using GCC, it works fine:

  $ g++ ... -Winvalid-pch --include=foo_pch.h ...

But then if I try to use tools based on clang with exactly the same
arguments, it throws an error (with or without -Winvalid-pch):

  $ clang++ ... --include=foo_pch.h ...
  error: no suitable precompiled header file found in directory
      './foo_pch.h.gch'
  1 error generated.

Note I'm really not using clang++, I'm using a tool linked with libLLVM
which parses the code, but I get the same behavior there.

Using strace I can see clang first look for .pch then .pth (neither of
which exist, which is fine), and finally .gch. Apparently clang cannot
parse the GCC-generated precompiled header file. I don't care if clang
can't read those files, I just want it to include the .h file.

How can I tell clang to just ignore the GCC-specific precompiled
headers, or equivalently ignore precompiled headers altogether? I
can't delete the gch directories because I need them for my build. I've
read through the clang docs and can't find any likely-looking options.

It's really frustrating when clang tries to appropriate GCC-specific
options and configurations when it's not actually compatible with them.
It makes modern multi-compiler development so unnecessarily difficult.

FWIW, I'm working with Clang 7.0.1 on GNU/Linux Ubuntu 18.04.

Sorry about that. Clang is trying to be a transparent drop-in
replacement for build systems that are designed for GCC, and that
means that -include needs to automatically pick up a corresponding
.pch / .gch file if a prior build step put one there. Unfortunately we
don't do any validation to check whether that's Clang's file or one
generated by GCC at that layer :frowning:

You can work around this by using "-Xclang -include -Xclang foo_pch.h"
instead of "-include foo_pch.h"; that will bypass the driver logic
that tries to convert -include to -include-pch.

Also, -include=foo_pch.h won't do what you think: in GCC (and in
Clang, because we usually follow GCC conventions even when they're
weird), that will include a file named "=foo_pch.h". (The space
between -include and the filename is optional, and there is no
optional equals, so if you put one in it ends up as part of the
argument value. This is the same behavior as for -I etc.)

> How can I tell clang to just ignore the GCC-specific precompiled
> headers, or equivalently ignore precompiled headers altogether? I
> can't delete the gch directories because I need them for my build. I've
> read through the clang docs and can't find any likely-looking options.
>
> It's really frustrating when clang tries to appropriate GCC-specific
> options and configurations when it's not actually compatible with them.
> It makes modern multi-compiler development so unnecessarily difficult.

Sorry about that. Clang is trying to be a transparent drop-in
replacement for build systems that are designed for GCC, and that
means that -include needs to automatically pick up a corresponding
.pch / .gch file if a prior build step put one there. Unfortunately
we don't do any validation to check whether that's Clang's file or
one generated by GCC at that layer :frowning:

Thanks for the response!

You can work around this by using "-Xclang -include -Xclang
foo_pch.h" instead of "-include foo_pch.h"; that will bypass the
driver logic that tries to convert -include to -include-pch.

I guess I should be more clear about what I'm doing: my software builds
with GCC, but I'm using ccls GitHub - MaskRay/ccls: C/C++/ObjC language server supporting cross references, hierarchies, completion and semantic highlighting as an LSP
server, which is built on libLLVM.

My project also uses CMake, and I generate compile_commands.json to
make the compiler command line options available to ccls.

As a result, I have very little ability to modify the command line
arguments used by libLLVM to parse my source code. The ones in
compile_commands.json obviously must be valid GCC command line
arguments, so I can't add things like -Xclang. I can add extra
arguments to the ccls command line (but just injected into the
beginning of the command line, I can't insert them wherever I want) and
I can remove specific individual flags (but not groups of flags), but
that's about it.

This is all great, but now people are hoping to reduce compile times by
introducing PCH into our build system. After we do this, I can no
longer use ccls because it immediately bails out when trying to parse
my files, as it discovers and fails to parse the GCC PCH files.

I filed 41579 – Clang fails if run in the presence of GCC PCH files in hopes someone
can address this.

I also discovered this bug filed against clang back in 2014:

https://bugs.llvm.org/show_bug.cgi?id=21174

I am looking into taking advantage of this difference in behavior
between clang and GCC to solve my problem: I'm putting the GCC PCH
files "somewhere else" and adding the "somewhere else" as an -iquote
option to my compile line (to ensure that it's searched first before
anywhere else). This requires a carefully constructed tower of hacks
which makes me unhappy, but it does so far appear to be working (early
days in testing yet): GCC will locate the PCH files in the -iquote
directory and clang will ignore them.

Hopefully, someone won't fix bug #21174 without first resolving my
issue #41579 somehow :stuck_out_tongue: :).

Also, -include=foo_pch.h won't do what you think:

In my example I wasn't using -include=foo_pch.h, I was using
--include=foo_pch.h My understanding is the GCC (and clang according
to its docs) will DTRT if you use --include rather than -include:

https://clang.llvm.org/docs/ClangCommandLineReference.html

-include<file>, --include<file>, --include=<arg>
    Include file before parsing

Now that CMake 3.16 supports precompiled headers directly, this problem
will only get more and more pronounced as people try to switch to it and
discover it completely breaks their environment.

Of course the built-in CMake support for PCH doesn't try to use the
grotesque hacks that my internal implementation was forced to resort to to
make this work, so I was sad.

So I grabbed a Git clone of the clang source and wrote a patch:
https://bugs.llvm.org/show_bug.cgi?id=41579

I did not try to write a test or anything. Hopefully someone with some
clang code fu can fix it up to be acceptable and apply it, to stop the
madness.

It may be better to have the code check affirmatively for clang PCH files
instead of ignoring GCC PCH files, but I don't know what the file format
for clang PCH files is and I don't use clang so I didn't try to create one
to find out.