]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
feat: Support multiple -Xarch_* arguments matching -arch (#1131)
authorTadej Novak <tadej@tano.si>
Wed, 12 Jul 2023 11:50:31 +0000 (13:50 +0200)
committerGitHub <noreply@github.com>
Wed, 12 Jul 2023 11:50:31 +0000 (13:50 +0200)
src/ArgsInfo.hpp
src/argprocessing.cpp
src/ccache.cpp
test/suites/multi_arch.bash

index b131f42d81dcecd4b52fafff3dbc47b074e60521..60cadce201aaae987cd93cb7547e54e2ca78c325 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <optional>
 #include <string>
+#include <unordered_map>
 #include <vector>
 
 // This class holds meta-information derived from the compiler arguments.
@@ -131,6 +132,9 @@ struct ArgsInfo
   // Architectures from -arch options.
   std::vector<std::string> arch_args;
 
+  // Values for -Xarch_* options.
+  std::unordered_map<std::string, std::vector<std::string>> xarch_args;
+
   // Relocating debuginfo in the format old=new.
   std::vector<std::string> debug_prefix_maps;
 
index 9acee120dedc8a2d3c253fbc6461c97b7a2145e4..63a432ca6bc17758a9e7bcf89fccf11887bf0095 100644 (file)
@@ -66,7 +66,7 @@ struct ArgumentProcessingState
   ColorDiagnostics color_diagnostics = ColorDiagnostics::automatic;
   bool found_directives_only = false;
   bool found_rewrite_includes = false;
-  std::optional<std::string> found_xarch_arch;
+  std::unordered_map<std::string, std::vector<std::string>> xarch_args;
   bool found_mf_opt = false;
   bool found_wp_md_or_mmd_opt = false;
   bool found_md_or_mmd_opt = false;
@@ -399,20 +399,17 @@ process_option_arg(const Context& ctx,
     config.set_direct_mode(false);
   }
 
-  // -Xarch_* options are too hard.
+  // -Xarch_* options need to be handled with care
   if (util::starts_with(arg, "-Xarch_")) {
     if (i == args.size() - 1) {
       LOG("Missing argument to {}", args[i]);
       return Statistic::bad_compiler_arguments;
     }
     const auto arch = arg.substr(7);
-    if (!state.found_xarch_arch) {
-      state.found_xarch_arch = arch;
-    } else if (*state.found_xarch_arch != arch) {
-      LOG_RAW("Multiple different -Xarch_* options not supported");
-      return Statistic::unsupported_compiler_option;
-    }
-    state.common_args.push_back(args[i]);
+    auto [it, inserted] =
+      state.xarch_args.emplace(arch, std::vector<std::string>());
+    it->second.emplace_back(args[i + 1]);
+    ++i;
     return Statistic::none;
   }
 
@@ -1513,20 +1510,28 @@ process_args(Context& ctx)
     compiler_args.push_back("-dc");
   }
 
