]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Rewrite include directory option arguments into relative to get better hit rate
authorJoel Rosdahl <joel@rosdahl.net>
Sat, 5 Dec 2009 10:27:35 +0000 (11:27 +0100)
committerJoel Rosdahl <joel@rosdahl.net>
Tue, 5 Jan 2010 17:53:02 +0000 (18:53 +0100)
A secondary effect is that paths in the standard error output produced by the
compiler will be normalized.

ccache.c
test.sh

index fce4d2864bfff2576f527cd8ed6b2d23ae3be895..ef5c46a08ce8b1ddd2a87d4112f30a0fae3b44e2 100644 (file)
--- a/ccache.c
+++ b/ccache.c
@@ -673,32 +673,24 @@ static int find_hash(ARGS *args, enum findhash_call_mode mode)
                   to the hash. The theory is that these arguments will change
                   the output of -E if they are going to have any effect at
                   all. */
-               if (i < args->argc-1) {
-                       if (strcmp(args->argv[i], "-I") == 0 ||
-                           strcmp(args->argv[i], "-include") == 0 ||
-                           strcmp(args->argv[i], "-D") == 0 ||
-                           strcmp(args->argv[i], "-idirafter") == 0 ||
-                           strcmp(args->argv[i], "-isystem") == 0) {
-                               if (mode == FINDHASH_DIRECT_MODE) {
-                                       hash_string(&hash, args->argv[i]);
-                                       s = make_relative_path(x_strdup(args->argv[i+1]));
-                                       hash_string(&hash, s);
-                                       free(s);
-                               } /* else: skip from hash */
-                               i++;
+               if (mode == FINDHASH_CPP_MODE) {
+                       if (i < args->argc-1) {
+                               if (strcmp(args->argv[i], "-I") == 0 ||
+                                   strcmp(args->argv[i], "-include") == 0 ||
+                                   strcmp(args->argv[i], "-D") == 0 ||
+                                   strcmp(args->argv[i], "-idirafter") == 0 ||
+                                   strcmp(args->argv[i], "-isystem") == 0) {
+                                       /* Skip from hash. */
+                                       i++;
+                                       continue;
+                               }
+                       }
+                       if (strncmp(args->argv[i], "-I", 2) == 0 ||
+                           strncmp(args->argv[i], "-D", 2) == 0) {
+                               /* Skip from hash. */
                                continue;
                        }
                }
-               if (strncmp(args->argv[i], "-I", 2) == 0 ||
-                   strncmp(args->argv[i], "-D", 2) == 0) {
-                       if (mode == FINDHASH_DIRECT_MODE) {
-                               hash_buffer(&hash, args->argv[i], 2);
-                               s = make_relative_path(x_strdup(args->argv[i] + 2));
-                               hash_string(&hash, s);
-                               free(s);
-                       } /* else: skip from hash */
-                       continue;
-               }
 
                if (strncmp(args->argv[i], "--specs=", 8) == 0 &&
                    stat(args->argv[i]+8, &st) == 0) {
@@ -1189,14 +1181,69 @@ static void process_args(int argc, char **argv)
                        }
                }
 
+               /*
+                * Options taking an argument that that we may want to rewrite
+                * to relative paths to get better hit rate. A secondary effect
+                * is that paths in the standard error output produced by the
+                * compiler will be normalized.
+                */
+               {
+                       const char *opts[] = {
+                               "-I", "-idirafter", "-include", "-isystem", NULL
+                       };
+                       int j;
+                       char *relpath;
+                       for (j = 0; opts[j]; j++) {
+                               if (strcmp(argv[i], opts[j]) == 0) {
+                                       if (i == argc-1) {
+                                               cc_log("missing argument to %s\n",
+                                                      argv[i]);
+                                               stats_update(STATS_ARGS);
+                                               failed();
+                                       }
+
+                                       args_add(stripped_args, argv[i]);
+                                       relpath = make_relative_path(x_strdup(argv[i+1]));
+                                       args_add(stripped_args, relpath);
+                                       free(relpath);
+                                       i++;
+                                       break;
+                               }
+                       }
+                       if (opts[j]) {
+                               continue;
+                       }
+               }
+
+               /* Same as above but options with concatenated argument. */
+               {
+                       const char *opts[] = {"-I", NULL};
+                       int j;
+                       char *relpath;
+                       char *option;
+                       for (j = 0; opts[j]; j++) {
+                               if (strncmp(argv[i], opts[j], strlen(opts[j])) == 0) {
+                                       relpath = make_relative_path(
+                                               x_strdup(argv[i] + strlen(opts[j])));
+                                       x_asprintf(&option, "%s%s", opts[j], relpath);
+                                       args_add(stripped_args, option);
+                                       free(relpath);
+                                       free(option);
+                                       break;
+                               }
+                       }
+                       if (opts[j]) {
+                               continue;
+                       }
+               }
+
                /* options that take an argument */
                {
-                       const char *opts[] = {"-I", "-include", "-imacros", "-iprefix",
+                       const char *opts[] = {"-imacros", "-iprefix",
                                              "-iwithprefix", "-iwithprefixbefore",
                                              "-L", "-D", "-U", "-x", "-MF",
-                                             "-MT", "-MQ", "-isystem", "-aux-info",
+                                             "-MT", "-MQ", "-aux-info",
                                              "--param", "-A", "-Xlinker", "-u",
-                                             "-idirafter",
                                              NULL};
                        int j;
                        for (j=0;opts[j];j++) {
@@ -1250,7 +1297,8 @@ static void process_args(int argc, char **argv)
                        failed();
                }
 
-               input_file = argv[i];
+               /* Rewrite to relative to increase hit rate. */
+               input_file = make_relative_path(x_strdup(argv[i]));
        }
 
        if (!input_file) {
diff --git a/test.sh b/test.sh
index 67ed900a7369233cbcaa00e9e87d10e4217e7f05..1c539179c7aa52775614cee01c9b8d2c440ae7ae 100755 (executable)
--- a/test.sh
+++ b/test.sh
@@ -15,8 +15,7 @@ TESTDIR=testdir.$$
 unset CCACHE_DISABLE
 
 test_failed() {
-    reason="$1"
-    echo $1
+    echo "SUITE: \"$testsuite\", TEST: \"$testname\" - $1"
     $CCACHE -s
     cd ..
     rm -rf $TESTDIR
@@ -48,16 +47,16 @@ checkstat() {
     expected_value="$2"
     value=`getstat "$stat"`
     if [ "$expected_value" != "$value" ]; then
-        test_failed "SUITE: $testsuite, TEST: \"$testname\" - Expected $stat to be $expected_value, got $value"
+        test_failed "Expected $stat to be $expected_value, got $value"
     fi
 }
 
 checkfile() {
     if [ ! -f $1 ]; then
-        test_failed "SUITE: $testsuite, TEST: \"$testname\" - $1 not found"
+        test_failed "$1 not found"
     fi
     if [ "`cat $1`" != "$2" ]; then
-        test_failed "SUITE: $testsuite, TEST: \"$testname\" - Bad content of $2.\nExpected: $2\nActual: `cat $1`"
+        test_failed "Bad content of $2.\nExpected: $2\nActual: `cat $1`"
     fi
 }
 
@@ -503,6 +502,16 @@ int test;
 EOF
     cp -r dir1 dir2
 
+    cat <<EOF >stderr.h
+int stderr(void)
+{
+       /* Trigger warning by having no return statement. */
+}
+EOF
+    cat <<EOF >stderr.c
+#include <stderr.h>
+EOF
+
     sleep 1 # Sleep to make the include files trusted.
 
     ##################################################################
@@ -581,6 +590,26 @@ EOF
     checkstat 'cache hit (preprocessed)' 1
     checkstat 'cache miss' 0
     cd ..
+
+    ##################################################################
+    # Check that rewriting triggered by CCACHE_BASEDIR also affects stderr.
+    testname="stderr"
+    $CCACHE -z >/dev/null
+    $CCACHE $COMPILER -Wall -W -I$PWD -c $PWD/stderr.c -o $PWD/stderr.o 2>stderr.txt
+    checkstat 'cache hit (direct)' 0
+    checkstat 'cache hit (preprocessed)' 0
+    checkstat 'cache miss' 1
+    if grep -q $PWD stderr.txt; then
+        test_failed "Base dir ($PWD) found in stderr:\n`cat stderr.txt`"
+    fi
+
+    $CCACHE $COMPILER -Wall -W -I$PWD -c $PWD/stderr.c -o $PWD/stderr.o 2>stderr.txt
+    checkstat 'cache hit (direct)' 0
+    checkstat 'cache hit (preprocessed)' 1
+    checkstat 'cache miss' 1
+    if grep -q $PWD stderr.txt; then
+        test_failed "Base dir ($PWD) found in stderr:\n`cat stderr.txt`"
+    fi
 }
 
 ######