diff options
author | Joel Rosdahl <joel@rosdahl.net> | 2022-10-19 22:13:21 +0200 |
---|---|---|
committer | Joel Rosdahl <joel@rosdahl.net> | 2022-10-19 22:27:34 +0200 |
commit | b53afeb556d55576ed3683fef6566361464393d5 (patch) | |
tree | b2fd2c70426ed52050b9fef1cac2d653c558ee9f | |
parent | 567a1f3c940c881b0718d4b06a04bc2f7f6b5246 (diff) | |
download | ccache-b53afeb556d55576ed3683fef6566361464393d5.tar.gz |
fix: Handle -MD/-MMD when compiling assembler file
When compiling an assembler file, -MD and -MMD don't produce any
dependency file, so don't expect one.
Also, make sure to fall back to running the real compiler in case an
expected output file is missing instead of exiting with an error.
Fixes #1189.
-rw-r--r-- | doc/MANUAL.adoc | 8 | ||||
-rw-r--r-- | src/argprocessing.cpp | 5 | ||||
-rw-r--r-- | src/ccache.cpp | 73 | ||||
-rw-r--r-- | src/core/Result.cpp | 9 | ||||
-rw-r--r-- | src/core/Result.hpp | 2 | ||||
-rw-r--r-- | src/core/Statistics.cpp | 6 | ||||
-rw-r--r-- | test/suites/direct.bash | 33 |
7 files changed, 99 insertions, 37 deletions
diff --git a/doc/MANUAL.adoc b/doc/MANUAL.adoc index 33165bea..e2453a70 100644 --- a/doc/MANUAL.adoc +++ b/doc/MANUAL.adoc @@ -1395,12 +1395,12 @@ The compilation failed. No result stored in the cache. A compiler check program specified by <<config_compiler_check,*compiler_check*>> (*CCACHE_COMPILERCHECK*) failed. -| Compiler produced empty output | -The compiler's output file (typically an object file) was empty after +| Compiler output file missing | +One of the files expected to be produced by the compiler was missing after compilation. -| Compiler produced no output | -The compiler's output file (typically an object file) was missing after +| Compiler produced empty output | +The compiler's output file (typically an object file) was empty after compilation. | Could not find the compiler | diff --git a/src/argprocessing.cpp b/src/argprocessing.cpp index d71425fb..b095b7a7 100644 --- a/src/argprocessing.cpp +++ b/src/argprocessing.cpp @@ -1293,6 +1293,11 @@ process_args(Context& ctx) return Statistic::unsupported_source_language; } + if (args_info.actual_language == "assembler") { + // -MD/-MMD for assembler file does not produce a dependency file. + args_info.generating_dependencies = false; + } + if (!config.run_second_cpp() && (args_info.actual_language == "cu" || args_info.actual_language == "cuda")) { diff --git a/src/ccache.cpp b/src/ccache.cpp index 861bc5b1..e701e204 100644 --- a/src/ccache.cpp +++ b/src/ccache.cpp @@ -874,7 +874,7 @@ find_coverage_file(const Context& ctx) return {true, found_file, found_file == mangled_form}; } -static bool +[[nodiscard]] static bool write_result(Context& ctx, const Digest& result_key, const Stat& obj_stat, @@ -891,41 +891,58 @@ write_result(Context& ctx, if (!stdout_data.empty()) { serializer.add_data(core::Result::FileType::stdout_output, stdout_data); } - if (obj_stat) { - serializer.add_file(core::Result::FileType::object, - ctx.args_info.output_obj); + if (obj_stat + && !serializer.add_file(core::Result::FileType::object, + ctx.args_info.output_obj)) { + LOG("Object file {} missing", ctx.args_info.output_obj); + return false; } - if (ctx.args_info.generating_dependencies) { - serializer.add_file(core::Result::FileType::dependency, - ctx.args_info.output_dep); + if (ctx.args_info.generating_dependencies + && !serializer.add_file(core::Result::FileType::dependency, + ctx.args_info.output_dep)) { + LOG("Dependency file {} missing", ctx.args_info.output_dep); + return false; } if (ctx.args_info.generating_coverage) { const auto coverage_file = find_coverage_file(ctx); if (!coverage_file.found) { + LOG_RAW("Coverage file not found"); + return false; + } + if (!serializer.add_file(coverage_file.mangled + ? core::Result::FileType::coverage_mangled + : core::Result::FileType::coverage_unmangled, + coverage_file.path)) { + LOG("Coverage file {} missing", coverage_file.path); return false; } - serializer.add_file(coverage_file.mangled - ? core::Result::FileType::coverage_mangled - : core::Result::FileType::coverage_unmangled, - coverage_file.path); } - if (ctx.args_info.generating_stackusage) { - serializer.add_file(core::Result::FileType::stackusage, - ctx.args_info.output_su); + if (ctx.args_info.generating_stackusage + && !serializer.add_file(core::Result::FileType::stackusage, + ctx.args_info.output_su)) { + LOG("Stack usage file {} missing", ctx.args_info.output_su); + return false; } - if (ctx.args_info.generating_diagnostics) { - serializer.add_file(core::Result::FileType::diagnostic, - ctx.args_info.output_dia); + if (ctx.args_info.generating_diagnostics + && !serializer.add_file(core::Result::FileType::diagnostic, + ctx.args_info.output_dia)) { + LOG("Diagnostics file {} missing", ctx.args_info.output_dia); + return false; } - if (ctx.args_info.seen_split_dwarf && Stat::stat(ctx.args_info.output_dwo)) { - // Only store .dwo file if it was created by the compiler (GCC and Clang - // behave differently e.g. for "-gsplit-dwarf -g1"). - serializer.add_file(core::Result::FileType::dwarf_object, - ctx.args_info.output_dwo); + if (ctx.args_info.seen_split_dwarf + // Only store .dwo file if it was created by the compiler (GCC and Clang + // behave differently e.g. for "-gsplit-dwarf -g1"). + && Stat::stat(ctx.args_info.output_dwo) + && !serializer.add_file(core::Result::FileType::dwarf_object, + ctx.args_info.output_dwo)) { + LOG("Split dwarf file {} missing", ctx.args_info.output_dwo); + return false; } - if (!ctx.args_info.output_al.empty()) { - serializer.add_file(core::Result::FileType::assembler_listing, - ctx.args_info.output_al); + if (!ctx.args_info.output_al.empty() + && !serializer.add_file(core::Result::FileType::assembler_listing, + ctx.args_info.output_al)) { + LOG("Assembler listing file {} missing", ctx.args_info.output_al); + return false; } core::CacheEntry::Header header(ctx.config, core::CacheEntryType::result); @@ -1130,8 +1147,10 @@ to_cache(Context& ctx, } MTR_BEGIN("result", "result_put"); - write_result( - ctx, *result_key, obj_stat, result->stdout_data, result->stderr_data); + if (!write_result( + ctx, *result_key, obj_stat, result->stdout_data, result->stderr_data)) { + return nonstd::make_unexpected(Statistic::compiler_produced_no_output); + } MTR_END("result", "result_put"); // Everything OK. diff --git a/src/core/Result.cpp b/src/core/Result.cpp index 079923eb..c1f84c64 100644 --- a/src/core/Result.cpp +++ b/src/core/Result.cpp @@ -242,14 +242,19 @@ Serializer::add_data(const FileType file_type, nonstd::span<const uint8_t> data) m_file_entries.push_back(FileEntry{file_type, data}); } -void +bool Serializer::add_file(const FileType file_type, const std::string& path) { m_serialized_size += 1 + 1 + 8; // marker + file_type + file_size if (!should_store_raw_file(m_config, file_type)) { - m_serialized_size += Stat::stat(path, Stat::OnError::throw_error).size(); + auto st = Stat::stat(path); + if (!st) { + return false; + } + m_serialized_size += st.size(); } m_file_entries.push_back(FileEntry{file_type, path}); + return true; } uint32_t diff --git a/src/core/Result.hpp b/src/core/Result.hpp index 92301e16..3080f719 100644 --- a/src/core/Result.hpp +++ b/src/core/Result.hpp @@ -142,7 +142,7 @@ public: void add_data(FileType file_type, nonstd::span<const uint8_t> data); // Register a file path whose content should be included in the result. - void add_file(FileType file_type, const std::string& path); + [[nodiscard]] bool add_file(FileType file_type, const std::string& path); // core::Serializer uint32_t serialized_size() const override; diff --git a/src/core/Statistics.cpp b/src/core/Statistics.cpp index 4952ce20..662b59ba 100644 --- a/src/core/Statistics.cpp +++ b/src/core/Statistics.cpp @@ -76,12 +76,12 @@ const StatisticsField k_statistics_fields[] = { FIELD(cleanups_performed, nullptr), FIELD(compile_failed, "Compilation failed", FLAG_UNCACHEABLE), FIELD(compiler_check_failed, "Compiler check failed", FLAG_ERROR), + FIELD(compiler_produced_no_output, + "Compiler output file missing", + FLAG_UNCACHEABLE), FIELD(compiler_produced_empty_output, "Compiler produced empty output", FLAG_UNCACHEABLE), - FIELD(compiler_produced_no_output, - "Compiler produced no output", - FLAG_UNCACHEABLE), FIELD(compiler_produced_stdout, "Compiler produced stdout", FLAG_UNCACHEABLE), FIELD(could_not_find_compiler, "Could not find compiler", FLAG_ERROR), FIELD(could_not_use_modules, "Could not use modules", FLAG_UNCACHEABLE), diff --git a/test/suites/direct.bash b/test/suites/direct.bash index 67334eef..0f4d0530 100644 --- a/test/suites/direct.bash +++ b/test/suites/direct.bash @@ -499,6 +499,39 @@ fi expect_equal_object_files reference_test.o test.o # ------------------------------------------------------------------------- + TEST "-MD for assembler file with missing dependency file" + + $COMPILER -S test.c + + $CCACHE_COMPILE -c -MD test.s + expect_stat direct_cache_hit 0 + expect_stat preprocessed_cache_hit 0 + expect_stat cache_miss 1 + + $CCACHE_COMPILE -c -MD test.s + expect_stat direct_cache_hit 1 + expect_stat preprocessed_cache_hit 0 + expect_stat cache_miss 1 + + # ------------------------------------------------------------------------- + TEST "-MD for assembler file with existing dependency file" + + $COMPILER -S test.c + echo foo >test.d + + $CCACHE_COMPILE -c -MD test.s + expect_stat direct_cache_hit 0 + expect_stat preprocessed_cache_hit 0 + expect_stat cache_miss 1 + rm test.d + + $CCACHE_COMPILE -c -MD test.s + expect_stat direct_cache_hit 1 + expect_stat preprocessed_cache_hit 0 + expect_stat cache_miss 1 + expect_missing test.d + + # ------------------------------------------------------------------------- TEST "-ftest-coverage" cat <<EOF >code.c |