]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
feat: Add support for caching assembler listing files
authorJoel Rosdahl <joel@rosdahl.net>
Sun, 28 Aug 2022 08:06:22 +0000 (10:06 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Sun, 28 Aug 2022 09:01:55 +0000 (11:01 +0200)
Closes #1090.

src/ArgsInfo.hpp
src/Result.cpp
src/Result.hpp
src/ResultRetriever.cpp
src/argprocessing.cpp
src/ccache.cpp
test/suites/base.bash

index 94a7fe428ebc86eb6a401ddffc7cf6da774acf16..793eb3dc00240f3a829bf8c45370f878fdf24807 100644 (file)
@@ -60,6 +60,9 @@ struct ArgsInfo
   // Split dwarf information (GCC 4.8 and up). Contains pathname if not empty.
   std::string output_dwo;
 
+  // Assembler listing file.
+  std::string output_al;
+
   // The .gch/.pch/.pth file used for compilation.
   std::string included_pch_file;
 
index 5ad57f2c6981a72c36f1697ef6dd65201877b571..7eb7777d5e8de24a904c95da70a5e82193b1edc2 100644 (file)
@@ -161,6 +161,9 @@ file_type_to_string(FileType type)
 
   case FileType::stdout_output:
     return "<stdout>";
+
+  case FileType::assembler_listing:
+    return ".al";
   }
 
   return k_unknown_file_type;
index 65aec25ab5894dd2dac64568dace10978abb6ed0..6e537a8c1f4cbf9b4fbdf0e2c495f11fc06da2a8 100644 (file)
@@ -82,6 +82,9 @@ enum class FileType : UnderlyingFileTypeInt {
 
   // Text sent to standard output.
   stdout_output = 8,
+
+  // Assembler listing file from -Wa,-a=file.
+  assembler_listing = 9,
 };
 
 const char* file_type_to_string(FileType type);
index a7edbc1848b7b0973934bd22e12549815c8ec5ac..bc456bfb4ce6f8975108445c12538c8f0cfc6696 100644 (file)
@@ -107,6 +107,10 @@ ResultRetriever::on_entry_start(uint8_t entry_number,
       dest_path = Result::gcno_file_in_mangled_form(m_ctx);
     }
     break;
