Bug 46110 - Precompiled headers: GCC fails to properly locate include files
Summary: Precompiled headers: GCC fails to properly locate include files
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: preprocessor (show other bugs)
Version: 4.4.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-10-21 04:38 UTC by Aleksey Covacevice
Modified: 2010-10-22 16:22 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2010-10-21 09:15:29


Attachments
Test case script (123 bytes, text/plain)
2010-10-21 04:38 UTC, Aleksey Covacevice
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Aleksey Covacevice 2010-10-21 04:38:48 UTC
Created attachment 22102 [details]
Test case script

GCC fails to properly locate include files when using precompiled headers that are located in a deeper directory in the search path. This problem happens when a file "z.h" includes two other files, "x.h" and "y.h", such that "y.h" also includes "x.h", and they are all located in another directory in the include path (yielding include lines such as '#include "dir/x.h"').

The issue is much better explained through a test case. The following command sequence is a simple test case that yields the symptom:

==
#!/bin/sh

mkdir -p include/dir pch/dir
touch include/dir/x.h
echo "#include \"dir/x.h\"" > include/dir/y.h
echo "#include \"dir/x.h\"" > include/dir/z.h
echo "#include \"dir/y.h\"" >> include/dir/z.h
gcc -I pch -I include include/dir/x.h -o pch/dir/x.h.gch
gcc -I pch -I include include/dir/y.h -o pch/dir/y.h.gch
gcc -I pch -I include include/dir/z.h -o pch/dir/z.h.gch
==

The output is the following:

==
In file included from include/dir/z.h:2:
include/dir/y.h:1:19: error: pch/dir/x.h: No such file or directory
==

If the include path "-I pch" is ommited from the above commands (i.e., removing the precompiled headers from the search path), everything runs fine. Also, if the subdirectory "dir/" is properly removed from every place above, everything runs fine. Now, if the include path "-I include" is ommited, the output is:

==
include/dir/z.h:2:19: error: dir/y.h: No such file or directory
==

although the precompiled header "pch/dir/y.h.gch" already exists (there should be no reason to avoid using it, "-Winvalid-pch" does not report anything and the compilation for "y.h", which is pretty similar, proceeds fine).

The snippet above should also help generate proper ".i" files for further investigation.

Running GCC on a Ubuntu 9.10 x86 host.

Output of gcc -v:
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.1-4ubuntu9' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
Thread model: posix
gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu9)

Cheers,
Alek
Comment 1 Richard Biener 2010-10-21 09:15:29 UTC
Including a precompiled header not as the very first preprocessor statement
in a file is not supported.

The issue seems to be that the preprocessor sticks with the first directory
it found the pch in (but obviously doesn't use it) and the original header
file isn't there.
Comment 2 Aleksey Covacevice 2010-10-21 21:31:14 UTC
Richard, thanks for the reply.

Actually the documentation states that other preprocessor directives (such as "#define"s) can appear before the include line that would include the PCH. Nevertheless, that is not really the case. In fact it also states that only a single precompiled header can be used in a particular compilation, and I think the symptom must be somewhat related to this.

I believe this must be a bug, because even if GCC couldn't use a PCH for any reason previously stated, it should ignore it and use the original include file, which in this scenario it can be properly found in the search path.

Thanks again,
Alek