]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Cache -fsyntax-only result (#685)
authorAlexander Lanin <alex@lanin.de>
Mon, 16 Nov 2020 17:45:44 +0000 (18:45 +0100)
committerGitHub <noreply@github.com>
Mon, 16 Nov 2020 17:45:44 +0000 (18:45 +0100)
src/ArgsInfo.hpp
src/argprocessing.cpp
src/ccache.cpp
test/suites/base.bash
unittest/test_argprocessing.cpp

index e79b1c9eb911558f59fbe7b6918cb7f5c34271e5..4d9eaf3942fff7bbc65027d9d9f62de47311b9d3 100644 (file)
@@ -31,6 +31,11 @@ struct ArgsInfo
   // The source file.
   std::string input_file;
 
+  // In normal compiler operation an output file is created if there is no
+  // compiler error. However certain flags like -fsyntax-only change this
+  // behavior.
+  bool expect_output_obj = true;
+
   // The output file being compiled to.
   std::string output_obj;
 
index 13bc89821bb54e165b3e28254f01762d62e34502..1783f9f0323cc6ee352abff3a0011b2df657dd0c 100644 (file)
@@ -553,6 +553,12 @@ process_arg(Context& ctx,
     return nullopt;
   }
 
+  if (args[i] == "-fsyntax-only") {
+    args_info.expect_output_obj = false;
+    state.compiler_only_args.push_back(args[i]);
+    return nullopt;
+  }
+
   if (args[i] == "--coverage"      // = -fprofile-arcs -ftest-coverage
       || args[i] == "-coverage") { // Undocumented but still works.
     args_info.profile_arcs = true;
index 3fd449a863097e3b7a62172cea0377c08aa4d890..3e383de3a9785779ccedf0828b5d2da7de1b4420 100644 (file)
@@ -1055,10 +1055,13 @@ to_cache(Context& ctx,
 
   const auto obj_stat = Stat::stat(ctx.args_info.output_obj);
   if (!obj_stat) {
-    LOG_RAW("Compiler didn't produce an object file");
-    throw Failure(Statistic::compiler_produced_no_output);
-  }
-  if (obj_stat.size() == 0) {
+    if (ctx.args_info.expect_output_obj) {
+      LOG_RAW("Compiler didn't produce an object file (unexpected)");
+      throw Failure(Statistic::compiler_produced_no_output);
+    } else {
+      LOG_RAW("Compiler didn't produce an object file (expected)");
+    }
+  } else if (obj_stat.size() == 0) {
     LOG_RAW("Compiler produced an empty object file");
     throw Failure(Statistic::compiler_produced_empty_output);
   }
@@ -1076,7 +1079,9 @@ to_cache(Context& ctx,
   if (stderr_stat.size() > 0) {
     result_writer.write(Result::FileType::stderr_output, tmp_stderr_path);
   }
-  result_writer.write(Result::FileType::object, ctx.args_info.output_obj);
+  if (obj_stat) {
+    result_writer.write(Result::FileType::object, ctx.args_info.output_obj);
+  }
   if (ctx.args_info.generating_dependencies) {
     result_writer.write(Result::FileType::dependency, ctx.args_info.output_dep);
   }
index b41138f7f7a438407038a3f73212a495474efbb0..75e2768f9b8130a9fca267a0af18b405de556acf 100644 (file)
@@ -1030,7 +1030,7 @@ EOF
     umask $saved_umask
 
     # -------------------------------------------------------------------------
-    TEST "No object file"
+    TEST "No object file due to bad prefix"
 
     cat <<'EOF' >test_no_obj.c
 int test_no_obj;
@@ -1043,6 +1043,33 @@ EOF
     CCACHE_PREFIX=$(pwd)/no-object-prefix $CCACHE_COMPILE -c test_no_obj.c
     expect_stat 'compiler produced no output' 1
 
+    CCACHE_PREFIX=$(pwd)/no-object-prefix $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 0
+    expect_stat 'files in cache' 0
+    expect_stat 'compiler produced no output' 2
+
+    # -------------------------------------------------------------------------
+    TEST "No object file due to -fsyntax-only"
+
+    echo '#warning This triggers a compiler warning' >stderr.c
+
+    $REAL_COMPILER -Wall -c stderr.c -fsyntax-only 2>reference_stderr.txt
+
+    expect_contains reference_stderr.txt "This triggers a compiler warning"
+
+    $CCACHE_COMPILE -Wall -c stderr.c -fsyntax-only 2>stderr.txt
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_text_content reference_stderr.txt stderr.txt
+
+    $CCACHE_COMPILE -Wall -c stderr.c -fsyntax-only 2>stderr.txt
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_text_content reference_stderr.txt stderr.txt
+
     # -------------------------------------------------------------------------
     TEST "Empty object file"
 
index 4f973a1cde9adc1f5c7e30f30c27373ea8a90369..7e2cbca17fa934d0e94294c8f16e33864870b907 100644 (file)
@@ -70,6 +70,22 @@ get_posix_path(const std::string& path)
 
 TEST_SUITE_BEGIN("argprocessing");
 
+TEST_CASE("pass -fsyntax-only to compiler only")
+{
+  TestContext test_context;
+  Context ctx;
+
+  ctx.orig_args = Args::from_string("cc -c foo.c -fsyntax-only");
+  Util::write_file("foo.c", "");
+
+  const ProcessArgsResult result = process_args(ctx);
+
+  CHECK(!result.error);
+  CHECK(result.preprocessor_args.to_string() == "cc");
+  CHECK(result.extra_args_to_hash.to_string() == "-fsyntax-only");
+  CHECK(result.compiler_args.to_string() == "cc -fsyntax-only -c");
+}
+
 TEST_CASE("dash_E_should_result_in_called_for_preprocessing")
 {
   TestContext test_context;