ability to disable cache. off by default except for...

...zig run, zig build, compiler_rt.a, and builtin.a
This commit is contained in:
Andrew Kelley 2018-09-11 00:32:40 -04:00
parent 5ee5933ade
commit 67735c6f15
No known key found for this signature in database
GPG Key ID: 4E7CD66038A4D47C
11 changed files with 167 additions and 35 deletions

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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 *manifest_dir = buf_alloc();
os_path_join(stage1_dir, buf_create_from_str("build"), manifest_dir);
Buf *artifact_dir = buf_alloc();
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 (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);
if ((err = check_cache(g, manifest_dir, &digest))) {
fprintf(stderr, "Unable to check cache: %s\n", err_str(err));
exit(1);
}
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);
}
Buf *artifact_dir = buf_alloc();
os_path_join(stage1_dir, buf_create_from_str("artifact"), 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");
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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) {

View File

@ -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,

View File

@ -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);