| author | |
| committer | |
| log | 363d9038c9b52878054505e905e133310b53086e |
| tree | 643a613f7502dab37a743049e1b28ee8cfe5b06a |
| parent | 38a04a267c11fdedc62102ab8e5989cafa3073ef |
closes #32816 files changed, 357 insertions(+), 146 deletions(-)
.gitignore+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | zig-cache/ | |
| 1 | 2 | build/ |
| 2 | 3 | build-release/ |
| 3 | 4 | /.cproject |
| 4 | 5 | /.project |
| 5 | 6 | /.settings/ |
| 6 | /test_artifacts/ |
build.zig+8-11| ... | ... | @@ -5,19 +5,16 @@ pub fn build(b: &Builder) { |
| 5 | 5 | const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter"); |
| 6 | 6 | const test_step = b.step("test", "Run all the tests"); |
| 7 | 7 | |
| 8 | const cleanup = b.addRemoveDirTree("test_artifacts"); | |
| 9 | test_step.dependOn(&cleanup.step); | |
| 10 | ||
| 11 | cleanup.step.dependOn(tests.addPkgTests(b, test_filter, | |
| 8 | test_step.dependOn(tests.addPkgTests(b, test_filter, | |
| 12 | 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 | 12 | "std/index.zig", "std", "Run the standard library tests")); |
| 16 | 13 | |
| 17 | cleanup.step.dependOn(tests.addCompareOutputTests(b, test_filter)); | |
| 18 | cleanup.step.dependOn(tests.addBuildExampleTests(b, test_filter)); | |
| 19 | cleanup.step.dependOn(tests.addCompileErrorTests(b, test_filter)); | |
| 20 | cleanup.step.dependOn(tests.addAssembleAndLinkTests(b, test_filter)); | |
| 21 | cleanup.step.dependOn(tests.addDebugSafetyTests(b, test_filter)); | |
| 22 | cleanup.step.dependOn(tests.addParseHTests(b, test_filter)); | |
| 14 | test_step.dependOn(tests.addCompareOutputTests(b, test_filter)); | |
| 15 | test_step.dependOn(tests.addBuildExampleTests(b, test_filter)); | |
| 16 | test_step.dependOn(tests.addCompileErrorTests(b, test_filter)); | |
| 17 | test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filter)); | |
| 18 | test_step.dependOn(tests.addDebugSafetyTests(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 | 12 | |
| 13 | 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 | 16 | run_cmd.step.dependOn(&exe.step); |
| 17 | 17 | |
| 18 | 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 | 12 | |
| 13 | 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 | 16 | run_cmd.step.dependOn(&exe.step); |
| 17 | 17 | |
| 18 | 18 | const test_step = b.step("test", "Test the program"); |
src/all_types.hpp+1| ... | ... | @@ -1488,6 +1488,7 @@ struct CodeGen { |
| 1488 | 1488 | ZigList<TimeEvent> timing_events; |
| 1489 | 1489 | |
| 1490 | 1490 | Buf *cache_dir; |
| 1491 | Buf *out_h_path; | |
| 1491 | 1492 | }; |
| 1492 | 1493 | |
| 1493 | 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 | 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 | 59 | CodeGen *g = allocate<CodeGen>(1); |
| 60 | 60 | |
| 61 | 61 | codegen_add_time_event(g, "Initialize"); |
| 62 | 62 | |
| 63 | g->out_type = out_type; | |
| 63 | 64 | g->import_table.init(32); |
| 64 | 65 | g->builtin_fn_table.init(32); |
| 65 | 66 | g->primitive_type_table.init(32); |
| ... | ... | @@ -74,7 +75,7 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target) { |
| 74 | 75 | g->external_prototypes.init(8); |
| 75 | 76 | g->is_release_build = false; |
| 76 | 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 | 80 | buf_resize(&g->global_asm, 0); |
| 80 | 81 | |
| ... | ... | @@ -145,6 +146,10 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target) { |
| 145 | 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 | 153 | void codegen_set_clang_argv(CodeGen *g, const char **args, size_t len) { |
| 149 | 154 | g->clang_argv = args; |
| 150 | 155 | g->clang_argv_len = len; |
| ... | ... | @@ -196,10 +201,6 @@ void codegen_set_strip(CodeGen *g, bool strip) { |
| 196 | 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 | 204 | void codegen_set_out_name(CodeGen *g, Buf *out_name) { |
| 204 | 205 | g->root_out_name = out_name; |
| 205 | 206 | } |
| ... | ... | @@ -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 | 4812 | void codegen_add_object(CodeGen *g, Buf *object_path) { |
| 4821 | 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 | 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 | 4947 | assert(!g->is_test_build); |
| 4951 | 4948 | |
| 4952 | Buf *h_file_out_path = buf_sprintf("%s.h", buf_ptr(g->root_out_name)); | |
| 4953 | FILE *out_h = fopen(buf_ptr(h_file_out_path), "wb"); | |
| 4949 | if (!g->out_h_path) { | |
| 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 | 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 | 4957 | Buf *export_macro = buf_sprintf("%s_EXPORT", buf_ptr(g->root_out_name)); |
| 4958 | 4958 | buf_upcase(export_macro); |
| ... | ... | @@ -5056,3 +5056,13 @@ void codegen_print_timing_report(CodeGen *g, FILE *f) { |
| 5056 | 5056 | void codegen_add_time_event(CodeGen *g, const char *name) { |
| 5057 | 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 | 14 | |
| 15 | 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 | 19 | void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len); |
| 20 | 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 | 25 | void codegen_set_strip(CodeGen *codegen, bool strip); |
| 26 | 26 | void codegen_set_verbose(CodeGen *codegen, bool verbose); |
| 27 | 27 | void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color); |
| 28 | void codegen_set_out_type(CodeGen *codegen, OutType out_type); | |
| 29 | 28 | void codegen_set_out_name(CodeGen *codegen, Buf *out_name); |
| 30 | 29 | void codegen_set_libc_lib_dir(CodeGen *codegen, Buf *libc_lib_dir); |
| 31 | 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 | 47 | void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix); |
| 49 | 48 | void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch); |
| 50 | 49 | void codegen_set_cache_dir(CodeGen *g, Buf *cache_dir); |
| 50 | void codegen_set_output_h_path(CodeGen *g, Buf *h_path); | |
| 51 | 51 | void codegen_add_time_event(CodeGen *g, const char *name); |
| 52 | 52 | void codegen_print_timing_report(CodeGen *g, FILE *f); |
| 53 | 53 | void codegen_build(CodeGen *g); |
| ... | ... | @@ -59,6 +59,5 @@ void codegen_add_object(CodeGen *g, Buf *object_path); |
| 59 | 59 | void codegen_parseh(CodeGen *g, Buf *path); |
| 60 | 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 | 63 | #endif |
src/link.cpp+5-15| ... | ... | @@ -37,7 +37,7 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) { |
| 37 | 37 | os_path_join(parent_gen->zig_std_special_dir, source_basename, full_path); |
| 38 | 38 | |
| 39 | 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 | 41 | child_gen->link_libc = parent_gen->link_libc; |
| 42 | 42 | |
| 43 | 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 | 55 | codegen_set_strip(child_gen, parent_gen->strip_debug_symbols); |
| 56 | 56 | codegen_set_is_static(child_gen, parent_gen->is_static); |
| 57 | 57 | |
| 58 | codegen_set_out_type(child_gen, OutTypeObj); | |
| 59 | 58 | codegen_set_out_name(child_gen, buf_create_from_str(oname)); |
| 60 | 59 | |
| 61 | 60 | codegen_set_verbose(child_gen, parent_gen->verbose); |
| ... | ... | @@ -186,9 +185,10 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 186 | 185 | } else if (shared) { |
| 187 | 186 | lj->args.append("-shared"); |
| 188 | 187 | |
| 189 | buf_resize(&lj->out_file, 0); | |
| 190 | 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); | |
| 188 | if (buf_len(&lj->out_file) == 0) { | |
| 189 | buf_appendf(&lj->out_file, "lib%s.so.%zu.%zu.%zu", | |
| 190 | buf_ptr(g->root_out_name), g->version_major, g->version_minor, g->version_patch); | |
| 191 | } | |
| 192 | 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 | 752 | } |
| 753 | 753 | |
| 754 | 754 | if (g->out_type == OutTypeObj) { |
| 755 | if (g->want_h_file) { | |
| 756 | codegen_generate_h_file(g); | |
| 757 | } | |
| 758 | 755 | if (override_out_file) { |
| 759 | 756 | assert(g->link_objects.length == 1); |
| 760 | 757 | Buf *o_file_path = g->link_objects.at(0); |
| ... | ... | @@ -798,13 +795,6 @@ void codegen_link(CodeGen *g, const char *out_file) { |
| 798 | 795 | fprintf(stderr, "%s\n", buf_ptr(&diag)); |
| 799 | 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 | 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 | 35 | " --libc-include-dir [path] directory where libc stdlib.h resides\n" |
| 36 | 36 | " --name [name] override output name\n" |
| 37 | 37 | " --output [file] override destination path\n" |
| 38 | " --output-h [file] override generated header file path\n" | |
| 38 | 39 | " --release build with optimizations on and debug protection off\n" |
| 39 | 40 | " --static output will be statically linked\n" |
| 40 | 41 | " --strip exclude debug symbols\n" |
| ... | ... | @@ -118,6 +119,8 @@ enum Cmd { |
| 118 | 119 | CmdTargets, |
| 119 | 120 | }; |
| 120 | 121 | |
| 122 | static const char *default_zig_cache_name = "zig-cache"; | |
| 123 | ||
| 121 | 124 | int main(int argc, char **argv) { |
| 122 | 125 | os_init(); |
| 123 | 126 | |
| ... | ... | @@ -125,6 +128,7 @@ int main(int argc, char **argv) { |
| 125 | 128 | Cmd cmd = CmdInvalid; |
| 126 | 129 | const char *in_file = nullptr; |
| 127 | 130 | const char *out_file = nullptr; |
| 131 | const char *out_file_h = nullptr; | |
| 128 | 132 | bool is_release_build = false; |
| 129 | 133 | bool strip = false; |
| 130 | 134 | bool is_static = false; |
| ... | ... | @@ -163,7 +167,7 @@ int main(int argc, char **argv) { |
| 163 | 167 | size_t ver_minor = 0; |
| 164 | 168 | size_t ver_patch = 0; |
| 165 | 169 | bool timing_info = false; |
| 166 | const char *cache_dir = "zig-cache"; | |
| 170 | const char *cache_dir = nullptr; | |
| 167 | 171 | |
| 168 | 172 | if (argc >= 2 && strcmp(argv[1], "build") == 0) { |
| 169 | 173 | const char *zig_exe_path = arg0; |
| ... | ... | @@ -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 | 208 | codegen_set_out_name(g, buf_create_from_str("build")); |
| 205 | codegen_set_out_type(g, OutTypeExe); | |
| 206 | 209 | codegen_set_verbose(g, verbose); |
| 207 | 210 | |
| 208 | 211 | Buf build_file_abs = BUF_INIT; |
| ... | ... | @@ -212,7 +215,12 @@ int main(int argc, char **argv) { |
| 212 | 215 | os_path_split(&build_file_abs, &build_file_dirname, &build_file_basename); |
| 213 | 216 | |
| 214 | 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 | 224 | Buf *path_to_build_exe = buf_alloc(); |
| 217 | 225 | os_path_join(full_cache_dir, buf_create_from_str("build"), path_to_build_exe); |
| 218 | 226 | codegen_set_cache_dir(g, full_cache_dir); |
| ... | ... | @@ -309,6 +317,8 @@ int main(int argc, char **argv) { |
| 309 | 317 | return usage(arg0); |
| 310 | 318 | } else if (strcmp(arg, "--output") == 0) { |
| 311 | 319 | out_file = argv[i]; |
| 320 | } else if (strcmp(arg, "--output-h") == 0) { | |
| 321 | out_file_h = argv[i]; | |
| 312 | 322 | } else if (strcmp(arg, "--color") == 0) { |
| 313 | 323 | if (strcmp(argv[i], "auto") == 0) { |
| 314 | 324 | color = ErrColorAuto; |
| ... | ... | @@ -396,6 +406,7 @@ int main(int argc, char **argv) { |
| 396 | 406 | cmd = CmdParseH; |
| 397 | 407 | } else if (strcmp(arg, "test") == 0) { |
| 398 | 408 | cmd = CmdTest; |
| 409 | out_type = OutTypeExe; | |
| 399 | 410 | } else if (strcmp(arg, "targets") == 0) { |
| 400 | 411 | cmd = CmdTargets; |
| 401 | 412 | } else { |
| ... | ... | @@ -495,9 +506,11 @@ int main(int argc, char **argv) { |
| 495 | 506 | Buf *zig_root_source_file = (cmd == CmdParseH) ? nullptr : in_file_buf; |
| 496 | 507 | |
| 497 | 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 | 514 | codegen_set_out_name(g, buf_out_name); |
| 502 | 515 | codegen_set_lib_version(g, ver_major, ver_minor, ver_patch); |
| 503 | 516 | codegen_set_is_release(g, is_release_build); |
| ... | ... | @@ -510,11 +523,6 @@ int main(int argc, char **argv) { |
| 510 | 523 | codegen_set_clang_argv(g, clang_argv.items, clang_argv.length); |
| 511 | 524 | codegen_set_strip(g, strip); |
| 512 | 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 | 526 | if (libc_lib_dir) |
| 519 | 527 | codegen_set_libc_lib_dir(g, buf_create_from_str(libc_lib_dir)); |
| 520 | 528 | if (libc_static_lib_dir) |
| ... | ... | @@ -568,6 +576,9 @@ int main(int argc, char **argv) { |
| 568 | 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 | 582 | if (cmd == CmdBuild) { |
| 572 | 583 | for (size_t i = 0; i < objects.length; i += 1) { |
| 573 | 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 | 37 | top_level_steps: List(&TopLevelStep), |
| 38 | 38 | prefix: []const u8, |
| 39 | 39 | lib_dir: []const u8, |
| 40 | out_dir: []u8, // TODO get rid of this | |
| 41 | 40 | installed_files: List([]const u8), |
| 42 | 41 | build_root: []const u8, |
| 43 | 42 | cache_root: []const u8, |
| ... | ... | @@ -97,7 +96,6 @@ pub const Builder = struct { |
| 97 | 96 | .env_map = %%os.getEnvMap(allocator), |
| 98 | 97 | .prefix = undefined, |
| 99 | 98 | .lib_dir = undefined, |
| 100 | .out_dir = %%os.getCwd(allocator), | |
| 101 | 99 | .installed_files = List([]const u8).init(allocator), |
| 102 | 100 | .uninstall_tls = TopLevelStep { |
| 103 | 101 | .step = Step.init("uninstall", allocator, makeUninstall), |
| ... | ... | @@ -111,7 +109,6 @@ pub const Builder = struct { |
| 111 | 109 | } |
| 112 | 110 | |
| 113 | 111 | pub fn deinit(self: &Builder) { |
| 114 | self.allocator.free(self.out_dir); | |
| 115 | 112 | self.lib_paths.deinit(); |
| 116 | 113 | self.include_paths.deinit(); |
| 117 | 114 | self.rpaths.deinit(); |
| ... | ... | @@ -172,12 +169,10 @@ pub const Builder = struct { |
| 172 | 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 | 173 | path: []const u8, args: []const []const u8) -> &CommandStep |
| 177 | 174 | { |
| 178 | const cmd = %%self.allocator.create(CommandStep); | |
| 179 | *cmd = CommandStep.init(self, cwd, env_map, path, args); | |
| 180 | return cmd; | |
| 175 | return CommandStep.create(self, cwd, env_map, path, args); | |
| 181 | 176 | } |
| 182 | 177 | |
| 183 | 178 | pub fn addWriteFile(self: &Builder, file_path: []const u8, data: []const u8) -> &WriteFileStep { |
| ... | ... | @@ -489,21 +484,22 @@ pub const Builder = struct { |
| 489 | 484 | } |
| 490 | 485 | |
| 491 | 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, | |
| 496 | args: []const []const u8) -> %void | |
| 490 | fn spawnChildEnvMap(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap, | |
| 491 | exe_path: []const u8, args: []const []const u8) -> %void | |
| 497 | 492 | { |
| 498 | 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 | 496 | for (args) |arg| { |
| 501 | %%io.stderr.printf(" {}", arg); | |
| 497 | %%io.stderr.print(" {}", arg); | |
| 502 | 498 | } |
| 503 | 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 | 503 | StdIo.Ignore, StdIo.Inherit, StdIo.Inherit, self.allocator) %% |err| |
| 508 | 504 | { |
| 509 | 505 | %%io.stderr.printf("Unable to spawn {}: {}\n", exe_path, @errorName(err)); |
| ... | ... | @@ -511,6 +507,7 @@ pub const Builder = struct { |
| 511 | 507 | }; |
| 512 | 508 | |
| 513 | 509 | const term = child.wait() %% |err| { |
| 510 | test (cwd) |yes_cwd| %%io.stderr.printf("cwd: {}\n", yes_cwd); | |
| 514 | 511 | %%io.stderr.printf("Unable to spawn {}: {}\n", exe_path, @errorName(err)); |
| 515 | 512 | return err; |
| 516 | 513 | }; |
| ... | ... | @@ -560,11 +557,12 @@ pub const Builder = struct { |
| 560 | 557 | |
| 561 | 558 | fn copyFile(self: &Builder, source_path: []const u8, dest_path: []const u8) { |
| 562 | 559 | const dirname = os.path.dirname(dest_path); |
| 560 | const abs_source_path = self.pathFromRoot(source_path); | |
| 563 | 561 | os.makePath(self.allocator, dirname) %% |err| { |
| 564 | 562 | debug.panic("Unable to create path {}: {}", dirname, @errorName(err)); |
| 565 | 563 | }; |
| 566 | os.copyFile(self.allocator, source_path, dest_path) %% |err| { | |
| 567 | debug.panic("Unable to copy {} to {}: {}", source_path, dest_path, @errorName(err)); | |
| 564 | os.copyFile(self.allocator, abs_source_path, dest_path) %% |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 | 626 | release: bool, |
| 629 | 627 | static: bool, |
| 630 | 628 | output_path: ?[]const u8, |
| 629 | output_h_path: ?[]const u8, | |
| 631 | 630 | kind: Kind, |
| 632 | 631 | version: Version, |
| 632 | out_h_filename: []const u8, | |
| 633 | 633 | out_filename: []const u8, |
| 634 | 634 | out_filename_major_only: []const u8, |
| 635 | 635 | out_filename_name_only: []const u8, |
| ... | ... | @@ -684,8 +684,10 @@ pub const LibExeObjStep = struct { |
| 684 | 684 | .link_libs = BufSet.init(builder.allocator), |
| 685 | 685 | .step = Step.init(name, builder.allocator, make), |
| 686 | 686 | .output_path = null, |
| 687 | .output_h_path = null, | |
| 687 | 688 | .version = *ver, |
| 688 | 689 | .out_filename = undefined, |
| 690 | .out_h_filename = builder.fmt("{}.h", name), | |
| 689 | 691 | .out_filename_major_only = undefined, |
| 690 | 692 | .out_filename_name_only = undefined, |
| 691 | 693 | .object_files = List([]const u8).init(builder.allocator), |
| ... | ... | @@ -747,6 +749,27 @@ pub const LibExeObjStep = struct { |
| 747 | 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 | 773 | pub fn addAssemblyFile(self: &LibExeObjStep, path: []const u8) { |
| 751 | 774 | %%self.assembly_files.append(path); |
| 752 | 775 | } |
| ... | ... | @@ -763,14 +786,7 @@ pub const LibExeObjStep = struct { |
| 763 | 786 | |
| 764 | 787 | self.step.dependOn(&obj.step); |
| 765 | 788 | |
| 766 | const path_to_obj = test (obj.output_path) |explicit_out_path| { | |
| 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); | |
| 789 | %%self.object_files.append(obj.getOutputPath()); | |
| 774 | 790 | } |
| 775 | 791 | |
| 776 | 792 | fn make(step: &Step) -> %void { |
| ... | ... | @@ -814,10 +830,16 @@ pub const LibExeObjStep = struct { |
| 814 | 830 | %%zig_args.append("--release"); |
| 815 | 831 | } |
| 816 | 832 | |
| 817 | test (self.output_path) |output_path| { | |
| 818 | %%zig_args.append("--output"); | |
| 819 | %%zig_args.append(builder.pathFromRoot(output_path)); | |
| 820 | } | |
| 833 | %%zig_args.append("--cache-dir"); | |
| 834 | %%zig_args.append(builder.cache_root); | |
| 835 | ||
| 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 | 844 | %%zig_args.append("--name"); |
| 823 | 845 | %%zig_args.append(self.name); |
| ... | ... | @@ -879,10 +901,8 @@ pub const LibExeObjStep = struct { |
| 879 | 901 | %return builder.spawnChild(builder.zig_exe, zig_args.toSliceConst()); |
| 880 | 902 | |
| 881 | 903 | if (self.kind == Kind.Lib and !self.static) { |
| 882 | // sym link for libfoo.so.1 to libfoo.so.1.2.3 | |
| 883 | %%os.atomicSymLink(builder.allocator, self.out_filename, self.out_filename_major_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); | |
| 904 | %return doAtomicSymLinks(builder.allocator, output_path, self.out_filename_major_only, | |
| 905 | self.out_filename_name_only); | |
| 886 | 906 | } |
| 887 | 907 | } |
| 888 | 908 | }; |
| ... | ... | @@ -987,10 +1007,12 @@ pub const TestStep = struct { |
| 987 | 1007 | } |
| 988 | 1008 | }; |
| 989 | 1009 | |
| 1010 | // TODO merge with CExecutable | |
| 990 | 1011 | pub const CLibrary = struct { |
| 991 | 1012 | step: Step, |
| 992 | 1013 | name: []const u8, |
| 993 | 1014 | out_filename: []const u8, |
| 1015 | output_path: ?[]const u8, | |
| 994 | 1016 | static: bool, |
| 995 | 1017 | version: Version, |
| 996 | 1018 | cflags: List([]const u8), |
| ... | ... | @@ -1024,6 +1046,7 @@ pub const CLibrary = struct { |
| 1024 | 1046 | .step = Step.init(name, builder.allocator, make), |
| 1025 | 1047 | .link_libs = BufSet.init(builder.allocator), |
| 1026 | 1048 | .include_dirs = List([]const u8).init(builder.allocator), |
| 1049 | .output_path = null, | |
| 1027 | 1050 | .out_filename = undefined, |
| 1028 | 1051 | .major_only_filename = undefined, |
| 1029 | 1052 | .name_only_filename = undefined, |
| ... | ... | @@ -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 | 1082 | pub fn linkSystemLibrary(self: &CLibrary, name: []const u8) { |
| 1047 | 1083 | %%self.link_libs.put(name); |
| 1048 | 1084 | } |
| ... | ... | @@ -1131,8 +1167,9 @@ pub const CLibrary = struct { |
| 1131 | 1167 | defer builder.allocator.free(soname_arg); |
| 1132 | 1168 | %%cc_args.append(soname_arg); |
| 1133 | 1169 | |
| 1170 | const output_path = builder.pathFromRoot(self.getOutputPath()); | |
| 1134 | 1171 | %%cc_args.append("-o"); |
| 1135 | %%cc_args.append(self.out_filename); | |
| 1172 | %%cc_args.append(output_path); | |
| 1136 | 1173 | |
| 1137 | 1174 | for (self.object_files.toSliceConst()) |object_file| { |
| 1138 | 1175 | %%cc_args.append(builder.pathFromRoot(object_file)); |
| ... | ... | @@ -1140,10 +1177,8 @@ pub const CLibrary = struct { |
| 1140 | 1177 | |
| 1141 | 1178 | %return builder.spawnChild(cc, cc_args.toSliceConst()); |
| 1142 | 1179 | |
| 1143 | // sym link for libfoo.so.1 to libfoo.so.1.2.3 | |
| 1144 | %%os.atomicSymLink(builder.allocator, self.out_filename, self.major_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); | |
| 1180 | %return doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename, | |
| 1181 | self.name_only_filename); | |
| 1147 | 1182 | } |
| 1148 | 1183 | } |
| 1149 | 1184 | |
| ... | ... | @@ -1169,9 +1204,11 @@ pub const CExecutable = struct { |
| 1169 | 1204 | link_libs: BufSet, |
| 1170 | 1205 | target: Target, |
| 1171 | 1206 | include_dirs: List([]const u8), |
| 1207 | output_path: ?[]const u8, | |
| 1208 | out_filename: []const u8, | |
| 1172 | 1209 | |
| 1173 | 1210 | pub fn init(builder: &Builder, name: []const u8) -> CExecutable { |
| 1174 | CExecutable { | |
| 1211 | var self = CExecutable { | |
| 1175 | 1212 | .builder = builder, |
| 1176 | 1213 | .name = name, |
| 1177 | 1214 | .target = Target.Native, |
| ... | ... | @@ -1182,6 +1219,27 @@ pub const CExecutable = struct { |
| 1182 | 1219 | .step = Step.init(name, builder.allocator, make), |
| 1183 | 1220 | .link_libs = BufSet.init(builder.allocator), |
| 1184 | 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 | 1249 | |
| 1192 | 1250 | pub fn linkCLibrary(self: &CExecutable, clib: &CLibrary) { |
| 1193 | 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 | 1255 | pub fn linkLibrary(self: &CExecutable, lib: &LibExeObjStep) { |
| 1198 | 1256 | assert(lib.kind == LibExeObjStep.Kind.Lib); |
| 1199 | 1257 | self.step.dependOn(&lib.step); |
| 1200 | %%self.full_path_libs.append(lib.out_filename); | |
| 1258 | %%self.full_path_libs.append(lib.getOutputPath()); | |
| 1201 | 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 | 1263 | pub fn addObject(self: &CExecutable, obj: &LibExeObjStep) { |
| ... | ... | @@ -1207,12 +1265,10 @@ pub const CExecutable = struct { |
| 1207 | 1265 | |
| 1208 | 1266 | self.step.dependOn(&obj.step); |
| 1209 | 1267 | |
| 1210 | // TODO make it so we always know where this will be | |
| 1211 | %%self.object_files.append(%%os.path.join(self.builder.allocator, self.builder.cache_root, | |
| 1212 | self.builder.fmt("{}{}", obj.name, obj.target.oFileExt()))); | |
| 1268 | %%self.object_files.append(obj.getOutputPath()); | |
| 1213 | 1269 | |
| 1214 | 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 | 1274 | pub fn addSourceFile(self: &CExecutable, file: []const u8) { |
| ... | ... | @@ -1256,7 +1312,6 @@ pub const CExecutable = struct { |
| 1256 | 1312 | %%cc_args.append("-c"); |
| 1257 | 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 | 1315 | const rel_src_path = %%os.path.relative(builder.allocator, builder.build_root, source_file); |
| 1261 | 1316 | const cache_o_src = %%os.path.join(builder.allocator, builder.cache_root, rel_src_path); |
| 1262 | 1317 | const cache_o_dir = os.path.dirname(cache_o_src); |
| ... | ... | @@ -1276,26 +1331,28 @@ pub const CExecutable = struct { |
| 1276 | 1331 | |
| 1277 | 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 | 1337 | %%cc_args.resize(0); |
| 1283 | 1338 | |
| 1284 | 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 | 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 | 1349 | defer builder.allocator.free(rpath_arg); |
| 1293 | 1350 | %%cc_args.append(rpath_arg); |
| 1294 | 1351 | |
| 1295 | 1352 | %%cc_args.append("-rdynamic"); |
| 1296 | 1353 | |
| 1297 | 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 | 1358 | %return builder.spawnChild(cc, cc_args.toSliceConst()); |
| ... | ... | @@ -1317,27 +1374,29 @@ pub const CommandStep = struct { |
| 1317 | 1374 | builder: &Builder, |
| 1318 | 1375 | exe_path: []const u8, |
| 1319 | 1376 | args: []const []const u8, |
| 1320 | cwd: []const u8, | |
| 1377 | cwd: ?[]const u8, | |
| 1321 | 1378 | env_map: &const BufMap, |
| 1322 | 1379 | |
| 1323 | pub fn init(builder: &Builder, cwd: []const u8, env_map: &const BufMap, | |
| 1324 | exe_path: []const u8, args: []const []const u8) -> CommandStep | |
| 1380 | pub fn create(builder: &Builder, cwd: ?[]const u8, env_map: &const BufMap, | |
| 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 | 1385 | .builder = builder, |
| 1328 | 1386 | .step = Step.init(exe_path, builder.allocator, make), |
| 1329 | 1387 | .exe_path = exe_path, |
| 1330 | 1388 | .args = args, |
| 1331 | 1389 | .cwd = cwd, |
| 1332 | 1390 | .env_map = env_map, |
| 1333 | } | |
| 1391 | }; | |
| 1392 | return self; | |
| 1334 | 1393 | } |
| 1335 | 1394 | |
| 1336 | 1395 | fn make(step: &Step) -> %void { |
| 1337 | 1396 | const self = @fieldParentPtr(CommandStep, "step", step); |
| 1338 | 1397 | |
| 1339 | // TODO set cwd | |
| 1340 | return self.builder.spawnChildEnvMap(self.env_map, self.exe_path, self.args); | |
| 1398 | const cwd = test (self.cwd) |cwd| self.builder.pathFromRoot(cwd) else null; | |
| 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 | 1426 | const self = @fieldParentPtr(InstallCLibraryStep, "step", step); |
| 1368 | 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 | 1430 | if (!self.lib.static) { |
| 1372 | const dest_major_only = %%os.path.join(builder.allocator, builder.lib_dir, self.lib.major_only_filename); | |
| 1373 | const dest_name_only = %%os.path.join(builder.allocator, builder.lib_dir, 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); | |
| 1431 | %return doAtomicSymLinks(self.builder.allocator, self.dest_file, self.lib.major_only_filename, | |
| 1432 | self.lib.name_only_filename); | |
| 1376 | 1433 | } |
| 1377 | 1434 | } |
| 1378 | 1435 | }; |
| ... | ... | @@ -1506,3 +1563,22 @@ pub const Step = struct { |
| 1506 | 1563 | |
| 1507 | 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 | 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 | 349 | var context = BufPrintContext { .remaining = buf, }; |
| 350 | 350 | _ = format(&context, bufPrintWrite, fmt, args); |
| 351 | return buf[0...buf.len - context.remaining.len]; | |
| 351 | 352 | } |
| 352 | 353 | |
| 353 | 354 | pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ...) -> %[]u8 { |
| 354 | 355 | var size: usize = 0; |
| 355 | 356 | _ = format(&size, countSize, fmt, args); |
| 356 | 357 | const buf = %return allocator.alloc(u8, size); |
| 357 | bufPrint(buf, fmt, args); | |
| 358 | return buf; | |
| 358 | return bufPrint(buf, fmt, args); | |
| 359 | 359 | } |
| 360 | 360 | |
| 361 | 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 | 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 | 35 | stdin: StdIo, stdout: StdIo, stderr: StdIo, allocator: &Allocator) -> %ChildProcess |
| 35 | 36 | { |
| 36 | 37 | switch (@compileVar("os")) { |
| 37 | 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 | 41 | else => @compileError("Unsupported OS"), |
| 41 | 42 | } |
| ... | ... | @@ -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 | 104 | stdin: StdIo, stdout: StdIo, stderr: StdIo, allocator: &Allocator) -> %ChildProcess |
| 103 | 105 | { |
| 104 | 106 | // TODO issue #295 |
| ... | ... | @@ -155,6 +157,11 @@ pub const ChildProcess = struct { |
| 155 | 157 | setUpChildIo(stderr, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) %% |
| 156 | 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 | 165 | os.posixExecve(exe_path, args, env_map, allocator) %% |
| 159 | 166 | |err| forkChildErrReport(err_pipe[1], err); |
| 160 | 167 | } |
std/os/index.zig+57| ... | ... | @@ -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 | 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 | 342 | pub fn execve(path: &const u8, argv: &const ?&const u8, envp: &const ?&const u8) -> usize { |
| 339 | 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 | 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 | 367 | pub fn mkdir(path: &const u8, mode: usize) -> usize { |
| 360 | 368 | arch.syscall2(arch.SYS_mkdir, usize(path), mode) |
| 361 | 369 | } |
std/os/path.zig+55| ... | ... | @@ -1,9 +1,11 @@ |
| 1 | 1 | const debug = @import("../debug.zig"); |
| 2 | 2 | const assert = debug.assert; |
| 3 | 3 | const mem = @import("../mem.zig"); |
| 4 | const fmt = @import("../fmt.zig"); | |
| 4 | 5 | const Allocator = mem.Allocator; |
| 5 | 6 | const os = @import("index.zig"); |
| 6 | 7 | const math = @import("../math.zig"); |
| 8 | const posix = os.posix; | |
| 7 | 9 | |
| 8 | 10 | pub const sep = switch (@compileVar("os")) { |
| 9 | 11 | Os.windows => '\\', |
| ... | ... | @@ -185,6 +187,45 @@ fn testDirname(input: []const u8, expected_output: []const u8) { |
| 185 | 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 | 229 | /// Returns the relative path from ::from to ::to. If ::from and ::to each |
| 189 | 230 | /// resolve to the same path (after calling ::resolve on each), a zero-length |
| 190 | 231 | /// string is returned. |
| ... | ... | @@ -252,3 +293,17 @@ fn testRelative(from: []const u8, to: []const u8, expected_output: []const u8) { |
| 252 | 293 | const result = %%relative(&debug.global_allocator, from, to); |
| 253 | 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 | 189 | |
| 190 | 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 | 193 | StdIo.Ignore, StdIo.Pipe, StdIo.Pipe, b.allocator) %% |err| |
| 194 | 194 | { |
| 195 | 195 | debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err)); |
| ... | ... | @@ -264,7 +264,7 @@ pub const CompareOutputContext = struct { |
| 264 | 264 | |
| 265 | 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 | 268 | StdIo.Ignore, StdIo.Pipe, StdIo.Pipe, b.allocator) %% |err| |
| 269 | 269 | { |
| 270 | 270 | debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err)); |
| ... | ... | @@ -344,8 +344,8 @@ pub const CompareOutputContext = struct { |
| 344 | 344 | pub fn addCase(self: &CompareOutputContext, case: &const TestCase) { |
| 345 | 345 | const b = self.b; |
| 346 | 346 | |
| 347 | const root_src = %%os.path.join(b.allocator, "test_artifacts", case.sources.items[0].filename); | |
| 348 | const exe_path = %%os.path.join(b.allocator, "test_artifacts", "test"); | |
| 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, b.cache_root, "test"); | |
| 349 | 349 | |
| 350 | 350 | switch (case.special) { |
| 351 | 351 | Special.Asm => { |
| ... | ... | @@ -360,7 +360,7 @@ pub const CompareOutputContext = struct { |
| 360 | 360 | exe.setOutputPath(exe_path); |
| 361 | 361 | |
| 362 | 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 | 364 | const write_src = b.addWriteFile(expanded_src_path, src_file.source); |
| 365 | 365 | exe.step.dependOn(&write_src.step); |
| 366 | 366 | } |
| ... | ... | @@ -388,7 +388,7 @@ pub const CompareOutputContext = struct { |
| 388 | 388 | } |
| 389 | 389 | |
| 390 | 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 | 392 | const write_src = b.addWriteFile(expanded_src_path, src_file.source); |
| 393 | 393 | exe.step.dependOn(&write_src.step); |
| 394 | 394 | } |
| ... | ... | @@ -401,7 +401,7 @@ pub const CompareOutputContext = struct { |
| 401 | 401 | } |
| 402 | 402 | }, |
| 403 | 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 | 405 | const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "debug-safety {}", case.name); |
| 406 | 406 | test (self.test_filter) |filter| { |
| 407 | 407 | if (mem.indexOf(u8, annotated_case_name, filter) == null) |
| ... | ... | @@ -415,7 +415,7 @@ pub const CompareOutputContext = struct { |
| 415 | 415 | } |
| 416 | 416 | |
| 417 | 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 | 419 | const write_src = b.addWriteFile(expanded_src_path, src_file.source); |
| 420 | 420 | exe.step.dependOn(&write_src.step); |
| 421 | 421 | } |
| ... | ... | @@ -488,8 +488,8 @@ pub const CompileErrorContext = struct { |
| 488 | 488 | const self = @fieldParentPtr(CompileCmpOutputStep, "step", step); |
| 489 | 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); | |
| 492 | const obj_path = %%os.path.join(b.allocator, "test_artifacts", "test.o"); | |
| 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, b.cache_root, "test.o"); | |
| 493 | 493 | |
| 494 | 494 | var zig_args = List([]const u8).init(b.allocator); |
| 495 | 495 | %%zig_args.append(if (self.case.is_exe) "build_exe" else "build_obj"); |
| ... | ... | @@ -511,7 +511,7 @@ pub const CompileErrorContext = struct { |
| 511 | 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 | 515 | StdIo.Ignore, StdIo.Pipe, StdIo.Pipe, b.allocator) %% |err| |
| 516 | 516 | { |
| 517 | 517 | debug.panic("Unable to spawn {}: {}\n", b.zig_exe, @errorName(err)); |
| ... | ... | @@ -632,7 +632,7 @@ pub const CompileErrorContext = struct { |
| 632 | 632 | self.step.dependOn(&compile_and_cmp_errors.step); |
| 633 | 633 | |
| 634 | 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 | 636 | const write_src = b.addWriteFile(expanded_src_path, src_file.source); |
| 637 | 637 | compile_and_cmp_errors.step.dependOn(&write_src.step); |
| 638 | 638 | } |
| ... | ... | @@ -675,7 +675,7 @@ pub const BuildExamplesContext = struct { |
| 675 | 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 | 680 | const log_step = b.addLog("PASS {}\n", annotated_case_name); |
| 681 | 681 | log_step.step.dependOn(&run_cmd.step); |
| ... | ... | @@ -762,7 +762,7 @@ pub const ParseHContext = struct { |
| 762 | 762 | const self = @fieldParentPtr(ParseHCmpOutputStep, "step", step); |
| 763 | 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 | 767 | var zig_args = List([]const u8).init(b.allocator); |
| 768 | 768 | %%zig_args.append("parseh"); |
| ... | ... | @@ -774,7 +774,7 @@ pub const ParseHContext = struct { |
| 774 | 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 | 778 | StdIo.Ignore, StdIo.Pipe, StdIo.Pipe, b.allocator) %% |err| |
| 779 | 779 | { |
| 780 | 780 | debug.panic("Unable to spawn {}: {}\n", b.zig_exe, @errorName(err)); |
| ... | ... | @@ -886,7 +886,7 @@ pub const ParseHContext = struct { |
| 886 | 886 | self.step.dependOn(&parseh_and_cmp.step); |
| 887 | 887 | |
| 888 | 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 | 890 | const write_src = b.addWriteFile(expanded_src_path, src_file.source); |
| 891 | 891 | parseh_and_cmp.step.dependOn(&write_src.step); |
| 892 | 892 | } |