diff options
Diffstat (limited to 'test.sh')
-rwxr-xr-x | test.sh | 3468 |
1 files changed, 3468 insertions, 0 deletions
@@ -0,0 +1,3468 @@ +#!/bin/sh +# +# A simple test suite for ccache. +# +# Copyright (C) 2002-2007 Andrew Tridgell +# Copyright (C) 2009-2017 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 +# 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. +# +# 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 + +green() { + printf "\033[1;32m$*\033[0;0m\n" +} + +red() { + printf "\033[1;31m$*\033[0;0m\n" +} + +bold() { + printf "\033[1;37m$*\033[0;0m\n" +} + +test_failed() { + echo + red FAILED + echo + echo "Test suite: $(bold $CURRENT_SUITE)" + echo "Test case: $(bold $CURRENT_TEST)" + echo "Failure reason: $(red $1)" + echo + echo "ccache -s:" + $CCACHE -s + echo + echo "Test data and log file have been left in $TESTDIR" + exit 1 +} + +generate_code() { + local nlines=$1 + local outfile=$2 + + rm -f $outfile + for i in $(seq $nlines); do + echo "int foo_$i(int x) { return x; }" >>$outfile + done +} + +remove_cache() { + if [ -d $CCACHE_DIR ]; then + chmod -R +w $CCACHE_DIR + rm -rf $CCACHE_DIR + fi +} + +clear_cache() { + $CCACHE -Cz >/dev/null +} + +sed_in_place() { + local expr=$1 + shift + + for file in $*; do + sed "$expr" $file >$file.sed + mv $file.sed $file + done +} + +backdate() { + touch -t 199901010000 "$@" +} + +expect_stat() { + local stat="$1" + local expected_value="$2" + local value="$(echo $($CCACHE -s | fgrep "$stat" | cut -c34-))" + + if [ "$expected_value" != "$value" ]; then + test_failed "Expected \"$stat\" to be $expected_value, actual $value" + fi +} + +expect_equal_files() { + if [ ! -e "$1" ]; then + test_failed "compare_files: $1 missing" + fi + if [ ! -e "$2" ]; then + test_failed "compare_files: $2 missing" + fi + if ! cmp -s "$1" "$2"; then + test_failed "compare_files:: $1 and $2 differ" + fi +} + +expect_equal_object_files() { + if $HOST_OS_LINUX && $COMPILER_TYPE_CLANG; then + if ! which eu-elfcmp >/dev/null 2>&1; then + test_failed "Please install elfutils to get eu-elfcmp" + fi + eu-elfcmp -q "$1" "$2" + else + cmp -s "$1" "$2" + fi + if [ $? -ne 0 ]; then + test_failed "Objects differ: $1 != $2" + fi +} + +expect_file_content() { + local file="$1" + local content="$2" + + if [ ! -f "$file" ]; then + test_failed "$file not found" + fi + if [ "$(cat $file)" != "$content" ]; then + test_failed "Bad content of $file.\nExpected: $content\nActual: $(cat $file)" + fi +} + +expect_file_count() { + local expected=$1 + local pattern=$2 + local dir=$3 + local actual=`find $dir -name "$pattern" | wc -l` + if [ $actual -ne $expected ]; then + test_failed "Found $actual (expected $expected) $pattern files in $dir" + fi +} + +run_suite() { + local name=$1 + + CURRENT_SUITE=$name + UNCACHED_COMPILE=uncached_compile + + cd $ABS_TESTDIR + rm -rf $ABS_TESTDIR/fixture + + if type SUITE_${name}_PROBE >/dev/null 2>&1; then + mkdir $ABS_TESTDIR/probe + cd $ABS_TESTDIR/probe + local skip_reason="$(SUITE_${name}_PROBE)" + cd $ABS_TESTDIR + rm -rf $ABS_TESTDIR/probe + if [ -n "$skip_reason" ]; then + echo "Skipped test suite $name [$skip_reason]" + return + fi + fi + + printf "Running test suite %s" "$(bold $name)" + SUITE_$name + echo +} + +uncached_compile() { + # $COMPILER could be a masquerading system ccache, so make sure it's + # disabled: + CCACHE_DISABLE=1 $COMPILER "$@" +} + +TEST() { + CURRENT_TEST=$1 + + unset CCACHE_BASEDIR + unset CCACHE_CC + unset CCACHE_COMMENTS + unset CCACHE_COMPILERCHECK + unset CCACHE_COMPRESS + unset CCACHE_CPP2 + unset CCACHE_DIR + unset CCACHE_DISABLE + unset CCACHE_EXTENSION + unset CCACHE_EXTRAFILES + unset CCACHE_HARDLINK + unset CCACHE_IGNOREHEADERS + unset CCACHE_LIMIT_MULTIPLE + unset CCACHE_LOGFILE + unset CCACHE_NLEVELS + unset CCACHE_NOCPP2 + unset CCACHE_NOHASHDIR + unset CCACHE_NOSTATS + unset CCACHE_PATH + unset CCACHE_PREFIX + unset CCACHE_PREFIX_CPP + unset CCACHE_READONLY + unset CCACHE_READONLY_DIRECT + unset CCACHE_RECACHE + unset CCACHE_SLOPPINESS + unset CCACHE_TEMPDIR + unset CCACHE_UMASK + unset CCACHE_UNIFY + unset GCC_COLORS + + export CCACHE_CONFIGPATH=$ABS_TESTDIR/ccache.conf + export CCACHE_DETECT_SHEBANG=1 + export CCACHE_DIR=$ABS_TESTDIR/.ccache + export CCACHE_LOGFILE=$ABS_TESTDIR/ccache.log + export CCACHE_NODIRECT=1 + + # 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 + export CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS" + + CCACHE_COMPILE="$CCACHE $COMPILER" + + if $VERBOSE; then + printf "\n %s" $CURRENT_TEST + else + printf . + fi + + cd / + remove_cache + rm -rf $ABS_TESTDIR/run + mkdir $ABS_TESTDIR/run + cd $ABS_TESTDIR/run + if type SUITE_${name}_SETUP >/dev/null 2>&1; then + SUITE_${name}_SETUP + fi +} + +# ============================================================================= + +base_tests() { + # ------------------------------------------------------------------------- + TEST "Base case" + + $UNCACHED_COMPILE -c -o reference_test1.o test1.c + + $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_stat 'files in cache' 1 + expect_equal_object_files reference_test1.o test1.o + + $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + expect_stat 'files in cache' 1 + expect_equal_object_files reference_test1.o test1.o + + # ------------------------------------------------------------------------- + TEST "Debug option" + + $CCACHE_COMPILE -c test1.c -g + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_stat 'files in cache' 1 + + $CCACHE_COMPILE -c test1.c -g + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + $UNCACHED_COMPILE -c -o reference_test1.o test1.c -g + expect_equal_object_files reference_test1.o reference_test1.o + + # ------------------------------------------------------------------------- + TEST "Output option" + + $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -c test1.c -o foo.o + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + $UNCACHED_COMPILE -c -o reference_test1.o test1.c + expect_equal_object_files reference_test1.o foo.o + + # ------------------------------------------------------------------------- + TEST "Called for link" + + $CCACHE_COMPILE test1.c -o test 2>/dev/null + expect_stat 'called for link' 1 + + $CCACHE_COMPILE -c test1.c + $CCACHE_COMPILE test1.o -o test 2>/dev/null + expect_stat 'called for link' 2 + + # ------------------------------------------------------------------------- + TEST "No input file" + + $CCACHE_COMPILE -c foo.c 2>/dev/null + expect_stat 'no input file' 1 + + # ------------------------------------------------------------------------- + TEST "Called for preprocessing" + + $CCACHE_COMPILE -E -c test1.c >/dev/null 2>&1 + expect_stat 'called for preprocessing' 1 + + # ------------------------------------------------------------------------- + TEST "Multiple source files" + + touch test2.c + $CCACHE_COMPILE -c test1.c test2.c + expect_stat 'multiple source files' 1 + + # ------------------------------------------------------------------------- + TEST "Couldn't find the compiler" + + $CCACHE blahblah -c test1.c 2>/dev/null + expect_stat "couldn't find the compiler" 1 + + # ------------------------------------------------------------------------- + TEST "Bad compiler arguments" + + $CCACHE_COMPILE -c test1.c -I 2>/dev/null + expect_stat 'bad compiler arguments' 1 + + # ------------------------------------------------------------------------- + TEST "Unsupported source language" + + ln -f test1.c test1.ccc + $CCACHE_COMPILE -c test1.ccc 2>/dev/null + expect_stat 'unsupported source language' 1 + + # ------------------------------------------------------------------------- + TEST "Unsupported compiler option" + + $CCACHE_COMPILE -M foo -c test1.c >/dev/null 2>&1 + expect_stat 'unsupported compiler option' 1 + + # ------------------------------------------------------------------------- + TEST "Compiler produced stdout" + + $CCACHE echo foo -c test1.c >/dev/null + expect_stat 'compiler produced stdout' 1 + + # ------------------------------------------------------------------------- + TEST "Output to a non-regular file" + + mkdir testd + $CCACHE_COMPILE -o testd -c test1.c >/dev/null 2>&1 + rmdir testd >/dev/null 2>&1 + expect_stat 'output to a non-regular file' 1 + + # ------------------------------------------------------------------------- + TEST "No input file" + + $CCACHE_COMPILE -c -O2 2>/dev/null + expect_stat 'no input file' 1 + + # ------------------------------------------------------------------------- + TEST "CCACHE_DISABLE" + + CCACHE_DISABLE=1 $CCACHE_COMPILE -c test1.c 2>/dev/null + if [ -d $CCACHE_DIR ]; then + test_failed "$CCACHE_DIR created despite CCACHE_DISABLE being set" + fi + + # ------------------------------------------------------------------------- + TEST "CCACHE_COMMENTS" + + $UNCACHED_COMPILE -c -o reference_test1.o test1.c + + mv test1.c test1-saved.c + echo '// initial comment' >test1.c + cat test1-saved.c >>test1.c + CCACHE_COMMENTS=1 $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + echo '// different comment' >test1.c + cat test1-saved.c >>test1.c + CCACHE_COMMENTS=1 $CCACHE_COMPILE -c test1.c + mv test1-saved.c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 + + $UNCACHED_COMPILE -c -o reference_test1.o test1.c + expect_equal_object_files reference_test1.o test1.o + + # ------------------------------------------------------------------------- + TEST "CCACHE_NOSTATS" + + CCACHE_NOSTATS=1 $CCACHE_COMPILE -c test1.c -O -O + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 0 + + # ------------------------------------------------------------------------- + TEST "CCACHE_RECACHE" + + $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_RECACHE=1 $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 + + $UNCACHED_COMPILE -c -o reference_test1.o test1.c + expect_equal_object_files reference_test1.o test1.o + + # CCACHE_RECACHE replaces the object file, so the statistics counter will + # be off-by-one until next cleanup. + expect_stat 'files in cache' 2 + $CCACHE -c >/dev/null + expect_stat 'files in cache' 1 + + # ------------------------------------------------------------------------- + TEST "Directory is hashed if using -g" + + mkdir dir1 dir2 + cp test1.c dir1 + cp test1.c dir2 + + cd dir1 + $CCACHE_COMPILE -c test1.c -g + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + $CCACHE_COMPILE -c test1.c -g + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + cd ../dir2 + $CCACHE_COMPILE -c test1.c -g + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 2 + $CCACHE_COMPILE -c test1.c -g + expect_stat 'cache hit (preprocessed)' 2 + expect_stat 'cache miss' 2 + + # ------------------------------------------------------------------------- + TEST "Directory is not hashed if not using -g" + + mkdir dir1 dir2 + cp test1.c dir1 + cp test1.c dir2 + + cd dir1 + $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + cd ../dir2 + $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 2 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "CCACHE_NOHASHDIR" + + mkdir dir1 dir2 + cp test1.c dir1 + cp test1.c dir2 + + cd dir1 + CCACHE_NOHASHDIR=1 $CCACHE_COMPILE -c test1.c -g + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + CCACHE_NOHASHDIR=1 $CCACHE_COMPILE -c test1.c -g + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + cd ../dir2 + CCACHE_NOHASHDIR=1 $CCACHE_COMPILE -c test1.c -g + expect_stat 'cache hit (preprocessed)' 2 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "CCACHE_UNIFY" + + echo '// a silly comment' >>test1.c + CCACHE_UNIFY=1 $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + echo '// another silly comment' >>test1.c + CCACHE_UNIFY=1 $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + $UNCACHED_COMPILE -c -o reference_test1.o test1.c + expect_equal_object_files reference_test1.o test1.o + + # ------------------------------------------------------------------------- + TEST "CCACHE_NLEVELS" + + CCACHE_NLEVELS=4 $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_stat 'files in cache' 1 + + CCACHE_NLEVELS=4 $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + expect_stat 'files in cache' 1 + + # Directories in $CCACHE_DIR: + # - . + # - tmp + # - a + # - a/b + # - a/b/c + # - a/b/c/d + actual_dirs=$(find $CCACHE_DIR -type d | wc -l) + expected_dirs=6 + if [ $actual_dirs -ne $expected_dirs ]; then + test_failed "Expected $expected_dirs directories, found $actual_dirs" + fi + + # ------------------------------------------------------------------------- + TEST "CCACHE_EXTRAFILES" + + echo a >a + echo b >b + + $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + CCACHE_EXTRAFILES="a${PATH_DELIM}b" $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 2 + + CCACHE_EXTRAFILES="a${PATH_DELIM}b" $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 2 + expect_stat 'cache miss' 2 + + echo b2 >b + + CCACHE_EXTRAFILES="a${PATH_DELIM}b" $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 2 + expect_stat 'cache miss' 3 + + CCACHE_EXTRAFILES="a${PATH_DELIM}b" $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 3 + expect_stat 'cache miss' 3 + + CCACHE_EXTRAFILES="doesntexist" $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 3 + expect_stat 'cache miss' 3 + expect_stat 'error hashing extra file' 1 + + # ------------------------------------------------------------------------- + TEST "CCACHE_PREFIX" + + cat <<'EOF' >prefix-a +#!/bin/sh +echo a >>prefix.result +exec "$@" +EOF + cat <<'EOF' >prefix-b +#!/bin/sh +echo b >>prefix.result +exec "$@" +EOF + chmod +x prefix-a prefix-b + cat <<'EOF' >file.c +int foo; +EOF + PATH=.:$PATH CCACHE_PREFIX="prefix-a prefix-b" $CCACHE_COMPILE -c file.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_file_content prefix.result "a +b" + + PATH=.:$PATH CCACHE_PREFIX="prefix-a prefix-b" $CCACHE_COMPILE -c file.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + expect_file_content prefix.result "a +b" + + rm -f prefix.result + PATH=.:$PATH CCACHE_PREFIX_CPP="prefix-a prefix-b" $CCACHE_COMPILE -c file.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 2 + expect_stat 'cache miss' 1 + expect_file_content prefix.result "a +b" + + # ------------------------------------------------------------------------- + TEST "Files in cache" + + for i in $(seq 32); do + generate_code $i test$i.c + $CCACHE_COMPILE -c test$i.c + done + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 32 + expect_stat 'files in cache' 32 + + # ------------------------------------------------------------------------- + TEST "Called for preprocessing" + + $CCACHE_COMPILE -c test1.c -E >test1.i + expect_stat 'called for preprocessing' 1 + + # ------------------------------------------------------------------------- + TEST "Direct .i compile" + + $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $UNCACHED_COMPILE -c test1.c -E >test1.i + $CCACHE_COMPILE -c test1.i + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "-x c" + + ln -f test1.c test1.ccc + + $CCACHE_COMPILE -x c -c test1.ccc + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -x c -c test1.ccc + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "-xc" + + ln -f test1.c test1.ccc + + $CCACHE_COMPILE -xc -c test1.ccc + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -xc -c test1.ccc + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "-x none" + + $CCACHE_COMPILE -x assembler -x none -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -x assembler -x none -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "-x unknown" + + $CCACHE_COMPILE -x unknown -c test1.c 2>/dev/null + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 0 + expect_stat 'unsupported source language' 1 + + # ------------------------------------------------------------------------- + TEST "-D not hashed" + + $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -DNOT_AFFECTING=1 -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "-S" + + $CCACHE_COMPILE -S test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -S test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -c test1.s + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 2 + + $CCACHE_COMPILE -c test1.s + expect_stat 'cache hit (preprocessed)' 2 + expect_stat 'cache miss' 2 + + # ------------------------------------------------------------------------- + TEST "CCACHE_PATH" + + override_path=`pwd`/override_path + mkdir $override_path + cat >$override_path/cc <<EOF +#!/bin/sh +touch override_path_compiler_executed +EOF + chmod +x $override_path/cc + CCACHE_PATH=$override_path $CCACHE cc -c test1.c + if [ ! -f override_path_compiler_executed ]; then + test_failed "CCACHE_PATH had no effect" + fi + + # ------------------------------------------------------------------------- + TEST "CCACHE_COMPILERCHECK=mtime" + + cat >compiler.sh <<EOF +#!/bin/sh +export CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink... +exec $COMPILER "\$@" +# A comment +EOF + chmod +x compiler.sh + backdate compiler.sh + CCACHE_COMPILERCHECK=mtime $CCACHE ./compiler.sh -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + sed_in_place 's/comment/yoghurt/' compiler.sh # Don't change the size + chmod +x compiler.sh + backdate compiler.sh # Don't change the timestamp + + CCACHE_COMPILERCHECK=mtime $CCACHE ./compiler.sh -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + touch compiler.sh + CCACHE_COMPILERCHECK=mtime $CCACHE ./compiler.sh -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 2 + + # ------------------------------------------------------------------------- + TEST "CCACHE_COMPILERCHECK=content" + + cat >compiler.sh <<EOF +#!/bin/sh +export CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink... +exec $COMPILER "\$@" +EOF + chmod +x compiler.sh + + CCACHE_COMPILERCHECK=content $CCACHE ./compiler.sh -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_COMPILERCHECK=content $CCACHE ./compiler.sh -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + echo "# Compiler upgrade" >>compiler.sh + + CCACHE_COMPILERCHECK=content $CCACHE ./compiler.sh -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 2 + + # ------------------------------------------------------------------------- + TEST "CCACHE_COMPILERCHECK=none" + + cat >compiler.sh <<EOF +#!/bin/sh +export CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink... +exec $COMPILER "\$@" +EOF + chmod +x compiler.sh + + CCACHE_COMPILERCHECK=none $CCACHE ./compiler.sh -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_COMPILERCHECK=none $CCACHE ./compiler.sh -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + echo "# Compiler upgrade" >>compiler.sh + CCACHE_COMPILERCHECK=none $CCACHE ./compiler.sh -c test1.c + expect_stat 'cache hit (preprocessed)' 2 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "CCACHE_COMPILERCHECK=string" + + cat >compiler.sh <<EOF +#!/bin/sh +export CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink... +exec $COMPILER "\$@" +EOF + chmod +x compiler.sh + + CCACHE_COMPILERCHECK=string:foo $CCACHE ./compiler.sh -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_COMPILERCHECK=string:foo $CCACHE ./compiler.sh -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + CCACHE_COMPILERCHECK=string:bar $CCACHE ./compiler.sh -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 2 + + CCACHE_COMPILERCHECK=string:bar $CCACHE ./compiler.sh -c test1.c + expect_stat 'cache hit (preprocessed)' 2 + expect_stat 'cache miss' 2 + + # ------------------------------------------------------------------------- + TEST "CCACHE_COMPILERCHECK=command" + + cat >compiler.sh <<EOF +#!/bin/sh +export CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink... +exec $COMPILER "\$@" +EOF + chmod +x compiler.sh + + CCACHE_COMPILERCHECK='echo %compiler%' $CCACHE ./compiler.sh -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + echo "# Compiler upgrade" >>compiler.sh + CCACHE_COMPILERCHECK="echo ./compiler.sh" $CCACHE ./compiler.sh -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + cat <<EOF >foobar.sh +#!/bin/sh +echo foo +echo bar +EOF + chmod +x foobar.sh + CCACHE_COMPILERCHECK='./foobar.sh' $CCACHE ./compiler.sh -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 2 + + CCACHE_COMPILERCHECK='echo foo; echo bar' $CCACHE ./compiler.sh -c test1.c + expect_stat 'cache hit (preprocessed)' 2 + expect_stat 'cache miss' 2 + + # ------------------------------------------------------------------------- + TEST "CCACHE_COMPILERCHECK=unknown_command" + + cat >compiler.sh <<EOF +#!/bin/sh +export CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink... +exec $COMPILER "\$@" +EOF + chmod +x compiler.sh + + CCACHE_COMPILERCHECK="unknown_command" $CCACHE ./compiler.sh -c test1.c 2>/dev/null + if [ "$?" -eq 0 ]; then + test_failed "Expected failure running unknown_command to verify compiler but was success" + fi + expect_stat 'compiler check failed' 1 + + # ------------------------------------------------------------------------- + TEST "CCACHE_RECACHE should remove previous .stderr" + + $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + num=`find $CCACHE_DIR -name '*.stderr' | wc -l` + if [ $num -ne 0 ]; then + test_failed "$num stderr files found, expected 0 (#1)" + fi + + obj_file=`find $CCACHE_DIR -name '*.o'` + stderr_file=`echo $obj_file | sed 's/..$/.stderr/'` + echo "Warning: foo" >$stderr_file + CCACHE_RECACHE=1 $CCACHE_COMPILE -c test1.c + num=`find $CCACHE_DIR -name '*.stderr' | wc -l` + if [ $num -ne 0 ]; then + test_failed "$num stderr files found, expected 0 (#2)" + fi + + # ------------------------------------------------------------------------- + TEST "No object file" + + cat <<'EOF' >test_no_obj.c +int test_no_obj; +EOF + cat <<'EOF' >prefix-remove.sh +#!/bin/sh +"$@" +[ x$2 = x-fcolor-diagnostics ] && shift +[ x$2 = x-fdiagnostics-color ] && shift +[ x$2 = x-std=gnu99 ] && shift +[ x$3 = x-o ] && rm $4 +EOF + chmod +x prefix-remove.sh + CCACHE_PREFIX=`pwd`/prefix-remove.sh $CCACHE_COMPILE -c test_no_obj.c + expect_stat 'compiler produced no output' 1 + + # ------------------------------------------------------------------------- + TEST "Empty object file" + + cat <<'EOF' >test_empty_obj.c +int test_empty_obj; +EOF + cat <<'EOF' >prefix-empty.sh +#!/bin/sh +"$@" +[ x$2 = x-fcolor-diagnostics ] && shift +[ x$2 = x-fdiagnostics-color ] && shift +[ x$2 = x-std=gnu99 ] && shift +[ x$3 = x-o ] && cp /dev/null $4 +EOF + chmod +x prefix-empty.sh + CCACHE_PREFIX=`pwd`/prefix-empty.sh $CCACHE_COMPILE -c test_empty_obj.c + expect_stat 'compiler produced empty output' 1 + + # ------------------------------------------------------------------------- + TEST "Caching stderr" + + cat <<EOF >stderr.c +int stderr(void) +{ + // Trigger warning by having no return statement. +} +EOF + $CCACHE_COMPILE -Wall -W -c stderr.c 2>/dev/null + num=`find $CCACHE_DIR -name '*.stderr' | wc -l` + if [ $num -ne 1 ]; then + test_failed "$num stderr files found, expected 1" + fi + expect_stat 'files in cache' 2 + + # ------------------------------------------------------------------------- + TEST "--zero-stats" + + $CCACHE_COMPILE -c test1.c + $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + expect_stat 'files in cache' 1 + + $CCACHE -z >/dev/null + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 0 + expect_stat 'files in cache' 1 + + # ------------------------------------------------------------------------- + TEST "--clear" + + $CCACHE_COMPILE -c test1.c + $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + expect_stat 'files in cache' 1 + + $CCACHE -C >/dev/null + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + expect_stat 'files in cache' 0 + + # ------------------------------------------------------------------------- + TEST "-P" + + # Check that -P disables ccache. (-P removes preprocessor information in + # such a way that the object file from compiling the preprocessed file will + # not be equal to the object file produced when compiling without ccache.) + + $CCACHE_COMPILE -c -P test1.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 0 + expect_stat 'unsupported compiler option' 1 + + # ------------------------------------------------------------------------- + TEST "-Wp,-P" + + # Check that -Wp,-P disables ccache. (-P removes preprocessor information + # in such a way that the object file from compiling the preprocessed file + # will not be equal to the object file produced when compiling without + # ccache.) + + $CCACHE_COMPILE -c -Wp,-P test1.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 0 + expect_stat 'unsupported compiler option' 1 + + $CCACHE_COMPILE -c -Wp,-P,-DFOO test1.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 0 + expect_stat 'unsupported compiler option' 2 + + $CCACHE_COMPILE -c -Wp,-DFOO,-P test1.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 0 + expect_stat 'unsupported compiler option' 3 + + # ------------------------------------------------------------------------- + TEST "-Wp,-D" + + $CCACHE_COMPILE -c -Wp,-DFOO test1.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -c -DFOO test1.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "Buggy GCC 6 cpp" + + cat >buggy-cpp <<EOF +#!/bin/sh +export CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink... +if echo "\$*" | grep -- -D >/dev/null; then + $COMPILER "\$@" +else + # Mistreat the preprocessor output in the same way as GCC 6 does. + $COMPILER "\$@" | + sed -e '/^# 1 "<command-line>"\$/ a\\ +# 31 "<command-line>"' \\ + -e 's/^# 1 "<command-line>" 2\$/# 32 "<command-line>" 2/' +fi +exit 0 +EOF + cat <<'EOF' >file.c +int foo; +EOF + chmod +x buggy-cpp + + $CCACHE ./buggy-cpp -c file.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $CCACHE ./buggy-cpp -DNOT_AFFECTING=1 -c file.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "Symlink to source directory" + + mkdir dir + cd dir + mkdir -p d1/d2 + echo '#define A "OK"' >d1/h.h + cat <<EOF >d1/d2/c.c +#include <stdio.h> +#include "../h.h" +int main() { printf("%s\n", A); } +EOF + echo '#define A "BUG"' >h.h + ln -s d1/d2 d3 + + CCACHE_BASEDIR=/ $CCACHE_COMPILE -c $PWD/d3/c.c + $UNCACHED_COMPILE c.o -o c + if [ "$(./c)" != OK ]; then + test_failed "Incorrect header file used" + fi + + # ------------------------------------------------------------------------- + TEST "Symlink to source file" + + mkdir dir + cd dir + mkdir d + echo '#define A "BUG"' >d/h.h + cat <<EOF >d/c.c +#include <stdio.h> +#include "h.h" +int main() { printf("%s\n", A); } +EOF + echo '#define A "OK"' >h.h + ln -s d/c.c c.c + + CCACHE_BASEDIR=/ $CCACHE_COMPILE -c $PWD/c.c + $UNCACHED_COMPILE c.o -o c + if [ "$(./c)" != OK ]; then + test_failed "Incorrect header file used" + fi + + # ------------------------------------------------------------------------- + TEST ".incbin" + + cat <<EOF >incbin.c +char x[] = ".incbin"; +EOF + + $CCACHE_COMPILE -c incbin.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 0 + expect_stat 'unsupported code directive' 1 +} + +# ============================================================================= + +SUITE_base_SETUP() { + generate_code 1 test1.c +} + +SUITE_base() { + base_tests +} + +# ============================================================================= + +SUITE_nocpp2_SETUP() { + export CCACHE_NOCPP2=1 + generate_code 1 test1.c +} + +SUITE_nocpp2() { + base_tests +} + +# ============================================================================= + +SUITE_multi_arch_PROBE() { + if ! $HOST_OS_APPLE; then + echo "multiple -arch options not supported on $(uname -s)" + return + fi +} + +SUITE_multi_arch_SETUP() { + generate_code 1 test1.c + unset CCACHE_NODIRECT +} + +SUITE_multi_arch() { + # ------------------------------------------------------------------------- + TEST "cache hit, direct mode" + + # Different arches shouldn't affect each other + $CCACHE_COMPILE -arch i386 -c test1.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -arch x86_64 -c test1.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache miss' 2 + + $CCACHE_COMPILE -arch i386 -c test1.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache miss' 2 + + # Multiple arches should be cached too + $CCACHE_COMPILE -arch i386 -arch x86_64 -c test1.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache miss' 3 + + $CCACHE_COMPILE -arch i386 -arch x86_64 -c test1.c + expect_stat 'cache hit (direct)' 2 + expect_stat 'cache miss' 3 + + # ------------------------------------------------------------------------- + TEST "cache hit, preprocessor mode" + + export CCACHE_NODIRECT=1 + + $CCACHE_COMPILE -arch i386 -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -arch x86_64 -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 + + $CCACHE_COMPILE -arch i386 -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 2 + + # Multiple arches should be cached too + $CCACHE_COMPILE -arch i386 -arch x86_64 -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 3 + + $CCACHE_COMPILE -arch i386 -arch x86_64 -c test1.c + expect_stat 'cache hit (preprocessed)' 2 + expect_stat 'cache miss' 3 +} + +# ============================================================================= + +SUITE_serialize_diagnostics_PROBE() { + touch test.c + if ! $UNCACHED_COMPILE -c --serialize-diagnostics \ + test1.dia test.c 2>/dev/null; then + echo "--serialize-diagnostics not supported by compiler" + fi +} + +SUITE_serialize_diagnostics_SETUP() { + generate_code 1 test1.c +} + +SUITE_serialize_diagnostics() { + # ------------------------------------------------------------------------- + TEST "Compile OK" + + $UNCACHED_COMPILE -c --serialize-diagnostics expected.dia test1.c + + $CCACHE_COMPILE -c --serialize-diagnostics test.dia test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_stat 'files in cache' 2 + expect_equal_files expected.dia test.dia + + rm test.dia + + $CCACHE_COMPILE -c --serialize-diagnostics test.dia test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + expect_stat 'files in cache' 2 + expect_equal_files expected.dia test.dia + + # ------------------------------------------------------------------------- + TEST "Compile failed" + + echo "bad source" >error.c + if $UNCACHED_COMPILE -c --serialize-diagnostics expected.dia error.c 2>expected.stderr; then + test_failed "Expected an error compiling error.c" + fi + + $CCACHE_COMPILE -c --serialize-diagnostics test.dia error.c 2>test.stderr + expect_stat 'compile failed' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 0 + expect_stat 'files in cache' 0 + expect_equal_files expected.dia test.dia + expect_equal_files expected.stderr test.stderr + + # ------------------------------------------------------------------------- + TEST "--serialize-diagnostics + CCACHE_BASEDIR" + + mkdir -p dir1/src dir1/include + cat <<EOF >dir1/src/test.c +#include <stdarg.h> +#include <test.h> +EOF + cat <<EOF >dir1/include/test.h +int test; +EOF + cp -r dir1 dir2 + backdate dir1/include/test.h dir2/include/test.h + + cat <<EOF >stderr.h +int stderr(void) +{ + // Trigger warning by having no return statement. +} +EOF + + unset CCACHE_NODIRECT + + cd dir1 + CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -w -MD -MF `pwd`/test.d -I`pwd`/include --serialize-diagnostics `pwd`/test.dia -c src/test.c -o `pwd`/test.o + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_stat 'files in cache' 4 + + cd ../dir2 + CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -w -MD -MF `pwd`/test.d -I`pwd`/include --serialize-diagnostics `pwd`/test.dia -c src/test.c -o `pwd`/test.o + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_stat 'files in cache' 4 +} + +# ============================================================================= + +SUITE_debug_prefix_map_PROBE() { + if ! $COMPILER_TYPE_GCC || $COMPILER_USES_MINGW; then + echo "-fdebug-prefix-map not supported by compiler" + fi +} + +SUITE_debug_prefix_map_SETUP() { + unset CCACHE_NODIRECT + + mkdir -p dir1/src dir1/include + cat <<EOF >dir1/src/test.c +#include <stdarg.h> +#include <test.h> +EOF + cat <<EOF >dir1/include/test.h +int test; +EOF + cp -r dir1 dir2 + backdate dir1/include/test.h dir2/include/test.h +} + +SUITE_debug_prefix_map() { + # ------------------------------------------------------------------------- + TEST "Mapping of debug info CWD" + + cd dir1 + CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -I`pwd`/include -g -fdebug-prefix-map=`pwd`=dir -c `pwd`/src/test.c -o `pwd`/test.o + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_stat 'files in cache' 2 + if grep -E "[^=]`pwd`[^=]" test.o >/dev/null 2>&1; then + test_failed "Source dir (`pwd`) found in test.o" + fi + + cd ../dir2 + CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -I`pwd`/include -g -fdebug-prefix-map=`pwd`=dir -c `pwd`/src/test.c -o `pwd`/test.o + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_stat 'files in cache' 2 + if grep -E "[^=]`pwd`[^=]" test.o >/dev/null 2>&1; then + test_failed "Source dir (`pwd`) found in test.o" + fi +} + +# ============================================================================= + +SUITE_masquerading_PROBE() { + local compiler_binary=$(echo $COMPILER | cut -d' ' -f1) + if [ "$(dirname $compiler_binary)" != . ]; then + echo "compiler ($compiler_binary) not taken from PATH" + fi +} + +SUITE_masquerading_SETUP() { + local compiler_binary=$(echo $COMPILER | cut -d' ' -f1) + local compiler_args=$(echo $COMPILER | cut -s -d' ' -f2-) + + ln -s "$CCACHE" $compiler_binary + CCACHE_COMPILE="./$compiler_binary $compiler_args" + generate_code 1 test1.c +} + +SUITE_masquerading() { + # ------------------------------------------------------------------------- + TEST "Masquerading via symlink" + + $UNCACHED_COMPILE -c -o reference_test1.o test1.c + + $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_stat 'files in cache' 1 + expect_equal_object_files reference_test1.o test1.o + + $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + expect_stat 'files in cache' 1 + expect_equal_object_files reference_test1.o test1.o +} + +# ============================================================================= + +SUITE_hardlink_PROBE() { + touch file1 + if ! ln file1 file2 >/dev/null 2>&1; then + echo "file system doesn't support hardlinks" + fi +} + +SUITE_hardlink() { + # ------------------------------------------------------------------------- + TEST "CCACHE_HARDLINK" + + generate_code 1 test1.c + + $UNCACHED_COMPILE -c -o reference_test1.o test1.c + + $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_stat 'files in cache' 1 + expect_equal_object_files reference_test1.o test1.o + + CCACHE_HARDLINK=1 $CCACHE_COMPILE -c test1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + expect_stat 'files in cache' 1 + expect_equal_object_files reference_test1.o test1.o + + local obj_in_cache=$(find $CCACHE_DIR -name '*.o') + if [ ! $obj_in_cache -ef test1.o ]; then + test_failed "Object file not hard-linked to cached object file" + fi +} + +# ============================================================================= + +SUITE_direct_SETUP() { + unset CCACHE_NODIRECT + + cat <<EOF >test.c +// test.c +#include "test1.h" +#include "test2.h" +EOF + cat <<EOF >test1.h +#include "test3.h" +int test1; +EOF + cat <<EOF >test2.h +int test2; +EOF + cat <<EOF >test3.h +int test3; +EOF + backdate test1.h test2.h test3.h + + $UNCACHED_COMPILE -c -Wp,-MD,expected.d test.c + $UNCACHED_COMPILE -c -Wp,-MMD,expected_mmd.d test.c + rm test.o +} + +SUITE_direct() { + # ------------------------------------------------------------------------- + TEST "Base case" + + $UNCACHED_COMPILE -c -o reference_test.o test.c + + $CCACHE_COMPILE -c test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_stat 'files in cache' 2 # .o + .manifest + expect_equal_object_files reference_test.o test.o + + $CCACHE_COMPILE -c test.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_stat 'files in cache' 2 + expect_equal_object_files reference_test.o test.o + + # ------------------------------------------------------------------------- + TEST "Corrupt manifest file" + + $CCACHE_COMPILE -c test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + manifest_file=`find $CCACHE_DIR -name '*.manifest'` + rm $manifest_file + touch $manifest_file + + $CCACHE_COMPILE -c test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -c test.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "CCACHE_NODIRECT" + + CCACHE_NODIRECT=1 $CCACHE_COMPILE -c test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_NODIRECT=1 $CCACHE_COMPILE -c test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "Modified include file" + + $CCACHE_COMPILE -c test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + echo "int test3_2;" >>test3.h + backdate test3.h + $CCACHE_COMPILE -c test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 + + $CCACHE_COMPILE -c test.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 + + # ------------------------------------------------------------------------- + TEST "Removed but previously compiled header file" + + $CCACHE_COMPILE -c test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + rm test3.h + cat <<EOF >test1.h +// No more include of test3.h +int test1; +EOF + backdate test1.h + + $CCACHE_COMPILE -c test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 + + $CCACHE_COMPILE -c test.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 + + # ------------------------------------------------------------------------- + TEST "Calculation of dependency file names" + + mkdir test.dir + for ext in .obj "" . .foo.bar; do + dep_file=test.dir/`echo test$ext | sed 's/\.[^.]*\$//'`.d + $CCACHE_COMPILE -MD -c test.c -o test.dir/test$ext + rm -f $dep_file + $CCACHE_COMPILE -MD -c test.c -o test.dir/test$ext + if [ ! -f $dep_file ]; then + test_failed "$dep_file missing" + fi + done + expect_stat 'files in cache' 12 + + # ------------------------------------------------------------------------- + TEST "-MMD for different source files" + + mkdir a b + touch a/source.c b/source.c + backdate a/source.h b/source.h + $CCACHE_COMPILE -MMD -c a/source.c + expect_file_content source.d "source.o: a/source.c" + + $CCACHE_COMPILE -MMD -c b/source.c + expect_file_content source.d "source.o: b/source.c" + + $CCACHE_COMPILE -MMD -c a/source.c + expect_file_content source.d "source.o: a/source.c" + + # ------------------------------------------------------------------------- + TEST "-MMD for different include file paths" + + mkdir a b + touch a/source.h b/source.h + backdate a/source.h b/source.h + echo '#include <source.h>' >source.c + $CCACHE_COMPILE -MMD -Ia -c source.c + expect_file_content source.d "source.o: source.c a/source.h" + + $CCACHE_COMPILE -MMD -Ib -c source.c + expect_file_content source.d "source.o: source.c b/source.h" + + $CCACHE_COMPILE -MMD -Ia -c source.c + expect_file_content source.d "source.o: source.c a/source.h" + + # ------------------------------------------------------------------------- + TEST "-Wp,-MD" + + $CCACHE_COMPILE -c -Wp,-MD,other.d test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_equal_files other.d expected.d + + $UNCACHED_COMPILE -c -Wp,-MD,other.d test.c -o reference_test.o + expect_equal_object_files reference_test.o test.o + + rm -f other.d + $CCACHE_COMPILE -c -Wp,-MD,other.d test.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_equal_files other.d expected.d + expect_equal_object_files reference_test.o test.o + + $CCACHE_COMPILE -c -Wp,-MD,different_name.d test.c + expect_stat 'cache hit (direct)' 2 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_equal_files different_name.d expected.d + expect_equal_object_files reference_test.o test.o + + # ------------------------------------------------------------------------- + TEST "-Wp,-MMD" + + $CCACHE_COMPILE -c -Wp,-MMD,other.d test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_equal_files other.d expected_mmd.d + + $UNCACHED_COMPILE -c -Wp,-MMD,other.d test.c -o reference_test.o + expect_equal_object_files reference_test.o test.o + + rm -f other.d + $CCACHE_COMPILE -c -Wp,-MMD,other.d test.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_equal_files other.d expected_mmd.d + expect_equal_object_files reference_test.o test.o + + $CCACHE_COMPILE -c -Wp,-MMD,different_name.d test.c + expect_stat 'cache hit (direct)' 2 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_equal_files different_name.d expected_mmd.d + expect_equal_object_files reference_test.o test.o + + # ------------------------------------------------------------------------- + TEST "-Wp,-D" + + $CCACHE_COMPILE -c -Wp,-DFOO test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -c -DFOO test.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "-Wp, with multiple arguments" + + # ccache could try to parse and make sense of -Wp, with multiple arguments, + # but it currently doesn't, so we have to disable direct mode. + + touch source.c + + $CCACHE_COMPILE -c -Wp,-MMD,source.d,-MT,source.o source.c 2>/dev/null + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_file_content source.d "source.o: source.c" + + $CCACHE_COMPILE -c -Wp,-MMD,source.d,-MT,source.o source.c 2>/dev/null + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + expect_file_content source.d "source.o: source.c" + + # ------------------------------------------------------------------------- + TEST "-MMD for different source files" + + mkdir a b + touch a/source.c b/source.c + $CCACHE_COMPILE -MMD -c a/source.c + expect_file_content source.d "source.o: a/source.c" + + $CCACHE_COMPILE -MMD -c b/source.c + expect_file_content source.d "source.o: b/source.c" + + $CCACHE_COMPILE -MMD -c a/source.c + expect_file_content source.d "source.o: a/source.c" + + # ------------------------------------------------------------------------- + TEST "Multiple object entries in manifest" + + for i in 0 1 2 3 4; do + echo "int test1_$i;" >>test1.h + backdate test1.h + $CCACHE_COMPILE -c test.c + $CCACHE_COMPILE -c test.c + done + expect_stat 'cache hit (direct)' 5 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 5 + + # ------------------------------------------------------------------------- + TEST "-MD" + + $CCACHE_COMPILE -c -MD test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_equal_files test.d expected.d + + $UNCACHED_COMPILE -c -MD test.c -o reference_test.o + expect_equal_object_files reference_test.o test.o + + rm -f test.d + $CCACHE_COMPILE -c -MD test.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_equal_files test.d expected.d + expect_equal_object_files reference_test.o test.o + + # ------------------------------------------------------------------------- + TEST "-ftest-coverage" + + cat <<EOF >code.c +int test() { return 0; } +EOF + + $CCACHE_COMPILE -c -fprofile-arcs -ftest-coverage code.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + test -r code.gcno || test_failed "code.gcno missing" + + rm code.gcno + + $CCACHE_COMPILE -c -fprofile-arcs -ftest-coverage code.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + test -r code.gcno || test_failed "code.gcno missing" + + # ------------------------------------------------------------------------- + TEST "Direct mode on cache created by ccache without direct mode support" + + CCACHE_NODIRECT=1 $CCACHE_COMPILE -c -MD test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_equal_files test.d expected.d + $UNCACHED_COMPILE -c -MD test.c -o reference_test.o + expect_equal_object_files reference_test.o test.o + + rm -f test.d + + CCACHE_NODIRECT=1 $CCACHE_COMPILE -c -MD test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + expect_equal_files test.d expected.d + expect_equal_object_files reference_test.o test.o + + rm -f test.d + + $CCACHE_COMPILE -c -MD test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 2 + expect_stat 'cache miss' 1 + expect_equal_files test.d expected.d + expect_equal_object_files reference_test.o test.o + + rm -f test.d + + $CCACHE_COMPILE -c -MD test.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 2 + expect_stat 'cache miss' 1 + expect_equal_files test.d expected.d + expect_equal_object_files reference_test.o test.o + + # ------------------------------------------------------------------------- + TEST "-MF" + + $CCACHE_COMPILE -c -MD -MF other.d test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_equal_files other.d expected.d + $UNCACHED_COMPILE -c -MD -MF other.d test.c -o reference_test.o + expect_equal_object_files reference_test.o test.o + + rm -f other.d + + $CCACHE_COMPILE -c -MD -MF other.d test.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_equal_files other.d expected.d + expect_equal_object_files reference_test.o test.o + + $CCACHE_COMPILE -c -MD -MF different_name.d test.c + expect_stat 'cache hit (direct)' 2 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_equal_files different_name.d expected.d + expect_equal_object_files reference_test.o test.o + + rm -f different_name.d + + $CCACHE_COMPILE -c -MD -MFthird_name.d test.c + expect_stat 'cache hit (direct)' 3 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_equal_files third_name.d expected.d + expect_equal_object_files reference_test.o test.o + + rm -f third_name.d + + # ------------------------------------------------------------------------- + TEST "Missing .d file" + + $CCACHE_COMPILE -c -MD test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -c -MD test.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + expect_equal_files test.d expected.d + + find $CCACHE_DIR -name '*.d' -delete + + $CCACHE_COMPILE -c -MD test.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + expect_equal_files test.d expected.d + + # ------------------------------------------------------------------------- + TEST "stderr from both preprocessor and compiler" + + cat <<EOF >cpp-warning.c +#if FOO +// Trigger preprocessor warning about extra token after #endif. +#endif FOO +int stderr(void) +{ + // Trigger compiler warning by having no return statement. +} +EOF + $CCACHE_COMPILE -Wall -W -c cpp-warning.c 2>stderr-orig.txt + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_NODIRECT=1 $CCACHE_COMPILE -Wall -W -c cpp-warning.c 2>stderr-cpp.txt + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + expect_file_content stderr-cpp.txt "`cat stderr-orig.txt`" + + $CCACHE_COMPILE -Wall -W -c cpp-warning.c 2>stderr-mf.txt + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + expect_file_content stderr-mf.txt "`cat stderr-orig.txt`" + + # ------------------------------------------------------------------------- + TEST "Empty source file" + + touch empty.c + + $CCACHE_COMPILE -c empty.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -c empty.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "Empty include file" + + touch empty.h + cat <<EOF >include_empty.c +#include "empty.h" +EOF + backdate empty.h + $CCACHE_COMPILE -c include_empty.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + $CCACHE_COMPILE -c include_empty.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "__FILE__ in source file disables direct mode" + + cat <<EOF >file.c +#define file __FILE__ +int test; +EOF + + $CCACHE_COMPILE -c file.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -c file.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -c `pwd`/file.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 + + # ------------------------------------------------------------------------- + TEST "__FILE__ in include file disables direct mode" + + cat <<EOF >file.h +#define file __FILE__ +int test; +EOF + backdate file.h + cat <<EOF >file_h.c +#include "file.h" +EOF + + $CCACHE_COMPILE -c file_h.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -c file_h.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + mv file_h.c file2_h.c + + $CCACHE_COMPILE -c `pwd`/file2_h.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 + + # ------------------------------------------------------------------------- + TEST "__FILE__ in source file ignored if sloppy" + + cat <<EOF >file.c +#define file __FILE__ +int test; +EOF + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c file.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c file.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c `pwd`/file.c + expect_stat 'cache hit (direct)' 2 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "__FILE__ in include file ignored if sloppy" + + cat <<EOF >file.h +#define file __FILE__ +int test; +EOF + backdate file.h + cat <<EOF >file_h.c +#include "file.h" +EOF + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c file_h.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c file_h.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + mv file_h.c file2_h.c + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c `pwd`/file2_h.c + expect_stat 'cache hit (direct)' 2 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "__TIME__ in source file disables direct mode" + + cat <<EOF >time.c +#define time __TIME__ +int test; +EOF + + $CCACHE_COMPILE -c time.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -c time.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "__TIME__ in include file disables direct mode" + + cat <<EOF >time.h +#define time __TIME__ +int test; +EOF + backdate time.h + + cat <<EOF >time_h.c +#include "time.h" +EOF + + $CCACHE_COMPILE -c time_h.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -c time_h.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "__TIME__ in source file ignored if sloppy" + + cat <<EOF >time.c +#define time __TIME__ +int test; +EOF + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE -c time.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE -c time.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "__TIME__ in include file ignored if sloppy" + + cat <<EOF >time.h +#define time __TIME__ +int test; +EOF + backdate time.h + cat <<EOF >time_h.c +#include "time.h" +EOF + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE -c time_h.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE -c time_h.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "Too new include file disables direct mode" + + cat <<EOF >new.c +#include "new.h" +EOF + cat <<EOF >new.h +int test; +EOF + touch -t 203801010000 new.h + + $CCACHE_COMPILE -c new.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -c new.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "New include file ignored if sloppy" + + cat <<EOF >new.c +#include "new.h" +EOF + cat <<EOF >new.h +int test; +EOF + touch -t 203801010000 new.h + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS include_file_mtime" $CCACHE_COMPILE -c new.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS include_file_mtime" $CCACHE_COMPILE -c new.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + # Check that environment variables that affect the preprocessor are taken + # into account. + TEST "CPATH included in hash" + + 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_COMPILE -c foo.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CPATH=subdir1 $CCACHE_COMPILE -c foo.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CPATH=subdir2 $CCACHE_COMPILE -c foo.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 # subdir2 is part of the preprocessor output + + CPATH=subdir2 $CCACHE_COMPILE -c foo.c + expect_stat 'cache hit (direct)' 2 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 + + # ------------------------------------------------------------------------- + TEST "Comment in strings" + + echo 'char *comment = " /* \\\\u" "foo" " */";' >comment.c + + $CCACHE_COMPILE -c comment.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -c comment.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + echo 'char *comment = " /* \\\\u" "goo" " */";' >comment.c + + $CCACHE_COMPILE -c comment.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 + + # ------------------------------------------------------------------------- + TEST "#line directives with troublesome files" + + cat <<EOF >strange.c +int foo; +EOF + for x in stdout tty sda hda; do + if [ -b /dev/$x ] || [ -c /dev/$x ]; then + echo "#line 1 \"/dev/$x\"" >>strange.c + fi + done + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS include_file_mtime" $CCACHE_COMPILE -c strange.c + + manifest=`find $CCACHE_DIR -name '*.manifest'` + if [ -n "$manifest" ]; then + data="`$CCACHE --dump-manifest $manifest | egrep '/dev/(stdout|tty|sda|hda'`" + if [ -n "$data" ]; then + test_failed "$manifest contained troublesome file(s): $data" + fi + fi + + # ------------------------------------------------------------------------- + TEST "--dump-manifest" + + $CCACHE_COMPILE test.c -c -o test.o + + manifest=`find $CCACHE_DIR -name '*.manifest'` + $CCACHE --dump-manifest $manifest >manifest.dump + + if grep 'Hash: d4de2f956b4a386c6660990a7a1ab13f' manifest.dump >/dev/null 2>&1 && \ + grep 'Hash: e94ceb9f1b196c387d098a5f1f4fe862' manifest.dump >/dev/null 2>&1 && \ + grep 'Hash: ba753bebf9b5eb99524bb7447095e2e6' manifest.dump >/dev/null 2>&1; then + : OK + else + test_failed "Unexpected output of --dump-manifest" + fi + + # ------------------------------------------------------------------------- + TEST "Argument-less -B and -L" + + cat <<EOF >test.c +#include <stdio.h> +int main(void) +{ +#ifdef FOO + puts("FOO"); +#endif + return 0; +} +EOF + + $CCACHE_COMPILE -B -L -DFOO -c test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -B -L -DBAR -c test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache miss' 2 + + # ------------------------------------------------------------------------- + TEST "CCACHE_IGNOREHEADERS" + + cat <<EOF >ignore.h +// We don't want this header in the manifest. +EOF + backdate ignore.h + cat <<EOF >ignore.c +#include "ignore.h" +int foo; +EOF + + CCACHE_IGNOREHEADERS="ignore.h" $CCACHE_COMPILE -c ignore.c + manifest=`find $CCACHE_DIR -name '*.manifest'` + data="`$CCACHE --dump-manifest $manifest | grep ignore.h`" + if [ -n "$data" ]; then + test_failed "$manifest contained ignored header: $data" + fi +} + +# ============================================================================= + +SUITE_basedir_SETUP() { + unset CCACHE_NODIRECT + + mkdir -p dir1/src dir1/include + cat <<EOF >dir1/src/test.c +#include <stdarg.h> +#include <test.h> +EOF + cat <<EOF >dir1/include/test.h +int test; +EOF + cp -r dir1 dir2 + backdate dir1/include/test.h dir2/include/test.h +} + +SUITE_basedir() { + # ------------------------------------------------------------------------- + TEST "Enabled CCACHE_BASEDIR" + + cd dir1 + CCACHE_BASEDIR="`pwd`" $CCACHE_COMPILE -I`pwd`/include -c src/test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + cd ../dir2 + CCACHE_BASEDIR="`pwd`" $CCACHE_COMPILE -I`pwd`/include -c src/test.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "Disabled (default) CCACHE_BASEDIR" + + cd dir1 + CCACHE_BASEDIR="`pwd`" $CCACHE_COMPILE -I`pwd`/include -c src/test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + # CCACHE_BASEDIR="" is the default: + $CCACHE_COMPILE -I`pwd`/include -c src/test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 + + # ------------------------------------------------------------------------- + TEST "Path normalization" + + cd dir1 + CCACHE_BASEDIR="`pwd`" $CCACHE_COMPILE -I`pwd`/include -c src/test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + # Rewriting triggered by CCACHE_BASEDIR should handle paths with multiple + # slashes correctly: + CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -I`pwd`//include -c `pwd`//src/test.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "Rewriting in stderr" + + cat <<EOF >stderr.h +int stderr(void) +{ + // Trigger warning by having no return statement. +} +EOF + backdate stderr.h + cat <<EOF >stderr.c +#include <stderr.h> +EOF + + CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -Wall -W -I`pwd` -c `pwd`/stderr.c -o `pwd`/stderr.o 2>stderr.txt + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + if grep `pwd` stderr.txt >/dev/null 2>&1; then + test_failed "Base dir (`pwd`) found in stderr:\n`cat stderr.txt`" + fi + + CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -Wall -W -I`pwd` -c `pwd`/stderr.c -o `pwd`/stderr.o 2>stderr.txt + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + if grep `pwd` stderr.txt >/dev/null 2>&1; then + test_failed "Base dir (`pwd`) found in stderr:\n`cat stderr.txt`" + fi + + # ------------------------------------------------------------------------- + TEST "-MF/-MQ/-MT with absolute paths" + + for option in MF "MF " MQ "MQ " MT "MT "; do + clear_cache + cd dir1 + CCACHE_BASEDIR="`pwd`" $CCACHE_COMPILE -I`pwd`/include -MD -${option}`pwd`/test.d -c src/test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + cd .. + + cd dir2 + CCACHE_BASEDIR="`pwd`" $CCACHE_COMPILE -I`pwd`/include -MD -${option}`pwd`/test.d -c src/test.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + cd .. + done + + # ------------------------------------------------------------------------- + # When BASEDIR is set to /, check that -MF, -MQ and -MT arguments with + # absolute paths are rewritten to relative and that the dependency file + # only contains relative paths. + TEST "-MF/-MQ/-MT with absolute paths and BASEDIR set to /" + + for option in MF "MF " MQ "MQ " MT "MT "; do + clear_cache + cd dir1 + CCACHE_BASEDIR="/" $CCACHE_COMPILE -I`pwd`/include -MD -${option}`pwd`/test.d -c src/test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + # Check that there is no absolute path in the dependency file: + while read line; do + for file in $line; do + case $file in /*) + test_failed "Absolute file path '$file' found in dependency file '`pwd`/test.d'" + esac + done + done <test.d + cd .. + + cd dir2 + CCACHE_BASEDIR="/" $CCACHE_COMPILE -I`pwd`/include -MD -${option}`pwd`/test.d -c src/test.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + cd .. + done +} + +# ============================================================================= + +SUITE_compression_SETUP() { + generate_code 1 test.c +} + +SUITE_compression() { + # ------------------------------------------------------------------------- + TEST "Hash sum equal for compressed and uncompressed files" + + CCACHE_COMPRESS=1 $CCACHE_COMPILE -c test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_COMPRESS=1 $CCACHE_COMPILE -c test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -c test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 2 + expect_stat 'cache miss' 1 +} + +# ============================================================================= + +SUITE_readonly_SETUP() { + generate_code 1 test.c + generate_code 2 test2.c +} + +SUITE_readonly() { + # ------------------------------------------------------------------------- + TEST "Cache hit" + + # Cache a compilation. + $CCACHE_COMPILE -c test.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + rm test.o + + # Make the cache read-only. + chmod -R a-w $CCACHE_DIR + + # Check that read-only mode finds the cached result. + CCACHE_READONLY=1 CCACHE_TEMPDIR=/tmp CCACHE_PREFIX=false $CCACHE_COMPILE -c test.c + status1=$? + + # Check that fallback to the real compiler works for a cache miss. + CCACHE_READONLY=1 CCACHE_TEMPDIR=/tmp $CCACHE_COMPILE -c test2.c + status2=$? + + # Leave test dir a nice state after test failure. + chmod -R +w $CCACHE_DIR + + if [ $status1 -ne 0 ]; then + test_failed "Failure when compiling test.c read-only" + fi + if [ $status2 -ne 0 ]; then + test_failed "Failure when compiling test2.c read-only" + fi + if [ ! -f test.o ]; then + test_failed "test.o missing" + fi + if [ ! -f test2.o ]; then + test_failed "test2.o missing" + fi + + # ------------------------------------------------------------------------- + TEST "Cache miss" + + # Check that read-only mode doesn't try to store new results. + CCACHE_READONLY=1 CCACHE_TEMPDIR=/tmp $CCACHE_COMPILE -c test.c + if [ $? -ne 0 ]; then + test_failed "Failure when compiling test2.c read-only" + fi + if [ -d $CCACHE_DIR ]; then + test_failed "ccache dir was created" + fi + + # ------------------------------------------------------------------------- + # Check that read-only mode and direct mode work together. + TEST "Cache hit, direct" + + # Cache a compilation. + $CCACHE_COMPILE -c test.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + rm test.o + + # Make the cache read-only. + chmod -R a-w $CCACHE_DIR + + # Direct mode should work: + files_before=`find $CCACHE_DIR -type f | wc -l` + CCACHE_DIRECT=1 CCACHE_READONLY=1 CCACHE_TEMPDIR=/tmp $CCACHE_COMPILE -c test.c + files_after=`find $CCACHE_DIR -type f | wc -l` + + # Leave test dir a nice state after test failure. + chmod -R +w $CCACHE_DIR + + if [ $? -ne 0 ]; then + test_failed "Failure when compiling test.c read-only" + fi + if [ $files_after -ne $files_before ]; then + test_failed "Read-only mode + direct mode stored files in the cache" + fi +} + +# ============================================================================= + +SUITE_readonly_direct_SETUP() { + unset CCACHE_NODIRECT + + generate_code 1 test.c +} + +SUITE_readonly_direct() { + # ------------------------------------------------------------------------- + TEST "Direct hit" + + $CCACHE_COMPILE -c test.c -o test.o + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_READONLY_DIRECT=1 $CCACHE_COMPILE -c test.c -o test.o + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "Direct miss doesn't lead to preprocessed hit" + + $CCACHE_COMPILE -c test.c -o test.o + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_READONLY_DIRECT=1 $CCACHE_COMPILE -DFOO -c test.c -o test.o + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 +} + +# ============================================================================= + +prepare_cleanup_test_dir() { + local dir=$1 + + rm -rf $dir + mkdir -p $dir + for i in $(seq 0 9); do + printf '%4017s' '' | tr ' ' 'A' >$dir/result$i-4017.o + touch $dir/result$i-4017.stderr + touch $dir/result$i-4017.d + if [ $i -gt 5 ]; then + backdate $dir/result$i-4017.stderr + fi + done + # NUMFILES: 30, TOTALSIZE: 40 KiB, MAXFILES: 0, MAXSIZE: 0 + echo "0 0 0 0 0 0 0 0 0 0 0 30 40 0 0" >$dir/stats +} + +SUITE_cleanup() { + # ------------------------------------------------------------------------- + TEST "Clear cache" + + prepare_cleanup_test_dir $CCACHE_DIR/a + + $CCACHE -C >/dev/null + expect_file_count 0 '*.o' $CCACHE_DIR + expect_file_count 0 '*.d' $CCACHE_DIR + expect_file_count 0 '*.stderr' $CCACHE_DIR + expect_stat 'files in cache' 0 + expect_stat 'cleanups performed' 1 + + # ------------------------------------------------------------------------- + TEST "Forced cache cleanup, no limits" + + prepare_cleanup_test_dir $CCACHE_DIR/a + + $CCACHE -F 0 -M 0 >/dev/null + $CCACHE -c >/dev/null + expect_file_count 10 '*.o' $CCACHE_DIR + expect_file_count 10 '*.d' $CCACHE_DIR + expect_file_count 10 '*.stderr' $CCACHE_DIR + expect_stat 'files in cache' 30 + expect_stat 'cleanups performed' 0 + + # ------------------------------------------------------------------------- + TEST "Forced cache cleanup, file limit" + + prepare_cleanup_test_dir $CCACHE_DIR/a + + # (9/10) * 30 * 16 = 432 + $CCACHE -F 432 -M 0 >/dev/null + $CCACHE -c >/dev/null + # floor(0.8 * 9) = 7 + expect_file_count 7 '*.o' $CCACHE_DIR + expect_file_count 7 '*.d' $CCACHE_DIR + expect_file_count 7 '*.stderr' $CCACHE_DIR + expect_stat 'files in cache' 21 + expect_stat 'cleanups performed' 1 + for i in 0 1 2 3 4 5 9; do + file=$CCACHE_DIR/a/result$i-4017.o + if [ ! -f $file ]; then + test_failed "File $file removed when it shouldn't" + fi + done + for i in 6 7 8; do + file=$CCACHE_DIR/a/result$i-4017.o + if [ -f $file ]; then + test_failed "File $file not removed when it should" + fi + done + + # ------------------------------------------------------------------------- + TEST "Forced cache cleanup, size limit" + + # NOTE: This test is known to fail on filesystems that have unusual block + # sizes, including ecryptfs. The workaround is to place the test directory + # elsewhere: + # + # cd /tmp + # CCACHE=$DIR/ccache $DIR/test.sh + + prepare_cleanup_test_dir $CCACHE_DIR/a + + # (4/10) * 10 * 4 * 16 = 256 + $CCACHE -F 0 -M 256K >/dev/null + $CCACHE -c >/dev/null + # floor(0.8 * 4) = 3 + expect_file_count 3 '*.o' $CCACHE_DIR + expect_file_count 3 '*.d' $CCACHE_DIR + expect_file_count 3 '*.stderr' $CCACHE_DIR + expect_stat 'files in cache' 9 + expect_stat 'cleanups performed' 1 + for i in 3 4 5; do + file=$CCACHE_DIR/a/result$i-4017.o + if [ ! -f $file ]; then + test_failed "File $file removed when it shouldn't" + fi + done + for i in 0 1 2 6 7 8 9; do + file=$CCACHE_DIR/a/result$i-4017.o + if [ -f $file ]; then + test_failed "File $file not removed when it should" + fi + done + + # ------------------------------------------------------------------------- + TEST "Automatic cache cleanup" + + for x in 0 1 2 3 4 5 6 7 8 9 a b c d e f; do + prepare_cleanup_test_dir $CCACHE_DIR/$x + done + + # (9/10) * 30 * 16 = 432 + $CCACHE -F 432 -M 0 >/dev/null + expect_file_count 160 '*.o' $CCACHE_DIR + expect_file_count 160 '*.d' $CCACHE_DIR + expect_file_count 160 '*.stderr' $CCACHE_DIR + expect_stat 'files in cache' 480 + + touch empty.c + $CCACHE_COMPILE -c empty.c -o empty.o + # floor(0.8 * 9) = 7 + expect_file_count 157 '*.o' $CCACHE_DIR + expect_file_count 156 '*.d' $CCACHE_DIR + expect_file_count 156 '*.stderr' $CCACHE_DIR + expect_stat 'files in cache' 469 + expect_stat 'cleanups performed' 1 + + # ------------------------------------------------------------------------- + TEST "Cleanup of sibling files" + + prepare_cleanup_test_dir $CCACHE_DIR/a + + # (9/10) * 30 * 16 = 432 + $CCACHE -F 432 -M 0 >/dev/null + backdate $CCACHE_DIR/a/result2-4017.stderr + $CCACHE -c >/dev/null + # floor(0.8 * 9) = 7 + expect_file_count 7 '*.o' $CCACHE_DIR + expect_file_count 7 '*.d' $CCACHE_DIR + expect_file_count 7 '*.stderr' $CCACHE_DIR + expect_stat 'files in cache' 21 + for i in 0 1 3 4 5 8 9; do + file=$CCACHE_DIR/a/result$i-4017.o + if [ ! -f $file ]; then + test_failed "File $file removed when it shouldn't" + fi + done + for i in 2 6 7; do + file=$CCACHE_DIR/a/result$i-4017.o + if [ -f $file ]; then + test_failed "File $file not removed when it should" + fi + done + + # ------------------------------------------------------------------------- + TEST "No cleanup of new unknown file" + + prepare_cleanup_test_dir $CCACHE_DIR/a + + touch $CCACHE_DIR/a/abcd.unknown + $CCACHE -F 0 -M 0 -c >/dev/null # update counters + expect_stat 'files in cache' 31 + # (9/10) * 30 * 16 = 432 + $CCACHE -F 432 -M 0 >/dev/null + $CCACHE -c >/dev/null + if [ ! -f $CCACHE_DIR/a/abcd.unknown ]; then + test_failed "$CCACHE_DIR/a/abcd.unknown removed" + fi + expect_stat 'files in cache' 19 + + # ------------------------------------------------------------------------- + TEST "Cleanup of old unknown file" + + prepare_cleanup_test_dir $CCACHE_DIR/a + # (9/10) * 30 * 16 = 432 + $CCACHE -F 432 -M 0 >/dev/null + touch $CCACHE_DIR/a/abcd.unknown + backdate $CCACHE_DIR/a/abcd.unknown + $CCACHE -c >/dev/null + if [ -f $CCACHE_DIR/a/abcd.unknown ]; then + test_failed "$CCACHE_DIR/a/abcd.unknown not removed" + fi + + # ------------------------------------------------------------------------- + TEST "Cleanup of tmp file" + + mkdir -p $CCACHE_DIR/a + touch $CCACHE_DIR/a/abcd.tmp.efgh + $CCACHE -c >/dev/null # update counters + expect_stat 'files in cache' 1 + backdate $CCACHE_DIR/a/abcd.tmp.efgh + $CCACHE -c >/dev/null + if [ -f $CCACHE_DIR/a/abcd.tmp.efgh ]; then + test_failed "$CCACHE_DIR/a/abcd.tmp.unknown not removed" + fi + expect_stat 'files in cache' 0 + + # ------------------------------------------------------------------------- + TEST "No cleanup of .nfs* files" + + prepare_cleanup_test_dir $CCACHE_DIR/a + + touch $CCACHE_DIR/a/.nfs0123456789 + $CCACHE -F 0 -M 0 >/dev/null + $CCACHE -c >/dev/null + expect_file_count 1 '.nfs*' $CCACHE_DIR + expect_stat 'files in cache' 30 + + # ------------------------------------------------------------------------- + TEST "CCACHE_LIMIT_MULTIPLE" + + prepare_cleanup_test_dir $CCACHE_DIR/a + + # (1/1) * 30 * 16 = 480 + $CCACHE -F 480 >/dev/null + CCACHE_LIMIT_MULTIPLE=0.5 $CCACHE -c >/dev/null + expect_stat 'files in cache' 15 +} + +# ============================================================================= + +SUITE_pch_PROBE() { + touch pch.h + if ! $UNCACHED_COMPILE $SYSROOT -fpch-preprocess pch.h 2>/dev/null \ + || [ ! -f pch.h.gch ]; then + echo "compiler ($($COMPILER --version | head -1)) doesn't support precompiled headers" + fi +} + +SUITE_pch_SETUP() { + unset CCACHE_NODIRECT + + cat <<EOF >pch.c +#include "pch.h" +int main() +{ + void *p = NULL; + return 0; +} +EOF + cat <<EOF >pch.h +#include <stdlib.h> +EOF + backdate pch.h + cat <<EOF >pch2.c +int main() +{ + void *p = NULL; + return 0; +} +EOF +} + +SUITE_pch() { + # Clang and GCC handle precompiled headers similarly, but GCC is much more + # forgiving with precompiled headers. Both GCC and Clang keep an absolute + # path reference to the original file except that Clang uses that reference + # to validate the pch and GCC ignores the reference. Also, Clang has an + # additional feature: pre-tokenized headers. For these reasons, Clang + # should be tested differently from GCC. Clang can only use pch or pth + # headers on the command line and not as an #include statement inside a + # source file. + + if $COMPILER_TYPE_CLANG; then + pch_suite_clang + else + pch_suite_gcc + fi +} + +pch_suite_gcc() { + # ------------------------------------------------------------------------- + TEST "Create .gch, -c, no -o, without opt-in" + + $CCACHE_COMPILE $SYSROOT -c pch.h + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 0 + expect_stat "can't use precompiled header" 1 + + # ------------------------------------------------------------------------- + TEST "Create .gch, no -c, -o, without opt-in" + + $CCACHE_COMPILE pch.h -o pch.gch + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 0 + expect_stat "can't use precompiled header" 1 + + # ------------------------------------------------------------------------- + TEST "Create .gch, -c, no -o, with opt-in" + + CCACHE_SLOPPINESS=pch_defines $CCACHE_COMPILE $SYSROOT -c pch.h + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + rm pch.h.gch + + CCACHE_SLOPPINESS=pch_defines $CCACHE_COMPILE $SYSROOT -c pch.h + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + if [ ! -f pch.h.gch ]; then + test_failed "pch.h.gch missing" + fi + + # ------------------------------------------------------------------------- + TEST "Create .gch, no -c, -o, with opt-in" + + CCACHE_SLOPPINESS=pch_defines,time_macros $CCACHE_COMPILE $SYSROOT pch.h -o pch.gch + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_SLOPPINESS=pch_defines,time_macros $CCACHE_COMPILE $SYSROOT pch.h -o pch.gch + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + if [ ! -f pch.gch ]; then + test_failed "pch.gch missing" + fi + + # ------------------------------------------------------------------------- + TEST "Use .gch, no -fpch-preprocess, #include" + + $UNCACHED_COMPILE $SYSROOT -c pch.h + backdate pch.h.gch + rm pch.h + + $CCACHE_COMPILE $SYSROOT -c pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 0 + # Preprocessor error because GCC can't find the real include file when + # trying to preprocess: + expect_stat 'preprocessor error' 1 + + # ------------------------------------------------------------------------- + TEST "Use .gch, no -fpch-preprocess, -include, no sloppiness" + + $UNCACHED_COMPILE $SYSROOT -c pch.h + backdate pch.h.gch + rm pch.h + + $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 0 + # Must enable sloppy time macros: + expect_stat "can't use precompiled header" 1 + + # ------------------------------------------------------------------------- + TEST "Use .gch, no -fpch-preprocess, -include, sloppiness" + + $UNCACHED_COMPILE $SYSROOT -c pch.h + backdate pch.h.gch + rm pch.h + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "Use .gch, -fpch-preprocess, #include, no sloppiness" + + $UNCACHED_COMPILE $SYSROOT -c pch.h + backdate pch.h.gch + rm pch.h + + $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + # Must enable sloppy time macros: + expect_stat "can't use precompiled header" 1 + + # ------------------------------------------------------------------------- + TEST "Use .gch, -fpch-preprocess, #include, sloppiness" + + $UNCACHED_COMPILE $SYSROOT -c pch.h + backdate pch.h.gch + rm pch.h + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "Use .gch, -fpch-preprocess, #include, file changed" + + $UNCACHED_COMPILE $SYSROOT -c pch.h + backdate pch.h.gch + rm pch.h + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + echo "updated" >>pch.h.gch # GCC seems to cope with this... + backdate pch.h.gch + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 2 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 + + # ------------------------------------------------------------------------- + TEST "Use .gch, preprocessor mode" + + $UNCACHED_COMPILE $SYSROOT -c pch.h + backdate pch.h.gch + rm pch.h + + CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "Use .gch, preprocessor mode, file changed" + + $UNCACHED_COMPILE $SYSROOT -c pch.h + backdate pch.h.gch + rm pch.h + + CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + echo "updated" >>pch.h.gch # GCC seems to cope with this... + backdate pch.h.gch + + CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 + + CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 2 +} + +pch_suite_clang() { + # ------------------------------------------------------------------------- + TEST "Create .gch, -c, no -o, without opt-in" + + $CCACHE_COMPILE $SYSROOT -c pch.h + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 0 + expect_stat "can't use precompiled header" 1 + + # ------------------------------------------------------------------------- + TEST "Create .gch, no -c, -o, without opt-in" + + $CCACHE_COMPILE pch.h -o pch.gch + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 0 + expect_stat "can't use precompiled header" 1 + + # ------------------------------------------------------------------------- + TEST "Create .gch, -c, no -o, with opt-in" + + CCACHE_SLOPPINESS=pch_defines,time_macros $CCACHE_COMPILE $SYSROOT -c pch.h + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + rm pch.h.gch + + CCACHE_SLOPPINESS=pch_defines,time_macros $CCACHE_COMPILE $SYSROOT -c pch.h + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + if [ ! -f pch.h.gch ]; then + test_failed "pch.h.gch missing" + fi + + # ------------------------------------------------------------------------- + TEST "Create .gch, no -c, -o, with opt-in" + + CCACHE_SLOPPINESS=pch_defines,time_macros $CCACHE_COMPILE $SYSROOT pch.h -o pch.gch + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_SLOPPINESS=pch_defines,time_macros $CCACHE_COMPILE $SYSROOT pch.h -o pch.gch + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + if [ ! -f pch.gch ]; then + test_failed "pch.gch missing" + fi + + # ------------------------------------------------------------------------- + TEST "Use .gch, no -fpch-preprocess, -include, no sloppiness" + + $UNCACHED_COMPILE $SYSROOT -c pch.h + backdate pch.h.gch + + $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c 2>/dev/null + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 0 + # Must enable sloppy time macros: + expect_stat "can't use precompiled header" 1 + + # ------------------------------------------------------------------------- + TEST "Use .gch, no -fpch-preprocess, -include, sloppiness" + + $UNCACHED_COMPILE $SYSROOT -c pch.h + backdate pch.h.gch + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "Use .gch, -fpch-preprocess, -include, file changed" + + $UNCACHED_COMPILE $SYSROOT -c pch.h + backdate pch.h.gch + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + echo "updated" >>pch.h.gch # clang seems to cope with this... + backdate pch.h.gch + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 + + # ------------------------------------------------------------------------- + TEST "Use .gch, preprocessor mode" + + $UNCACHED_COMPILE $SYSROOT -c pch.h + backdate pch.h.gch + + CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "Use .gch, preprocessor mode, file changed" + + $UNCACHED_COMPILE $SYSROOT -c pch.h + backdate pch.h.gch + + CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + echo "updated" >>pch.h.gch # clang seems to cope with this... + backdate pch.h.gch + + CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 + + CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 2 + + # ------------------------------------------------------------------------- + TEST "Create .pth, -c, -o" + + CCACHE_SLOPPINESS=pch_defines,time_macros $CCACHE_COMPILE $SYSROOT -c pch.h -o pch.h.pth + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + rm -f pch.h.pth + + CCACHE_SLOPPINESS=pch_defines,time_macros $CCACHE_COMPILE $SYSROOT -c pch.h -o pch.h.pth + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + if [ ! -f pch.h.pth ]; then + test_failed "pch.h.pth missing" + fi + + # ------------------------------------------------------------------------- + TEST "Use .pth, no -fpch-preprocess, -include, no sloppiness" + + $UNCACHED_COMPILE $SYSROOT -c pch.h -o pch.h.pth + backdate pch.h.pth + + $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 0 + # Must enable sloppy time macros: + expect_stat "can't use precompiled header" 1 + + # ------------------------------------------------------------------------- + TEST "Use .pth, no -fpch-preprocess, -include, sloppiness" + + $UNCACHED_COMPILE $SYSROOT -c pch.h -o pch.h.pth + backdate pch.h.pth + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "Use .pth, -fpch-preprocess, -include, file changed" + + $UNCACHED_COMPILE $SYSROOT -c pch.h -o pch.h.pth + backdate pch.h.pth + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + echo "updated" >>pch.h.pth # clang seems to cope with this... + backdate pch.h.pth + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 + + # ------------------------------------------------------------------------- + TEST "Use .pth, preprocessor mode" + + $UNCACHED_COMPILE $SYSROOT -c pch.h -o pch.h.pth + backdate pch.h.pth + + CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "Use .pth, preprocessor mode, file changed" + + $UNCACHED_COMPILE $SYSROOT -c pch.h -o pch.h.pth + backdate pch.h.pth + + CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + echo "updated" >>pch.h.pth # clang seems to cope with this... + backdate pch.h.pth + + CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 2 + + CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 2 +} + +# ============================================================================= + +SUITE_upgrade() { + TEST "Keep maxfiles and maxsize settings" + + rm $CCACHE_CONFIGPATH + mkdir -p $CCACHE_DIR/0 + echo "0 0 0 0 0 0 0 0 0 0 0 0 0 2000 131072" >$CCACHE_DIR/0/stats + expect_stat 'max files' 32000 + expect_stat 'max cache size' '2.1 GB' +} + +# ============================================================================= + +SUITE_input_charset_PROBE() { + touch test.c + if ! $UNCACHED_COMPILE -c -finput-charset=latin1 test.c >/dev/null 2>&1; then + echo "compiler doesn't support -finput-charset" + fi +} + +SUITE_input_charset() { + # ------------------------------------------------------------------------- + TEST "-finput-charset" + + printf '#include <wchar.h>\nwchar_t foo[] = L"\xbf";\n' >latin1.c + + $CCACHE_COMPILE -c -finput-charset=latin1 latin1.c + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -c -finput-charset=latin1 latin1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + CCACHE_NOCPP2=1 $CCACHE_COMPILE -c -finput-charset=latin1 latin1.c + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 2 + + CCACHE_NOCPP2=1 $CCACHE_COMPILE -c -finput-charset=latin1 latin1.c + expect_stat 'cache hit (preprocessed)' 2 + expect_stat 'cache miss' 2 +} + +# ============================================================================= +# main program + +if pwd | grep '[^A-Za-z0-9/.,=_%+-]' >/dev/null 2>&1; then + cat <<EOF +Error: The test suite doesn't work in directories with whitespace or other +funny characters in the name. Sorry. +EOF + exit 1 +fi + +if [ -n "$CC" ]; then + COMPILER="$CC" +else + COMPILER=gcc +fi +if [ -z "$CCACHE" ]; then + CCACHE=`pwd`/ccache +fi + +COMPILER_TYPE_CLANG=false +COMPILER_TYPE_GCC=false + +COMPILER_USES_LLVM=false +COMPILER_USES_MINGW=false + +HOST_OS_APPLE=false +HOST_OS_LINUX=false +HOST_OS_WINDOWS=false + +compiler_version="`$COMPILER --version 2>&1 | head -1`" +case $compiler_version in + *gcc*|*g++*|2.95*) + COMPILER_TYPE_GCC=true + ;; + *clang*) + COMPILER_TYPE_CLANG=true + ;; + *) + echo "WARNING: Compiler $COMPILER not supported (version: $compiler_version) -- not running tests" >&2 + exit 0 + ;; +esac + +case $compiler_version in + *llvm*|*LLVM*) + COMPILER_USES_LLVM=true + ;; + *MINGW*|*mingw*) + COMPILER_USES_MINGW=true + ;; +esac + +case $(uname -s) in + *MINGW*|*mingw*) + HOST_OS_WINDOWS=true + ;; + *Darwin*) + HOST_OS_APPLE=true + ;; + *Linux*) + HOST_OS_LINUX=true + ;; +esac + +if $HOST_OS_WINDOWS; then + PATH_DELIM=";" +else + PATH_DELIM=":" +fi + +if $HOST_OS_APPLE; then + # Grab the developer directory from the environment or try xcode-select + if [ "$XCODE_DEVELOPER_DIR" = "" ]; then + XCODE_DEVELOPER_DIR=`xcode-select --print-path` + if [ "$XCODE_DEVELOPER_DIR" = "" ]; then + echo "Error: XCODE_DEVELOPER_DIR environment variable not set and xcode-select path not set" + exit 1 + fi + fi + + # Choose the latest SDK if an SDK root is not set + MAC_PLATFORM_DIR=$XCODE_DEVELOPER_DIR/Platforms/MacOSX.platform + if [ "$SDKROOT" = "" ]; then + SDKROOT="`eval ls -f -1 -d \"$MAC_PLATFORM_DIR/Developer/SDKs/\"*.sdk | tail -1`" + if [ "$SDKROOT" = "" ]; then + echo "Error: Cannot find a valid SDK root directory" + exit 1 + fi + fi + + SYSROOT="-isysroot `echo \"$SDKROOT\" | sed 's/ /\\ /g'`" +else + SYSROOT= +fi + +# --------------------------------------- + +TESTDIR=testdir.$$ +ABS_TESTDIR=$PWD/$TESTDIR +rm -rf $TESTDIR +mkdir $TESTDIR +cd $TESTDIR || exit 1 + +# --------------------------------------- + +all_suites=" +base +nocpp2 +multi_arch +serialize_diagnostics +debug_prefix_map +masquerading +hardlink +direct +basedir +compression +readonly +readonly_direct +cleanup +pch +upgrade +input_charset +" + +compiler_location=$(which $(echo "$COMPILER" | awk '{print $1}')) +if [ "$compiler_location" = "$COMPILER" ]; then + echo "Compiler: $COMPILER" +else + echo "Compiler: $COMPILER ($compiler_location)" +fi +echo "Compiler version: $($COMPILER --version | head -n 1)" +echo + +VERBOSE=false +[ "$1" = "-v" ] && { VERBOSE=true; shift; } + +suites="$*" +if [ -z "$suites" ]; then + suites="$all_suites" +fi + +for suite in $suites; do + run_suite $suite +done + +cd / +rm -rf $ABS_TESTDIR +green PASSED +exit 0 |