-  if (state.found_xarch_arch && !args_info.arch_args.empty()) {
-    if (args_info.arch_args.size() > 1) {
-      LOG_RAW(
-        "Multiple -arch options in combination with -Xarch_* not supported");
-      return Statistic::unsupported_compiler_option;
-    } else if (args_info.arch_args[0] != *state.found_xarch_arch) {
-      LOG_RAW("-arch option not matching -Xarch_* option not supported");
-      return Statistic::unsupported_compiler_option;
+  if (!state.xarch_args.empty()) {
+    for (const auto& arch : args_info.arch_args) {
+      auto it = state.xarch_args.find(arch);
+      if (it != state.xarch_args.end()) {
+        args_info.xarch_args.emplace(arch, it->second);
+      }
     }
   }
 
   for (const auto& arch : args_info.arch_args) {
     compiler_args.push_back("-arch");
     compiler_args.push_back(arch);
+
+    auto it = args_info.xarch_args.find(arch);
+    if (it != args_info.xarch_args.end()) {
+      args_info.xarch_args.emplace(arch, it->second);
+
+      for (const auto& xarch : it->second) {
+        compiler_args.push_back("-Xarch_" + arch);
+        compiler_args.push_back(xarch);
+      }
+    }
   }
 
   Args preprocessor_args = state.common_args;
index 351007708130a0123ebd195d319c4efaa105c1cc..bc21ea18a7f67aea2524f348fcee6c14fe846309 100644 (file)
@@ -2012,6 +2012,15 @@ calculate_result_and_manifest_key(Context& ctx,
   for (const auto& arch : ctx.args_info.arch_args) {
     hash.hash_delimiter("-arch");
     hash.hash(arch);
+
+    // Adding -Xarch_* to hash since cpp output is affected.
+    auto it = ctx.args_info.xarch_args.find(arch);
+    if (it != ctx.args_info.xarch_args.end()) {
+      for (const auto& xarch : it->second) {
+        hash.hash_delimiter("-Xarch_" + arch);
+        hash.hash(xarch);
+      }
+    }
   }
 
   std::optional<Hash::Digest> result_key;
@@ -2037,19 +2046,31 @@ calculate_result_and_manifest_key(Context& ctx,
   } else {
     preprocessor_args->push_back("-arch");
     for (size_t i = 0; i < ctx.args_info.arch_args.size(); ++i) {
-      preprocessor_args->push_back(ctx.args_info.arch_args[i]);
+      const auto& arch = ctx.args_info.arch_args[i];
+      size_t xarch_count{};
+      preprocessor_args->push_back(arch);
+      auto it = ctx.args_info.xarch_args.find(arch);
+      if (it != ctx.args_info.xarch_args.end()) {
+        for (const auto& xarch : it->second) {
+          preprocessor_args->push_back("-Xarch_" + arch);
+          preprocessor_args->push_back(xarch);
+          xarch_count += 2;
+        }
+      }
       const auto digest =
         get_result_key_from_cpp(ctx, *preprocessor_args, hash);
       if (!digest) {
         return nonstd::make_unexpected(digest.error());
       }
       result_key = *digest;
-      LOG("Got result key from preprocessor with -arch {}",
-          ctx.args_info.arch_args[i]);
+      LOG("Got result key from preprocessor with -arch {}", arch);
       if (i != ctx.args_info.arch_args.size() - 1) {
         result_key = std::nullopt;
       }
       preprocessor_args->pop_back();
+      if (xarch_count > 0) {
+        preprocessor_args->pop_back(xarch_count);
+      }
     }
     preprocessor_args->pop_back();
   }
index 058bae2a70dae3851f86a015645040d454d70525..460ff16de7b58853da0847307bbbcd5490535e6a 100644 (file)
@@ -36,20 +36,43 @@ SUITE_multi_arch() {
     expect_stat direct_cache_hit 2
     expect_stat cache_miss 3
 
-    # A single -Xarch_* matching -arch is supported.
     CCACHE_DEBUG=1 $CCACHE_COMPILE -arch x86_64 -Xarch_x86_64 -I. -c test1.c
     expect_stat direct_cache_hit 2
     expect_stat cache_miss 4
-    expect_contains     test1.o.*.ccache-log "clang -Xarch_x86_64 -I. -arch x86_64 -E"
-    expect_not_contains test1.o.*.ccache-log "clang -Xarch_x86_64 -I. -I. -arch x86_64 -E"
+    expect_contains     test1.o.*.ccache-log "clang -arch x86_64 -Xarch_x86_64 -I. -E"
+    expect_not_contains test1.o.*.ccache-log "clang -arch x86_64 -Xarch_x86_64 -I. -I. -E"
 
     $CCACHE_COMPILE -arch x86_64 -Xarch_x86_64 -I. -c test1.c
     expect_stat direct_cache_hit 3
     expect_stat cache_miss 4
 
-    # The parameter following -Xarch should be processed.
-    $CCACHE_COMPILE -arch x86_64 -Xarch_x86_64 -analyze -I. -c test1.c
-    expect_stat unsupported_compiler_option 1
+    # -------------------------------------------------------------------------
+    TEST "cache hit, direct mode, multiple -Xarch_* arguments"
+
+    CCACHE_DEBUG=1 $CCACHE_COMPILE -arch x86_64 -arch arm64 -Xarch_x86_64 -I. -Xarch_arm64 -I. -c test1.c
+    expect_stat direct_cache_hit 0
+    expect_stat cache_miss 1
+    expect_contains     test1.o.*.ccache-log "clang -arch x86_64 -Xarch_x86_64 -I. -E"
+    expect_not_contains test1.o.*.ccache-log "clang -arch x86_64 -Xarch_x86_64 -I. -I. -E"
+    expect_contains     test1.o.*.ccache-log "clang -arch arm64 -Xarch_arm64 -I. -E"
+    expect_not_contains test1.o.*.ccache-log "clang -arch arm64 -Xarch_arm64 -I. -I. -E"
+
+    $CCACHE_COMPILE -arch x86_64 -arch arm64 -Xarch_x86_64 -I. -Xarch_arm64 -I. -c test1.c
+    expect_stat direct_cache_hit 1
+    expect_stat cache_miss 1
+
+    # -------------------------------------------------------------------------
+    TEST "cache hit, direct mode, multiple -Xarch_* arguments for single arch"
+
+    CCACHE_DEBUG=1 $CCACHE_COMPILE -arch x86_64 -Xarch_x86_64 -I. -Xarch_x86_64 -Ifoo -c test1.c
+    expect_stat direct_cache_hit 0
+    expect_stat cache_miss 1
+    expect_contains     test1.o.*.ccache-log "clang -arch x86_64 -Xarch_x86_64 -I. -Xarch_x86_64 -Ifoo -E"
+    expect_not_contains test1.o.*.ccache-log "clang -arch x86_64 -Xarch_x86_64 -I. -I. -Xarch_x86_64 -Ifoo -E"
+
+    $CCACHE_COMPILE -arch x86_64 -Xarch_x86_64 -I. -Xarch_x86_64 -Ifoo -c test1.c
+    expect_stat direct_cache_hit 1
+    expect_stat cache_miss 1
 
     # -------------------------------------------------------------------------
     TEST "cache hit, preprocessor mode"