Commit e4edc6d118

Andrew Kelley <andrew@ziglang.org>
2020-04-02 21:47:27
zig cc: respect -MF -MV -MD options
Zig disables its caching and forwards these args when any are provided. see #4784
1 parent 4aa797b
src/all_types.hpp
@@ -2230,6 +2230,7 @@ struct CodeGen {
     bool reported_bad_link_libc_error;
     bool is_dynamic; // shared library rather than static library. dynamic musl rather than static musl.
     bool need_frame_size_prefix_data;
+    bool disable_c_depfile;
 
     //////////////////////////// Participates in Input Parameter Cache Hash
     /////// Note: there is a separate cache hash for builtin.zig, when adding fields,
@@ -2258,6 +2259,7 @@ struct CodeGen {
     const ZigTarget *zig_target;
     TargetSubsystem subsystem; // careful using this directly; see detect_subsystem
     ValgrindSupport valgrind_support;
+    CodeModel code_model;
     bool strip_debug_symbols;
     bool is_test_build;
     bool is_single_threaded;
@@ -2278,7 +2280,6 @@ struct CodeGen {
     bool emit_asm;
     bool emit_llvm_ir;
     bool test_is_evented;
-    CodeModel code_model;
 
     Buf *root_out_name;
     Buf *test_filter;
src/codegen.cpp
@@ -9803,7 +9803,7 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) {
             exit(1);
         }
     }
-    bool is_cache_miss = (buf_len(&digest) == 0);
+    bool is_cache_miss = g->disable_c_depfile || (buf_len(&digest) == 0);
     if (is_cache_miss) {
         // we can't know the digest until we do the C compiler invocation, so we
         // need a tmp filename.
@@ -9822,9 +9822,10 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) {
             args.append("-c");
         }
 
-        Buf *out_dep_path = buf_sprintf("%s.d", buf_ptr(out_obj_path));
+        Buf *out_dep_path = g->disable_c_depfile ? nullptr : buf_sprintf("%s.d", buf_ptr(out_obj_path));
+        const char *out_dep_path_cstr = (out_dep_path == nullptr) ? nullptr : buf_ptr(out_dep_path);
         FileExt ext = classify_file_ext(buf_ptr(c_source_basename), buf_len(c_source_basename));
-        add_cc_args(g, args, buf_ptr(out_dep_path), false, ext);
+        add_cc_args(g, args, out_dep_path_cstr, false, ext);
 
         args.append("-o");
         args.append(buf_ptr(out_obj_path));
@@ -9845,22 +9846,24 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) {
             exit(1);
         }
 
