From: Jørgen P. Tjernø Date: Sat, 8 Jun 2013 01:43:18 +0000 (-0700) Subject: Skip dependency filename options for object hash. X-Git-Tag: v3.2~41 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cea77ffd4c15040e2e677677f20347ea77d82407;p=thirdparty%2Fccache.git Skip dependency filename options for object hash. The filename of a dependency file doesn't have any bearing on the result, so using it to calculate object hashes gives incorrect results. This skips the part of: -Wp,-MD, -Wp,-MMD, -MF -MF Also tests for this functionality. Fixes issue jrosdahl#28. --- diff --git a/ccache.c b/ccache.c index 77590359c..0d6df5452 100644 --- a/ccache.c +++ b/ccache.c @@ -1152,6 +1152,36 @@ calculate_object_hash(struct args *args, struct mdfour *hash, int direct_mode) } } + /* If we're generating dependencies, we make sure to skip the + * filename of the dependency file, since it doesn't impact the + * output. + */ + if (generating_dependencies) { + if (str_startswith(args->argv[i], "-Wp,")) { + if (str_startswith(args->argv[i], "-Wp,-MD,") + && !strchr(args->argv[i] + 8, ',')) { + hash_string_length(hash, args->argv[i], 8); + continue; + } else if (str_startswith(args->argv[i], "-Wp,-MMD,") + && !strchr(args->argv[i] + 9, ',')) { + hash_string_length(hash, args->argv[i], 9); + continue; + } + } else if (str_startswith(args->argv[i], "-MF")) { + bool separate_argument = (strlen(args->argv[i]) == 3); + + /* In either case, hash the "-MF" part. */ + hash_string_length(hash, args->argv[i], 3); + + if (separate_argument) { + /* Next argument is dependency name, so + * skip it. */ + i++; + } + continue; + } + } + p = NULL; if (str_startswith(args->argv[i], "-specs=")) { p = args->argv[i] + 7; diff --git a/ccache.h b/ccache.h index 00aec468a..48812df05 100644 --- a/ccache.h +++ b/ccache.h @@ -101,6 +101,7 @@ void hash_result_as_bytes(struct mdfour *md, unsigned char *out); bool hash_equal(struct mdfour *md1, struct mdfour *md2); void hash_delimiter(struct mdfour *md, const char *type); void hash_string(struct mdfour *md, const char *s); +void hash_string_length(struct mdfour *md, const char *s, int length); void hash_int(struct mdfour *md, int x); bool hash_fd(struct mdfour *md, int fd); bool hash_file(struct mdfour *md, const char *fname); diff --git a/hash.c b/hash.c index b6a9e5ea2..80beed23a 100644 --- a/hash.c +++ b/hash.c @@ -80,7 +80,13 @@ hash_delimiter(struct mdfour *md, const char *type) void hash_string(struct mdfour *md, const char *s) { - hash_buffer(md, s, strlen(s)); + hash_string_length(md, s, strlen(s)); +} + +void +hash_string_length(struct mdfour *md, const char *s, int length) +{ + hash_buffer(md, s, length); } void diff --git a/test.sh b/test.sh index 95409ff44..efabac2c0 100755 --- a/test.sh +++ b/test.sh @@ -841,6 +841,15 @@ EOF rm -f other.d + $CCACHE $COMPILER -c -Wp,-MD,different_name.d test.c + checkstat 'cache hit (direct)' 2 + checkstat 'cache hit (preprocessed)' 0 + checkstat 'cache miss' 1 + checkfile different_name.d "$expected_d_content" + compare_file reference_test.o test.o + + rm -f different_name.d + ################################################################## # Check that -Wp,-MMD,file.d works. testname="-Wp,-MMD" @@ -865,6 +874,15 @@ EOF rm -f other.d + $CCACHE $COMPILER -c -Wp,-MMD,different_name.d test.c + checkstat 'cache hit (direct)' 2 + checkstat 'cache hit (preprocessed)' 0 + checkstat 'cache miss' 1 + checkfile different_name.d "$expected_mmd_d_content" + compare_file reference_test.o test.o + + rm -f different_name.d + ################################################################## # Test some header modifications to get multiple objects in the manifest. testname="several objects" @@ -963,6 +981,24 @@ EOF checkfile other.d "$expected_d_content" compare_file reference_test.o test.o + $CCACHE $COMPILER -c -MD -MF different_name.d test.c + checkstat 'cache hit (direct)' 2 + checkstat 'cache hit (preprocessed)' 0 + checkstat 'cache miss' 1 + checkfile different_name.d "$expected_d_content" + compare_file reference_test.o test.o + + rm -f different_name.d + + $CCACHE $COMPILER -c -MD -MFthird_name.d test.c + checkstat 'cache hit (direct)' 3 + checkstat 'cache hit (preprocessed)' 0 + checkstat 'cache miss' 1 + checkfile third_name.d "$expected_d_content" + compare_file reference_test.o test.o + + rm -f third_name.d + ################################################################## # Check that a missing .d file in the cache is handled correctly. testname="missing dependency file"