[ccache] ccache and precompiled headers

Tor Arne Vestbø torarnv at gmail.com
Mon Jun 21 05:09:23 MDT 2010


Hey,

I ran into a problem where ccache would log "Preprocessor gave exit
status 1" and fail to cache builds. Closer inspection revealed that
this was due to the use of precompiled headers though an -include
argument to gcc. When ccache then tried to run the preprocessor on the
source file gcc reported "file not found" for the precompiled header.
Aparenly gcc appends ".gch" and some other magic to the filename
during build but not during preprocessing.

The solution seems to be to add the -fpch-preprocess flag, which will
add a custom #pragma include to the preprocessed output, see:

  http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Preprocessor-Options.html#index-fpch_002dpreprocess-877

The question is, is it safe to use ccache with precompiled headers at all?

If so, would a patch like this work, basically adding the flag if a
pch include is detected, and making sure it's included and hashed in
the direct mode manifest's list of includes?

diff --git i/ccache.c w/ccache.c
index 310d3e2..40d0e9d 100644
--- i/ccache.c
+++ w/ccache.c
@@ -477,6 +477,7 @@ static int process_preprocessed_file(struct mdfour
*hash, const char *path)
                 *
                 *   # N "file"
                 *   # N "file" N
+                *   #pragma GCC pch_preprocess "file"
                 *
                 * HP's compiler:
                 *
@@ -488,6 +489,9 @@ static int process_preprocessed_file(struct mdfour
*hash, const char *path)
                if (q[0] == '#'
                        /* GCC: */
                    && ((q[1] == ' ' && q[2] >= '0' && q[2] <= '9')
+                        || (q[1] == 'p' && q[2] == 'r' && q[3] == 'a'
&& q[4] == 'g'
+                            && q[5] == 'm' && q[6] == 'a' && (q < end - 30)
+                            && (strncmp(q + 8, "GCC pch_preprocess", 18) == 0))
                        /* HP: */
                        || (q[1] == 'l' && q[2] == 'i' && q[3] == 'n'
&& q[4] == 'e'
                            && q[5] == ' '))
@@ -1336,6 +1340,7 @@ static void process_args(int argc, char **argv,
ARGS **preprocessor_args,
        int found_c_opt = 0;
        int found_S_opt = 0;
        int found_arch_opt = 0;
+       int found_pch = 0;
        const char *explicit_language = NULL; /* As specified with -x. */
        const char *file_language;            /* As deduced from file
extension. */
        const char *actual_language;          /* Language to actually use. */
@@ -1557,6 +1562,12 @@ static void process_args(int argc, char **argv,
ARGS **preprocessor_args,
                                        }

                                        args_add(stripped_args, argv[i]);
+                                       if (strcmp(argv[i], "-include")
+                                                       &&
strstr(argv[i+1], "pch")) {
+                                               found_pch = 1;
+                                               cc_log("Found
precompiled header: %s",
+                                                      argv[i+1]);
+                                       }
                                        relpath =
make_relative_path(x_strdup(argv[i+1]));
                                        args_add(stripped_args, relpath);
                                        free(relpath);
@@ -1781,6 +1792,9 @@ static void process_args(int argc, char **argv,
ARGS **preprocessor_args,
        if (input_charset) {
                args_add(*preprocessor_args, input_charset);
        }
+       if (found_pch) {
+               args_add(*preprocessor_args, "-fpch-preprocess");
+       }
        if (explicit_language) {
                args_add(*preprocessor_args, "-x");
                args_add(*preprocessor_args, explicit_language);

Thanks for any input!

Tor Arne


More information about the ccache mailing list