]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
fix: Handle -MD/-MMD when compiling assembler file
authorJoel Rosdahl <joel@rosdahl.net>
Wed, 19 Oct 2022 20:13:21 +0000 (22:13 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Wed, 19 Oct 2022 20:27:34 +0000 (22:27 +0200)
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.

doc/MANUAL.adoc
src/argprocessing.cpp
src/ccache.cpp
src/core/Result.cpp
src/core/Result.hpp
src/core/Statistics.cpp
test/suites/direct.bash

index 33165bea43a9a9aae3bafb8a9b02b3b6c6e29842..e2453a70fbae1920b8b105c2a3c6c1eaef45d19b 100644 (file)
@@ -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 |
index d71425fb5b31a24d5ca138698bdb40e44ecd971d..b095b7a71d118084f224893b468c2d3941578acf 100644 (file)
@@ -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")) {
index 861bc5b1ef71fcd18f0f0bf897661895466fc6db..e701e204a29c49dd3253bd61e366078b86cb2f35 100644 (file)
@@ -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.
index 079923eba0204c46cb32292a1285f5f9f1fa41a0..c1f84c64be5cbe91b591acf6202fedc96d412d4d 100644 (file)
@@ -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
index 92301e16ccfc53b9d3fb8354eeb38492ecab1327..3080f71956d9e8ea5ca0212adec39a25907a7170 100644 (file)
@@ -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;
index 4952ce2085460898b76bca3060cb480ccbd47be9..662b59ba37a34431996865ec0ccd00120f0d2a88 100644 (file)
@@ -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),
index 67334eef0346d23c8f1d943f59ce186c6abc6413..0f4d053069a053c774af54e2e8d2674a19661df5 100644 (file)
@@ -498,6 +498,39 @@ fi
     expect_equal_content test.d expected.d
     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"