-        // add the files depended on to the cache system
-        if ((err = cache_add_dep_file(cache_hash, out_dep_path, true))) {
-            // Don't treat the absence of the .d file as a fatal error, the
-            // compiler may not produce one eg. when compiling .s files
+        if (out_dep_path != nullptr) {
+            // add the files depended on to the cache system
+            if ((err = cache_add_dep_file(cache_hash, out_dep_path, true))) {
+                // Don't treat the absence of the .d file as a fatal error, the
+                // compiler may not produce one eg. when compiling .s files
+                if (err != ErrorFileNotFound) {
+                    fprintf(stderr, "Failed to add C source dependencies to cache: %s\n", err_str(err));
+                    exit(1);
+                }
+            }
             if (err != ErrorFileNotFound) {
-                fprintf(stderr, "Failed to add C source dependencies to cache: %s\n", err_str(err));
-                exit(1);
+                os_delete_file(out_dep_path);
             }
-        }
-        if (err != ErrorFileNotFound) {
-            os_delete_file(out_dep_path);
-        }
 
-        if ((err = cache_final(cache_hash, &digest))) {
-            fprintf(stderr, "Unable to finalize cache hash: %s\n", err_str(err));
-            exit(1);
+            if ((err = cache_final(cache_hash, &digest))) {
+                fprintf(stderr, "Unable to finalize cache hash: %s\n", err_str(err));
+                exit(1);
+            }
         }
         artifact_dir = buf_alloc();
         os_path_join(o_dir, &digest, artifact_dir);
src/main.cpp
@@ -458,6 +458,7 @@ static int main0(int argc, char **argv) {
     bool only_pp_or_asm = false;
     bool ensure_libc_on_non_freestanding = false;
     bool ensure_libcpp_on_non_freestanding = false;
+    bool disable_c_depfile = false;
 
     ZigList<const char *> llvm_argv = {0};
     llvm_argv.append("zig (LLVM option parsing)");
@@ -741,6 +742,12 @@ static int main0(int argc, char **argv) {
                 case Stage2ClangArgMCpu:
                     mcpu = it.only_arg;
                     break;
+                case Stage2ClangArgDepFile:
+                    disable_c_depfile = true;
+                    for (size_t i = 0; i < it.other_args_len; i += 1) {
+                        clang_argv.append(it.other_args_ptr[i]);
+                    }
+                    break;
             }
         }
         // Parse linker args
@@ -1520,6 +1527,7 @@ static int main0(int argc, char **argv) {
             g->system_linker_hack = system_linker_hack;
             g->function_sections = function_sections;
             g->code_model = code_model;
+            g->disable_c_depfile = disable_c_depfile;
 
             if (override_soname) {
                 g->override_soname = buf_create_from_str(override_soname);
src/stage2.h
@@ -349,6 +349,7 @@ enum Stage2ClangArg {
     Stage2ClangArgLinkerInputZ,
     Stage2ClangArgLibDir,
     Stage2ClangArgMCpu,
+    Stage2ClangArgDepFile,
 };
 
 // ABI warning
src-self-hosted/clang_options_data.zig
@@ -26,12 +26,26 @@ flagpd1("H"),
 },
 flagpd1("I-"),
 flagpd1("M"),
-flagpd1("MD"),
+.{
+    .name = "MD",
+    .syntax = .flag,
+    .zig_equivalent = .dep_file,
+    .pd1 = true,
+    .pd2 = false,
+    .psl = false,
+},
 flagpd1("MG"),
 flagpd1("MM"),
 flagpd1("MMD"),
 flagpd1("MP"),
-flagpd1("MV"),
+.{
+    .name = "MV",
+    .syntax = .flag,
+    .zig_equivalent = .dep_file,
+    .pd1 = true,
+    .pd2 = false,
+    .psl = false,
+},
 flagpd1("Mach"),
 flagpd1("O0"),
 flagpd1("O4"),
@@ -490,7 +504,7 @@ sepd1("Zlinker-input"),
 .{
     .name = "MD",
     .syntax = .flag,
-    .zig_equivalent = .other,
+    .zig_equivalent = .dep_file,
     .pd1 = true,
     .pd2 = false,
     .psl = true,
@@ -5434,7 +5448,14 @@ joinpd1("mtp="),
 joinpd1("gz="),
 joinpd1("A-"),
 joinpd1("G="),
-jspd1("MF"),
+.{
+    .name = "MF",
+    .syntax = .joined_or_separate,
+    .zig_equivalent = .dep_file,
+    .pd1 = true,
+    .pd2 = false,
+    .psl = false,
+},
 jspd1("MJ"),
 jspd1("MQ"),
 jspd1("MT"),
src-self-hosted/stage2.zig
@@ -1290,6 +1290,7 @@ pub const ClangArgIterator = extern struct {
         linker_input_z,
         lib_dir,
         mcpu,
+        dep_file,
     };
 
     const Args = struct {
tools/update_clang_options.zig
@@ -194,6 +194,18 @@ const known_options = [_]KnownOpt{
         .name = "mtune",
         .ident = "mcpu",
     },
+    .{
+        .name = "MD",
+        .ident = "dep_file",
+    },
+    .{
+        .name = "MV",
+        .ident = "dep_file",
+    },
+    .{
+        .name = "MF",
+        .ident = "dep_file",
+    },
 };
 
 const blacklisted_options = [_][]const u8{};