From: Alexander Lanin Date: Mon, 16 Nov 2020 17:45:44 +0000 (+0100) Subject: Cache -fsyntax-only result (#685) X-Git-Tag: v4.1~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f258b70e5ae3be5789ff07f6281bbfcfeb9bf37c;p=thirdparty%2Fccache.git Cache -fsyntax-only result (#685) --- diff --git a/src/ArgsInfo.hpp b/src/ArgsInfo.hpp index e79b1c9eb..4d9eaf394 100644 --- a/src/ArgsInfo.hpp +++ b/src/ArgsInfo.hpp @@ -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; diff --git a/src/argprocessing.cpp b/src/argprocessing.cpp index 13bc89821..1783f9f03 100644 --- a/src/argprocessing.cpp +++ b/src/argprocessing.cpp @@ -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; diff --git a/src/ccache.cpp b/src/ccache.cpp index 3fd449a86..3e383de3a 100644 --- a/src/ccache.cpp +++ b/src/ccache.cpp @@ -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); } diff --git a/test/suites/base.bash b/test/suites/base.bash index b41138f7f..75e2768f9 100644 --- a/test/suites/base.bash +++ b/test/suites/base.bash @@ -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" diff --git a/unittest/test_argprocessing.cpp b/unittest/test_argprocessing.cpp index 4f973a1cd..7e2cbca17 100644 --- a/unittest/test_argprocessing.cpp +++ b/unittest/test_argprocessing.cpp @@ -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;