Commit 67735c6f15

Andrew Kelley <superjoe30@gmail.com>
2018-09-11 06:32:40
ability to disable cache. off by default except for...
...zig run, zig build, compiler_rt.a, and builtin.a
1 parent 5ee5933
src/all_types.hpp
@@ -1718,6 +1718,7 @@ struct CodeGen {
     bool verbose_cimport;
     bool error_during_imports;
     bool generate_error_name_table;
+    bool enable_cache;
 
     //////////////////////////// Participates in Input Parameter Cache Hash
     ZigList<LinkLib *> link_libs_list;
src/analyze.cpp
@@ -6367,3 +6367,11 @@ not_integer:
     }
     return nullptr;
 }
+
+Error file_fetch(CodeGen *g, Buf *resolved_path, Buf *contents) {
+    if (g->enable_cache) {
+        return cache_add_file_fetch(&g->cache_hash, resolved_path, contents);
+    } else {
+        return os_fetch_file_path(resolved_path, contents, false);
+    }
+}
src/analyze.hpp
@@ -210,4 +210,7 @@ ZigType *get_primitive_type(CodeGen *g, Buf *name);
 bool calling_convention_allows_zig_types(CallingConvention cc);
 const char *calling_convention_name(CallingConvention cc);
 
+
+Error ATTRIBUTE_MUST_USE file_fetch(CodeGen *g, Buf *resolved_path, Buf *contents);
+
 #endif
src/cache_hash.cpp
@@ -467,3 +467,11 @@ void cache_release(CacheHash *ch) {
     assert(ch->manifest_file_path != nullptr);
     os_file_close(ch->manifest_file);
 }
+
+Buf *get_random_basename() {
+    Buf *result = buf_alloc();
+    for (size_t i = 0; i < 16; i += 1) {
+        buf_append_char(result, base64_fs_alphabet[rand() % 64]);
+    }
+    return result;
+}
src/cache_hash.hpp
@@ -67,4 +67,9 @@ Error ATTRIBUTE_MUST_USE cache_final(CacheHash *ch, Buf *out_b64_digest);
 // Until this function is called, no one will be able to get a lock on your input params.
 void cache_release(CacheHash *ch);
 
+
+
+// Completely independent function. Just returns a random filename safe basename.
+Buf *get_random_basename();
+
 #endif
