summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders F Björklund <anders.f.bjorklund@gmail.com>2018-07-03 23:01:26 +0200
committerJoel Rosdahl <joel@rosdahl.net>2018-09-23 21:47:54 +0200
commitf7085d623fbffaee39002a47d1721ac894733b80 (patch)
tree70df73a272594dbe656bda6d0eba61a7c95e00fb
parent181298b9eb32c4e31d207c7bedeaa58c29bbfe4a (diff)
downloadccache-f7085d623fbffaee39002a47d1721ac894733b80.tar.gz
Add option to disable ctime check for manifest
Make it possible to use e.g. "git-restore-mtime"*, to use the original timestamps and avoid checksums. * https://github.com/MestreLion/git-tools Restoring ctime is much harder than restoring mtime, since you need to change the system clock to do it.
-rw-r--r--doc/MANUAL.adoc3
-rw-r--r--src/ccache.h3
-rw-r--r--src/conf.c5
-rw-r--r--src/manifest.c17
-rw-r--r--unittest/test_conf.c12
5 files changed, 30 insertions, 10 deletions
diff --git a/doc/MANUAL.adoc b/doc/MANUAL.adoc
index 9bcc4ede..283e5525 100644
--- a/doc/MANUAL.adoc
+++ b/doc/MANUAL.adoc
@@ -525,6 +525,9 @@ still has to do _some_ preprocessing (like macros).
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 mtimes and ctimes match.
+*file_stat_matches_ctime*::
+ By default, ccache will not consider a file as matching its cached
+ version if the ctimes do not match. This option disables that check.
*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/src/ccache.h b/src/ccache.h
index 973d42dd..ff60a582 100644
--- a/src/ccache.h
+++ b/src/ccache.h
@@ -79,6 +79,9 @@ extern enum guessed_compiler guessed_compiler;
// 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
+// Allow us to ignore ctimes when comparing file stats, so we can fake mtimes
+// if we want to (it is much harder to fake ctimes, requires changing clock)
+#define SLOPPY_FILE_STAT_MATCHES_CTIME 128
#define str_eq(s1, s2) (strcmp((s1), (s2)) == 0)
#define str_startswith(s, prefix) \
diff --git a/src/conf.c b/src/conf.c
index dc917092..fa8283fb 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -106,6 +106,8 @@ parse_sloppiness(const char *str, void *result, char **errmsg)
*value |= SLOPPY_FILE_MACRO;
} else if (str_eq(word, "file_stat_matches")) {
*value |= SLOPPY_FILE_STAT_MATCHES;
+ } else if (str_eq(word, "file_stat_matches_ctime")) {
+ *value |= SLOPPY_FILE_STAT_MATCHES_CTIME;
} else if (str_eq(word, "include_file_ctime")) {
*value |= SLOPPY_INCLUDE_FILE_CTIME;
} else if (str_eq(word, "include_file_mtime")) {
@@ -656,6 +658,9 @@ conf_print_items(struct conf *conf,
if (conf->sloppiness & SLOPPY_FILE_STAT_MATCHES) {
reformat(&s, "%sfile_stat_matches, ", s);
}
+ if (conf->sloppiness & SLOPPY_FILE_STAT_MATCHES_CTIME) {
+ reformat(&s, "%sfile_stat_matches_ctime, ", s);
+ }
if (conf->sloppiness & SLOPPY_NO_SYSTEM_HEADERS) {
reformat(&s, "%sno_system_headers, ", s);
}
diff --git a/src/manifest.c b/src/manifest.c
index 1eeccdf9..b2847a08 100644
--- a/src/manifest.c
+++ b/src/manifest.c
@@ -391,11 +391,20 @@ verify_object(struct conf *conf, struct manifest *mf, struct object *obj,
}
if (conf->sloppiness & SLOPPY_FILE_STAT_MATCHES) {
- if (fi->mtime == st->mtime && fi->ctime == st->ctime) {
- cc_log("mtime/ctime hit for %s", path);
- continue;
+ if (!(conf->sloppiness & SLOPPY_FILE_STAT_MATCHES_CTIME)) {
+ if (fi->mtime == st->mtime && fi->ctime == st->ctime) {
+ cc_log("mtime/ctime hit for %s", path);
+ continue;
+ } else {
+ cc_log("mtime/ctime miss for %s", path);
+ }
} else {
- cc_log("mtime/ctime miss for %s", path);
+ if (fi->mtime == st->mtime) {
+ cc_log("mtime hit for %s", path);
+ continue;
+ } else {
+ cc_log("mtime miss for %s", path);
+ }
}
}
diff --git a/unittest/test_conf.c b/unittest/test_conf.c
index 9271a88c..12a193bd 100644
--- a/unittest/test_conf.c
+++ b/unittest/test_conf.c
@@ -128,7 +128,7 @@ TEST(conf_read_valid_config)
"read_only_direct = true\n"
"recache = true\n"
"run_second_cpp = false\n"
- "sloppiness = file_macro ,time_macros, include_file_mtime,include_file_ctime,file_stat_matches,pch_defines , no_system_headers \n"
+ "sloppiness = file_macro ,time_macros, include_file_mtime,include_file_ctime,file_stat_matches,file_stat_matches_ctime,pch_defines , no_system_headers \n"
"stats = false\n"
"temporary_dir = ${USER}_foo\n"
"umask = 777\n"
@@ -169,8 +169,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_NO_SYSTEM_HEADERS|
- SLOPPY_PCH_DEFINES,
+ SLOPPY_FILE_STAT_MATCHES|SLOPPY_FILE_STAT_MATCHES_CTIME|
+ SLOPPY_NO_SYSTEM_HEADERS|SLOPPY_PCH_DEFINES,
conf->sloppiness);
CHECK(!conf->stats);
CHECK_STR_EQ_FREE1(format("%s_foo", user), conf->temporary_dir);
@@ -414,8 +414,8 @@ TEST(conf_print_items)
.run_second_cpp = false,
SLOPPY_FILE_MACRO|SLOPPY_INCLUDE_FILE_MTIME|
SLOPPY_INCLUDE_FILE_CTIME|SLOPPY_TIME_MACROS|
- SLOPPY_FILE_STAT_MATCHES|SLOPPY_PCH_DEFINES|
- SLOPPY_NO_SYSTEM_HEADERS,
+ SLOPPY_FILE_STAT_MATCHES|SLOPPY_FILE_STAT_MATCHES_CTIME|
+ SLOPPY_PCH_DEFINES|SLOPPY_NO_SYSTEM_HEADERS,
false,
"td",
022,
@@ -465,7 +465,7 @@ TEST(conf_print_items)
CHECK_STR_EQ("run_second_cpp = false", received_conf_items[n++].descr);
CHECK_STR_EQ("sloppiness = file_macro, include_file_mtime,"
" include_file_ctime, time_macros, pch_defines,"
- " file_stat_matches, no_system_headers",
+ " file_stat_matches, file_stat_matches_ctime, 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);