From f7085d623fbffaee39002a47d1721ac894733b80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Tue, 3 Jul 2018 23:01:26 +0200 Subject: 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. --- doc/MANUAL.adoc | 3 +++ src/ccache.h | 3 +++ src/conf.c | 5 +++++ src/manifest.c | 17 +++++++++++++---- unittest/test_conf.c | 12 ++++++------ 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); -- cgit v1.2.1