]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Let run_second_cpp default to true
authorJoel Rosdahl <joel@rosdahl.net>
Wed, 27 Jul 2016 18:49:00 +0000 (20:49 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Wed, 27 Jul 2016 20:13:24 +0000 (22:13 +0200)
ccache has since day 1 (OK, actually day 13: 5f6f5010) relied on the
fact that GCC and similar enough compilers are able to compile their own
preprocessed output with the same outcome as if they compiled the real
source code directly.

However, newer versions of GCC no longer quite work this way since they
perform an increasing amount of diagnostics analysis only if the source
code is compiled directly. The same goes for Clang. It's impossible for
ccache to work around this changed behavior in a good way.

Closes #116.

MANUAL.txt
NEWS.txt
ccache.c
conf.c
test.sh
test/test_argument_processing.c
test/test_conf.c

index a2108b0e79d8fae78b814d50bd739664ee3bce87..0fe67e502b73cae5d18ff712b1861f249ef30aea 100644 (file)
@@ -447,12 +447,17 @@ WRAPPERS>>.
 
 *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*)::
 
@@ -885,15 +890,6 @@ problems and what may be done to increase the hit rate:
   <<_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
 ~~~~~~~~~~~~~~~~~~~~
 
index d7930c89e0c9df1304832c5108e3e06c19a11bc2..4b16b7accbbe4f0d87456db15cb6ca2e0135366c 100644 (file)
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -14,6 +14,11 @@ Notes
 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
index 2cb95bb65da79059d7469962fe9be772092a737e..263c077b825ecda984a6f5dc57113f243e008cd2 100644 (file)
--- a/ccache.c
+++ b/ccache.c
@@ -2676,7 +2676,7 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                        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;
                }
@@ -2762,7 +2762,7 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
 
        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;
diff --git a/conf.c b/conf.c
index 6b80e37ed5c9aa80eb2d0fccd85be0409b9c05be..f72bca12d1b0849f7fd2b040c43eb5fec8fc23b8 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -318,7 +318,7 @@ conf_create(void)
        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("");
diff --git a/test.sh b/test.sh
index df9170b75e88dbc4fa204907b2bdea565c91157d..d1f071a04dc084294fef27108057a2c5a14a78cd 100755 (executable)
--- a/test.sh
+++ b/test.sh
@@ -176,9 +176,9 @@ TEST() {
 
     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
@@ -189,6 +189,7 @@ TEST() {
     unset CCACHE_IGNOREHEADERS
     unset CCACHE_LOGFILE
     unset CCACHE_NLEVELS
+    unset CCACHE_NOCPP2
     unset CCACHE_NOSTATS
     unset CCACHE_PATH
     unset CCACHE_PREFIX
@@ -387,20 +388,6 @@ base_tests() {
     $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"
 
@@ -1097,12 +1084,12 @@ SUITE_base() {
 
 # =============================================================================
 
-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
 }
 
@@ -1150,8 +1137,7 @@ SUITE_serialize_diagnostics() {
 
     $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
@@ -1159,7 +1145,7 @@ SUITE_serialize_diagnostics() {
 
     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
@@ -1173,7 +1159,7 @@ SUITE_serialize_diagnostics() {
         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
@@ -3182,19 +3168,19 @@ SUITE_input_charset() {
 
     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
 }
@@ -3307,7 +3293,7 @@ cd $TESTDIR || exit 1
 
 all_suites="
 base
-cpp2
+nocpp2
 multi_arch
 serialize_diagnostics
 debug_prefix_map
index 5fb244a3311d9e2422824d427160fc2e556c4977..7dba4934e6ce9a6aa2ed3dd877c59049ac0983b7 100644 (file)
@@ -105,7 +105,7 @@ TEST(dependency_flags_should_only_be_sent_to_the_preprocessor)
        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 ." \
@@ -121,6 +121,33 @@ TEST(preprocessor_only_flags_should_only_be_sent_to_the_preprocessor)
        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);
index 90f99fd9346847187b9e9edae840ab728a314744..ea809ac0a3f4f6e01072a854a84097f856d94070 100644 (file)
@@ -73,7 +73,7 @@ TEST(conf_create)
        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);
@@ -123,7 +123,7 @@ TEST(conf_read_valid_config)
          "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"
@@ -160,7 +160,7 @@ TEST(conf_read_valid_config)
        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|
@@ -385,7 +385,7 @@ TEST(conf_print_items)
                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|
@@ -434,7 +434,7 @@ TEST(conf_print_items)
        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",