+
+  case FileType::assembler_listing:
+    dest_path = m_ctx.args_info.output_al;
+    break;
   }
 
   if (file_type == FileType::stdout_output
index ca8d379d4004d64698c2548302eb080519dd1bef..dfe4e90f82fd461d0ced98f4e5676206f966001e 100644 (file)
@@ -69,6 +69,7 @@ struct ArgumentProcessingState
   bool found_mf_opt = false;
   bool found_wp_md_or_mmd_opt = false;
   bool found_md_or_mmd_opt = false;
+  bool found_opt_Wa_a = false;
 
   std::string explicit_language;    // As specified with -x.
   std::string input_charset_option; // -finput-charset=...
@@ -416,11 +417,22 @@ process_option_arg(const Context& ctx,
     ++i;
   }
 
-  if (util::starts_with(args[i], "-Wa,")
-      && args[i].find('=') != std::string::npos) {
-    LOG("Assembler listing file (-Wa,...=file) is currently not supported: {}",
-        args[i]);
-    return Statistic::unsupported_compiler_option;
+  if (util::starts_with(args[i], "-Wa,")) {
+    for (const auto part : util::Tokenizer(&args[i][4], ",")) {
+      if (util::starts_with(part, "-a")) {
+        if (state.found_opt_Wa_a) {
+          LOG_RAW(
+            "Multiple assembler listing options (-Wa,-a) are not supported");
+          return Statistic::unsupported_compiler_option;
+        }
+        state.found_opt_Wa_a = true;
+
+        const auto eq_pos = part.find('=');
+        if (eq_pos != std::string_view::npos) {
+          args_info.output_al = part.substr(eq_pos + 1);
+        }
+      }
+    }
   }
 
   // Handle options that should not be passed to the preprocessor.
index 4f2ae2a347a834b4934ce3aa7f4b7befaa950255..95bded45a3b30161ca860525024c66b153f5e09f 100644 (file)
@@ -922,6 +922,10 @@ write_result(Context& ctx,
     result_writer.write_file(Result::FileType::dwarf_object,
                              ctx.args_info.output_dwo);
   }
+  if (!ctx.args_info.output_al.empty()) {
+    result_writer.write_file(Result::FileType::assembler_listing,
+                             ctx.args_info.output_al);
+  }
 
   const auto file_size_and_count_diff = result_writer.finalize();
   if (file_size_and_count_diff) {
@@ -1581,6 +1585,41 @@ calculate_result_and_manifest_key(Context& ctx,
       continue;
     }
 
+    if (util::starts_with(args[i], "-Wa,")) {
+      // We have to distinguish between three cases:
+      //
+      // Case 1: -Wa,-a      (write to stdout)
+      // Case 2: -Wa,-a=     (write to stdout and stderr)
+      // Case 3: -Wa,-a=file (write to file)
+      //
+      // No need to include the file part in case 3 since the filename is not
+      // part of the output.
+
+      using util::Tokenizer;
+      hash.hash_delimiter("arg");
+      bool first = true;
+      for (const auto part :
+           Tokenizer(args[i], ",", Tokenizer::Mode::include_empty)) {
+        if (first) {
+          first = false;
+        } else {
+          hash.hash(",");
+        }
+        if (util::starts_with(part, "-a")) {
+          const auto eq_pos = part.find('=');
+          if (eq_pos < part.size() - 1) {
+            // Case 3:
+            hash.hash(part.substr(0, eq_pos + 1));
+            hash.hash("file");
+            continue;
+          }
+        }
+        // Case 1 and 2:
+        hash.hash(part);
+      }
+      continue;
+    }
+
     // The -fdebug-prefix-map option may be used in combination with
     // CCACHE_BASEDIR to reuse results across different directories. Skip using
     // the value of the option from hashing but still hash the existence of the
index 9b53237eb90764d279f2d1c39a424d04b73813aa..0314ee48906166b92e9aa4ea88fbe9e8c0f92a87 100644 (file)
@@ -1371,13 +1371,59 @@ EOF
     fi
 
     # -------------------------------------------------------------------------
-    if $COMPILER -c -Wa,-a=test1.lst test1.c >&/dev/null; then
+    if $COMPILER -c -Wa,-a=test1.lst,-L test1.c >&/dev/null && [ -e test1.lst ]; then
         TEST "-Wa,-a=file"
 
-        $CCACHE_COMPILE -c -Wa,-a=test1.lst test1.c
+        # Check that -Wa options after -a are handled.
+
+        $CCACHE_COMPILE -c -Wa,-a=test1.lst,-L test1.c
         expect_stat preprocessed_cache_hit 0
-        expect_stat cache_miss 0
+        expect_stat cache_miss 1
+        rm test1.lst
+
+        $CCACHE_COMPILE -c -Wa,-a=test1.lst,-L test1.c
+        expect_stat preprocessed_cache_hit 1
+        expect_stat cache_miss 1
+        rm test1.lst
+
+        # Check that the filename can be changed without changing the hash.
+
+        $CCACHE_COMPILE -c -Wa,-a=test2.lst,-L test1.c
+        expect_stat preprocessed_cache_hit 2
+        expect_stat cache_miss 1
+        rm test2.lst
+
+        # Check that -Wa options before -a are handled.
+
+        $CCACHE_COMPILE -c -Wa,-L,-a=test1.lst test1.c
+        expect_stat preprocessed_cache_hit 2
+        expect_stat cache_miss 2
+        rm test1.lst
+
+        $CCACHE_COMPILE -c -Wa,-L,-a=test1.lst test1.c
+        expect_stat preprocessed_cache_hit 3
+        expect_stat cache_miss 2
+        rm test1.lst
+
+        # Check that -Wa,-aOPTIONS=file is different than -Wa,-a=file.
+
+        $CCACHE_COMPILE -c -Wa,-as=test1.lst test1.c
+        expect_stat preprocessed_cache_hit 3
+        expect_stat cache_miss 3
+        rm test1.lst
+
+        $CCACHE_COMPILE -c -Wa,-as=test1.lst test1.c
+        expect_stat preprocessed_cache_hit 4
+        expect_stat cache_miss 3
+        rm test1.lst
+
+        # Multiple -Wa,-a options are not supported.
+
+        $CCACHE_COMPILE -c -Wa,-a=test1.lst -Wa,-as=test1.lst test1.c
+        expect_stat preprocessed_cache_hit 4
+        expect_stat cache_miss 3
         expect_stat unsupported_compiler_option 1
+        rm test1.lst
     fi
 
     # -------------------------------------------------------------------------