| author | |
| committer | |
| log | 363d9038c9b52878054505e905e133310b53086e |
| tree | 643a613f7502dab37a743049e1b28ee8cfe5b06a |
| parent | 38a04a267c11fdedc62102ab8e5989cafa3073ef |
closes #32816 files changed, 357 insertions(+), 146 deletions(-)
.gitignore+1-1| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | zig-cache/ | ||
| 1 | build/ | 2 | build/ |
| 2 | build-release/ | 3 | build-release/ |
| 3 | /.cproject | 4 | /.cproject |
| 4 | /.project | 5 | /.project |
| 5 | /.settings/ | 6 | /.settings/ |
| 6 | /test_artifacts/ |
build.zig+8-11| ... | @@ -5,19 +5,16 @@ pub fn build(b: &Builder) { | ... | @@ -5,19 +5,16 @@ pub fn build(b: &Builder) { |
| 5 | const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter"); | 5 | const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter"); |
| 6 | const test_step = b.step("test", "Run all the tests"); | 6 | const test_step = b.step("test", "Run all the tests"); |
| 7 | 7 | ||
| 8 | const cleanup = b.addRemoveDirTree("test_artifacts"); | 8 | test_step.dependOn(tests.addPkgTests(b, test_filter, |
| 9 | test_step.dependOn(&cleanup.step); | ||
| 10 | |||
| 11 | cleanup.step.dependOn(tests.addPkgTests(b, test_filter, | ||
| 12 | "test/behavior.zig", "behavior", "Run the behavior tests")); | 9 | "test/behavior.zig", "behavior", "Run the behavior tests")); |
| 13 | 10 | ||
| 14 | cleanup.step.dependOn(tests.addPkgTests(b, test_filter, | 11 | test_step.dependOn(tests.addPkgTests(b, test_filter, |
| 15 | "std/index.zig", "std", "Run the standard library tests")); | 12 | "std/index.zig", "std", "Run the standard library tests")); |
| 16 | 13 | ||
| 17 | cleanup.step.dependOn(tests.addCompareOutputTests(b, test_filter)); | 14 | test_step.dependOn(tests.addCompareOutputTests(b, test_filter)); |
| 18 | cleanup.step.dependOn(tests.addBuildExampleTests(b, test_filter)); | 15 | test_step.dependOn(tests.addBuildExampleTests(b, test_filter)); |
| 19 | cleanup.step.dependOn(tests.addCompileErrorTests(b, test_filter)); | 16 | test_step.dependOn(tests.addCompileErrorTests(b, test_filter)); |
| 20 | cleanup.step.dependOn(tests.addAssembleAndLinkTests(b, test_filter)); | 17 | test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filter)); |
| 21 | cleanup.step.dependOn(tests.addDebugSafetyTests(b, test_filter)); | 18 | test_step.dependOn(tests.addDebugSafetyTests(b, test_filter)); |
| 22 | cleanup.step.dependOn(tests.addParseHTests(b, test_filter)); | 19 | test_step.dependOn(tests.addParseHTests(b, test_filter)); |
| 23 | } | 20 | } |
example/mix_o_files/build.zig+1-1| ... | @@ -12,7 +12,7 @@ pub fn build(b: &Builder) { | ... | @@ -12,7 +12,7 @@ pub fn build(b: &Builder) { |
| 12 | 12 | ||
| 13 | b.default_step.dependOn(&exe.step); | 13 | b.default_step.dependOn(&exe.step); |
| 14 | 14 | ||
| 15 | const run_cmd = b.addCommand(b.out_dir, b.env_map, "./test", [][]const u8{}); | 15 | const run_cmd = b.addCommand(b.cache_root, b.env_map, "./test", [][]const u8{}); |
| 16 | run_cmd.step.dependOn(&exe.step); | 16 | run_cmd.step.dependOn(&exe.step); |
| 17 | 17 | ||
| 18 | const test_step = b.step("test", "Test the program"); | 18 | const test_step = b.step("test", "Test the program"); |
example/shared_library/build.zig+1-1| ... | @@ -12,7 +12,7 @@ pub fn build(b: &Builder) { | ... | @@ -12,7 +12,7 @@ pub fn build(b: &Builder) { |
| 12 | 12 | ||
| 13 | b.default_step.dependOn(&exe.step); | 13 | b.default_step.dependOn(&exe.step); |
| 14 | 14 | ||
| 15 | const run_cmd = b.addCommand(b.out_dir, b.env_map, "./test", [][]const u8{}); | 15 | const run_cmd = b.addCommand(b.cache_root, b.env_map, "./test", [][]const u8{}); |
| 16 | run_cmd.step.dependOn(&exe.step); | 16 | run_cmd.step.dependOn(&exe.step); |
| 17 | 17 | ||
| 18 | const test_step = b.step("test", "Test the program"); | 18 | const test_step = b.step("test", "Test the program"); |
src/all_types.hpp+1| ... | @@ -1488,6 +1488,7 @@ struct CodeGen { | ... | @@ -1488,6 +1488,7 @@ struct CodeGen { |
| 1488 | ZigList<TimeEvent> timing_events; | 1488 | ZigList<TimeEvent> timing_events; |
| 1489 | 1489 | ||
| 1490 | Buf *cache_dir; | 1490 | Buf *cache_dir; |
| 1491 | Buf *out_h_path; | ||
| 1491 | }; | 1492 | }; |
| 1492 | 1493 | ||
| 1493 | enum VarLinkage { | 1494 | enum VarLinkage { |
src/codegen.cpp+29-19| ... | @@ -55,11 +55,12 @@ PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_pa | ... | @@ -55,11 +55,12 @@ PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_pa |
| 55 | return entry; | 55 | return entry; |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target) { | 58 | CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type) { |
| 59 | CodeGen *g = allocate<CodeGen>(1); | 59 | CodeGen *g = allocate<CodeGen>(1); |
| 60 | 60 | ||
| 61 | codegen_add_time_event(g, "Initialize"); | 61 | codegen_add_time_event(g, "Initialize"); |
| 62 | 62 | ||
| 63 | g->out_type = out_type; | ||
| 63 | g->import_table.init(32); | 64 | g->import_table.init(32); |
| 64 | g->builtin_fn_table.init(32); | 65 | g->builtin_fn_table.init(32); |
| 65 | g->primitive_type_table.init(32); | 66 | g->primitive_type_table.init(32); |
| ... | @@ -74,7 +75,7 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target) { | ... | @@ -74,7 +75,7 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target) { |
| 74 | g->external_prototypes.init(8); | 75 | g->external_prototypes.init(8); |
| 75 | g->is_release_build = false; | 76 | g->is_release_build = false; |
| 76 | g->is_test_build = false; | 77 | g->is_test_build = false; |
| 77 | g->want_h_file = true; | 78 | g->want_h_file = (out_type == OutTypeObj || out_type == OutTypeLib); |
| 78 | 79 | ||
| 79 | buf_resize(&g->global_asm, 0); | 80 | buf_resize(&g->global_asm, 0); |
| 80 | 81 | ||
| ... | @@ -145,6 +146,10 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target) { | ... | @@ -145,6 +146,10 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target) { |
| 145 | return g; | 146 | return g; |
| 146 | } | 147 | } |
| 147 | 148 | ||
| 149 | void codegen_set_output_h_path(CodeGen *g, Buf *h_path) { | ||
| 150 | g->out_h_path = h_path; | ||
| 151 | } | ||
| 152 | |||
| 148 | void codegen_set_clang_argv(CodeGen *g, const char **args, size_t len) { | 153 | void codegen_set_clang_argv(CodeGen *g, const char **args, size_t len) { |
| 149 | g->clang_argv = args; | 154 | g->clang_argv = args; |
| 150 | g->clang_argv_len = len; | 155 | g->clang_argv_len = len; |
| ... | @@ -196,10 +201,6 @@ void codegen_set_strip(CodeGen *g, bool strip) { | ... | @@ -196,10 +201,6 @@ void codegen_set_strip(CodeGen *g, bool strip) { |
| 196 | g->strip_debug_symbols = strip; | 201 | g->strip_debug_symbols = strip; |
| 197 | } | 202 | } |
| 198 | 203 | ||
| 199 | void codegen_set_out_type(CodeGen *g, OutType out_type) { | ||
| 200 | g->out_type = out_type; | ||
| 201 | } | ||
| 202 | |||
| 203 | void codegen_set_out_name(CodeGen *g, Buf *out_name) { | 204 | void codegen_set_out_name(CodeGen *g, Buf *out_name) { |
| 204 | g->root_out_name = out_name; | 205 | g->root_out_name = out_name; |
| 205 | } | 206 | } |
| ... | @@ -4808,15 +4809,6 @@ static void gen_global_asm(CodeGen *g) { | ... | @@ -4808,15 +4809,6 @@ static void gen_global_asm(CodeGen *g) { |
| 4808 | } | 4809 | } |
| 4809 | } | 4810 | } |
| 4810 | 4811 | ||
| 4811 | void codegen_build(CodeGen *g) { | ||
| 4812 | assert(g->out_type != OutTypeUnknown); | ||
| 4813 | init(g); | ||
| 4814 | |||
| 4815 | gen_global_asm(g); | ||
| 4816 | gen_root_source(g); | ||
| 4817 | do_code_gen(g); | ||
| 4818 | } | ||
| 4819 | |||
| 4820 | void codegen_add_object(CodeGen *g, Buf *object_path) { | 4812 | void codegen_add_object(CodeGen *g, Buf *object_path) { |
| 4821 | g->link_objects.append(object_path); | 4813 | g->link_objects.append(object_path); |
| 4822 | } | 4814 | } |
| ... | @@ -4946,13 +4938,21 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) { | ... | @@ -4946,13 +4938,21 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) { |
| 4946 | } | 4938 | } |
| 4947 | } | 4939 | } |
| 4948 | 4940 | ||
| 4949 | void codegen_generate_h_file(CodeGen *g) { | 4941 | static void gen_h_file(CodeGen *g) { |
| 4942 | if (!g->want_h_file) | ||
| 4943 | return; | ||
| 4944 | |||
| 4945 | codegen_add_time_event(g, "Generate .h"); | ||
| 4946 | |||
| 4950 | assert(!g->is_test_build); | 4947 | assert(!g->is_test_build); |
| 4951 | 4948 | ||
| 4952 | Buf *h_file_out_path = buf_sprintf("%s.h", buf_ptr(g->root_out_name)); | 4949 | if (!g->out_h_path) { |
| 4953 | FILE *out_h = fopen(buf_ptr(h_file_out_path), "wb"); | 4950 | g->out_h_path = buf_sprintf("%s.h", buf_ptr(g->root_out_name)); |
| 4951 | } | ||
| 4952 | |||
| 4953 | FILE *out_h = fopen(buf_ptr(g->out_h_path), "wb"); | ||
| 4954 | if (!out_h) | 4954 | if (!out_h) |
| 4955 | zig_panic("unable to open %s: %s", buf_ptr(h_file_out_path), strerror(errno)); | 4955 | zig_panic("unable to open %s: %s", buf_ptr(g->out_h_path), strerror(errno)); |
| 4956 | 4956 | ||
| 4957 | Buf *export_macro = buf_sprintf("%s_EXPORT", buf_ptr(g->root_out_name)); | 4957 | Buf *export_macro = buf_sprintf("%s_EXPORT", buf_ptr(g->root_out_name)); |
| 4958 | buf_upcase(export_macro); | 4958 | buf_upcase(export_macro); |
| ... | @@ -5056,3 +5056,13 @@ void codegen_print_timing_report(CodeGen *g, FILE *f) { | ... | @@ -5056,3 +5056,13 @@ void codegen_print_timing_report(CodeGen *g, FILE *f) { |
| 5056 | void codegen_add_time_event(CodeGen *g, const char *name) { | 5056 | void codegen_add_time_event(CodeGen *g, const char *name) { |
| 5057 | g->timing_events.append({os_get_time(), name}); | 5057 | g->timing_events.append({os_get_time(), name}); |
| 5058 | } | 5058 | } |
| 5059 | |||
| 5060 | void codegen_build(CodeGen *g) { | ||
| 5061 | assert(g->out_type != OutTypeUnknown); | ||
| 5062 | init(g); | ||
| 5063 | |||
| 5064 | gen_global_asm(g); | ||
| 5065 | gen_root_source(g); | ||
| 5066 | do_code_gen(g); | ||
| 5067 | gen_h_file(g); | ||
| 5068 | } |
src/codegen.hpp+2-3| ... | @@ -14,7 +14,7 @@ | ... | @@ -14,7 +14,7 @@ |
| 14 | 14 | ||
| 15 | #include <stdio.h> | 15 | #include <stdio.h> |
| 16 | 16 | ||
| 17 | CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target); | 17 | CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type); |
| 18 | 18 | ||
| 19 | void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len); | 19 | void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len); |
| 20 | void codegen_set_is_release(CodeGen *codegen, bool is_release); | 20 | void codegen_set_is_release(CodeGen *codegen, bool is_release); |
| ... | @@ -25,7 +25,6 @@ void codegen_set_is_static(CodeGen *codegen, bool is_static); | ... | @@ -25,7 +25,6 @@ void codegen_set_is_static(CodeGen *codegen, bool is_static); |
| 25 | void codegen_set_strip(CodeGen *codegen, bool strip); | 25 | void codegen_set_strip(CodeGen *codegen, bool strip); |
| 26 | void codegen_set_verbose(CodeGen *codegen, bool verbose); | 26 | void codegen_set_verbose(CodeGen *codegen, bool verbose); |
| 27 | void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color); | 27 | void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color); |
| 28 | void codegen_set_out_type(CodeGen *codegen, OutType out_type); | ||
| 29 | void codegen_set_out_name(CodeGen *codegen, Buf *out_name); | 28 | void codegen_set_out_name(CodeGen *codegen, Buf *out_name); |
| 30 | void codegen_set_libc_lib_dir(CodeGen *codegen, Buf *libc_lib_dir); | 29 | void codegen_set_libc_lib_dir(CodeGen *codegen, Buf *libc_lib_dir); |
| 31 | void codegen_set_libc_static_lib_dir(CodeGen *g, Buf *libc_static_lib_dir); | 30 | void codegen_set_libc_static_lib_dir(CodeGen *g, Buf *libc_static_lib_dir); |
| ... | @@ -48,6 +47,7 @@ void codegen_set_test_filter(CodeGen *g, Buf *filter); | ... | @@ -48,6 +47,7 @@ void codegen_set_test_filter(CodeGen *g, Buf *filter); |
| 48 | void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix); | 47 | void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix); |
| 49 | void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch); | 48 | void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch); |
| 50 | void codegen_set_cache_dir(CodeGen *g, Buf *cache_dir); | 49 | void codegen_set_cache_dir(CodeGen *g, Buf *cache_dir); |
| 50 | void codegen_set_output_h_path(CodeGen *g, Buf *h_path); | ||
| 51 | void codegen_add_time_event(CodeGen *g, const char *name); | 51 | void codegen_add_time_event(CodeGen *g, const char *name); |
| 52 | void codegen_print_timing_report(CodeGen *g, FILE *f); | 52 | void codegen_print_timing_report(CodeGen *g, FILE *f); |
| 53 | void codegen_build(CodeGen *g); | 53 | void codegen_build(CodeGen *g); |
| ... | @@ -59,6 +59,5 @@ void codegen_add_object(CodeGen *g, Buf *object_path); | ... | @@ -59,6 +59,5 @@ void codegen_add_object(CodeGen *g, Buf *object_path); |
| 59 | void codegen_parseh(CodeGen *g, Buf *path); | 59 | void codegen_parseh(CodeGen *g, Buf *path); |
| 60 | void codegen_render_ast(CodeGen *g, FILE *f, int indent_size); | 60 | void codegen_render_ast(CodeGen *g, FILE *f, int indent_size); |
| 61 | 61 | ||
| 62 | void codegen_generate_h_file(CodeGen *g); | ||
| 63 | 62 | ||
| 64 | #endif | 63 | #endif |
src/link.cpp+5-15| ... | @@ -37,7 +37,7 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) { | ... | @@ -37,7 +37,7 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) { |
| 37 | os_path_join(parent_gen->zig_std_special_dir, source_basename, full_path); | 37 | os_path_join(parent_gen->zig_std_special_dir, source_basename, full_path); |
| 38 | 38 | ||
| 39 | ZigTarget *child_target = parent_gen->is_native_target ? nullptr : &parent_gen->zig_target; | 39 | ZigTarget *child_target = parent_gen->is_native_target ? nullptr : &parent_gen->zig_target; |
| 40 | CodeGen *child_gen = codegen_create(full_path, child_target); | 40 | CodeGen *child_gen = codegen_create(full_path, child_target, OutTypeObj); |
| 41 | child_gen->link_libc = parent_gen->link_libc; | 41 | child_gen->link_libc = parent_gen->link_libc; |
| 42 | 42 | ||
| 43 | child_gen->link_libs.resize(parent_gen->link_libs.length); | 43 | child_gen->link_libs.resize(parent_gen->link_libs.length); |
| ... | @@ -55,7 +55,6 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) { | ... | @@ -55,7 +55,6 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) { |
| 55 | codegen_set_strip(child_gen, parent_gen->strip_debug_symbols); | 55 | codegen_set_strip(child_gen, parent_gen->strip_debug_symbols); |
| 56 | codegen_set_is_static(child_gen, parent_gen->is_static); | 56 | codegen_set_is_static(child_gen, parent_gen->is_static); |
| 57 | 57 | ||
| 58 | codegen_set_out_type(child_gen, OutTypeObj); | ||
| 59 | codegen_set_out_name(child_gen, buf_create_from_str(oname)); | 58 | codegen_set_out_name(child_gen, buf_create_from_str(oname)); |
| 60 | 59 | ||
| 61 | codegen_set_verbose(child_gen, parent_gen->verbose); | 60 | codegen_set_verbose(child_gen, parent_gen->verbose); |
| ... | @@ -186,9 +185,10 @@ static void construct_linker_job_elf(LinkJob *lj) { | ... | @@ -186,9 +185,10 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 186 | } else if (shared) { | 185 | } else if (shared) { |
| 187 | lj->args.append("-shared"); | 186 | lj->args.append("-shared"); |
| 188 | 187 | ||
| 189 | buf_resize(&lj->out_file, 0); | 188 | if (buf_len(&lj->out_file) == 0) { |
| 190 | buf_appendf(&lj->out_file, "lib%s.so.%zu.%zu.%zu", | 189 | buf_appendf(&lj->out_file, "lib%s.so.%zu.%zu.%zu", |
| 191 | buf_ptr(g->root_out_name), g->version_major, g->version_minor, g->version_patch); | 190 | buf_ptr(g->root_out_name), g->version_major, g->version_minor, g->version_patch); |
| 191 | } | ||
| 192 | soname = buf_sprintf("lib%s.so.%zu", buf_ptr(g->root_out_name), g->version_major); | 192 | soname = buf_sprintf("lib%s.so.%zu", buf_ptr(g->root_out_name), g->version_major); |
| 193 | } | 193 | } |
| 194 | 194 | ||
| ... | @@ -752,9 +752,6 @@ void codegen_link(CodeGen *g, const char *out_file) { | ... | @@ -752,9 +752,6 @@ void codegen_link(CodeGen *g, const char *out_file) { |
| 752 | } | 752 | } |
| 753 | 753 | ||
| 754 | if (g->out_type == OutTypeObj) { | 754 | if (g->out_type == OutTypeObj) { |
| 755 | if (g->want_h_file) { | ||
| 756 | codegen_generate_h_file(g); | ||
| 757 | } | ||
| 758 | if (override_out_file) { | 755 | if (override_out_file) { |
| 759 | assert(g->link_objects.length == 1); | 756 | assert(g->link_objects.length == 1); |
| 760 | Buf *o_file_path = g->link_objects.at(0); | 757 | Buf *o_file_path = g->link_objects.at(0); |
| ... | @@ -798,13 +795,6 @@ void codegen_link(CodeGen *g, const char *out_file) { | ... | @@ -798,13 +795,6 @@ void codegen_link(CodeGen *g, const char *out_file) { |
| 798 | fprintf(stderr, "%s\n", buf_ptr(&diag)); | 795 | fprintf(stderr, "%s\n", buf_ptr(&diag)); |
| 799 | exit(1); | 796 | exit(1); |
| 800 | } | 797 | } |
| 801 | codegen_add_time_event(g, "Generate .h"); | ||
| 802 | |||
| 803 | if (g->out_type == OutTypeLib || | ||
| 804 | g->out_type == OutTypeObj) | ||
| 805 | { | ||
| 806 | codegen_generate_h_file(g); | ||
| 807 | } | ||
| 808 | 798 | ||
| 809 | codegen_add_time_event(g, "Done"); | 799 | codegen_add_time_event(g, "Done"); |
| 810 | 800 |
src/main.cpp+22-11| ... | @@ -35,6 +35,7 @@ static int usage(const char *arg0) { | ... | @@ -35,6 +35,7 @@ static int usage(const char *arg0) { |
| 35 | " --libc-include-dir [path] directory where libc stdlib.h resides\n" | 35 | " --libc-include-dir [path] directory where libc stdlib.h resides\n" |
| 36 | " --name [name] override output name\n" | 36 | " --name [name] override output name\n" |
| 37 | " --output [file] override destination path\n" | 37 | " --output [file] override destination path\n" |
| 38 | " --output-h [file] override generated header file path\n" | ||
| 38 | " --release build with optimizations on and debug protection off\n" | 39 | " --release build with optimizations on and debug protection off\n" |
| 39 | " --static output will be statically linked\n" | 40 | " --static output will be statically linked\n" |
| 40 | " --strip exclude debug symbols\n" | 41 | " --strip exclude debug symbols\n" |
| ... | @@ -118,6 +119,8 @@ enum Cmd { | ... | @@ -118,6 +119,8 @@ enum Cmd { |
| 118 | CmdTargets, | 119 | CmdTargets, |
| 119 | }; | 120 | }; |
| 120 | 121 | ||
| 122 | static const char *default_zig_cache_name = "zig-cache"; | ||
| 123 | |||
| 121 | int main(int argc, char **argv) { | 124 | int main(int argc, char **argv) { |
| 122 | os_init(); | 125 | os_init(); |
| 123 | 126 | ||
| ... | @@ -125,6 +128,7 @@ int main(int argc, char **argv) { | ... | @@ -125,6 +128,7 @@ int main(int argc, char **argv) { |
| 125 | Cmd cmd = CmdInvalid; | 128 | Cmd cmd = CmdInvalid; |
| 126 | const char *in_file = nullptr; | 129 | const char *in_file = nullptr; |
| 127 | const char *out_file = nullptr; | 130 | const char *out_file = nullptr; |
| 131 | const char *out_file_h = nullptr; | ||
| 128 | bool is_release_build = false; | 132 | bool is_release_build = false; |
| 129 | bool strip = false; | 133 | bool strip = false; |
| 130 | bool is_static = false; | 134 | bool is_static = false; |
| ... | @@ -163,7 +167,7 @@ int main(int argc, char **argv) { | ... | @@ -163,7 +167,7 @@ int main(int argc, char **argv) { |
| 163 | size_t ver_minor = 0; | 167 | size_t ver_minor = 0; |
| 164 | size_t ver_patch = 0; | 168 | size_t ver_patch = 0; |
| 165 | bool timing_info = false; | 169 | bool timing_info = false; |
| 166 | const char *cache_dir = "zig-cache"; | 170 | const char *cache_dir = nullptr; |
| 167 | 171 | ||
| 168 | if (argc >= 2 && strcmp(argv[1], "build") == 0) { | 172 | if (argc >= 2 && strcmp(argv[1], "build") == 0) { |
| 169 | const char *zig_exe_path = arg0; | 173 | const char *zig_exe_path = arg0; |
| ... | @@ -200,9 +204,8 @@ int main(int argc, char **argv) { | ... | @@ -200,9 +204,8 @@ int main(int argc, char **argv) { |
| 200 | } | 204 | } |
| 201 | } | 205 | } |
| 202 | 206 | ||
| 203 | CodeGen *g = codegen_create(build_runner_path, nullptr); | 207 | CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe); |
| 204 | codegen_set_out_name(g, buf_create_from_str("build")); | 208 | codegen_set_out_name(g, buf_create_from_str("build")); |
| 205 | codegen_set_out_type(g, OutTypeExe); | ||
| 206 | codegen_set_verbose(g, verbose); | 209 | codegen_set_verbose(g, verbose); |
| 207 | 210 | ||
| 208 | Buf build_file_abs = BUF_INIT; | 211 | Buf build_file_abs = BUF_INIT; |
| ... | @@ -212,7 +215,12 @@ int main(int argc, char **argv) { | ... | @@ -212,7 +215,12 @@ int main(int argc, char **argv) { |
| 212 | os_path_split(&build_file_abs, &build_file_dirname, &build_file_basename); | 215 | os_path_split(&build_file_abs, &build_file_dirname, &build_file_basename); |
| 213 | 216 | ||
| 214 | Buf *full_cache_dir = buf_alloc(); | 217 | Buf *full_cache_dir = buf_alloc(); |
| 215 | os_path_resolve(buf_create_from_str("."), buf_create_from_str(cache_dir), full_cache_dir); | 218 | if (cache_dir == nullptr) { |
| 219 | os_path_join(&build_file_dirname, buf_create_from_str(default_zig_cache_name), full_cache_dir); | ||
| 220 | } else { | ||
| 221 | os_path_resolve(buf_create_from_str("."), buf_create_from_str(cache_dir), full_cache_dir); | ||
| 222 | } | ||
| 223 | |||
| 216 | Buf *path_to_build_exe = buf_alloc(); | 224 | Buf *path_to_build_exe = buf_alloc(); |
| 217 | os_path_join(full_cache_dir, buf_create_from_str("build"), path_to_build_exe); | 225 | os_path_join(full_cache_dir, buf_create_from_str("build"), path_to_build_exe); |
| 218 | codegen_set_cache_dir(g, full_cache_dir); | 226 | codegen_set_cache_dir(g, full_cache_dir); |
| ... | @@ -309,6 +317,8 @@ int main(int argc, char **argv) { | ... | @@ -309,6 +317,8 @@ int main(int argc, char **argv) { |
| 309 | return usage(arg0); | 317 | return usage(arg0); |
| 310 | } else if (strcmp(arg, "--output") == 0) { | 318 | } else if (strcmp(arg, "--output") == 0) { |
| 311 | out_file = argv[i]; | 319 | out_file = argv[i]; |
| 320 | } else if (strcmp(arg, "--output-h") == 0) { | ||
| 321 | out_file_h = argv[i]; | ||
| 312 | } else if (strcmp(arg, "--color") == 0) { | 322 | } else if (strcmp(arg, "--color") == 0) { |
| 313 | if (strcmp(argv[i], "auto") == 0) { | 323 | if (strcmp(argv[i], "auto") == 0) { |
| 314 | color = ErrColorAuto; | 324 | color = ErrColorAuto; |
| ... | @@ -396,6 +406,7 @@ int main(int argc, char **argv) { | ... | @@ -396,6 +406,7 @@ int main(int argc, char **argv) { |
| 396 | cmd = CmdParseH; | 406 | cmd = CmdParseH; |
| 397 | } else if (strcmp(arg, "test") == 0) { | 407 | } else if (strcmp(arg, "test") == 0) { |
| 398 | cmd = CmdTest; | 408 | cmd = CmdTest; |
| 409 | out_type = OutTypeExe; | ||
| 399 | } else if (strcmp(arg, "targets") == 0) { | 410 | } else if (strcmp(arg, "targets") == 0) { |
| 400 | cmd = CmdTargets; | 411 | cmd = CmdTargets; |
| 401 | } else { | 412 | } else { |
| ... | @@ -495,9 +506,11 @@ int main(int argc, char **argv) { | ... | @@ -495,9 +506,11 @@ int main(int argc, char **argv) { |
| 495 | Buf *zig_root_source_file = (cmd == CmdParseH) ? nullptr : in_file_buf; | 506 | Buf *zig_root_source_file = (cmd == CmdParseH) ? nullptr : in_file_buf; |
| 496 | 507 | ||
| 497 | Buf *full_cache_dir = buf_alloc(); | 508 | Buf *full_cache_dir = buf_alloc(); |
| 498 | os_path_resolve(buf_create_from_str("."), buf_create_from_str(cache_dir), full_cache_dir); | 509 | os_path_resolve(buf_create_from_str("."), |
| 510 | buf_create_from_str((cache_dir == nullptr) ? default_zig_cache_name : cache_dir), | ||
| 511 | full_cache_dir); | ||
| 499 | 512 | ||
| 500 | CodeGen *g = codegen_create(zig_root_source_file, target); | 513 | CodeGen *g = codegen_create(zig_root_source_file, target, out_type); |
| 501 | codegen_set_out_name(g, buf_out_name); | 514 | codegen_set_out_name(g, buf_out_name); |
| 502 | codegen_set_lib_version(g, ver_major, ver_minor, ver_patch); | 515 | codegen_set_lib_version(g, ver_major, ver_minor, ver_patch); |
| 503 | codegen_set_is_release(g, is_release_build); | 516 | codegen_set_is_release(g, is_release_build); |
| ... | @@ -510,11 +523,6 @@ int main(int argc, char **argv) { | ... | @@ -510,11 +523,6 @@ int main(int argc, char **argv) { |
| 510 | codegen_set_clang_argv(g, clang_argv.items, clang_argv.length); | 523 | codegen_set_clang_argv(g, clang_argv.items, clang_argv.length); |
| 511 | codegen_set_strip(g, strip); | 524 | codegen_set_strip(g, strip); |
| 512 | codegen_set_is_static(g, is_static); | 525 | codegen_set_is_static(g, is_static); |
| 513 | if (out_type != OutTypeUnknown) { | ||
| 514 | codegen_set_out_type(g, out_type); | ||
| 515 | } else if (cmd == CmdTest) { | ||
| 516 | codegen_set_out_type(g, OutTypeExe); | ||
| 517 | } | ||
| 518 | if (libc_lib_dir) | 526 | if (libc_lib_dir) |
| 519 | codegen_set_libc_lib_dir(g, buf_create_from_str(libc_lib_dir)); | 527 | codegen_set_libc_lib_dir(g, buf_create_from_str(libc_lib_dir)); |
| 520 | if (libc_static_lib_dir) | 528 | if (libc_static_lib_dir) |
| ... | @@ -568,6 +576,9 @@ int main(int argc, char **argv) { | ... | @@ -568,6 +576,9 @@ int main(int argc, char **argv) { |
| 568 | codegen_set_test_name_prefix(g, buf_create_from_str(test_name_prefix)); | 576 | codegen_set_test_name_prefix(g, buf_create_from_str(test_name_prefix)); |
| 569 | } | 577 | } |
| 570 | 578 | ||
| 579 | if (out_file_h) | ||
| 580 | codegen_set_output_h_path(g, buf_create_from_str(out_file_h)); | ||
| 581 | |||
| 571 | if (cmd == CmdBuild) { | 582 | if (cmd == CmdBuild) { |
| 572 | for (size_t i = 0; i < objects.length; i += 1) { | 583 | for (size_t i = 0; i < objects.length; i += 1) { |
| 573 | codegen_add_object(g, buf_create_from_str(objects.at(i))); | 584 | codegen_add_object(g, buf_create_from_str(objects.at(i))); |
std/build.zig+138-62| ... | @@ -37,7 +37,6 @@ pub const Builder = struct { | ... | @@ -37,7 +37,6 @@ pub const Builder = struct { |
| 37 | top_level_steps: List(&TopLevelStep), | 37 | top_level_steps: List(&TopLevelStep), |
| 38 | prefix: []const u8, | 38 | prefix: []const u8, |
| 39 | lib_dir: []const u8, | 39 | lib_dir: []const u8, |
| 40 | out_dir: []u8, // TODO get rid of this | ||
| 41 | installed_files: List([]const u8), | 40 | installed_files: List([]const u8), |
| 42 | build_root: []const u8, | 41 | build_root: []const u8, |
| 43 | cache_root: []const u8, | 42 | cache_root: []const u8, |
| ... | @@ -97,7 +96,6 @@ pub const Builder = struct { | ... | @@ -97,7 +96,6 @@ pub const Builder = struct { |
| 97 | .env_map = %%os.getEnvMap(allocator), | 96 | .env_map = %%os.getEnvMap(allocator), |
| 98 | .prefix = undefined, | 97 | .prefix = undefined, |
| 99 | .lib_dir = undefined, | 98 | .lib_dir = undefined, |
| 100 | .out_dir = %%os.getCwd(allocator), | ||
| 101 | .installed_files = List([]const u8).init(allocator), | 99 | .installed_files = List([]const u8).init(allocator), |
| 102 | .uninstall_tls = TopLevelStep { | 100 | .uninstall_tls = TopLevelStep { |
| 103 | .step = Step.init("uninstall", allocator, makeUninstall), | 101 | .step = Step.init("uninstall", allocator, makeUninstall), |
| ... | @@ -111,7 +109,6 @@ pub const Builder = struct { | ... | @@ -111,7 +109,6 @@ pub const Builder = struct { |
| 111 | } | 109 | } |
| 112 | 110 | ||
| 113 | pub fn deinit(self: &Builder) { | 111 | pub fn deinit(self: &Builder) { |
| 114 | self.allocator.free(self.out_dir); | ||
| 115 | self.lib_paths.deinit(); | 112 | self.lib_paths.deinit(); |
| 116 | self.include_paths.deinit(); | 113 | self.include_paths.deinit(); |
| 117 | self.rpaths.deinit(); | 114 | self.rpaths.deinit(); |
| ... | @@ -172,12 +169,10 @@ pub const Builder = struct { | ... | @@ -172,12 +169,10 @@ pub const Builder = struct { |
| 172 | return exe; | 169 | return exe; |
| 173 | } | 170 | } |
| 174 | 171 | ||
| 175 | pub fn addCommand(self: &Builder, cwd: []const u8, env_map: &const BufMap, | 172 | pub fn addCommand(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap, |
| 176 | path: []const u8, args: []const []const u8) -> &CommandStep | 173 | path: []const u8, args: []const []const u8) -> &CommandStep |
| 177 | { | 174 | { |
| 178 | const cmd = %%self.allocator.create(CommandStep); | 175 | return CommandStep.create(self, cwd, env_map, path, args); |
| 179 | *cmd = CommandStep.init(self, cwd, env_map, path, args); | ||
| 180 | return cmd; | ||
| 181 | } | 176 | } |
| 182 | 177 | ||
| 183 | pub fn addWriteFile(self: &Builder, file_path: []const u8, data: []const u8) -> &WriteFileStep { | 178 | pub fn addWriteFile(self: &Builder, file_path: []const u8, data: []const u8) -> &WriteFileStep { |
| ... | @@ -489,21 +484,22 @@ pub const Builder = struct { | ... | @@ -489,21 +484,22 @@ pub const Builder = struct { |
| 489 | } | 484 | } |
| 490 | 485 | ||
| 491 | fn spawnChild(self: &Builder, exe_path: []const u8, args: []const []const u8) -> %void { | 486 | fn spawnChild(self: &Builder, exe_path: []const u8, args: []const []const u8) -> %void { |
| 492 | return self.spawnChildEnvMap(&self.env_map, exe_path, args); | 487 | return self.spawnChildEnvMap(null, &self.env_map, exe_path, args); |
| 493 | } | 488 | } |
| 494 | 489 | ||
| 495 | fn spawnChildEnvMap(self: &Builder, env_map: &const BufMap, exe_path: []const u8, | 490 | fn spawnChildEnvMap(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap, |
| 496 | args: []const []const u8) -> %void | 491 | exe_path: []const u8, args: []const []const u8) -> %void |
| 497 | { | 492 | { |
| 498 | if (self.verbose) { | 493 | if (self.verbose) { |
| 499 | %%io.stderr.printf("{}", exe_path); | 494 | test (cwd) |yes_cwd| %%io.stderr.print("cd {}; ", yes_cwd); |
| 495 | %%io.stderr.print("{}", exe_path); | ||
| 500 | for (args) |arg| { | 496 | for (args) |arg| { |
| 501 | %%io.stderr.printf(" {}", arg); | 497 | %%io.stderr.print(" {}", arg); |
| 502 | } | 498 | } |
| 503 | %%io.stderr.printf("\n"); | 499 | %%io.stderr.printf("\n"); |
| 504 | } | 500 | } |
| 505 | 501 | ||
| 506 | var child = os.ChildProcess.spawn(exe_path, args, env_map, | 502 | var child = os.ChildProcess.spawn(exe_path, args, cwd, env_map, |
| 507 | StdIo.Ignore, StdIo.Inherit, StdIo.Inherit, self.allocator) %% |err| | 503 | StdIo.Ignore, StdIo.Inherit, StdIo.Inherit, self.allocator) %% |err| |
| 508 | { | 504 | { |
| 509 | %%io.stderr.printf("Unable to spawn {}: {}\n", exe_path, @errorName(err)); | 505 | %%io.stderr.printf("Unable to spawn {}: {}\n", exe_path, @errorName(err)); |
| ... | @@ -511,6 +507,7 @@ pub const Builder = struct { | ... | @@ -511,6 +507,7 @@ pub const Builder = struct { |
| 511 | }; | 507 | }; |
| 512 | 508 | ||
| 513 | const term = child.wait() %% |err| { | 509 | const term = child.wait() %% |err| { |
| 510 | test (cwd) |yes_cwd| %%io.stderr.printf("cwd: {}\n", yes_cwd); | ||
| 514 | %%io.stderr.printf("Unable to spawn {}: {}\n", exe_path, @errorName(err)); | 511 | %%io.stderr.printf("Unable to spawn {}: {}\n", exe_path, @errorName(err)); |
| 515 | return err; | 512 | return err; |
| 516 | }; | 513 | }; |
| ... | @@ -560,11 +557,12 @@ pub const Builder = struct { | ... | @@ -560,11 +557,12 @@ pub const Builder = struct { |
| 560 | 557 | ||
| 561 | fn copyFile(self: &Builder, source_path: []const u8, dest_path: []const u8) { | 558 | fn copyFile(self: &Builder, source_path: []const u8, dest_path: []const u8) { |
| 562 | const dirname = os.path.dirname(dest_path); | 559 | const dirname = os.path.dirname(dest_path); |
| 560 | const abs_source_path = self.pathFromRoot(source_path); | ||
| 563 | os.makePath(self.allocator, dirname) %% |err| { | 561 | os.makePath(self.allocator, dirname) %% |err| { |
| 564 | debug.panic("Unable to create path {}: {}", dirname, @errorName(err)); | 562 | debug.panic("Unable to create path {}: {}", dirname, @errorName(err)); |
| 565 | }; | 563 | }; |
| 566 | os.copyFile(self.allocator, source_path, dest_path) %% |err| { | 564 | os.copyFile(self.allocator, abs_source_path, dest_path) %% |err| { |
| 567 | debug.panic("Unable to copy {} to {}: {}", source_path, dest_path, @errorName(err)); | 565 | debug.panic("Unable to copy {} to {}: {}", abs_source_path, dest_path, @errorName(err)); |
| 568 | }; | 566 | }; |
| 569 | } | 567 | } |
| 570 | 568 | ||
| ... | @@ -628,8 +626,10 @@ pub const LibExeObjStep = struct { | ... | @@ -628,8 +626,10 @@ pub const LibExeObjStep = struct { |
| 628 | release: bool, | 626 | release: bool, |
| 629 | static: bool, | 627 | static: bool, |
| 630 | output_path: ?[]const u8, | 628 | output_path: ?[]const u8, |
| 629 | output_h_path: ?[]const u8, | ||
| 631 | kind: Kind, | 630 | kind: Kind, |
| 632 | version: Version, | 631 | version: Version, |
| 632 | out_h_filename: []const u8, | ||
| 633 | out_filename: []const u8, | 633 | out_filename: []const u8, |
| 634 | out_filename_major_only: []const u8, | 634 | out_filename_major_only: []const u8, |
| 635 | out_filename_name_only: []const u8, | 635 | out_filename_name_only: []const u8, |
| ... | @@ -684,8 +684,10 @@ pub const LibExeObjStep = struct { | ... | @@ -684,8 +684,10 @@ pub const LibExeObjStep = struct { |
| 684 | .link_libs = BufSet.init(builder.allocator), | 684 | .link_libs = BufSet.init(builder.allocator), |
| 685 | .step = Step.init(name, builder.allocator, make), | 685 | .step = Step.init(name, builder.allocator, make), |
| 686 | .output_path = null, | 686 | .output_path = null, |
| 687 | .output_h_path = null, | ||
| 687 | .version = *ver, | 688 | .version = *ver, |
| 688 | .out_filename = undefined, | 689 | .out_filename = undefined, |
| 690 | .out_h_filename = builder.fmt("{}.h", name), | ||
| 689 | .out_filename_major_only = undefined, | 691 | .out_filename_major_only = undefined, |
| 690 | .out_filename_name_only = undefined, | 692 | .out_filename_name_only = undefined, |
| 691 | .object_files = List([]const u8).init(builder.allocator), | 693 | .object_files = List([]const u8).init(builder.allocator), |
| ... | @@ -747,6 +749,27 @@ pub const LibExeObjStep = struct { | ... | @@ -747,6 +749,27 @@ pub const LibExeObjStep = struct { |
| 747 | self.output_path = value; | 749 | self.output_path = value; |
| 748 | } | 750 | } |
| 749 | 751 | ||
| 752 | pub fn getOutputPath(self: &LibExeObjStep) -> []const u8 { | ||
| 753 | test (self.output_path) |output_path| { | ||
| 754 | output_path | ||
| 755 | } else { | ||
| 756 | const wanted_path = %%os.path.join(self.builder.allocator, self.builder.cache_root, self.out_filename); | ||
| 757 | %%os.path.relative(self.builder.allocator, self.builder.build_root, wanted_path) | ||
| 758 | } | ||
| 759 | } | ||
| 760 | |||
| 761 | pub fn setOutputHPath(self: &LibExeObjStep, value: []const u8) { | ||
| 762 | self.output_h_path = value; | ||
| 763 | } | ||
| 764 | |||
| 765 | pub fn getOutputHPath(self: &LibExeObjStep) -> []const u8 { | ||
| 766 | test (self.output_h_path) |output_h_path| { | ||
| 767 | output_h_path | ||
| 768 | } else { | ||
| 769 | %%os.path.join(self.builder.allocator, self.builder.cache_root, self.out_h_filename) | ||
| 770 | } | ||
| 771 | } | ||
| 772 | |||
| 750 | pub fn addAssemblyFile(self: &LibExeObjStep, path: []const u8) { | 773 | pub fn addAssemblyFile(self: &LibExeObjStep, path: []const u8) { |
| 751 | %%self.assembly_files.append(path); | 774 | %%self.assembly_files.append(path); |
| 752 | } | 775 | } |
| ... | @@ -763,14 +786,7 @@ pub const LibExeObjStep = struct { | ... | @@ -763,14 +786,7 @@ pub const LibExeObjStep = struct { |
| 763 | 786 | ||
| 764 | self.step.dependOn(&obj.step); | 787 | self.step.dependOn(&obj.step); |
| 765 | 788 | ||
| 766 | const path_to_obj = test (obj.output_path) |explicit_out_path| { | 789 | %%self.object_files.append(obj.getOutputPath()); |
| 767 | explicit_out_path | ||
| 768 | } else { | ||
| 769 | // TODO make it so we always know where this will be | ||
| 770 | %%os.path.join(self.builder.allocator, self.builder.cache_root, | ||
| 771 | self.builder.fmt("{}{}", obj.name, obj.target.oFileExt())) | ||
| 772 | }; | ||
| 773 | %%self.object_files.append(path_to_obj); | ||
| 774 | } | 790 | } |
| 775 | 791 | ||
| 776 | fn make(step: &Step) -> %void { | 792 | fn make(step: &Step) -> %void { |
| ... | @@ -814,10 +830,16 @@ pub const LibExeObjStep = struct { | ... | @@ -814,10 +830,16 @@ pub const LibExeObjStep = struct { |
| 814 | %%zig_args.append("--release"); | 830 | %%zig_args.append("--release"); |
| 815 | } | 831 | } |
| 816 | 832 | ||
| 817 | test (self.output_path) |output_path| { | 833 | %%zig_args.append("--cache-dir"); |
| 818 | %%zig_args.append("--output"); | 834 | %%zig_args.append(builder.cache_root); |
| 819 | %%zig_args.append(builder.pathFromRoot(output_path)); | 835 | |
| 820 | } | 836 | const output_path = builder.pathFromRoot(self.getOutputPath()); |
| 837 | %%zig_args.append("--output"); | ||
| 838 | %%zig_args.append(output_path); | ||
| 839 | |||
| 840 | const output_h_path = self.getOutputHPath(); | ||
| 841 | %%zig_args.append("--output-h"); | ||
| 842 | %%zig_args.append(builder.pathFromRoot(output_h_path)); | ||
| 821 | 843 | ||
| 822 | %%zig_args.append("--name"); | 844 | %%zig_args.append("--name"); |
| 823 | %%zig_args.append(self.name); | 845 | %%zig_args.append(self.name); |
| ... | @@ -879,10 +901,8 @@ pub const LibExeObjStep = struct { | ... | @@ -879,10 +901,8 @@ pub const LibExeObjStep = struct { |
| 879 | %return builder.spawnChild(builder.zig_exe, zig_args.toSliceConst()); | 901 | %return builder.spawnChild(builder.zig_exe, zig_args.toSliceConst()); |
| 880 | 902 | ||
| 881 | if (self.kind == Kind.Lib and !self.static) { | 903 | if (self.kind == Kind.Lib and !self.static) { |
| 882 | // sym link for libfoo.so.1 to libfoo.so.1.2.3 | 904 | %return doAtomicSymLinks(builder.allocator, output_path, self.out_filename_major_only, |
| 883 | %%os.atomicSymLink(builder.allocator, self.out_filename, self.out_filename_major_only); | 905 | self.out_filename_name_only); |
| 884 | // sym link for libfoo.so to libfoo.so.1 | ||
| 885 | %%os.atomicSymLink(builder.allocator, self.out_filename_major_only, self.out_filename_name_only); | ||
| 886 | } | 906 | } |
| 887 | } | 907 | } |
| 888 | }; | 908 | }; |
| ... | @@ -987,10 +1007,12 @@ pub const TestStep = struct { | ... | @@ -987,10 +1007,12 @@ pub const TestStep = struct { |
| 987 | } | 1007 | } |
| 988 | }; | 1008 | }; |
| 989 | 1009 | ||
| 1010 | // TODO merge with CExecutable | ||
| 990 | pub const CLibrary = struct { | 1011 | pub const CLibrary = struct { |
| 991 | step: Step, | 1012 | step: Step, |
| 992 | name: []const u8, | 1013 | name: []const u8, |
| 993 | out_filename: []const u8, | 1014 | out_filename: []const u8, |
| 1015 | output_path: ?[]const u8, | ||
| 994 | static: bool, | 1016 | static: bool, |
| 995 | version: Version, | 1017 | version: Version, |
| 996 | cflags: List([]const u8), | 1018 | cflags: List([]const u8), |
| ... | @@ -1024,6 +1046,7 @@ pub const CLibrary = struct { | ... | @@ -1024,6 +1046,7 @@ pub const CLibrary = struct { |
| 1024 | .step = Step.init(name, builder.allocator, make), | 1046 | .step = Step.init(name, builder.allocator, make), |
| 1025 | .link_libs = BufSet.init(builder.allocator), | 1047 | .link_libs = BufSet.init(builder.allocator), |
| 1026 | .include_dirs = List([]const u8).init(builder.allocator), | 1048 | .include_dirs = List([]const u8).init(builder.allocator), |
| 1049 | .output_path = null, | ||
| 1027 | .out_filename = undefined, | 1050 | .out_filename = undefined, |
| 1028 | .major_only_filename = undefined, | 1051 | .major_only_filename = undefined, |
| 1029 | .name_only_filename = undefined, | 1052 | .name_only_filename = undefined, |
| ... | @@ -1043,6 +1066,19 @@ pub const CLibrary = struct { | ... | @@ -1043,6 +1066,19 @@ pub const CLibrary = struct { |
| 1043 | } | 1066 | } |
| 1044 | } | 1067 | } |
| 1045 | 1068 | ||
| 1069 | pub fn setOutputPath(self: &CLibrary, value: []const u8) { | ||
| 1070 | self.output_path = value; | ||
| 1071 | } | ||
| 1072 | |||
| 1073 | pub fn getOutputPath(self: &CLibrary) -> []const u8 { | ||
| 1074 | test (self.output_path) |output_path| { | ||
| 1075 | output_path | ||
| 1076 | } else { | ||
| 1077 | const wanted_path = %%os.path.join(self.builder.allocator, self.builder.cache_root, self.out_filename); | ||
| 1078 | %%os.path.relative(self.builder.allocator, self.builder.build_root, wanted_path) | ||
| 1079 | } | ||
| 1080 | } | ||
| 1081 | |||
| 1046 | pub fn linkSystemLibrary(self: &CLibrary, name: []const u8) { | 1082 | pub fn linkSystemLibrary(self: &CLibrary, name: []const u8) { |
| 1047 | %%self.link_libs.put(name); | 1083 | %%self.link_libs.put(name); |
| 1048 | } | 1084 | } |
| ... | @@ -1131,8 +1167,9 @@ pub const CLibrary = struct { | ... | @@ -1131,8 +1167,9 @@ pub const CLibrary = struct { |
| 1131 | defer builder.allocator.free(soname_arg); | 1167 | defer builder.allocator.free(soname_arg); |
| 1132 | %%cc_args.append(soname_arg); | 1168 | %%cc_args.append(soname_arg); |
| 1133 | 1169 | ||
| 1170 | const output_path = builder.pathFromRoot(self.getOutputPath()); | ||
| 1134 | %%cc_args.append("-o"); | 1171 | %%cc_args.append("-o"); |
| 1135 | %%cc_args.append(self.out_filename); | 1172 | %%cc_args.append(output_path); |
| 1136 | 1173 | ||
| 1137 | for (self.object_files.toSliceConst()) |object_file| { | 1174 | for (self.object_files.toSliceConst()) |object_file| { |
| 1138 | %%cc_args.append(builder.pathFromRoot(object_file)); | 1175 | %%cc_args.append(builder.pathFromRoot(object_file)); |
| ... | @@ -1140,10 +1177,8 @@ pub const CLibrary = struct { | ... | @@ -1140,10 +1177,8 @@ pub const CLibrary = struct { |
| 1140 | 1177 | ||
| 1141 | %return builder.spawnChild(cc, cc_args.toSliceConst()); | 1178 | %return builder.spawnChild(cc, cc_args.toSliceConst()); |
| 1142 | 1179 | ||
| 1143 | // sym link for libfoo.so.1 to libfoo.so.1.2.3 | 1180 | %return doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename, |
| 1144 | %%os.atomicSymLink(builder.allocator, self.out_filename, self.major_only_filename); | 1181 | self.name_only_filename); |
| 1145 | // sym link for libfoo.so to libfoo.so.1 | ||
| 1146 | %%os.atomicSymLink(builder.allocator, self.major_only_filename, self.name_only_filename); | ||
| 1147 | } | 1182 | } |
| 1148 | } | 1183 | } |
| 1149 | 1184 | ||
| ... | @@ -1169,9 +1204,11 @@ pub const CExecutable = struct { | ... | @@ -1169,9 +1204,11 @@ pub const CExecutable = struct { |
| 1169 | link_libs: BufSet, | 1204 | link_libs: BufSet, |
| 1170 | target: Target, | 1205 | target: Target, |
| 1171 | include_dirs: List([]const u8), | 1206 | include_dirs: List([]const u8), |
| 1207 | output_path: ?[]const u8, | ||
| 1208 | out_filename: []const u8, | ||
| 1172 | 1209 | ||
| 1173 | pub fn init(builder: &Builder, name: []const u8) -> CExecutable { | 1210 | pub fn init(builder: &Builder, name: []const u8) -> CExecutable { |
| 1174 | CExecutable { | 1211 | var self = CExecutable { |
| 1175 | .builder = builder, | 1212 | .builder = builder, |
| 1176 | .name = name, | 1213 | .name = name, |
| 1177 | .target = Target.Native, | 1214 | .target = Target.Native, |
| ... | @@ -1182,6 +1219,27 @@ pub const CExecutable = struct { | ... | @@ -1182,6 +1219,27 @@ pub const CExecutable = struct { |
| 1182 | .step = Step.init(name, builder.allocator, make), | 1219 | .step = Step.init(name, builder.allocator, make), |
| 1183 | .link_libs = BufSet.init(builder.allocator), | 1220 | .link_libs = BufSet.init(builder.allocator), |
| 1184 | .include_dirs = List([]const u8).init(builder.allocator), | 1221 | .include_dirs = List([]const u8).init(builder.allocator), |
| 1222 | .output_path = null, | ||
| 1223 | .out_filename = undefined, | ||
| 1224 | }; | ||
| 1225 | self.computeOutFileName(); | ||
| 1226 | return self; | ||
| 1227 | } | ||
| 1228 | |||
| 1229 | fn computeOutFileName(self: &CExecutable) { | ||
| 1230 | self.out_filename = self.builder.fmt("{}{}", self.name, self.target.exeFileExt()); | ||
| 1231 | } | ||
| 1232 | |||
| 1233 | pub fn setOutputPath(self: &CExecutable, value: []const u8) { | ||
| 1234 | self.output_path = value; | ||
| 1235 | } | ||
| 1236 | |||
| 1237 | pub fn getOutputPath(self: &CExecutable) -> []const u8 { | ||
| 1238 | test (self.output_path) |output_path| { | ||
| 1239 | self.builder.pathFromRoot(output_path) | ||
| 1240 | } else { | ||
| 1241 | const wanted_path = %%os.path.join(self.builder.allocator, self.builder.cache_root, self.out_filename); | ||
| 1242 | %%os.path.relative(self.builder.allocator, self.builder.build_root, wanted_path) | ||
| 1185 | } | 1243 | } |
| 1186 | } | 1244 | } |
| 1187 | 1245 | ||
| ... | @@ -1191,15 +1249,15 @@ pub const CExecutable = struct { | ... | @@ -1191,15 +1249,15 @@ pub const CExecutable = struct { |
| 1191 | 1249 | ||
| 1192 | pub fn linkCLibrary(self: &CExecutable, clib: &CLibrary) { | 1250 | pub fn linkCLibrary(self: &CExecutable, clib: &CLibrary) { |
| 1193 | self.step.dependOn(&clib.step); | 1251 | self.step.dependOn(&clib.step); |
| 1194 | %%self.full_path_libs.append(clib.out_filename); | 1252 | %%self.full_path_libs.append(clib.getOutputPath()); |
| 1195 | } | 1253 | } |
| 1196 | 1254 | ||
| 1197 | pub fn linkLibrary(self: &CExecutable, lib: &LibExeObjStep) { | 1255 | pub fn linkLibrary(self: &CExecutable, lib: &LibExeObjStep) { |
| 1198 | assert(lib.kind == LibExeObjStep.Kind.Lib); | 1256 | assert(lib.kind == LibExeObjStep.Kind.Lib); |
| 1199 | self.step.dependOn(&lib.step); | 1257 | self.step.dependOn(&lib.step); |
| 1200 | %%self.full_path_libs.append(lib.out_filename); | 1258 | %%self.full_path_libs.append(lib.getOutputPath()); |
| 1201 | // TODO should be some kind of isolated directory that only has this header in it | 1259 | // TODO should be some kind of isolated directory that only has this header in it |
| 1202 | %%self.include_dirs.append(self.builder.out_dir); | 1260 | %%self.include_dirs.append(self.builder.cache_root); |
| 1203 | } | 1261 | } |
| 1204 | 1262 | ||
| 1205 | pub fn addObject(self: &CExecutable, obj: &LibExeObjStep) { | 1263 | pub fn addObject(self: &CExecutable, obj: &LibExeObjStep) { |
| ... | @@ -1207,12 +1265,10 @@ pub const CExecutable = struct { | ... | @@ -1207,12 +1265,10 @@ pub const CExecutable = struct { |
| 1207 | 1265 | ||
| 1208 | self.step.dependOn(&obj.step); | 1266 | self.step.dependOn(&obj.step); |
| 1209 | 1267 | ||
| 1210 | // TODO make it so we always know where this will be | 1268 | %%self.object_files.append(obj.getOutputPath()); |
| 1211 | %%self.object_files.append(%%os.path.join(self.builder.allocator, self.builder.cache_root, | ||
| 1212 | self.builder.fmt("{}{}", obj.name, obj.target.oFileExt()))); | ||
| 1213 | 1269 | ||
| 1214 | // TODO should be some kind of isolated directory that only has this header in it | 1270 | // TODO should be some kind of isolated directory that only has this header in it |
| 1215 | %%self.include_dirs.append(self.builder.out_dir); | 1271 | %%self.include_dirs.append(self.builder.cache_root); |
| 1216 | } | 1272 | } |
| 1217 | 1273 | ||
| 1218 | pub fn addSourceFile(self: &CExecutable, file: []const u8) { | 1274 | pub fn addSourceFile(self: &CExecutable, file: []const u8) { |
| ... | @@ -1256,7 +1312,6 @@ pub const CExecutable = struct { | ... | @@ -1256,7 +1312,6 @@ pub const CExecutable = struct { |
| 1256 | %%cc_args.append("-c"); | 1312 | %%cc_args.append("-c"); |
| 1257 | %%cc_args.append(builder.pathFromRoot(source_file)); | 1313 | %%cc_args.append(builder.pathFromRoot(source_file)); |
| 1258 | 1314 | ||
| 1259 | // TODO don't dump the .o file in the same place as the source file | ||
| 1260 | const rel_src_path = %%os.path.relative(builder.allocator, builder.build_root, source_file); | 1315 | const rel_src_path = %%os.path.relative(builder.allocator, builder.build_root, source_file); |
| 1261 | const cache_o_src = %%os.path.join(builder.allocator, builder.cache_root, rel_src_path); | 1316 | const cache_o_src = %%os.path.join(builder.allocator, builder.cache_root, rel_src_path); |
| 1262 | const cache_o_dir = os.path.dirname(cache_o_src); | 1317 | const cache_o_dir = os.path.dirname(cache_o_src); |
| ... | @@ -1276,26 +1331,28 @@ pub const CExecutable = struct { | ... | @@ -1276,26 +1331,28 @@ pub const CExecutable = struct { |
| 1276 | 1331 | ||
| 1277 | %return builder.spawnChild(cc, cc_args.toSliceConst()); | 1332 | %return builder.spawnChild(cc, cc_args.toSliceConst()); |
| 1278 | 1333 | ||
| 1279 | %%self.object_files.append(cache_o_file); | 1334 | %%self.object_files.append(%%os.path.relative(builder.allocator, builder.build_root, cache_o_file)); |
| 1280 | } | 1335 | } |
| 1281 | 1336 | ||
| 1282 | %%cc_args.resize(0); | 1337 | %%cc_args.resize(0); |
| 1283 | 1338 | ||
| 1284 | for (self.object_files.toSliceConst()) |object_file| { | 1339 | for (self.object_files.toSliceConst()) |object_file| { |
| 1285 | %%cc_args.append(object_file); | 1340 | %%cc_args.append(builder.pathFromRoot(object_file)); |
| 1286 | } | 1341 | } |
| 1287 | 1342 | ||
| 1343 | const output_path = builder.pathFromRoot(self.getOutputPath()); | ||
| 1288 | %%cc_args.append("-o"); | 1344 | %%cc_args.append("-o"); |
| 1289 | %%cc_args.append(self.name); | 1345 | %%cc_args.append(output_path); |
| 1290 | 1346 | ||
| 1291 | const rpath_arg = builder.fmt("-Wl,-rpath,{}", builder.out_dir); | 1347 | const rpath_arg = builder.fmt("-Wl,-rpath,{}", |
| 1348 | %%os.path.real(builder.allocator, builder.cache_root)); | ||
| 1292 | defer builder.allocator.free(rpath_arg); | 1349 | defer builder.allocator.free(rpath_arg); |
| 1293 | %%cc_args.append(rpath_arg); | 1350 | %%cc_args.append(rpath_arg); |
| 1294 | 1351 | ||
| 1295 | %%cc_args.append("-rdynamic"); | 1352 | %%cc_args.append("-rdynamic"); |
| 1296 | 1353 | ||
| 1297 | for (self.full_path_libs.toSliceConst()) |full_path_lib| { | 1354 | for (self.full_path_libs.toSliceConst()) |full_path_lib| { |
| 1298 | %%cc_args.append(full_path_lib); | 1355 | %%cc_args.append(builder.pathFromRoot(full_path_lib)); |
| 1299 | } | 1356 | } |
| 1300 | 1357 | ||
| 1301 | %return builder.spawnChild(cc, cc_args.toSliceConst()); | 1358 | %return builder.spawnChild(cc, cc_args.toSliceConst()); |
| ... | @@ -1317,27 +1374,29 @@ pub const CommandStep = struct { | ... | @@ -1317,27 +1374,29 @@ pub const CommandStep = struct { |
| 1317 | builder: &Builder, | 1374 | builder: &Builder, |
| 1318 | exe_path: []const u8, | 1375 | exe_path: []const u8, |
| 1319 | args: []const []const u8, | 1376 | args: []const []const u8, |
| 1320 | cwd: []const u8, | 1377 | cwd: ?[]const u8, |
| 1321 | env_map: &const BufMap, | 1378 | env_map: &const BufMap, |
| 1322 | 1379 | ||
| 1323 | pub fn init(builder: &Builder, cwd: []const u8, env_map: &const BufMap, | 1380 | pub fn create(builder: &Builder, cwd: ?[]const u8, env_map: &const BufMap, |
| 1324 | exe_path: []const u8, args: []const []const u8) -> CommandStep | 1381 | exe_path: []const u8, args: []const []const u8) -> &CommandStep |
| 1325 | { | 1382 | { |
| 1326 | CommandStep { | 1383 | const self = %%builder.allocator.create(CommandStep); |
| 1384 | *self = CommandStep { | ||
| 1327 | .builder = builder, | 1385 | .builder = builder, |
| 1328 | .step = Step.init(exe_path, builder.allocator, make), | 1386 | .step = Step.init(exe_path, builder.allocator, make), |
| 1329 | .exe_path = exe_path, | 1387 | .exe_path = exe_path, |
| 1330 | .args = args, | 1388 | .args = args, |
| 1331 | .cwd = cwd, | 1389 | .cwd = cwd, |
| 1332 | .env_map = env_map, | 1390 | .env_map = env_map, |
| 1333 | } | 1391 | }; |
| 1392 | return self; | ||
| 1334 | } | 1393 | } |
| 1335 | 1394 | ||
| 1336 | fn make(step: &Step) -> %void { | 1395 | fn make(step: &Step) -> %void { |
| 1337 | const self = @fieldParentPtr(CommandStep, "step", step); | 1396 | const self = @fieldParentPtr(CommandStep, "step", step); |
| 1338 | 1397 | ||
| 1339 | // TODO set cwd | 1398 | const cwd = test (self.cwd) |cwd| self.builder.pathFromRoot(cwd) else null; |
| 1340 | return self.builder.spawnChildEnvMap(self.env_map, self.exe_path, self.args); | 1399 | return self.builder.spawnChildEnvMap(cwd, self.env_map, self.exe_path, self.args); |
| 1341 | } | 1400 | } |
| 1342 | }; | 1401 | }; |
| 1343 | 1402 | ||
| ... | @@ -1367,12 +1426,10 @@ pub const InstallCLibraryStep = struct { | ... | @@ -1367,12 +1426,10 @@ pub const InstallCLibraryStep = struct { |
| 1367 | const self = @fieldParentPtr(InstallCLibraryStep, "step", step); | 1426 | const self = @fieldParentPtr(InstallCLibraryStep, "step", step); |
| 1368 | const builder = self.builder; | 1427 | const builder = self.builder; |
| 1369 | 1428 | ||
| 1370 | self.builder.copyFile(self.lib.out_filename, self.dest_file); | 1429 | self.builder.copyFile(self.lib.getOutputPath(), self.dest_file); |
| 1371 | if (!self.lib.static) { | 1430 | if (!self.lib.static) { |
| 1372 | const dest_major_only = %%os.path.join(builder.allocator, builder.lib_dir, self.lib.major_only_filename); | 1431 | %return doAtomicSymLinks(self.builder.allocator, self.dest_file, self.lib.major_only_filename, |
| 1373 | const dest_name_only = %%os.path.join(builder.allocator, builder.lib_dir, self.lib.name_only_filename); | 1432 | self.lib.name_only_filename); |
| 1374 | %%os.atomicSymLink(self.builder.allocator, self.lib.out_filename, dest_major_only); | ||
| 1375 | %%os.atomicSymLink(self.builder.allocator, self.lib.major_only_filename, dest_name_only); | ||
| 1376 | } | 1433 | } |
| 1377 | } | 1434 | } |
| 1378 | }; | 1435 | }; |
| ... | @@ -1506,3 +1563,22 @@ pub const Step = struct { | ... | @@ -1506,3 +1563,22 @@ pub const Step = struct { |
| 1506 | 1563 | ||
| 1507 | fn makeNoOp(self: &Step) -> %void {} | 1564 | fn makeNoOp(self: &Step) -> %void {} |
| 1508 | }; | 1565 | }; |
| 1566 | |||
| 1567 | fn doAtomicSymLinks(allocator: &Allocator, output_path: []const u8, filename_major_only: []const u8, | ||
| 1568 | filename_name_only: []const u8) -> %void | ||
| 1569 | { | ||
| 1570 | const out_dir = os.path.dirname(output_path); | ||
| 1571 | const out_basename = os.path.basename(output_path); | ||
| 1572 | // sym link for libfoo.so.1 to libfoo.so.1.2.3 | ||
| 1573 | const major_only_path = %%os.path.join(allocator, out_dir, filename_major_only); | ||
| 1574 | os.atomicSymLink(allocator, out_basename, major_only_path) %% |err| { | ||
| 1575 | %%io.stderr.printf("Unable to symlink {} -> {}\n", major_only_path, out_basename); | ||
| 1576 | return err; | ||
| 1577 | }; | ||
| 1578 | // sym link for libfoo.so to libfoo.so.1 | ||
| 1579 | const name_only_path = %%os.path.join(allocator, out_dir, filename_name_only); | ||
| 1580 | os.atomicSymLink(allocator, filename_major_only, name_only_path) %% |err| { | ||
| 1581 | %%io.stderr.printf("Unable to symlink {} -> {}\n", name_only_path, filename_major_only); | ||
| 1582 | return err; | ||
| 1583 | }; | ||
| 1584 | } |
std/fmt.zig+3-3| ... | @@ -345,17 +345,17 @@ fn bufPrintWrite(context: &BufPrintContext, bytes: []const u8) -> bool { | ... | @@ -345,17 +345,17 @@ fn bufPrintWrite(context: &BufPrintContext, bytes: []const u8) -> bool { |
| 345 | return true; | 345 | return true; |
| 346 | } | 346 | } |
| 347 | 347 | ||
| 348 | pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) { | 348 | pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) -> []u8 { |
| 349 | var context = BufPrintContext { .remaining = buf, }; | 349 | var context = BufPrintContext { .remaining = buf, }; |
| 350 | _ = format(&context, bufPrintWrite, fmt, args); | 350 | _ = format(&context, bufPrintWrite, fmt, args); |
| 351 | return buf[0...buf.len - context.remaining.len]; | ||
| 351 | } | 352 | } |
| 352 | 353 | ||
| 353 | pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ...) -> %[]u8 { | 354 | pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ...) -> %[]u8 { |
| 354 | var size: usize = 0; | 355 | var size: usize = 0; |
| 355 | _ = format(&size, countSize, fmt, args); | 356 | _ = format(&size, countSize, fmt, args); |
| 356 | const buf = %return allocator.alloc(u8, size); | 357 | const buf = %return allocator.alloc(u8, size); |
| 357 | bufPrint(buf, fmt, args); | 358 | return bufPrint(buf, fmt, args); |
| 358 | return buf; | ||
| 359 | } | 359 | } |
| 360 | 360 | ||
| 361 | fn countSize(size: &usize, bytes: []const u8) -> bool { | 361 | fn countSize(size: &usize, bytes: []const u8) -> bool { |
std/os/child_process.zig+10-3| ... | @@ -30,12 +30,13 @@ pub const ChildProcess = struct { | ... | @@ -30,12 +30,13 @@ pub const ChildProcess = struct { |
| 30 | Close, | 30 | Close, |
| 31 | }; | 31 | }; |
| 32 | 32 | ||
| 33 | pub fn spawn(exe_path: []const u8, args: []const []const u8, env_map: &const BufMap, | 33 | pub fn spawn(exe_path: []const u8, args: []const []const u8, |
| 34 | cwd: ?[]const u8, env_map: &const BufMap, | ||
| 34 | stdin: StdIo, stdout: StdIo, stderr: StdIo, allocator: &Allocator) -> %ChildProcess | 35 | stdin: StdIo, stdout: StdIo, stderr: StdIo, allocator: &Allocator) -> %ChildProcess |
| 35 | { | 36 | { |
| 36 | switch (@compileVar("os")) { | 37 | switch (@compileVar("os")) { |
| 37 | Os.linux, Os.macosx, Os.ios, Os.darwin => { | 38 | Os.linux, Os.macosx, Os.ios, Os.darwin => { |
| 38 | return spawnPosix(exe_path, args, env_map, stdin, stdout, stderr, allocator); | 39 | return spawnPosix(exe_path, args, cwd, env_map, stdin, stdout, stderr, allocator); |
| 39 | }, | 40 | }, |
| 40 | else => @compileError("Unsupported OS"), | 41 | else => @compileError("Unsupported OS"), |
| 41 | } | 42 | } |
| ... | @@ -98,7 +99,8 @@ pub const ChildProcess = struct { | ... | @@ -98,7 +99,8 @@ pub const ChildProcess = struct { |
| 98 | }; | 99 | }; |
| 99 | } | 100 | } |
| 100 | 101 | ||
| 101 | fn spawnPosix(exe_path: []const u8, args: []const []const u8, env_map: &const BufMap, | 102 | fn spawnPosix(exe_path: []const u8, args: []const []const u8, |
| 103 | maybe_cwd: ?[]const u8, env_map: &const BufMap, | ||
| 102 | stdin: StdIo, stdout: StdIo, stderr: StdIo, allocator: &Allocator) -> %ChildProcess | 104 | stdin: StdIo, stdout: StdIo, stderr: StdIo, allocator: &Allocator) -> %ChildProcess |
| 103 | { | 105 | { |
| 104 | // TODO issue #295 | 106 | // TODO issue #295 |
| ... | @@ -155,6 +157,11 @@ pub const ChildProcess = struct { | ... | @@ -155,6 +157,11 @@ pub const ChildProcess = struct { |
| 155 | setUpChildIo(stderr, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) %% | 157 | setUpChildIo(stderr, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) %% |
| 156 | |err| forkChildErrReport(err_pipe[1], err); | 158 | |err| forkChildErrReport(err_pipe[1], err); |
| 157 | 159 | ||
| 160 | test (maybe_cwd) |cwd| { | ||
| 161 | os.changeCurDir(allocator, cwd) %% | ||
| 162 | |err| forkChildErrReport(err_pipe[1], err); | ||
| 163 | } | ||
| 164 | |||
| 158 | os.posixExecve(exe_path, args, env_map, allocator) %% | 165 | os.posixExecve(exe_path, args, env_map, allocator) %% |
| 159 | |err| forkChildErrReport(err_pipe[1], err); | 166 | |err| forkChildErrReport(err_pipe[1], err); |
| 160 | } | 167 | } |
std/os/index.zig+57| ... | @@ -780,3 +780,60 @@ pub const Dir = struct { | ... | @@ -780,3 +780,60 @@ pub const Dir = struct { |
| 780 | }; | 780 | }; |
| 781 | } | 781 | } |
| 782 | }; | 782 | }; |
| 783 | |||
| 784 | pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) -> %void { | ||
| 785 | const path_buf = %return allocator.alloc(u8, dir_path.len + 1); | ||
| 786 | defer allocator.free(path_buf); | ||
| 787 | |||
| 788 | mem.copy(u8, path_buf, dir_path); | ||
| 789 | path_buf[dir_path.len] = 0; | ||
| 790 | |||
| 791 | const err = posix.getErrno(posix.chdir(path_buf.ptr)); | ||
| 792 | if (err > 0) { | ||
| 793 | return switch (err) { | ||
| 794 | errno.EACCES => error.AccessDenied, | ||
| 795 | errno.EFAULT => unreachable, | ||
| 796 | errno.EIO => error.FileSystem, | ||
| 797 | errno.ELOOP => error.SymLinkLoop, | ||
| 798 | errno.ENAMETOOLONG => error.NameTooLong, | ||
| 799 | errno.ENOENT => error.FileNotFound, | ||
| 800 | errno.ENOMEM => error.SystemResources, | ||
| 801 | errno.ENOTDIR => error.NotDir, | ||
| 802 | else => error.Unexpected, | ||
| 803 | }; | ||
| 804 | } | ||
| 805 | } | ||
| 806 | |||
| 807 | /// Read value of a symbolic link. | ||
| 808 | pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 { | ||
| 809 | const path_buf = %return allocator.alloc(u8, pathname.len + 1); | ||
| 810 | defer allocator.free(path_buf); | ||
| 811 | |||
| 812 | mem.copy(u8, path_buf, pathname); | ||
| 813 | path_buf[pathname.len] = 0; | ||
| 814 | |||
| 815 | var result_buf = %return allocator.alloc(u8, 1024); | ||
| 816 | %defer allocator.free(result_buf); | ||
| 817 | while (true) { | ||
| 818 | const ret_val = posix.readlink(path_buf.ptr, result_buf.ptr, result_buf.len); | ||
| 819 | const err = posix.getErrno(ret_val); | ||
| 820 | if (err > 0) { | ||
| 821 | return switch (err) { | ||
| 822 | errno.EACCES => error.AccessDenied, | ||
| 823 | errno.EFAULT, errno.EINVAL => unreachable, | ||
| 824 | errno.EIO => error.FileSystem, | ||
| 825 | errno.ELOOP => error.SymLinkLoop, | ||
| 826 | errno.ENAMETOOLONG => error.NameTooLong, | ||
| 827 | errno.ENOENT => error.FileNotFound, | ||
| 828 | errno.ENOMEM => error.SystemResources, | ||
| 829 | errno.ENOTDIR => error.NotDir, | ||
| 830 | else => error.Unexpected, | ||
| 831 | }; | ||
| 832 | } | ||
| 833 | if (ret_val == result_buf.len) { | ||
| 834 | result_buf = %return allocator.realloc(u8, result_buf, result_buf.len * 2); | ||
| 835 | continue; | ||
| 836 | } | ||
| 837 | return result_buf[0...ret_val]; | ||
| 838 | } | ||
| 839 | } |
std/os/linux.zig+8| ... | @@ -335,6 +335,10 @@ pub fn dup2(old: i32, new: i32) -> usize { | ... | @@ -335,6 +335,10 @@ pub fn dup2(old: i32, new: i32) -> usize { |
| 335 | arch.syscall2(arch.SYS_dup2, usize(old), usize(new)) | 335 | arch.syscall2(arch.SYS_dup2, usize(old), usize(new)) |
| 336 | } | 336 | } |
| 337 | 337 | ||
| 338 | pub fn chdir(path: &const u8) -> usize { | ||
| 339 | arch.syscall1(arch.SYS_chdir, usize(path)) | ||
| 340 | } | ||
| 341 | |||
| 338 | pub fn execve(path: &const u8, argv: &const ?&const u8, envp: &const ?&const u8) -> usize { | 342 | pub fn execve(path: &const u8, argv: &const ?&const u8, envp: &const ?&const u8) -> usize { |
| 339 | arch.syscall3(arch.SYS_execve, usize(path), usize(argv), usize(envp)) | 343 | arch.syscall3(arch.SYS_execve, usize(path), usize(argv), usize(envp)) |
| 340 | } | 344 | } |
| ... | @@ -356,6 +360,10 @@ pub fn isatty(fd: i32) -> bool { | ... | @@ -356,6 +360,10 @@ pub fn isatty(fd: i32) -> bool { |
| 356 | return arch.syscall3(arch.SYS_ioctl, usize(fd), TIOCGWINSZ, usize(&wsz)) == 0; | 360 | return arch.syscall3(arch.SYS_ioctl, usize(fd), TIOCGWINSZ, usize(&wsz)) == 0; |
| 357 | } | 361 | } |
| 358 | 362 | ||
| 363 | pub fn readlink(noalias path: &const u8, noalias buf_ptr: &u8, buf_len: usize) -> usize { | ||
| 364 | arch.syscall3(arch.SYS_readlink, usize(path), usize(buf_ptr), buf_len) | ||
| 365 | } | ||
| 366 | |||
| 359 | pub fn mkdir(path: &const u8, mode: usize) -> usize { | 367 | pub fn mkdir(path: &const u8, mode: usize) -> usize { |
| 360 | arch.syscall2(arch.SYS_mkdir, usize(path), mode) | 368 | arch.syscall2(arch.SYS_mkdir, usize(path), mode) |
| 361 | } | 369 | } |
std/os/path.zig+55| ... | @@ -1,9 +1,11 @@ | ... | @@ -1,9 +1,11 @@ |
| 1 | const debug = @import("../debug.zig"); | 1 | const debug = @import("../debug.zig"); |
| 2 | const assert = debug.assert; | 2 | const assert = debug.assert; |
| 3 | const mem = @import("../mem.zig"); | 3 | const mem = @import("../mem.zig"); |
| 4 | const fmt = @import("../fmt.zig"); | ||
| 4 | const Allocator = mem.Allocator; | 5 | const Allocator = mem.Allocator; |
| 5 | const os = @import("index.zig"); | 6 | const os = @import("index.zig"); |
| 6 | const math = @import("../math.zig"); | 7 | const math = @import("../math.zig"); |
| 8 | const posix = os.posix; | ||
| 7 | 9 | ||
| 8 | pub const sep = switch (@compileVar("os")) { | 10 | pub const sep = switch (@compileVar("os")) { |
| 9 | Os.windows => '\\', | 11 | Os.windows => '\\', |
| ... | @@ -185,6 +187,45 @@ fn testDirname(input: []const u8, expected_output: []const u8) { | ... | @@ -185,6 +187,45 @@ fn testDirname(input: []const u8, expected_output: []const u8) { |
| 185 | assert(mem.eql(u8, dirname(input), expected_output)); | 187 | assert(mem.eql(u8, dirname(input), expected_output)); |
| 186 | } | 188 | } |
| 187 | 189 | ||
| 190 | pub fn basename(path: []const u8) -> []const u8 { | ||
| 191 | if (path.len == 0) | ||
| 192 | return []u8{}; | ||
| 193 | |||
| 194 | var end_index: usize = path.len - 1; | ||
| 195 | while (path[end_index] == '/') { | ||
| 196 | if (end_index == 0) | ||
| 197 | return []u8{}; | ||
| 198 | end_index -= 1; | ||
| 199 | } | ||
| 200 | var start_index: usize = end_index; | ||
| 201 | end_index += 1; | ||
| 202 | while (path[start_index] != '/') { | ||
| 203 | if (start_index == 0) | ||
| 204 | return path[0...end_index]; | ||
| 205 | start_index -= 1; | ||
| 206 | } | ||
| 207 | |||
| 208 | return path[start_index + 1...end_index]; | ||
| 209 | } | ||
| 210 | |||
| 211 | test "os.path.basename" { | ||
| 212 | testBasename("", ""); | ||
| 213 | testBasename("/", ""); | ||
| 214 | testBasename("/dir/basename.ext", "basename.ext"); | ||
| 215 | testBasename("/basename.ext", "basename.ext"); | ||
| 216 | testBasename("basename.ext", "basename.ext"); | ||
| 217 | testBasename("basename.ext/", "basename.ext"); | ||
| 218 | testBasename("basename.ext//", "basename.ext"); | ||
| 219 | testBasename("/aaa/bbb", "bbb"); | ||
| 220 | testBasename("/aaa/", "aaa"); | ||
| 221 | testBasename("/aaa/b", "b"); | ||
| 222 | testBasename("/a/b", "b"); | ||
| 223 | testBasename("//a", "a"); | ||
| 224 | } | ||
| 225 | fn testBasename(input: []const u8, expected_output: []const u8) { | ||
| 226 | assert(mem.eql(u8, basename(input), expected_output)); | ||
| 227 | } | ||
| 228 | |||
| 188 | /// Returns the relative path from ::from to ::to. If ::from and ::to each | 229 | /// Returns the relative path from ::from to ::to. If ::from and ::to each |
| 189 | /// resolve to the same path (after calling ::resolve on each), a zero-length | 230 | /// resolve to the same path (after calling ::resolve on each), a zero-length |
| 190 | /// string is returned. | 231 | /// string is returned. |
| ... | @@ -252,3 +293,17 @@ fn testRelative(from: []const u8, to: []const u8, expected_output: []const u8) { | ... | @@ -252,3 +293,17 @@ fn testRelative(from: []const u8, to: []const u8, expected_output: []const u8) { |
| 252 | const result = %%relative(&debug.global_allocator, from, to); | 293 | const result = %%relative(&debug.global_allocator, from, to); |
| 253 | assert(mem.eql(u8, result, expected_output)); | 294 | assert(mem.eql(u8, result, expected_output)); |
| 254 | } | 295 | } |
| 296 | |||
| 297 | /// Return the canonicalized absolute pathname. | ||
| 298 | /// Expands all symbolic links and resolves references to `.`, `..`, and | ||
| 299 | /// extra `/` characters in ::pathname. | ||
| 300 | /// Caller must deallocate result. | ||
| 301 | pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 { | ||
| 302 | const fd = %return os.posixOpen(pathname, posix.O_PATH|posix.O_NONBLOCK|posix.O_CLOEXEC, 0, allocator); | ||
| 303 | defer os.posixClose(fd); | ||
| 304 | |||
| 305 | var buf: ["/proc/self/fd/-2147483648".len]u8 = undefined; | ||
| 306 | const proc_path = fmt.bufPrint(buf[0...], "/proc/self/fd/{}", fd); | ||
| 307 | |||
| 308 | return os.readLink(allocator, proc_path); | ||
| 309 | } |
test/tests.zig+16-16| ... | @@ -189,7 +189,7 @@ pub const CompareOutputContext = struct { | ... | @@ -189,7 +189,7 @@ pub const CompareOutputContext = struct { |
| 189 | 189 | ||
| 190 | %%io.stderr.printf("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name); | 190 | %%io.stderr.printf("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name); |
| 191 | 191 | ||
| 192 | var child = os.ChildProcess.spawn(full_exe_path, [][]u8{}, &b.env_map, | 192 | var child = os.ChildProcess.spawn(full_exe_path, [][]u8{}, null, &b.env_map, |
| 193 | StdIo.Ignore, StdIo.Pipe, StdIo.Pipe, b.allocator) %% |err| | 193 | StdIo.Ignore, StdIo.Pipe, StdIo.Pipe, b.allocator) %% |err| |
| 194 | { | 194 | { |
| 195 | debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err)); | 195 | debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err)); |
| ... | @@ -264,7 +264,7 @@ pub const CompareOutputContext = struct { | ... | @@ -264,7 +264,7 @@ pub const CompareOutputContext = struct { |
| 264 | 264 | ||
| 265 | %%io.stderr.printf("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name); | 265 | %%io.stderr.printf("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name); |
| 266 | 266 | ||
| 267 | var child = os.ChildProcess.spawn(full_exe_path, [][]u8{}, &b.env_map, | 267 | var child = os.ChildProcess.spawn(full_exe_path, [][]u8{}, null, &b.env_map, |
| 268 | StdIo.Ignore, StdIo.Pipe, StdIo.Pipe, b.allocator) %% |err| | 268 | StdIo.Ignore, StdIo.Pipe, StdIo.Pipe, b.allocator) %% |err| |
| 269 | { | 269 | { |
| 270 | debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err)); | 270 | debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err)); |
| ... | @@ -344,8 +344,8 @@ pub const CompareOutputContext = struct { | ... | @@ -344,8 +344,8 @@ pub const CompareOutputContext = struct { |
| 344 | pub fn addCase(self: &CompareOutputContext, case: &const TestCase) { | 344 | pub fn addCase(self: &CompareOutputContext, case: &const TestCase) { |
| 345 | const b = self.b; | 345 | const b = self.b; |
| 346 | 346 | ||
| 347 | const root_src = %%os.path.join(b.allocator, "test_artifacts", case.sources.items[0].filename); | 347 | const root_src = %%os.path.join(b.allocator, b.cache_root, case.sources.items[0].filename); |
| 348 | const exe_path = %%os.path.join(b.allocator, "test_artifacts", "test"); | 348 | const exe_path = %%os.path.join(b.allocator, b.cache_root, "test"); |
| 349 | 349 | ||
| 350 | switch (case.special) { | 350 | switch (case.special) { |
| 351 | Special.Asm => { | 351 | Special.Asm => { |
| ... | @@ -360,7 +360,7 @@ pub const CompareOutputContext = struct { | ... | @@ -360,7 +360,7 @@ pub const CompareOutputContext = struct { |
| 360 | exe.setOutputPath(exe_path); | 360 | exe.setOutputPath(exe_path); |
| 361 | 361 | ||
| 362 | for (case.sources.toSliceConst()) |src_file| { | 362 | for (case.sources.toSliceConst()) |src_file| { |
| 363 | const expanded_src_path = %%os.path.join(b.allocator, "test_artifacts", src_file.filename); | 363 | const expanded_src_path = %%os.path.join(b.allocator, b.cache_root, src_file.filename); |
| 364 | const write_src = b.addWriteFile(expanded_src_path, src_file.source); | 364 | const write_src = b.addWriteFile(expanded_src_path, src_file.source); |
| 365 | exe.step.dependOn(&write_src.step); | 365 | exe.step.dependOn(&write_src.step); |
| 366 | } | 366 | } |
| ... | @@ -388,7 +388,7 @@ pub const CompareOutputContext = struct { | ... | @@ -388,7 +388,7 @@ pub const CompareOutputContext = struct { |
| 388 | } | 388 | } |
| 389 | 389 | ||
| 390 | for (case.sources.toSliceConst()) |src_file| { | 390 | for (case.sources.toSliceConst()) |src_file| { |
| 391 | const expanded_src_path = %%os.path.join(b.allocator, "test_artifacts", src_file.filename); | 391 | const expanded_src_path = %%os.path.join(b.allocator, b.cache_root, src_file.filename); |
| 392 | const write_src = b.addWriteFile(expanded_src_path, src_file.source); | 392 | const write_src = b.addWriteFile(expanded_src_path, src_file.source); |
| 393 | exe.step.dependOn(&write_src.step); | 393 | exe.step.dependOn(&write_src.step); |
| 394 | } | 394 | } |
| ... | @@ -401,7 +401,7 @@ pub const CompareOutputContext = struct { | ... | @@ -401,7 +401,7 @@ pub const CompareOutputContext = struct { |
| 401 | } | 401 | } |
| 402 | }, | 402 | }, |
| 403 | Special.DebugSafety => { | 403 | Special.DebugSafety => { |
| 404 | const obj_path = %%os.path.join(b.allocator, "test_artifacts", "test.o"); | 404 | const obj_path = %%os.path.join(b.allocator, b.cache_root, "test.o"); |
| 405 | const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "debug-safety {}", case.name); | 405 | const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "debug-safety {}", case.name); |
| 406 | test (self.test_filter) |filter| { | 406 | test (self.test_filter) |filter| { |
| 407 | if (mem.indexOf(u8, annotated_case_name, filter) == null) | 407 | if (mem.indexOf(u8, annotated_case_name, filter) == null) |
| ... | @@ -415,7 +415,7 @@ pub const CompareOutputContext = struct { | ... | @@ -415,7 +415,7 @@ pub const CompareOutputContext = struct { |
| 415 | } | 415 | } |
| 416 | 416 | ||
| 417 | for (case.sources.toSliceConst()) |src_file| { | 417 | for (case.sources.toSliceConst()) |src_file| { |
| 418 | const expanded_src_path = %%os.path.join(b.allocator, "test_artifacts", src_file.filename); | 418 | const expanded_src_path = %%os.path.join(b.allocator, b.cache_root, src_file.filename); |
| 419 | const write_src = b.addWriteFile(expanded_src_path, src_file.source); | 419 | const write_src = b.addWriteFile(expanded_src_path, src_file.source); |
| 420 | exe.step.dependOn(&write_src.step); | 420 | exe.step.dependOn(&write_src.step); |
| 421 | } | 421 | } |
| ... | @@ -488,8 +488,8 @@ pub const CompileErrorContext = struct { | ... | @@ -488,8 +488,8 @@ pub const CompileErrorContext = struct { |
| 488 | const self = @fieldParentPtr(CompileCmpOutputStep, "step", step); | 488 | const self = @fieldParentPtr(CompileCmpOutputStep, "step", step); |
| 489 | const b = self.context.b; | 489 | const b = self.context.b; |
| 490 | 490 | ||
| 491 | const root_src = %%os.path.join(b.allocator, "test_artifacts", self.case.sources.items[0].filename); | 491 | const root_src = %%os.path.join(b.allocator, b.cache_root, self.case.sources.items[0].filename); |
| 492 | const obj_path = %%os.path.join(b.allocator, "test_artifacts", "test.o"); | 492 | const obj_path = %%os.path.join(b.allocator, b.cache_root, "test.o"); |
| 493 | 493 | ||
| 494 | var zig_args = List([]const u8).init(b.allocator); | 494 | var zig_args = List([]const u8).init(b.allocator); |
| 495 | %%zig_args.append(if (self.case.is_exe) "build_exe" else "build_obj"); | 495 | %%zig_args.append(if (self.case.is_exe) "build_exe" else "build_obj"); |
| ... | @@ -511,7 +511,7 @@ pub const CompileErrorContext = struct { | ... | @@ -511,7 +511,7 @@ pub const CompileErrorContext = struct { |
| 511 | printInvocation(b.zig_exe, zig_args.toSliceConst()); | 511 | printInvocation(b.zig_exe, zig_args.toSliceConst()); |
| 512 | } | 512 | } |
| 513 | 513 | ||
| 514 | var child = os.ChildProcess.spawn(b.zig_exe, zig_args.toSliceConst(), &b.env_map, | 514 | var child = os.ChildProcess.spawn(b.zig_exe, zig_args.toSliceConst(), null, &b.env_map, |
| 515 | StdIo.Ignore, StdIo.Pipe, StdIo.Pipe, b.allocator) %% |err| | 515 | StdIo.Ignore, StdIo.Pipe, StdIo.Pipe, b.allocator) %% |err| |
| 516 | { | 516 | { |
| 517 | debug.panic("Unable to spawn {}: {}\n", b.zig_exe, @errorName(err)); | 517 | debug.panic("Unable to spawn {}: {}\n", b.zig_exe, @errorName(err)); |
| ... | @@ -632,7 +632,7 @@ pub const CompileErrorContext = struct { | ... | @@ -632,7 +632,7 @@ pub const CompileErrorContext = struct { |
| 632 | self.step.dependOn(&compile_and_cmp_errors.step); | 632 | self.step.dependOn(&compile_and_cmp_errors.step); |
| 633 | 633 | ||
| 634 | for (case.sources.toSliceConst()) |src_file| { | 634 | for (case.sources.toSliceConst()) |src_file| { |
| 635 | const expanded_src_path = %%os.path.join(b.allocator, "test_artifacts", src_file.filename); | 635 | const expanded_src_path = %%os.path.join(b.allocator, b.cache_root, src_file.filename); |
| 636 | const write_src = b.addWriteFile(expanded_src_path, src_file.source); | 636 | const write_src = b.addWriteFile(expanded_src_path, src_file.source); |
| 637 | compile_and_cmp_errors.step.dependOn(&write_src.step); | 637 | compile_and_cmp_errors.step.dependOn(&write_src.step); |
| 638 | } | 638 | } |
| ... | @@ -675,7 +675,7 @@ pub const BuildExamplesContext = struct { | ... | @@ -675,7 +675,7 @@ pub const BuildExamplesContext = struct { |
| 675 | %%zig_args.append("--verbose"); | 675 | %%zig_args.append("--verbose"); |
| 676 | } | 676 | } |
| 677 | 677 | ||
| 678 | const run_cmd = b.addCommand(b.cache_root, b.env_map, b.zig_exe, zig_args.toSliceConst()); | 678 | const run_cmd = b.addCommand(null, b.env_map, b.zig_exe, zig_args.toSliceConst()); |
| 679 | 679 | ||
| 680 | const log_step = b.addLog("PASS {}\n", annotated_case_name); | 680 | const log_step = b.addLog("PASS {}\n", annotated_case_name); |
| 681 | log_step.step.dependOn(&run_cmd.step); | 681 | log_step.step.dependOn(&run_cmd.step); |
| ... | @@ -762,7 +762,7 @@ pub const ParseHContext = struct { | ... | @@ -762,7 +762,7 @@ pub const ParseHContext = struct { |
| 762 | const self = @fieldParentPtr(ParseHCmpOutputStep, "step", step); | 762 | const self = @fieldParentPtr(ParseHCmpOutputStep, "step", step); |
| 763 | const b = self.context.b; | 763 | const b = self.context.b; |
| 764 | 764 | ||
| 765 | const root_src = %%os.path.join(b.allocator, "test_artifacts", self.case.sources.items[0].filename); | 765 | const root_src = %%os.path.join(b.allocator, b.cache_root, self.case.sources.items[0].filename); |
| 766 | 766 | ||
| 767 | var zig_args = List([]const u8).init(b.allocator); | 767 | var zig_args = List([]const u8).init(b.allocator); |
| 768 | %%zig_args.append("parseh"); | 768 | %%zig_args.append("parseh"); |
| ... | @@ -774,7 +774,7 @@ pub const ParseHContext = struct { | ... | @@ -774,7 +774,7 @@ pub const ParseHContext = struct { |
| 774 | printInvocation(b.zig_exe, zig_args.toSliceConst()); | 774 | printInvocation(b.zig_exe, zig_args.toSliceConst()); |
| 775 | } | 775 | } |
| 776 | 776 | ||
| 777 | var child = os.ChildProcess.spawn(b.zig_exe, zig_args.toSliceConst(), &b.env_map, | 777 | var child = os.ChildProcess.spawn(b.zig_exe, zig_args.toSliceConst(), null, &b.env_map, |
| 778 | StdIo.Ignore, StdIo.Pipe, StdIo.Pipe, b.allocator) %% |err| | 778 | StdIo.Ignore, StdIo.Pipe, StdIo.Pipe, b.allocator) %% |err| |
| 779 | { | 779 | { |
| 780 | debug.panic("Unable to spawn {}: {}\n", b.zig_exe, @errorName(err)); | 780 | debug.panic("Unable to spawn {}: {}\n", b.zig_exe, @errorName(err)); |
| ... | @@ -886,7 +886,7 @@ pub const ParseHContext = struct { | ... | @@ -886,7 +886,7 @@ pub const ParseHContext = struct { |
| 886 | self.step.dependOn(&parseh_and_cmp.step); | 886 | self.step.dependOn(&parseh_and_cmp.step); |
| 887 | 887 | ||
| 888 | for (case.sources.toSliceConst()) |src_file| { | 888 | for (case.sources.toSliceConst()) |src_file| { |
| 889 | const expanded_src_path = %%os.path.join(b.allocator, "test_artifacts", src_file.filename); | 889 | const expanded_src_path = %%os.path.join(b.allocator, b.cache_root, src_file.filename); |
| 890 | const write_src = b.addWriteFile(expanded_src_path, src_file.source); | 890 | const write_src = b.addWriteFile(expanded_src_path, src_file.source); |
| 891 | parseh_and_cmp.step.dependOn(&write_src.step); | 891 | parseh_and_cmp.step.dependOn(&write_src.step); |
| 892 | } | 892 | } |