src/codegen.cpp
@@ -7048,7 +7048,7 @@ static ImportTableEntry *add_special_code(CodeGen *g, PackageTableEntry *package
     *resolved_path = os_path_resolve(resolve_paths, 1);
     Buf *import_code = buf_alloc();
     Error err;
-    if ((err = cache_add_file_fetch(&g->cache_hash, resolved_path, import_code))) {
+    if ((err = file_fetch(g, resolved_path, import_code))) {
         zig_panic("unable to open '%s': %s\n", buf_ptr(&path_to_code_src), err_str(err));
     }
 
@@ -7480,10 +7480,7 @@ static void gen_h_file(CodeGen *g) {
     GenH *gen_h = &gen_h_data;
 
     assert(!g->is_test_build);
-
-    if (!g->out_h_path) {
-        g->out_h_path = buf_sprintf("%s.h", buf_ptr(g->root_out_name));
-    }
+    assert(g->out_h_path != nullptr);
 
     FILE *out_h = fopen(buf_ptr(g->out_h_path), "wb");
     if (!out_h)
@@ -7790,17 +7787,56 @@ static void resolve_out_paths(CodeGen *g) {
             zig_unreachable();
     }
 
-    os_path_join(&g->artifact_dir, o_basename, &g->o_file_output_path);
+    if (g->enable_cache || g->out_type != OutTypeObj) {
+        os_path_join(&g->artifact_dir, o_basename, &g->o_file_output_path);
+    } else {
+        buf_init_from_buf(&g->o_file_output_path, o_basename);
+    }
 
     if (g->out_type == OutTypeObj) {
         buf_init_from_buf(&g->output_file_path, &g->o_file_output_path);
     } else if (g->out_type == OutTypeExe) {
-        assert(g->root_out_name);
+        if (!g->enable_cache && g->wanted_output_file_path != nullptr) {
+            buf_init_from_buf(&g->output_file_path, g->wanted_output_file_path);
+        } else {
+            assert(g->root_out_name);
 
-        Buf basename = BUF_INIT;
-        buf_init_from_buf(&basename, g->root_out_name);
-        buf_append_str(&basename, target_exe_file_ext(&g->zig_target));
-        os_path_join(&g->artifact_dir, &basename, &g->output_file_path);
+            Buf basename = BUF_INIT;
+            buf_init_from_buf(&basename, g->root_out_name);
+            buf_append_str(&basename, target_exe_file_ext(&g->zig_target));
+            if (g->enable_cache) {
+                os_path_join(&g->artifact_dir, &basename, &g->output_file_path);
+            } else {
+                buf_init_from_buf(&g->output_file_path, &basename);
+            }
+        }
+    } else if (g->out_type == OutTypeLib) {
+        if (!g->enable_cache && g->wanted_output_file_path != nullptr) {
+            buf_init_from_buf(&g->output_file_path, g->wanted_output_file_path);
+        } else {
+            Buf basename = BUF_INIT;
+            buf_init_from_buf(&basename, g->root_out_name);
+            buf_append_str(&basename, target_lib_file_ext(&g->zig_target, g->is_static,
+                        g->version_major, g->version_minor, g->version_patch));
+            if (g->enable_cache) {
+                os_path_join(&g->artifact_dir, &basename, &g->output_file_path);
+            } else {
+                buf_init_from_buf(&g->output_file_path, &basename);
+            }
+        }
+    } else {
+        zig_unreachable();
+    }
+
+    if (g->want_h_file && !g->out_h_path) {
+        assert(g->root_out_name);
+        Buf *h_basename = buf_sprintf("%s.h", buf_ptr(g->root_out_name)); 
+        if (g->enable_cache) {
+            g->out_h_path = buf_alloc();
+            os_path_join(&g->artifact_dir, h_basename, g->out_h_path);
+        } else {
+            g->out_h_path = h_basename;
+        }
     }
 }
 
@@ -7809,23 +7845,26 @@ void codegen_build_and_link(CodeGen *g) {
     Error err;
     assert(g->out_type != OutTypeUnknown);
 
-    codegen_add_time_event(g, "Check Cache");
-
     Buf *stage1_dir = get_stage1_cache_path();
+    Buf *artifact_dir = buf_alloc();
+    Buf digest = BUF_INIT;
+    if (g->enable_cache) {
+        codegen_add_time_event(g, "Check Cache");
 
-    Buf *manifest_dir = buf_alloc();
-    os_path_join(stage1_dir, buf_create_from_str("build"), manifest_dir);
+        Buf *manifest_dir = buf_alloc();
+        os_path_join(stage1_dir, buf_create_from_str("build"), manifest_dir);
 
-    Buf digest = BUF_INIT;
-    if ((err = check_cache(g, manifest_dir, &digest))) {
-        fprintf(stderr, "Unable to check cache: %s\n", err_str(err));
-        exit(1);
-    }
+        if ((err = check_cache(g, manifest_dir, &digest))) {
+            fprintf(stderr, "Unable to check cache: %s\n", err_str(err));
+            exit(1);
+        }
 
-    Buf *artifact_dir = buf_alloc();
-    os_path_join(stage1_dir, buf_create_from_str("artifact"), artifact_dir);
+        os_path_join(stage1_dir, buf_create_from_str("artifact"), artifact_dir);
+    } else {
+        os_path_join(stage1_dir, buf_create_from_str("tmp"), artifact_dir);
+    }
 
-    if (buf_len(&digest) != 0) {
+    if (g->enable_cache && buf_len(&digest) != 0) {
         os_path_join(artifact_dir, &digest, &g->artifact_dir);
         resolve_out_paths(g);
     } else {
@@ -7836,11 +7875,16 @@ void codegen_build_and_link(CodeGen *g) {
         gen_global_asm(g);
         gen_root_source(g);
 
-        if ((err = cache_final(&g->cache_hash, &digest))) {
-            fprintf(stderr, "Unable to finalize cache hash: %s\n", err_str(err));
-            exit(1);
+        if (g->enable_cache) {
+            if ((err = cache_final(&g->cache_hash, &digest))) {
+                fprintf(stderr, "Unable to finalize cache hash: %s\n", err_str(err));
+                exit(1);
+            }
+            os_path_join(artifact_dir, &digest, &g->artifact_dir);
+        } else {
+            Buf *tmp_basename = get_random_basename(); 
+            os_path_join(artifact_dir, tmp_basename, &g->artifact_dir);
         }
-        os_path_join(artifact_dir, &digest, &g->artifact_dir);
         if ((err = os_make_path(&g->artifact_dir))) {
             fprintf(stderr, "Unable to create artifact directory: %s\n", err_str(err));
             exit(1);
@@ -7857,9 +7901,10 @@ void codegen_build_and_link(CodeGen *g) {
             codegen_link(g);
         }
     }
-    // TODO hard link output_file_path to wanted_output_file_path
 
-    cache_release(&g->cache_hash);
+    if (g->enable_cache) {
+        cache_release(&g->cache_hash);
+    }
     codegen_add_time_event(g, "Done");
 }
 
src/ir.cpp
@@ -16277,7 +16277,7 @@ static ZigType *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructionImpor
         return ira->codegen->builtin_types.entry_namespace;
     }
 
-    if ((err = cache_add_file_fetch(&ira->codegen->cache_hash, resolved_path, import_code))) {
+    if ((err = file_fetch(ira->codegen, resolved_path, import_code))) {
         if (err == ErrorFileNotFound) {
             ir_add_error_node(ira, source_node,
                     buf_sprintf("unable to find '%s'", buf_ptr(import_target_path)));
@@ -18108,7 +18108,7 @@ static ZigType *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstructionE
     // load from file system into const expr
     Buf *file_contents = buf_alloc();
     int err;
-    if ((err = cache_add_file_fetch(&ira->codegen->cache_hash, &file_path, file_contents))) {
+    if ((err = file_fetch(ira->codegen, &file_path, file_contents))) {
         if (err == ErrorFileNotFound) {
             ir_add_error(ira, instruction->name, buf_sprintf("unable to find '%s'", buf_ptr(&file_path)));
             return ira->codegen->builtin_types.entry_invalid;
src/link.cpp
@@ -58,6 +58,7 @@ static Buf *build_o_raw(CodeGen *parent_gen, const char *oname, Buf *full_path)
         new_link_lib->provided_explicitly = link_lib->provided_explicitly;
     }
 
+    child_gen->enable_cache = true;
     codegen_build_and_link(child_gen);
     return &child_gen->output_file_path;
 }
src/main.cpp
@@ -34,6 +34,7 @@ static int usage(const char *arg0) {
         "Compile Options:\n"
         "  --assembly [source]          add assembly file to build\n"
         "  --cache-dir [path]           override the cache directory\n"
+        "  --cache [auto|off|on]        build to the global cache and print output path to stdout\n"
         "  --color [auto|off|on]        enable or disable colored error messages\n"
         "  --emit [asm|bin|llvm-ir]     emit a specific file format as compilation output\n"
         "  --enable-timing-info         print timing diagnostics\n"
@@ -257,6 +258,24 @@ static void add_package(CodeGen *g, CliPkg *cli_pkg, PackageTableEntry *pkg) {
     }
 }
 
+enum CacheOpt {
+    CacheOptAuto,
+    CacheOptOn,
+    CacheOptOff,
+};
+
+static bool get_cache_opt(CacheOpt opt, bool default_value) {
+    switch (opt) {
+        case CacheOptAuto:
+            return default_value;
+        case CacheOptOn:
+            return true;
+        case CacheOptOff:
+            return false;
+    }
+    zig_unreachable();
+}
+
 int main(int argc, char **argv) {
     if (argc == 2 && strcmp(argv[1], "BUILD_INFO") == 0) {
         printf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
@@ -301,6 +320,7 @@ int main(int argc, char **argv) {
     bool verbose_llvm_ir = false;
     bool verbose_cimport = false;
     ErrColor color = ErrColorAuto;
+    CacheOpt enable_cache = CacheOptAuto;
     const char *libc_lib_dir = nullptr;
     const char *libc_static_lib_dir = nullptr;
     const char *libc_include_dir = nullptr;
@@ -465,6 +485,7 @@ int main(int argc, char **argv) {
         PackageTableEntry *build_pkg = codegen_create_package(g, buf_ptr(&build_file_dirname),
                 buf_ptr(&build_file_basename));
         g->root_package->package_table.put(buf_create_from_str("@build"), build_pkg);
+        g->enable_cache = get_cache_opt(enable_cache, true);
         codegen_build_and_link(g);
 
         Termination term;
@@ -562,6 +583,17 @@ int main(int argc, char **argv) {
                         fprintf(stderr, "--color options are 'auto', 'on', or 'off'\n");
                         return usage(arg0);
                     }
+                } else if (strcmp(arg, "--cache") == 0) {
+                    if (strcmp(argv[i], "auto") == 0) {
+                        enable_cache = CacheOptAuto;
+                    } else if (strcmp(argv[i], "on") == 0) {
+                        enable_cache = CacheOptOn;
+                    } else if (strcmp(argv[i], "off") == 0) {
+                        enable_cache = CacheOptOff;
+                    } else {
+                        fprintf(stderr, "--cache options are 'auto', 'on', or 'off'\n");
+                        return usage(arg0);
+                    }
                 } else if (strcmp(arg, "--emit") == 0) {
                     if (strcmp(argv[i], "asm") == 0) {
                         emit_file_type = EmitFileTypeAssembly;
@@ -894,6 +926,7 @@ int main(int argc, char **argv) {
             if (cmd == CmdBuild || cmd == CmdRun) {
                 codegen_set_emit_file_type(g, emit_file_type);
 
+                g->enable_cache = get_cache_opt(enable_cache, cmd == CmdRun);
                 codegen_build_and_link(g);
                 if (timing_info)
                     codegen_print_timing_report(g, stdout);
@@ -913,9 +946,17 @@ int main(int argc, char **argv) {
                     Termination term;
                     os_spawn_process(exec_path, args, &term);
                     return term.code;
+                } else if (cmd == CmdBuild) {
+                    if (g->enable_cache) {
+                        printf("%s\n", buf_ptr(&g->output_file_path));
+                        if (g->out_h_path != nullptr) {
+                            printf("%s\n", buf_ptr(g->out_h_path));
+                        }
+                    }
+                    return EXIT_SUCCESS;
+                } else {
+                    zig_unreachable();
                 }
-
-                return EXIT_SUCCESS;
             } else if (cmd == CmdTranslateC) {
                 codegen_translate_c(g, in_file_buf);
                 ast_render(g, stdout, g->root_import->root, 4);
@@ -928,8 +969,11 @@ int main(int argc, char **argv) {
                 ZigTarget native;
                 get_native_target(&native);
 
+                g->enable_cache = get_cache_opt(enable_cache, false);
                 codegen_build_and_link(g);
-                Buf *test_exe_path = &g->output_file_path;
+                Buf *test_exe_path_unresolved = &g->output_file_path;
+                Buf *test_exe_path = buf_alloc();
+                *test_exe_path = os_path_resolve(&test_exe_path_unresolved, 1);
 
                 for (size_t i = 0; i < test_exec_args.length; i += 1) {
                     if (test_exec_args.items[i] == nullptr) {
src/target.cpp
@@ -813,6 +813,22 @@ const char *target_exe_file_ext(ZigTarget *target) {
     }
 }
 
+const char *target_lib_file_ext(ZigTarget *target, bool is_static, size_t version_major, size_t version_minor, size_t version_patch) {
+    if (target->os == OsWindows) {
+        if (is_static) {
+            return ".lib";
+        } else {
+            return ".dll";
+        }
+    } else {
+        if (is_static) {
+            return ".a";
+        } else {
+            return buf_ptr(buf_sprintf(".so.%zu", version_major));
+        }
+    }
+}
+
 enum FloatAbi {
     FloatAbiHard,
     FloatAbiSoft,
src/target.hpp
@@ -113,6 +113,7 @@ const char *target_o_file_ext(ZigTarget *target);
 const char *target_asm_file_ext(ZigTarget *target);
 const char *target_llvm_ir_file_ext(ZigTarget *target);
 const char *target_exe_file_ext(ZigTarget *target);
+const char *target_lib_file_ext(ZigTarget *target, bool is_static, size_t version_major, size_t version_minor, size_t version_patch);
 
 Buf *target_dynamic_linker(ZigTarget *target);