Skip to content

Commit

Permalink
Change the checksum into a runtime option instead
Browse files Browse the repository at this point in the history
  • Loading branch information
afbjorklund committed May 13, 2019
1 parent d735064 commit 54d1373
Show file tree
Hide file tree
Showing 16 changed files with 162 additions and 52 deletions.
5 changes: 3 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -179,16 +179,17 @@ if test x${enable_tracing} = xyes; then
fi


ccache_checksum='CCACHE_CHECKSUM=md4 '
ccache_checksum="md4"
AC_ARG_ENABLE(blake2,
[AS_HELP_STRING([--enable-blake2],
[use blake2b checksum instead of md4])])
if test x${enable_blake2} = xyes; then
CPPFLAGS="$CPPFLAGS -DUSE_BLAKE2"
ccache_checksum='CCACHE_CHECKSUM=blake2b '
ccache_checksum="$ccache_checksum blake2b"
AC_CHECK_HEADERS(blake2.h)
AC_CHECK_LIB([b2],[blake2b])
fi
ccache_checksum="CHECKSUMS='$ccache_checksum' "
AC_SUBST(ccache_checksum)

dnl Linking on Windows needs ws2_32
Expand Down
5 changes: 5 additions & 0 deletions doc/MANUAL.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,11 @@ IN DIFFERENT DIRECTORIES>>.
This setting allows you to choose the number of directory levels in the
cache directory. The default is 2. The minimum is 1 and the maximum is 8.

*checksum* (*CCACHE_CHECKSUM*)::

This setting specifies which checksum that ccache will use for the hashes.
The default is *md4*.

*compiler* (*CCACHE_COMPILER* or (deprecated) *CCACHE_CC*)::

This setting can be used to force the name of the compiler to use. If set
Expand Down
5 changes: 5 additions & 0 deletions misc/performance
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ def test(tmp_dir, options, compiler_args, source_file):

