]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Allow not including system headers in manifest
authorAnders Björklund <anders@itension.se>
Sat, 24 Oct 2015 14:41:33 +0000 (16:41 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Sat, 19 Dec 2015 14:57:58 +0000 (15:57 +0100)
If CCACHE_SLOPPINESS includes "no_system_headers", ccache will not add any
system headers to the manifest's list of include files to always check.
This allows ccache to only check non-system headers, but will also cause
it to return stale cache hits if such system headers have been changed.

MANUAL.txt
ccache.c
ccache.h
conf.c
test/test_conf.c

index e7e4bf225eb462f75e03da769a9f93a4e09e4b53..228a2d79d7462f4f8c5cb2dd063e1bfef15c05c1 100644 (file)
@@ -447,6 +447,10 @@ WRAPPERS>>.
     ccache normally examines a file's contents to determine whether it matches
     the cached version. With this option set, ccache will consider a file as
     matching its cached version if the sizes, mtimes and ctimes match.
+*no_system_headers*::
+    By default, ccache will also include all system headers in the manifest.
+    With this option set, ccache will only include system headers in the hash
+    but not add the system header files to the list of include files.
 *include_file_ctime*::
     By default, ccache also will not cache a file if it includes a header whose
     ctime is too new. This option disables that check.
index 9043804da4349814ca4caf4a2ac6299470d11511..e974f328af3e7637c506040c5088ce9252fdca98 100644 (file)
--- a/ccache.c
+++ b/ccache.c
@@ -513,7 +513,7 @@ get_path_in_cache(const char *name, const char *suffix)
  * also updated. Takes over ownership of path.
  */
 static void
-remember_include_file(char *path, struct mdfour *cpp_hash)
+remember_include_file(char *path, struct mdfour *cpp_hash, bool system)
 {
 #ifdef _WIN32
        DWORD attributes;
@@ -535,6 +535,11 @@ remember_include_file(char *path, struct mdfour *cpp_hash)
                goto ignore;
        }
 
+       if (system && (conf->sloppiness & SLOPPY_NO_SYSTEM_HEADERS)) {
+               /* Don't remember this system header. */
+               goto ignore;
+       }
+
        if (hashtable_search(included_files, path)) {
                /* Already known include file. */
                goto ignore;
@@ -697,7 +702,7 @@ static bool
 process_preprocessed_file(struct mdfour *hash, const char *path)
 {
        char *data;
-       char *p, *q, *end;
+       char *p, *q, *r, *end;
        size_t size;
 
        if (!read_file(path, 0, &data, &size)) {
@@ -746,6 +751,7 @@ process_preprocessed_file(struct mdfour *hash, const char *path)
                            && q[5] == ' '))
                    && (q == data || q[-1] == '\n')) {
                        char *path;
+                       bool system;
 
                        while (q < end && *q != '"' && *q != '\n') {
                                q++;
@@ -766,12 +772,20 @@ process_preprocessed_file(struct mdfour *hash, const char *path)
                        while (q < end && *q != '"') {
                                q++;
                        }
+                       /* look for preprocessor flags, after the "filename" */
+                       system = false;
+                       r = q + 1;
+                       while (r < end && *r != '\n') {
+                               if (*r == '3') /* system header */
+                                       system = true;
+                               r++;
+                       }
                        /* p and q span the include file path */
                        path = x_strndup(p, q - p);
                        path = make_relative_path(path);
                        hash_string(hash, path);
-                       remember_include_file(path, hash);
-                       p = q;
+                       remember_include_file(path, hash, system);
+                       p = r;
                } else {
                        q++;
                }
@@ -786,7 +800,7 @@ process_preprocessed_file(struct mdfour *hash, const char *path)
                char *path = x_strdup(included_pch_file);
                path = make_relative_path(path);
                hash_string(hash, path);
-               remember_include_file(path, hash);
+               remember_include_file(path, hash, false);
        }
 
        return true;
index 1354423c4373a1f22940e958faf8da0f95d2bc77..71a13f02507f5d81c4fe6e105277853bb3f73b85 100644 (file)
--- a/ccache.h
+++ b/ccache.h
@@ -65,6 +65,11 @@ enum stats {
  * looking at their contents.
  */
 #define SLOPPY_FILE_STAT_MATCHES 32
+/*
+ * Allow us to not include any system headers in the manifest include files,
+ * similar to -MM versus -M for dependencies.
+ */
+#define SLOPPY_NO_SYSTEM_HEADERS 64
 
 #define str_eq(s1, s2) (strcmp((s1), (s2)) == 0)
 #define str_startswith(s, p) (strncmp((s), (p), strlen((p))) == 0)
diff --git a/conf.c b/conf.c
index e8bd523d3819cb3a2190cb26dd0f471ae21d61a7..1461ed58624fe0bc8999ed6868c362802796ee52 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -96,6 +96,8 @@ parse_sloppiness(const char *str, void *result, char **errmsg)
                        *value |= SLOPPY_INCLUDE_FILE_CTIME;
                } else if (str_eq(word, "include_file_mtime")) {
                        *value |= SLOPPY_INCLUDE_FILE_MTIME;
+               } else if (str_eq(word, "no_system_headers")) {
+                       *value |= SLOPPY_NO_SYSTEM_HEADERS;
                } else if (str_eq(word, "pch_defines")) {
                        *value |= SLOPPY_PCH_DEFINES;
                } else if (str_eq(word, "time_macros")) {
@@ -610,6 +612,9 @@ conf_print_items(struct conf *conf,
        if (conf->sloppiness & SLOPPY_FILE_STAT_MATCHES) {
                reformat(&s, "%sfile_stat_matches, ", s);
        }
+       if (conf->sloppiness & SLOPPY_NO_SYSTEM_HEADERS) {
+               reformat(&s, "%sno_system_headers, ", s);
+       }
        if (conf->sloppiness) {
                /* Strip last ", ". */
                s[strlen(s) - 2] = '\0';
index df344c553bfc37d0de555c363ada36f0996d19e6..4c6f2521183bb4e23ad43eba217cd0895494ef86 100644 (file)
@@ -116,7 +116,7 @@ TEST(conf_read_valid_config)
          "read_only_direct = true\n"
          "recache = true\n"
          "run_second_cpp = true\n"
-         "sloppiness =     file_macro   ,time_macros,  include_file_mtime,include_file_ctime,file_stat_matches  pch_defines  \n"
+         "sloppiness =     file_macro   ,time_macros,  include_file_mtime,include_file_ctime,file_stat_matches,no_system_headers  pch_defines  \n"
          "stats = false\n"
          "temporary_dir = ${USER}_foo\n"
          "umask = 777\n"
@@ -148,7 +148,8 @@ TEST(conf_read_valid_config)
        CHECK(conf->run_second_cpp);
        CHECK_INT_EQ(SLOPPY_INCLUDE_FILE_MTIME|SLOPPY_INCLUDE_FILE_CTIME|
                     SLOPPY_FILE_MACRO|SLOPPY_TIME_MACROS|
-                    SLOPPY_FILE_STAT_MATCHES|SLOPPY_PCH_DEFINES,
+                    SLOPPY_FILE_STAT_MATCHES|SLOPPY_NO_SYSTEM_HEADERS|
+                    SLOPPY_PCH_DEFINES,
                     conf->sloppiness);
        CHECK(!conf->stats);
        CHECK_STR_EQ_FREE1(format("%s_foo", user), conf->temporary_dir);
@@ -369,7 +370,7 @@ TEST(conf_print_items)
                true,
                SLOPPY_FILE_MACRO|SLOPPY_INCLUDE_FILE_MTIME|
                SLOPPY_INCLUDE_FILE_CTIME|SLOPPY_TIME_MACROS|
-               SLOPPY_FILE_STAT_MATCHES,
+               SLOPPY_FILE_STAT_MATCHES|SLOPPY_NO_SYSTEM_HEADERS,
                false,
                "td",
                022,
@@ -408,7 +409,8 @@ TEST(conf_print_items)
        CHECK_STR_EQ("recache = true", received_conf_items[n++].descr);
        CHECK_STR_EQ("run_second_cpp = true", received_conf_items[n++].descr);
        CHECK_STR_EQ("sloppiness = file_macro, include_file_mtime,"
-                    " include_file_ctime, time_macros, file_stat_matches",
+                    " include_file_ctime, time_macros,"
+                    " file_stat_matches, no_system_headers",
                     received_conf_items[n++].descr);
        CHECK_STR_EQ("stats = false", received_conf_items[n++].descr);
        CHECK_STR_EQ("temporary_dir = td", received_conf_items[n++].descr);