]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Merge branch 'maint'
authorJoel Rosdahl <joel@rosdahl.net>
Fri, 6 Jan 2012 15:32:45 +0000 (16:32 +0100)
committerJoel Rosdahl <joel@rosdahl.net>
Fri, 6 Jan 2012 15:32:45 +0000 (16:32 +0100)
* maint:
  Correct log message when unify mode is enabled
  Hash environment variables that affect the preprocessor output
  Hash mtime or content of GCC plugins specified with -fplugin=
  Use hash_compiler for explicit --specs= options as well
  Refactor code into a hash_compiler function
  Improve description on how to fix bad object files in the cache
  Make failure to create files in cache fatal
  Make failure to create cache directories fatal
  Remove unused print_executed_command function
  Handle non-writable CCACHE_DIR gracefully

Conflicts:
    ccache.c
    test.sh

MANUAL.txt
ccache.c
ccache.h
execute.c
test.sh

index 0a67b9f1d59f3aca572d6dc45abaaa962ad62563..f15d6667e6e111bda3ec4eedcf9b1e8d48e292ca 100644 (file)
@@ -771,10 +771,15 @@ It should be noted that ccache is susceptible to general storage problems. If a
 bad object file sneaks into the cache for some reason, it will of course stay
 bad. Some possible reasons for erroneous object files are bad hardware (disk
 drive, disk controller, memory, etc), buggy drivers or file systems, a bad
-*CCACHE_PREFIX* command or compiler wrapper. If this happens, you can either
-find out which object file is broken by reading the debug log and then delete
-the bad object file from the cache, or you can simply clear the whole cache
-with *ccache -C* if you don't mind losing other cached results.
+*CCACHE_PREFIX* command or compiler wrapper. If this happens, the easiest way
+of fixing it is this:
+
+1. Build so that the bad object file ends up in the build tree.
+2. Remove the bad object file from the build tree.
+3. Rebuild with *CCACHE_RECACHE* set.
+
+An alternative is to clear the whole cache with *ccache -C* if you don't mind
+losing other cached results.
 
 There are no reported issues about ccache producing broken object files
 reproducibly. That doesn't mean it can't happen, so if you find a repeatable
index 23c7758c902290fa42b3caea4c89eea3f07669a1..2b0fce065d84b1aec29de52c1705f3bd7d7ac624 100644 (file)
--- a/ccache.c
+++ b/ccache.c
@@ -2,7 +2,7 @@
  * ccache -- a fast C/C++ compiler cache
  *
  * Copyright (C) 2002-2007 Andrew Tridgell
- * Copyright (C) 2009-2011 Joel Rosdahl
+ * Copyright (C) 2009-2012 Joel Rosdahl
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -595,7 +595,10 @@ to_cache(struct args *args)
        status = execute(args->argv, tmp_stdout, tmp_stderr);
        args_pop(args, 3);
 
