]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Skip dependency filename options for object hash.
authorJørgen P. Tjernø <jorgen@valvesoftware.com>
Sat, 8 Jun 2013 01:43:18 +0000 (18:43 -0700)
committerJoel Rosdahl <joel@rosdahl.net>
Sun, 25 Aug 2013 19:45:06 +0000 (21:45 +0200)
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 <file> part of:
  -Wp,-MD,<file>
  -Wp,-MMD,<file>
  -MF<file>
  -MF <file>

Also tests for this functionality.

Fixes issue jrosdahl#28.

ccache.c
ccache.h
hash.c
test.sh

index 77590359c5af366ccb5b9930635843159fc11547..0d6df545259bf1c0e83ee7c2b31afe4929afd2cb 100644 (file)
--- 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;
index 00aec468a154b44087d6c066aff75b2cf343079a..48812df05556ba026bcd4178de701711dcbbb63b 100644 (file)
--- 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 b6a9e5ea2dad46f4cad36106ee6bc7f9403a7124..80beed23aebf6bcdd9f94b0a7dd5ee9103302f89 100644 (file)
--- 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 95409ff449401a89024bec674909ccc7713b7fb0..efabac2c0960f9cfd5e43e04e916e4bea3d3ff16 100755 (executable)
--- 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"