environment = {"CCACHE_DIR": ccache_dir, "PATH": environ["PATH"]}
environment["CCACHE_COMPILERCHECK"] = options.compilercheck
if options.checksum:
environment["CCACHE_CHECKSUM"] = options.checksum
if options.compression:
environment["CCACHE_COMPRESS"] = "1"
if options.hardlink:
Expand Down Expand Up @@ -252,6 +254,7 @@ def main(argv):
op.add_option(
"--compilercheck", help="specify compilercheck (default: mtime)"
)
op.add_option("--checksum", help="hash checksum")
op.add_option("--compression", help="use compression", action="store_true")
op.add_option(
"-d",
Expand Down Expand Up @@ -287,6 +290,7 @@ def main(argv):
op.add_option("--xml", help="print results as XML", action="store_true")
op.set_defaults(
ccache=DEFAULT_CCACHE,
checksum="md4",
compilercheck="mtime",
directory=DEFAULT_DIRECTORY,
hit_factor=DEFAULT_HIT_FACTOR,
Expand Down Expand Up @@ -316,6 +320,7 @@ def main(argv):
% (" ".join(args), splitext(argv[-1])[0])
)
print("Compilercheck:", options.compilercheck)
print("Checksum:", options.checksum)
print("Compression:", on_off(options.compression))
print("Hardlink:", on_off(options.hardlink))
print("Nostats:", on_off(options.nostats))
Expand Down
2 changes: 2 additions & 0 deletions src/ccache.c
Original file line number Diff line number Diff line change
Expand Up @@ -3697,6 +3697,8 @@ initialize(void)
cc_log("=== CCACHE %s STARTED =========================================",
CCACHE_VERSION);

hash_checksum(conf->checksum);

if (conf->umask != UINT_MAX) {
umask(conf->umask);
}
Expand Down
3 changes: 3 additions & 0 deletions src/conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ conf_create(void)
conf->base_dir = x_strdup("");
conf->cache_dir = format("%s/.ccache", get_home_directory());
conf->cache_dir_levels = 2;
conf->checksum = x_strdup("md4");
conf->compiler = x_strdup("");
conf->compiler_check = x_strdup("mtime");
conf->compression = false;
Expand Down Expand Up @@ -176,6 +177,7 @@ conf_free(struct conf *conf)
}
free(conf->base_dir);
free(conf->cache_dir);
free(conf->checksum);
free(conf->compiler);
free(conf->compiler_check);
free(conf->cpp_extension);
Expand Down Expand Up @@ -393,6 +395,7 @@ conf_print_items(struct conf *conf,
ok &= print_item(conf, "base_dir", printer, context);
ok &= print_item(conf, "cache_dir", printer, context);
ok &= print_item(conf, "cache_dir_levels", printer, context);
ok &= print_item(conf, "checksum", printer, context);
ok &= print_item(conf, "compiler", printer, context);
ok &= print_item(conf, "compiler_check", printer, context);
ok &= print_item(conf, "compression", printer, context);
Expand Down
1 change: 1 addition & 0 deletions src/conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ struct conf {
char *base_dir;
char *cache_dir;
unsigned cache_dir_levels;
char *checksum;
char *compiler;
char *compiler_check;
bool compression;
Expand Down
1 change: 1 addition & 0 deletions src/confitems.gperf
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ struct conf_item;
base_dir, ITEM_V(base_dir, env_string, absolute_path)
cache_dir, ITEM(cache_dir, env_string)
cache_dir_levels, ITEM_V(cache_dir_levels, unsigned, dir_levels)
checksum, ITEM(checksum, string)
compiler, ITEM(compiler, string)
compiler_check, ITEM(compiler_check, string)
compression, ITEM(compression, bool)
Expand Down
1 change: 1 addition & 0 deletions src/envtoconfitems.gperf
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ struct env_to_conf_item;
%%
BASEDIR, "base_dir"
CC, "compiler"
CHECKSUM, "checksum"
COMPILER, "compiler"
COMPILERCHECK, "compiler_check"
COMPRESS, "compression"
Expand Down
72 changes: 50 additions & 22 deletions src/hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,19 @@

#define HASH_DELIMITER "\000cCaChE"

enum {
CHECKSUM_MD4 = 0,
CHECKSUM_BLAKE2B
};

static int hash_csum = CHECKSUM_MD4;

struct hash {
#ifdef USE_BLAKE2
blake2b_state state;
size_t total;
#else
struct mdfour md;
#endif
struct mdfour md;
FILE *debug_binary;
FILE *debug_text;
};
Expand All @@ -42,11 +48,12 @@ do_hash_buffer(struct hash *hash, const void *s, size_t len)
assert(s);

#ifdef USE_BLAKE2
blake2b_update(&hash->state, (const uint8_t *)s, len);
hash->total += len;
#else
mdfour_update(&hash->md, (const unsigned char *)s, len);
if (hash_csum == CHECKSUM_BLAKE2B) {
blake2b_update(&hash->state, (const uint8_t *)s, len);
hash->total += len;
} else
#endif
mdfour_update(&hash->md, (const unsigned char *)s, len);
if (len > 0 && hash->debug_binary) {
(void) fwrite(s, 1, len, hash->debug_binary);
}
Expand All @@ -60,31 +67,50 @@ do_debug_text(struct hash *hash, const void *s, size_t len)
}
}

// Change the checksum being used
bool hash_checksum(const char *checksum)
{
if (str_eq(checksum, "md4")) {
hash_csum = CHECKSUM_MD4;
return true;
} else if (str_eq(checksum, "blake2b")) {
hash_csum = CHECKSUM_BLAKE2B;
return true;
}
return false;
}

struct hash *
hash_init(void)
{
struct hash *hash = malloc(sizeof(struct hash));
hash_reset(hash);
return hash;
}

void
hash_reset(struct hash *hash)
{
#ifdef USE_BLAKE2
blake2b_init(&hash->state, 16);
hash->total = 0;
#else
mdfour_begin(&hash->md);
#endif
mdfour_begin(&hash->md);
hash->debug_binary = NULL;
hash->debug_text = NULL;
return hash;
}

