Add some opt-in sloppiness

This commit is contained in:
Joel Rosdahl 2010-05-17 22:29:42 +02:00
parent ba303352bb
commit eb5d9bd3be
6 changed files with 208 additions and 8 deletions

View File

@ -77,6 +77,9 @@ New features and improvements
- Messages printed to the debug log (specified by `CCACHE_LOGFILE`) have
been improved.
- You can relax some checks that ccache does in direct mode by setting
`CCACHE_SLOPPINESS`. See the manual for more information.
- `CCACHE_TEMPDIR` no longer needs to be on the same filesystem as
`CCACHE_DIR`.

View File

@ -133,6 +133,9 @@ static char *manifest_path;
*/
static time_t time_of_compilation;
/* Bitmask of SLOPPY_*. */
unsigned sloppiness = 0;
/*
* Files included by the preprocessor and their hashes/sizes. Key: file path.
* Value: struct file_hash.
@ -330,7 +333,8 @@ static void remember_include_file(char *path, size_t path_len)
/* Ignore directory, typically $PWD. */
goto ignore;
}
if (st.st_mtime >= time_of_compilation) {
if (!(sloppiness & SLOPPY_INCLUDE_FILE_MTIME)
&& st.st_mtime >= time_of_compilation) {
cc_log("Include file %s too new", path);
goto failure;
}
@ -910,13 +914,15 @@ static struct file_hash *calculate_object_hash(
}
if (direct_mode) {
/*
* The source code file or an include file may contain
* __FILE__, so make sure that the hash is unique for the file
* name.
*/
hash_delimiter(hash, "inputfile");
hash_string(hash, input_file);
if (!(sloppiness & SLOPPY_FILE_MACRO)) {
/*
* The source code file or an include file may contain
* __FILE__, so make sure that the hash is unique for
* the file name.
*/
hash_delimiter(hash, "inputfile");
hash_string(hash, input_file);
}
hash_delimiter(hash, "sourcecode");
result = hash_source_code_file(hash, input_file);
@ -1617,6 +1623,35 @@ static void process_args(int argc, char **argv, ARGS **preprocessor_args,
*compiler_args = stripped_args;
}
static unsigned parse_sloppiness(char *p)
{
unsigned result = 0;
char *word, *q;
if (!p) {
return result;
}
p = x_strdup(p);
q = p;
while ((word = strtok(q, ", "))) {
if (strcmp(word, "file_macro") == 0) {
cc_log("Being sloppy about __FILE__");
result |= SLOPPY_FILE_MACRO;
}
if (strcmp(word, "include_file_mtime") == 0) {
cc_log("Being sloppy about include file mtime");
result |= SLOPPY_INCLUDE_FILE_MTIME;
}
if (strcmp(word, "time_macros") == 0) {
cc_log("Being sloppy about __DATE__ and __TIME__");
result |= SLOPPY_TIME_MACROS;
}
q = NULL;
}
free(p);
return result;
}
/* the main ccache driver function */
static void ccache(int argc, char *argv[])
{
@ -1636,6 +1671,8 @@ static void ccache(int argc, char *argv[])
cc_log("=== CCACHE STARTED =========================================");
sloppiness = parse_sloppiness(getenv("CCACHE_SLOPPINESS"));
if (base_dir) {
cc_log("Base directory: %s", base_dir);
}

View File

@ -55,6 +55,10 @@ enum stats {
STATS_END
};
#define SLOPPY_INCLUDE_FILE_MTIME 1
#define SLOPPY_FILE_MACRO 2
#define SLOPPY_TIME_MACROS 4
void hash_start(struct mdfour *md);
void hash_delimiter(struct mdfour *md, const char* type);
void hash_string(struct mdfour *md, const char *s);

View File

@ -64,6 +64,7 @@ hash_source_code_string(
char hashbuf[64];
size_t hashbuflen = 0;
int result = HASH_SOURCE_CODE_OK;
extern unsigned sloppiness;
p = str;
end = str + len;
@ -159,6 +160,9 @@ hash_source_code_string(
end:
hash_buffer(hash, hashbuf, hashbuflen);
if (sloppiness & SLOPPY_TIME_MACROS) {
return 0;
}
if (result & HASH_SOURCE_CODE_FOUND_DATE) {
/*
* Make sure that the hash sum changes if the (potential)

View File

@ -299,6 +299,18 @@ cases you won't need any of these as the defaults will be fine.
This forces ccache to not use any cached results, even if it finds them.
New results are still cached, but existing cache entries are ignored.
*CCACHE_SLOPPINESS*::
By default, ccache tries to give as few false cache hits as possible.
However, in certain situations it's possible that you know things that
ccache can't take for granted. The *CCACHE_SLOPPINESS* environment variable
makes it possible to tell ccache to relax some checks in order to increase
the hit rate. The value should be a comma-separated string with options.
Available options are: *file_macro* (ignore *\_\_FILE\__* being present in
the source), *include_file_mtime* (don't check the modification time of
include files in direct mode) and *time_macros* (ignore *\_\_DATE\__* and
*\_\_TIME__* being present in the source code).
*CCACHE_TEMPDIR*::
The *CCACHE_TEMPDIR* environment variable specifies where ccache will put

140
test.sh
View File

@ -53,6 +53,7 @@ unset CCACHE_PATH
unset CCACHE_PREFIX
unset CCACHE_READONLY
unset CCACHE_RECACHE
unset CCACHE_SLOPPINESS
unset CCACHE_TEMPDIR
unset CCACHE_UMASK
unset CCACHE_UNIFY
@ -837,6 +838,51 @@ EOF
checkstat 'cache hit (preprocessed)' 0
checkstat 'cache miss' 2
##################################################################
# Check that direct mode ignores __FILE__ if sloppiness is specified.
testname="__FILE__ in source file, sloppy"
$CCACHE -Cz >/dev/null
cat <<EOF >file.c
#define file __FILE__
int test;
EOF
CCACHE_SLOPPINESS=file_macro $CCACHE $COMPILER -c file.c
checkstat 'cache hit (direct)' 0
checkstat 'cache hit (preprocessed)' 0
checkstat 'cache miss' 1
CCACHE_SLOPPINESS=file_macro $CCACHE $COMPILER -c file.c
checkstat 'cache hit (direct)' 1
checkstat 'cache hit (preprocessed)' 0
checkstat 'cache miss' 1
CCACHE_SLOPPINESS=file_macro $CCACHE $COMPILER -c $PWD/file.c
checkstat 'cache hit (direct)' 2
checkstat 'cache hit (preprocessed)' 0
checkstat 'cache miss' 1
testname="__FILE__ in include file, sloppy"
$CCACHE -Cz >/dev/null
cat <<EOF >file.h
#define file __FILE__
int test;
EOF
backdate file.h
cat <<EOF >file_h.c
#include "file.h"
EOF
CCACHE_SLOPPINESS=file_macro $CCACHE $COMPILER -c file_h.c
checkstat 'cache hit (direct)' 0
checkstat 'cache hit (preprocessed)' 0
checkstat 'cache miss' 1
CCACHE_SLOPPINESS=file_macro $CCACHE $COMPILER -c file_h.c
checkstat 'cache hit (direct)' 1
checkstat 'cache hit (preprocessed)' 0
checkstat 'cache miss' 1
mv file_h.c file2_h.c
CCACHE_SLOPPINESS=file_macro $CCACHE $COMPILER -c $PWD/file2_h.c
checkstat 'cache hit (direct)' 2
checkstat 'cache hit (preprocessed)' 0
checkstat 'cache miss' 1
##################################################################
# Check that we never get direct hits when __TIME__ is used.
testname="__TIME__ in source file"
@ -873,6 +919,100 @@ EOF
checkstat 'cache hit (preprocessed)' 1
checkstat 'cache miss' 1
##################################################################
# Check that direct mode ignores __TIME__ when sloppiness is specified.
testname="__TIME__ in source file, sloppy"
$CCACHE -Cz >/dev/null
cat <<EOF >time.c
#define time __TIME__
int test;
EOF
CCACHE_SLOPPINESS=time_macros $CCACHE $COMPILER -c time.c
checkstat 'cache hit (direct)' 0
checkstat 'cache hit (preprocessed)' 0
checkstat 'cache miss' 1
CCACHE_SLOPPINESS=time_macros $CCACHE $COMPILER -c time.c
checkstat 'cache hit (direct)' 1
checkstat 'cache hit (preprocessed)' 0
checkstat 'cache miss' 1
testname="__TIME__ in include time, sloppy"
$CCACHE -Cz >/dev/null
cat <<EOF >time.h
#define time __TIME__
int test;
EOF
backdate time.h
cat <<EOF >time_h.c
#include "time.h"
EOF
CCACHE_SLOPPINESS=time_macros $CCACHE $COMPILER -c time_h.c
checkstat 'cache hit (direct)' 0
checkstat 'cache hit (preprocessed)' 0
checkstat 'cache miss' 1
CCACHE_SLOPPINESS=time_macros $CCACHE $COMPILER -c time_h.c
checkstat 'cache hit (direct)' 1
checkstat 'cache hit (preprocessed)' 0
checkstat 'cache miss' 1
##################################################################
# Check that a too new include file turns off direct mode.
testname="too new include file"
$CCACHE -Cz >/dev/null
cat <<EOF >new.c
#include "new.h"
EOF
cat <<EOF >new.h
int test;
EOF
touchy_compiler=touchy-compiler.sh
cat <<EOF >$touchy_compiler
#!/bin/sh
CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink...
export CCACHE_DISABLE
[ x\$2 = "x-E" ] && touch \$3 # Be sure that mtime >= time_of_compilation
exec $COMPILER "\$@"
EOF
chmod +x $touchy_compiler
$CCACHE ./$touchy_compiler -c new.c
checkstat 'cache hit (direct)' 0
checkstat 'cache hit (preprocessed)' 0
checkstat 'cache miss' 1
$CCACHE ./$touchy_compiler -c new.c
checkstat 'cache hit (direct)' 0
checkstat 'cache hit (preprocessed)' 1
checkstat 'cache miss' 1
##################################################################
# Check that include file mtime is ignored when sloppiness is specified.
testname="too new include file, sloppy"
$CCACHE -Cz >/dev/null
cat <<EOF >new.c
#include "new.h"
EOF
cat <<EOF >new.h
int test;
EOF
touchy_compiler=touchy-compiler.sh
cat <<EOF >$touchy_compiler
#!/bin/sh
CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink...
export CCACHE_DISABLE
[ x\$2 = "x-E" ] && touch \$3 # Be sure that mtime >= time_of_compilation
exec $COMPILER "\$@"
EOF
chmod +x $touchy_compiler
CCACHE_SLOPPINESS=include_file_mtime $CCACHE ./$touchy_compiler -c new.c
checkstat 'cache hit (direct)' 0
checkstat 'cache hit (preprocessed)' 0
checkstat 'cache miss' 1
CCACHE_SLOPPINESS=include_file_mtime $CCACHE ./$touchy_compiler -c new.c
checkstat 'cache hit (direct)' 1
checkstat 'cache hit (preprocessed)' 0
checkstat 'cache miss' 1
##################################################################
# Reset things.
CCACHE_NODIRECT=1