]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
feat: Support -Wp,-M[M]D with -o without -MMD/-MQ/-MT for GCC and Clang
authorJoel Rosdahl <joel@rosdahl.net>
Thu, 3 Nov 2022 20:47:59 +0000 (21:47 +0100)
committerJoel Rosdahl <joel@rosdahl.net>
Thu, 3 Nov 2022 21:10:48 +0000 (22:10 +0100)
Closes #1203.

src/argprocessing.cpp
test/suites/direct.bash

index e26ca590df760b0bd421fda79c075938bb8d8407..0bc37e5754a8452595e758a8f0bddbf6d9e6a6af 100644 (file)
@@ -1153,16 +1153,6 @@ process_args(Context& ctx)
     LOG_RAW("-Wp,-M[M]D in combination with -MF is not supported");
     return Statistic::unsupported_compiler_option;
   }
-  if (state.found_wp_md_or_mmd_opt && !args_info.output_obj.empty()
-      && !state.found_md_or_mmd_opt && !args_info.dependency_target) {
-    // GCC and Clang behave differently when "-Wp,-M[M]D,wp.d" is used with "-o"
-    // but with neither "-MMD" nor "-MT"/"-MQ": GCC uses a dependency target
-    // based on the source filename but Clang bases it on the output filename.
-    // We could potentially support by behaving differently depending on the
-    // compiler type, but let's just bail out for now.
-    LOG_RAW("-Wp,-M[M]D with -o without -MMD, -MQ or -MT is not supported");
-    return Statistic::unsupported_compiler_option;
-  }
 
   // Don't try to second guess the compiler's heuristics for stdout handling.
   if (args_info.output_obj == "-") {
@@ -1402,8 +1392,33 @@ process_args(Context& ctx)
     }
 
     if (!args_info.dependency_target) {
-      args_info.dependency_target =
-        Depfile::escape_filename(args_info.orig_output_obj);
+      std::string dep_target = args_info.orig_output_obj;
+
+      // GCC and Clang behave differently when "-Wp,-M[M]D,wp.d" is used with
+      // "-o" but with neither "-MMD" nor "-MT"/"-MQ": GCC uses a dependency
+      // target based on the source filename but Clang bases it on the output
+      // filename.
+      if (state.found_wp_md_or_mmd_opt && !args_info.output_obj.empty()
+          && !state.found_md_or_mmd_opt) {
+        if (config.compiler_type() == CompilerType::clang) {
+          // Clang does the sane thing: the dependency target is the output file
+          // so that the dependency file actually makes sense.
+        } else if (config.compiler_type() == CompilerType::gcc) {
+          // GCC strangely uses the base name of the source file but with a .o
+          // extension.
+          dep_target = Util::change_extension(
+            Util::base_name(args_info.orig_input_file),
+            get_default_object_file_extension(ctx.config));
+        } else {
+          // How other compilers behave is currently unknown, so bail out.
+          LOG_RAW(
+            "-Wp,-M[M]D with -o without -MMD, -MQ or -MT is only supported for"
+            " GCC or Clang");
+          return Statistic::unsupported_compiler_option;
+        }
+      }
+
+      args_info.dependency_target = Depfile::escape_filename(dep_target);
     }
   }
 
index 560aac831ad9ec8e831b57abbfe8bbf8eb5602b8..8a227d0b6b5c104418a5d236987ffd9e0f4126ef 100644 (file)
@@ -261,12 +261,6 @@ fi
         done
     done
 
-    # -----------------------------------------------------------------
-    TEST "Unsupported -Wp,-MMD with -o without -MMD/-MT/-MQ"
-
-    $CCACHE_COMPILE -c test.c -Wp,-MMD,wp.d -o object.o
-    expect_stat unsupported_compiler_option 1
-
     # -----------------------------------------------------------------
     TEST "Unsupported -Wp,-MMD with -MF"
 
@@ -417,6 +411,30 @@ fi
     expect_equal_content different_name.d expected_mmd.d
     expect_equal_object_files reference_test.o test.o
 
+    # -------------------------------------------------------------------------
+    TEST "-Wp,-MMD with -o without -MMD/-MT/-MQ"
+
+    $COMPILER -c -Wp,-MMD,expected.d -o out.o "$(pwd)/test.c"
+
+    $CCACHE_COMPILE -c -Wp,-MMD,other.d -o out.o "$(pwd)/test.c"
+    expect_stat direct_cache_hit 0
+    expect_stat preprocessed_cache_hit 0
+    expect_stat cache_miss 1
+    expect_equal_text_content other.d expected.d
+
+    rm -f other.d
+    $CCACHE_COMPILE -c -Wp,-MMD,other.d -o out.o "$(pwd)/test.c"
+    expect_stat direct_cache_hit 1
+    expect_stat preprocessed_cache_hit 0
+    expect_stat cache_miss 1
+    expect_equal_text_content other.d expected.d
+
+    $CCACHE_COMPILE -c -Wp,-MMD,different_name.d -o out.o "$(pwd)/test.c"
+    expect_stat direct_cache_hit 2
+    expect_stat preprocessed_cache_hit 0
+    expect_stat cache_miss 1
+    expect_equal_text_content different_name.d expected.d
+
     # -------------------------------------------------------------------------
     TEST "-Wp,-D"