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.
* 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;
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;
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)) {
&& q[5] == ' '))
&& (q == data || q[-1] == '\n')) {
char *path;
+ bool system;
while (q < end && *q != '"' && *q != '\n') {
q++;
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++;
}
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;
* 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)
*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")) {
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';
"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"
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);
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,
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);