From: Anders Björklund Date: Sat, 24 Oct 2015 14:41:33 +0000 (+0200) Subject: Allow not including system headers in manifest X-Git-Tag: v3.3~144 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=219783844c63d37c26f771c1471f3fe2943f9a88;p=thirdparty%2Fccache.git Allow not including system headers in manifest 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. --- diff --git a/MANUAL.txt b/MANUAL.txt index e7e4bf225..228a2d79d 100644 --- a/MANUAL.txt +++ b/MANUAL.txt @@ -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. diff --git a/ccache.c b/ccache.c index 9043804da..e974f328a 100644 --- 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; diff --git a/ccache.h b/ccache.h index 1354423c4..71a13f025 100644 --- 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 e8bd523d3..1461ed586 100644 --- 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'; diff --git a/test/test_conf.c b/test/test_conf.c index df344c553..4c6f25211 100644 --- a/test/test_conf.c +++ b/test/test_conf.c @@ -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);