*run_second_cpp* (*CCACHE_CPP2* or *CCACHE_NOCPP2*, see <<_boolean_values,Boolean values>> above)::
- If true, ccache will not use the optimisation of avoiding the second call
- to the preprocessor by compiling the preprocessed output that was used for
- finding the hash in the case of a cache miss. This is primarily a debugging
- option, although it is possible that some unusual compilers will have
- problems with compiling the preprocessed output, in which case this option
- could allow ccache to be used anyway.
+ If true, ccache will first run the preprocessor to preprocess the source
+ code (see <<_the_preprocessor_mode,THE PREPROCESSOR MODE>>) and then on a
+ cache miss run the compiler on the source code to get hold of the object
+ file. This is the default.
+
+ If false, ccache will first run preprocessor to preprocess the source code
+ and then on a cache miss run the compiler on the _preprocessed source code_
+ instead of the original source code. This makes cache misses slightly
+ faster since the source code only has to be preprocessed once. The downside
+ is that some compilers won't produce the same result (for instance
+ diagnostics warnings) when compiling preprocessed source code.
*sloppiness* (*CCACHE_SLOPPINESS*)::
<<_precompiled_headers,PRECOMPILED HEADERS>>.
-Errors when compiling with ccache
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If compilation doesn't work with ccache, but it works without it, one possible
-reason is that the compiler can't compile preprocessed output correctly. A
-workaround that may work is to enable *run_second_cpp*. This will make cache
-misses slower, though, so it is better to find and fix the root cause.
-
-
Corrupt object files
~~~~~~~~~~~~~~~~~~~~
New features and improvements
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+- The configuration option `run_second_cpp` (`CCACHE_CPP2`) now defaults to
+ true. This improves ccache's out-of-the-box experience for compilers that
+ can't compile their own preprocessed output with the same outcome as if they
+ compiled the real source code directly, e.g. newer versions of GCC and Clang.
+
- Added support for cuda including the -optf/--options-file option.
- Added new sloppiness option `no_system_headers`, which tells ccache not to
cc_log("%s used; disabling unify mode", debug_argument);
conf->unify = false;
}
- if (debug_level >= 3) {
+ if (debug_level >= 3 && !conf->run_second_cpp) {
cc_log("%s used; not compiling preprocessed code", debug_argument);
conf->run_second_cpp = true;
}
direct_i_file = language_is_preprocessed(actual_language);
- if (output_is_precompiled_header) {
+ if (output_is_precompiled_header && !conf->run_second_cpp) {
// It doesn't work to create the .gch from preprocessed source.
cc_log("Creating precompiled header; not compiling preprocessed code");
conf->run_second_cpp = true;
conf->read_only = false;
conf->read_only_direct = false;
conf->recache = false;
- conf->run_second_cpp = false;
+ conf->run_second_cpp = true;
conf->sloppiness = 0;
conf->stats = true;
conf->temporary_dir = x_strdup("");
unset CCACHE_BASEDIR
unset CCACHE_CC
+ unset CCACHE_COMMENTS
unset CCACHE_COMPILERCHECK
unset CCACHE_COMPRESS
- unset CCACHE_COMMENTS
unset CCACHE_CPP2
unset CCACHE_DIR
unset CCACHE_DISABLE
unset CCACHE_IGNOREHEADERS
unset CCACHE_LOGFILE
unset CCACHE_NLEVELS
+ unset CCACHE_NOCPP2
unset CCACHE_NOSTATS
unset CCACHE_PATH
unset CCACHE_PREFIX
$UNCACHED_COMPILE -c -o reference_test1.o test1.c
expect_equal_object_files reference_test1.o test1.o
- # -------------------------------------------------------------------------
- TEST "CCACHE_CPP2"
-
- CCACHE_CPP2=1 $CCACHE_COMPILE -c test1.c
- expect_stat 'cache hit (preprocessed)' 0
- expect_stat 'cache miss' 1
-
- CCACHE_CPP2=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_NOSTATS"
# =============================================================================
-SUITE_cpp2_SETUP() {
- export CCACHE_CPP2=1
+SUITE_nocpp2_SETUP() {
+ export CCACHE_NOCPP2=1
generate_code 1 test1.c
}
-SUITE_cpp2() {
+SUITE_nocpp2() {
base_tests
}
$UNCACHED_COMPILE -c --serialize-diagnostics expected.dia test1.c
- # Run with CCACHE_CPP2 to ensure the same diagnostics output as above
- CCACHE_CPP2=1 $CCACHE_COMPILE -c --serialize-diagnostics test.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
rm test.dia
- CCACHE_CPP2=1 $CCACHE_COMPILE -c --serialize-diagnostics test.dia test1.c
+ $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
test_failed "Expected an error compiling error.c"
fi
- CCACHE_CPP2=1 $CCACHE_COMPILE -c --serialize-diagnostics test.dia error.c 2>test.stderr
+ $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
printf '#include <wchar.h>\nwchar_t foo[] = L"\xbf";\n' >latin1.c
- CCACHE_CPP2=1 $CCACHE_COMPILE -c -finput-charset=latin1 latin1.c
+ $CCACHE_COMPILE -c -finput-charset=latin1 latin1.c
expect_stat 'cache hit (preprocessed)' 0
expect_stat 'cache miss' 1
- CCACHE_CPP2=1 $CCACHE_COMPILE -c -finput-charset=latin1 latin1.c
+ $CCACHE_COMPILE -c -finput-charset=latin1 latin1.c
expect_stat 'cache hit (preprocessed)' 1
expect_stat 'cache miss' 1
- $CCACHE_COMPILE -c -finput-charset=latin1 latin1.c
+ CCACHE_NOCPP2=1 $CCACHE_COMPILE -c -finput-charset=latin1 latin1.c
expect_stat 'cache hit (preprocessed)' 1
expect_stat 'cache miss' 2
- $CCACHE_COMPILE -c -finput-charset=latin1 latin1.c
+ CCACHE_NOCPP2=1 $CCACHE_COMPILE -c -finput-charset=latin1 latin1.c
expect_stat 'cache hit (preprocessed)' 2
expect_stat 'cache miss' 2
}
all_suites="
base
-cpp2
+nocpp2
multi_arch
serialize_diagnostics
debug_prefix_map
args_free(orig);
}
-TEST(preprocessor_only_flags_should_only_be_sent_to_the_preprocessor)
+TEST(cpp_only_flags_to_preprocessor_if_run_second_cpp_is_false)
{
#define CMD \
"cc -I. -idirafter . -iframework. -imacros . -imultilib ." \
struct args *act_cpp = NULL, *act_cc = NULL;
create_file("foo.c", "");
+ conf->run_second_cpp = false;
+ CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+ CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
+ CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
+
+ args_free(orig);
+}
+
+TEST(cpp_only_flags_to_preprocessor_and_compiler_if_run_second_cpp_is_true)
+{
+#define CMD \
+ "cc -I. -idirafter . -iframework. -imacros . -imultilib ." \
+ " -include test.h -include-pch test.pch -iprefix . -iquote ." \
+ " -isysroot . -isystem . -iwithprefix . -iwithprefixbefore ." \
+ " -DTEST_MACRO -DTEST_MACRO2=1 -F. -trigraphs -fworking-directory" \
+ " -fno-working-directory"
+#define DEP_OPTS \
+ " -MD -MMD -MP -MF foo.d -MT mt1 -MT mt2 " \
+ " -MQ mq1 -MQ mq2 -Wp,-MD,wpmd -Wp,-MMD,wpmmd"
+ struct args *orig = args_init_from_string(CMD DEP_OPTS " -c foo.c -o foo.o");
+ struct args *exp_cpp = args_init_from_string(CMD DEP_OPTS);
+ struct args *exp_cc = args_init_from_string(CMD " -c");
+#undef CMD
+ struct args *act_cpp = NULL, *act_cc = NULL;
+ create_file("foo.c", "");
+
+ conf->run_second_cpp = true;
CHECK(cc_process_args(orig, &act_cpp, &act_cc));
CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
CHECK(!conf->read_only);
CHECK(!conf->read_only_direct);
CHECK(!conf->recache);
- CHECK(!conf->run_second_cpp);
+ CHECK(conf->run_second_cpp);
CHECK_INT_EQ(0, conf->sloppiness);
CHECK(conf->stats);
CHECK_STR_EQ("", conf->temporary_dir);
"read_only = true\n"
"read_only_direct = true\n"
"recache = true\n"
- "run_second_cpp = true\n"
+ "run_second_cpp = false\n"
"sloppiness = file_macro ,time_macros, include_file_mtime,include_file_ctime,file_stat_matches,pch_defines , no_system_headers \n"
"stats = false\n"
"temporary_dir = ${USER}_foo\n"
CHECK(conf->read_only);
CHECK(conf->read_only_direct);
CHECK(conf->recache);
- CHECK(conf->run_second_cpp);
+ CHECK(!conf->run_second_cpp);
CHECK_INT_EQ(SLOPPY_INCLUDE_FILE_MTIME|SLOPPY_INCLUDE_FILE_CTIME|
SLOPPY_FILE_MACRO|SLOPPY_TIME_MACROS|
SLOPPY_FILE_STAT_MATCHES|SLOPPY_NO_SYSTEM_HEADERS|
true,
true,
true,
- true,
+ .run_second_cpp = false,
SLOPPY_FILE_MACRO|SLOPPY_INCLUDE_FILE_MTIME|
SLOPPY_INCLUDE_FILE_CTIME|SLOPPY_TIME_MACROS|
SLOPPY_FILE_STAT_MATCHES|SLOPPY_PCH_DEFINES|
CHECK_STR_EQ("read_only = true", received_conf_items[n++].descr);
CHECK_STR_EQ("read_only_direct = true", received_conf_items[n++].descr);
CHECK_STR_EQ("recache = true", received_conf_items[n++].descr);
- CHECK_STR_EQ("run_second_cpp = true", received_conf_items[n++].descr);
+ CHECK_STR_EQ("run_second_cpp = false", received_conf_items[n++].descr);
CHECK_STR_EQ("sloppiness = file_macro, include_file_mtime,"
" include_file_ctime, time_macros, pch_defines,"
" file_stat_matches, no_system_headers",