-       if (stat(tmp_stdout, &st) != 0 || st.st_size != 0) {
+       if (stat(tmp_stdout, &st) != 0) {
+               fatal("Could not create %s (permission denied?)", tmp_stdout);
+       }
+       if (st.st_size != 0) {
                cc_log("Compiler produced stdout");
                stats_update(STATS_STDOUT);
                tmp_unlink(tmp_stdout);
@@ -888,6 +891,36 @@ update_cached_result_globals(struct file_hash *hash)
        free(object_name);
 }
 
+/*
+ * Hash mtime or content of a file, or the output of a command, according to
+ * the CCACHE_COMPILERCHECK setting.
+ */
+static void
+hash_compiler(struct mdfour *hash, struct stat *st, const char *path,
+              bool allow_command)
+{
+       const char *compilercheck;
+
+       compilercheck = getenv("CCACHE_COMPILERCHECK");
+       if (!compilercheck) {
+               compilercheck = "mtime";
+       }
+       if (str_eq(compilercheck, "none")) {
+               /* Do nothing. */
+       } else if (str_eq(compilercheck, "mtime")) {
+               hash_delimiter(hash, "cc_mtime");
+               hash_int(hash, st->st_size);
+               hash_int(hash, st->st_mtime);
+       } else if (str_eq(compilercheck, "content") || !allow_command) {
+               hash_delimiter(hash, "cc_content");
+               hash_file(hash, path);
+       } else { /* command string */
+               if (!hash_multicommand_output(hash, compilercheck, orig_args->argv[0])) {
+                       fatal("Failure running compiler check command: %s", compilercheck);
+               }
+       }
+}
+
 /*
  * Update a hash sum with information common for the direct and preprocessor
  * modes.
@@ -896,7 +929,6 @@ static void
 calculate_common_hash(struct args *args, struct mdfour *hash)
 {
        struct stat st;
-       const char *compilercheck;
        char *p;
 
        hash_string(hash, HASH_PREFIX);
@@ -917,24 +949,7 @@ calculate_common_hash(struct args *args, struct mdfour *hash)
        /*
         * Hash information about the compiler.
         */
-       compilercheck = getenv("CCACHE_COMPILERCHECK");
-       if (!compilercheck) {
-               compilercheck = "mtime";
-       }
-       if (str_eq(compilercheck, "none")) {
-               /* Do nothing. */
-       } else if (str_eq(compilercheck, "content")) {
-               hash_delimiter(hash, "cc_content");
-               hash_file(hash, args->argv[0]);
-       } else if (str_eq(compilercheck, "mtime")) {
-               hash_delimiter(hash, "cc_mtime");
-               hash_int(hash, st.st_size);
-               hash_int(hash, st.st_mtime);
-       } else { /* command string */
-               if (!hash_multicommand_output(hash, compilercheck, orig_args->argv[0])) {
-                       fatal("Failure running compiler check command: %s", compilercheck);
-               }
-       }
+       hash_compiler(hash, &st, args->argv[0], true);
 
        /*
         * Also hash the compiler name as some compilers use hard links and
@@ -1011,14 +1026,19 @@ calculate_object_hash(struct args *args, struct mdfour *hash, int direct_mode)
                        }
                }
 
-               if (str_startswith(args->argv[i], "--specs=") &&
-                   stat(args->argv[i] + 8, &st) == 0) {
-                       /* If given a explicit specs file, then hash that file,
+               if (str_startswith(args->argv[i], "--specs=")
+                   && stat(args->argv[i] + 8, &st) == 0) {
+                       /* If given an explicit specs file, then hash that file,
                           but don't include the path to it in the hash. */
                        hash_delimiter(hash, "specs");
-                       if (!hash_file(hash, args->argv[i] + 8)) {
-                               failed();
-                       }
+                       hash_compiler(hash, &st, args->argv[i] + 8, false);
+                       continue;
+               }
+
+               if (str_startswith(args->argv[i], "-fplugin=")
+                   && stat(args->argv[i] + 9, &st) == 0) {
+                       hash_delimiter(hash, "plugin");
+                       hash_compiler(hash, &st, args->argv[i] + 9, false);
                        continue;
                }
 