struct hash *
hash_copy(struct hash *hash)
{
struct hash *result = malloc(sizeof(struct hash));
#ifdef USE_BLAKE2
result->state = hash->state;
result->total = hash->total;
#else
result->md = hash->md;
if (hash_csum == CHECKSUM_BLAKE2B) {
result->state = hash->state;
result->total = hash->total;
} else
#endif
result->md = hash->md;
result->debug_binary = NULL;
result->debug_text = NULL;
return result;
Expand All @@ -111,10 +137,11 @@ size_t
hash_input_size(struct hash *hash)
{
#ifdef USE_BLAKE2
return hash->total;
#else
return hash->md.totalN + hash->md.tail_len;
if (hash_csum == CHECKSUM_BLAKE2B) {
return hash->total;
} else
#endif
return hash->md.totalN + hash->md.tail_len;
}

void
Expand All @@ -137,13 +164,14 @@ void
hash_result_as_bytes(struct hash *hash, unsigned char *out)
{
#ifdef USE_BLAKE2
// make a copy before altering state
struct hash *copy = hash_copy(hash);
blake2b_final(&copy->state, out, 16);
free(copy);
#else
mdfour_result(&hash->md, out);
if (hash_csum == CHECKSUM_BLAKE2B) {
// make a copy before altering state
struct hash *copy = hash_copy(hash);
blake2b_final(&copy->state, out, 16);
free(copy);
} else
#endif
mdfour_result(&hash->md, out);
}

bool
Expand Down
6 changes: 6 additions & 0 deletions src/hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,15 @@

struct hash;

// Change the checksum being used.
bool hash_checksum(const char *checksum);

// Create a new hash.
struct hash *hash_init(void);

// Reset hash to the initial state.
void hash_reset(struct hash *hash);

// Create a new hash from an existing hash state.
struct hash *hash_copy(struct hash *hash);

Expand Down
6 changes: 1 addition & 5 deletions test/run
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,6 @@ run_suite() {
TEST() {
CURRENT_TEST=$1

checksum=$CCACHE_CHECKSUM

while read name; do
unset $name
done <<EOF
Expand All @@ -249,9 +247,6 @@ EOF
export CCACHE_LOGFILE=$ABS_TESTDIR/ccache.log
export CCACHE_NODIRECT=1

# export current checksum used
export CCACHE_CHECKSUM=$checksum

# Many tests backdate files, which updates their ctimes. In those tests, we
# must ignore ctimes. Might as well do so everywhere.
DEFAULT_SLOPPINESS=include_file_ctime
Expand Down Expand Up @@ -402,6 +397,7 @@ direct
direct_gcc
depend
basedir
checksum
compression
readonly
readonly_direct
Expand Down
8 changes: 7 additions & 1 deletion test/suites/base.bash
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,10 @@ EOF
# -------------------------------------------------------------------------
TEST "--hash-file"

for CCACHE_CHECKSUM in ${CHECKSUMS:-md4}
do
export CCACHE_CHECKSUM

>empty
$CCACHE --hash-file empty > hash.out
printf "a" | $CCACHE --hash-file - >> hash.out
Expand All @@ -1087,11 +1091,13 @@ EOF
fi

if grep "$hash_0" hash.out >/dev/null 2>&1 && \
grep "$hash_1" hash.out >/dev/null 2>&1; then
grep "$hash_1" hash.out >/dev/null 2>&1; then
: OK
else
test_failed "Unexpected output of --hash-file"
fi

done
}

# =============================================================================
Expand Down
24 changes: 24 additions & 0 deletions test/suites/checksum.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
SUITE_checksum_SETUP() {
generate_code 1 test.c
}

SUITE_checksum() {

for CHECKSUM in ${CHECKSUMS:-md4}
do

# -------------------------------------------------------------------------
TEST "Test $CHECKSUM"

CCACHE_CHECKSUM=$CHECKSUM $CCACHE_COMPILE -c test.c
expect_stat 'cache hit (direct)' 0
expect_stat 'cache hit (preprocessed)' 0
expect_stat 'cache miss' 1

CCACHE_CHECKSUM=$CHECKSUM $CCACHE_COMPILE -c test.c
expect_stat 'cache hit (direct)' 0
expect_stat 'cache hit (preprocessed)' 1
expect_stat 'cache miss' 1

done
}
10 changes: 8 additions & 2 deletions test/suites/direct.bash
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,10 @@ EOF
# -------------------------------------------------------------------------
TEST "--dump-manifest"

for CCACHE_CHECKSUM in ${CHECKSUMS:-md4}
do
export CCACHE_CHECKSUM

$CCACHE_COMPILE test.c -c -o test.o

manifest=`find $CCACHE_DIR -name '*.manifest'`
Expand All @@ -919,13 +923,15 @@ EOF
fi

if grep "Hash: $checksum_test1_h" manifest.dump >/dev/null 2>&1 && \
grep "Hash: $checksum_test2_h" manifest.dump >/dev/null 2>&1 && \
grep "Hash: $checksum_test3_h" manifest.dump >/dev/null 2>&1; then
grep "Hash: $checksum_test2_h" manifest.dump >/dev/null 2>&1 && \
grep "Hash: $checksum_test3_h" manifest.dump >/dev/null 2>&1; then
: OK
else
test_failed "Unexpected output of --dump-manifest"
fi

done

# -------------------------------------------------------------------------
TEST "Argument-less -B and -L"

Expand Down
Loading

0 comments on commit 54d1373

Please sign in to comment.