From 695c8f756b7ef12c4e8993720503b9c6d2242689 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 2 Jan 2020 22:45:48 -0500 Subject: add test harness for "run translated C" tests --- src/main.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 43a89b4efe..ea9f089072 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,7 +43,6 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { " libc [paths_file] Display native libc paths file or validate one\n" " run [source] [-- [args]] create executable and run immediately\n" " translate-c [source] convert c code to zig code\n" - " translate-c-2 [source] experimental self-hosted translate-c\n" " targets list available compilation targets\n" " test [source] create and run a test build\n" " version print version number and exit\n" -- cgit v1.2.3 From 14fcfe29817c03c3cac023b045433ea7abe4bd47 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 3 Jan 2020 22:11:19 -0500 Subject: translate-c supports --cache on this will be used to provide a zig build step --- src/codegen.cpp | 98 ++++++++++++++++++++++++++++++++++++++++++++++- src/codegen.hpp | 2 +- src/main.cpp | 5 ++- test/run_translated_c.zig | 4 +- 4 files changed, 103 insertions(+), 6 deletions(-) (limited to 'src/main.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 17ae34a1c4..95263e167f 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -194,6 +194,7 @@ static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *na static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstruction *source_instr, LLVMValueRef target_frame_ptr, ZigType *result_type, ZigType *ptr_result_type, LLVMValueRef result_loc, bool non_async); +static Error get_tmp_filename(CodeGen *g, Buf *out, Buf *suffix); static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const char *attr_name) { unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name)); @@ -9102,8 +9103,9 @@ void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_pa } -void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file) { +void codegen_translate_c(CodeGen *g, Buf *full_path) { Error err; + Buf *src_basename = buf_alloc(); Buf *src_dirname = buf_alloc(); os_path_split(full_path, src_dirname, src_basename); @@ -9111,12 +9113,61 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file) { Buf noextname = BUF_INIT; os_path_extname(src_basename, &noextname, nullptr); + Buf *zig_basename = buf_sprintf("%s.zig", buf_ptr(&noextname)); + detect_libc(g); + Buf cache_digest = BUF_INIT; + buf_resize(&cache_digest, 0); + + CacheHash *cache_hash = nullptr; + if (g->enable_cache) { + if ((err = create_c_object_cache(g, &cache_hash, true))) { + // Already printed error; verbose = true + exit(1); + } + cache_file(cache_hash, full_path); + // to distinguish from generating a C object + cache_buf(cache_hash, buf_create_from_str("translate-c")); + + if ((err = cache_hit(cache_hash, &cache_digest))) { + if (err != ErrorInvalidFormat) { + fprintf(stderr, "unable to check cache: %s\n", err_str(err)); + exit(1); + } + } + if (cache_hash->manifest_file_path != nullptr) { + g->caches_to_release.append(cache_hash); + } + } + + if (g->enable_cache && buf_len(&cache_digest) != 0) { + // cache hit + Buf *cached_path = buf_sprintf("%s" OS_SEP CACHE_OUT_SUBDIR OS_SEP "%s" OS_SEP "%s", + buf_ptr(g->cache_dir), buf_ptr(&cache_digest), buf_ptr(zig_basename)); + fprintf(stdout, "%s\n", buf_ptr(cached_path)); + return; + } + + // cache miss or cache disabled init(g); + Buf *out_dep_path = nullptr; + const char *out_dep_path_cstr = nullptr; + + if (g->enable_cache) { + buf_alloc();// we can't know the digest until we do the C compiler invocation, so we + // need a tmp filename. + out_dep_path = buf_alloc(); + if ((err = get_tmp_filename(g, out_dep_path, buf_sprintf("%s.d", buf_ptr(zig_basename))))) { + fprintf(stderr, "unable to create tmp dir: %s\n", err_str(err)); + exit(1); + } + out_dep_path_cstr = buf_ptr(out_dep_path); + } + ZigList clang_argv = {0}; - add_cc_args(g, clang_argv, nullptr, true); + add_cc_args(g, clang_argv, out_dep_path_cstr, true); clang_argv.append(buf_ptr(full_path)); @@ -9160,7 +9211,50 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file) { exit(1); } + if (!g->enable_cache) { + stage2_render_ast(ast, stdout); + return; + } + + // 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) { + os_delete_file(out_dep_path); + } + + if ((err = cache_final(cache_hash, &cache_digest))) { + fprintf(stderr, "Unable to finalize cache hash: %s\n", err_str(err)); + exit(1); + } + + Buf *artifact_dir = buf_sprintf("%s" OS_SEP CACHE_OUT_SUBDIR OS_SEP "%s", + buf_ptr(g->cache_dir), buf_ptr(&cache_digest)); + + if ((err = os_make_path(artifact_dir))) { + fprintf(stderr, "Unable to make dir: %s\n", err_str(err)); + exit(1); + } + + Buf *cached_path = buf_sprintf("%s" OS_SEP "%s", buf_ptr(artifact_dir), buf_ptr(zig_basename)); + + FILE *out_file = fopen(buf_ptr(cached_path), "wb"); + if (out_file == nullptr) { + fprintf(stderr, "Unable to open output file: %s\n", strerror(errno)); + exit(1); + } stage2_render_ast(ast, out_file); + if (fclose(out_file) != 0) { + fprintf(stderr, "Unable to write to output file: %s\n", strerror(errno)); + exit(1); + } + fprintf(stdout, "%s\n", buf_ptr(cached_path)); } static void update_test_functions_builtin_decl(CodeGen *g) { diff --git a/src/codegen.hpp b/src/codegen.hpp index 4f06d4b65d..b9bcf05d28 100644 --- a/src/codegen.hpp +++ b/src/codegen.hpp @@ -54,7 +54,7 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c void codegen_add_assembly(CodeGen *g, Buf *path); void codegen_add_object(CodeGen *g, Buf *object_path); -void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file); +void codegen_translate_c(CodeGen *g, Buf *full_path); Buf *codegen_generate_builtin_source(CodeGen *g); diff --git a/src/main.cpp b/src/main.cpp index ea9f089072..8a661bfa05 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1164,7 +1164,7 @@ int main(int argc, char **argv) { return print_error_usage(arg0); } - Buf *zig_root_source_file = cmd == CmdTranslateC ? nullptr : in_file_buf; + Buf *zig_root_source_file = (cmd == CmdTranslateC) ? nullptr : in_file_buf; if (cmd == CmdRun && buf_out_name == nullptr) { buf_out_name = buf_create_from_str("run"); @@ -1330,7 +1330,8 @@ int main(int argc, char **argv) { zig_unreachable(); } } else if (cmd == CmdTranslateC) { - codegen_translate_c(g, in_file_buf, stdout); + g->enable_cache = get_cache_opt(enable_cache, false); + codegen_translate_c(g, in_file_buf); if (timing_info) codegen_print_timing_report(g, stderr); return main_exit(root_progress_node, EXIT_SUCCESS); diff --git a/test/run_translated_c.zig b/test/run_translated_c.zig index 4bfe22d366..42dd97873c 100644 --- a/test/run_translated_c.zig +++ b/test/run_translated_c.zig @@ -1,4 +1,6 @@ +const std = @import("std"); const tests = @import("tests.zig"); +const nl = std.cstr.line_sep; pub fn addCases(cases: *tests.RunTranslatedCContext) void { cases.add("hello world", @@ -8,7 +10,7 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { \\ printf("hello, world!\n"); \\ return 0; \\} - , "hello, world!\n"); + , "hello, world!" ++ nl); cases.add("anon struct init", \\#include -- cgit v1.2.3