@@ -1074,6 +1094,24 @@ calculate_object_hash(struct args *args, struct mdfour *hash, int direct_mode)
        }
 
        if (direct_mode) {
+               /* Hash environment variables that affect the preprocessor output. */
+               const char **p;
+               const char *envvars[] = {
+                       "CPATH",
+                       "C_INCLUDE_PATH",
+                       "CPLUS_INCLUDE_PATH",
+                       "OBJC_INCLUDE_PATH",
+                       "OBJCPLUS_INCLUDE_PATH", /* clang */
+                       NULL
+               };
+               for (p = envvars; *p != NULL ; ++p) {
+                       char *v = getenv(*p);
+                       if (v) {
+                               hash_delimiter(hash, *p);
+                               hash_string(hash, v);
+                       }
+               }
+
                if (!(sloppiness & SLOPPY_FILE_MACRO)) {
                        /*
                         * The source code file or an include file may contain
@@ -2038,7 +2076,7 @@ ccache(int argc, char *argv[])
        }
 
        if (getenv("CCACHE_UNIFY")) {
-               cc_log("Unify mode disabled");
+               cc_log("Unify mode enabled");
                enable_unify = true;
        }
 
index 64baf7348a8e94678d1f630ed2b057add3843b29..6a62753d39941cf3a4c76f70d63a780a6f032c22 100644 (file)
--- a/ccache.h
+++ b/ccache.h
@@ -196,7 +196,6 @@ int execute(char **argv,
             const char *path_stderr);
 char *find_executable(const char *name, const char *exclude_name);
 void print_command(FILE *fp, char **argv);
-void print_executed_command(FILE *fp, char **argv);
 
 /* ------------------------------------------------------------------------- */
 /* lockfile.c */
index 8773e71a4e46fecdc527c827f5fa62695cd5db06..8c7f4f4d728095d8f6eebce846c4b67e7cc2578f 100644 (file)
--- a/execute.c
+++ b/execute.c
@@ -314,10 +314,3 @@ print_command(FILE *fp, char **argv)
        }
        fprintf(fp, "\n");
 }
-
-void
-print_executed_command(FILE *fp, char **argv)
-{
-       fprintf(fp, "%s: executing ", MYNAME);
-       print_command(fp, argv);
-}
diff --git a/test.sh b/test.sh
index 91646bc8b6beac0ab11ed6a4cc6daa5fde27031c..128641fda02744a32d4032afb759ce4930ab0cba 100755 (executable)
--- a/test.sh
+++ b/test.sh
@@ -3,7 +3,7 @@
 # A simple test suite for ccache.
 #
 # Copyright (C) 2002-2007 Andrew Tridgell
-# Copyright (C) 2009-2011 Joel Rosdahl
+# Copyright (C) 2009-2012 Joel Rosdahl
 #
 # This program is free software; you can redistribute it and/or modify it under
 # the terms of the GNU General Public License as published by the Free Software
@@ -1152,6 +1152,40 @@ EOF
     checkstat 'cache miss' 1
 
     ##################################################################
+    # Check that environment variables that affect the preprocessor are taken
+    # into account.
+    testname="environment variables"
+    $CCACHE -Cz >/dev/null
+    rm -rf subdir1 subdir2
+    mkdir subdir1 subdir2
+    cat <<EOF >subdir1/foo.h
+int foo;
+EOF
+    cat <<EOF >subdir2/foo.h
+int foo;
+EOF
+    cat <<EOF >foo.c
+#include <foo.h>
+EOF
+    backdate subdir1/foo.h subdir2/foo.h
+    CPATH=subdir1 $CCACHE $COMPILER -c foo.c
+    checkstat 'cache hit (direct)' 0
+    checkstat 'cache hit (preprocessed)' 0
+    checkstat 'cache miss' 1
+    CPATH=subdir1 $CCACHE $COMPILER -c foo.c
+    checkstat 'cache hit (direct)' 1
+    checkstat 'cache hit (preprocessed)' 0
+    checkstat 'cache miss' 1
+    CPATH=subdir2 $CCACHE $COMPILER -c foo.c
+    checkstat 'cache hit (direct)' 1
+    checkstat 'cache hit (preprocessed)' 0
+    checkstat 'cache miss' 2 # subdir2 is part of the preprocessor output
+    CPATH=subdir2 $CCACHE $COMPILER -c foo.c
+    checkstat 'cache hit (direct)' 2
+    checkstat 'cache hit (preprocessed)' 0
+    checkstat 'cache miss' 2
+
+    #################################################################
     # Check that strange "#line" directives are handled.
     testname="#line directives with troublesome files"
     $CCACHE -Cz >/dev/null