summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Rosdahl <joel@rosdahl.net>2012-01-06 17:03:38 +0100
committerJoel Rosdahl <joel@rosdahl.net>2012-01-06 17:03:38 +0100
commitaab78af38c0d21356c887c1ec3bb3699e4052e81 (patch)
tree830da34e85d202435c6c387e93d33b24b8496b78
parent8c018f6315044e6d9e4c992e2b3e7be0ebb81d96 (diff)
parent222ce68f156941d19f064878bda406c8704247cb (diff)
downloadccache-aab78af38c0d21356c887c1ec3bb3699e4052e81.tar.gz
Merge branch 'master' into config
* master: Merge branch 'maint' Sync mdfour.c license header with other files, notably fixing FSF's address. Conflicts: ccache.c
-rw-r--r--MANUAL.txt13
-rw-r--r--ccache.c83
-rw-r--r--ccache.h1
-rw-r--r--execute.c7
-rw-r--r--mdfour.c22
-rwxr-xr-xtest.sh36
6 files changed, 115 insertions, 47 deletions
diff --git a/MANUAL.txt b/MANUAL.txt
index d6a315f0..51b2dd74 100644
--- a/MANUAL.txt
+++ b/MANUAL.txt
@@ -764,10 +764,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
diff --git a/ccache.c b/ccache.c
index 234dd6a2..ddc919b7 100644
--- 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
@@ -572,7 +572,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);
@@ -867,6 +870,31 @@ update_cached_result_globals(struct file_hash *hash)
}
/*
+ * 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)
+{
+ if (str_eq(conf->compiler_check, "none")) {
+ /* Do nothing. */
+ } else if (str_eq(conf->compiler_check, "mtime")) {
+ hash_delimiter(hash, "cc_mtime");
+ hash_int(hash, st->st_size);
+ hash_int(hash, st->st_mtime);
+ } else if (str_eq(conf->compiler_check, "content") || !allow_command) {
+ hash_delimiter(hash, "cc_content");
+ hash_file(hash, path);
+ } else { /* command string */
+ if (!hash_multicommand_output(
+ hash, conf->compiler_check, orig_args->argv[0])) {
+ fatal("Failure running compiler check command: %s", conf->compiler_check);
+ }
+ }
+}
+
+/*
* Update a hash sum with information common for the direct and preprocessor
* modes.
*/
@@ -893,21 +921,7 @@ calculate_common_hash(struct args *args, struct mdfour *hash)
/*
* Hash information about the compiler.
*/
- if (str_eq(conf->compiler_check, "none")) {
- /* Do nothing. */
- } else if (str_eq(conf->compiler_check, "content")) {
- hash_delimiter(hash, "cc_content");
- hash_file(hash, args->argv[0]);
- } else if (str_eq(conf->compiler_check, "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, conf->compiler_check, orig_args->argv[0])) {
- fatal("Failure running compiler check command: %s", conf->compiler_check);
- }
- }
+ hash_compiler(hash, &st, args->argv[0], true);
/*
* Also hash the compiler name as some compilers use hard links and
@@ -983,14 +997,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;
}
@@ -1046,6 +1065,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 (!(conf->sloppiness & SLOPPY_FILE_MACRO)) {
/*
* The source code file or an include file may contain
diff --git a/ccache.h b/ccache.h
index 3608c408..2ef65c5f 100644
--- a/ccache.h
+++ b/ccache.h
@@ -200,7 +200,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 */
diff --git a/execute.c b/execute.c
index a12c563e..f19b090a 100644
--- a/execute.c
+++ b/execute.c
@@ -316,10 +316,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/mdfour.c b/mdfour.c
index 6547dc07..8d5b9a72 100644
--- a/mdfour.c
+++ b/mdfour.c
@@ -1,19 +1,19 @@
/*
* Copyright (C) 1997-1998 Andrew Tridgell
*
- * 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 Foundation; either version 3 of the License, or
- * (at your option) any later version.
+ * 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 Foundation; either version 3 of the License, or (at your option)
+ * any later version.
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "ccache.h"
diff --git a/test.sh b/test.sh
index 64040f65..982fbbd3 100755
--- 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
@@ -1164,6 +1164,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