| author | |
| committer | |
| log | a147f065850af8f9422d19d14aec0476b641cb07 |
| tree | 7a4a2393b18027ddc3cfd972ebe0dda9d0a89b50 |
| parent | 458afb0ef9634b6a0480bcb6e07a92cd9a330d84 |
See #29812 files changed, 124 insertions(+), 17 deletions(-)
src/all_types.hpp+2| ... | ... | @@ -1486,6 +1486,8 @@ struct CodeGen { |
| 1486 | 1486 | Buf *test_name_prefix; |
| 1487 | 1487 | |
| 1488 | 1488 | ZigList<TimeEvent> timing_events; |
| 1489 | ||
| 1490 | Buf *cache_dir; | |
| 1489 | 1491 | }; |
| 1490 | 1492 | |
| 1491 | 1493 | enum VarLinkage { |
src/codegen.cpp+14-4| ... | ... | @@ -204,6 +204,10 @@ void codegen_set_out_name(CodeGen *g, Buf *out_name) { |
| 204 | 204 | g->root_out_name = out_name; |
| 205 | 205 | } |
| 206 | 206 | |
| 207 | void codegen_set_cache_dir(CodeGen *g, Buf *cache_dir) { | |
| 208 | g->cache_dir = cache_dir; | |
| 209 | } | |
| 210 | ||
| 207 | 211 | void codegen_set_libc_lib_dir(CodeGen *g, Buf *libc_lib_dir) { |
| 208 | 212 | g->libc_lib_dir = libc_lib_dir; |
| 209 | 213 | } |
| ... | ... | @@ -3910,16 +3914,22 @@ static void do_code_gen(CodeGen *g) { |
| 3910 | 3914 | codegen_add_time_event(g, "LLVM Emit Object"); |
| 3911 | 3915 | |
| 3912 | 3916 | char *err_msg = nullptr; |
| 3913 | Buf *out_file_o = buf_create_from_buf(g->root_out_name); | |
| 3917 | Buf *o_basename = buf_create_from_buf(g->root_out_name); | |
| 3914 | 3918 | const char *o_ext = target_o_file_ext(&g->zig_target); |
| 3915 | buf_append_str(out_file_o, o_ext); | |
| 3916 | if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(out_file_o), | |
| 3919 | buf_append_str(o_basename, o_ext); | |
| 3920 | Buf *output_path = buf_alloc(); | |
| 3921 | os_path_join(g->cache_dir, o_basename, output_path); | |
| 3922 | int err; | |
| 3923 | if ((err = os_make_path(g->cache_dir))) { | |
| 3924 | zig_panic("unable to make cache dir: %s", err_str(err)); | |
| 3925 | } | |
| 3926 | if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), | |
| 3917 | 3927 | LLVMObjectFile, &err_msg, !g->is_release_build)) |
| 3918 | 3928 | { |
| 3919 | 3929 | zig_panic("unable to write object file: %s", err_msg); |
| 3920 | 3930 | } |
| 3921 | 3931 | |
| 3922 | g->link_objects.append(out_file_o); | |
| 3932 | g->link_objects.append(output_path); | |
| 3923 | 3933 | } |
| 3924 | 3934 | |
| 3925 | 3935 | static const uint8_t int_sizes_in_bits[] = { |
src/codegen.hpp+1| ... | ... | @@ -47,6 +47,7 @@ void codegen_set_omit_zigrt(CodeGen *g, bool omit_zigrt); |
| 47 | 47 | void codegen_set_test_filter(CodeGen *g, Buf *filter); |
| 48 | 48 | void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix); |
| 49 | 49 | 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); | |
| 50 | 51 | void codegen_add_time_event(CodeGen *g, const char *name); |
| 51 | 52 | void codegen_print_timing_report(CodeGen *g, FILE *f); |
| 52 | 53 | void codegen_build(CodeGen *g); |
src/error.cpp+2| ... | ... | @@ -21,6 +21,8 @@ const char *err_str(int err) { |
| 21 | 21 | case ErrorFileTooBig: return "file too big"; |
| 22 | 22 | case ErrorDivByZero: return "division by zero"; |
| 23 | 23 | case ErrorOverflow: return "overflow"; |
| 24 | case ErrorPathAlreadyExists: return "path already exists"; | |
| 25 | case ErrorUnexpected: return "unexpected error"; | |
| 24 | 26 | } |
| 25 | 27 | return "(invalid error)"; |
| 26 | 28 | } |
src/error.hpp+3-1| ... | ... | @@ -20,7 +20,9 @@ enum Error { |
| 20 | 20 | ErrorFileSystem, |
| 21 | 21 | ErrorFileTooBig, |
| 22 | 22 | ErrorDivByZero, |
| 23 | ErrorOverflow | |
| 23 | ErrorOverflow, | |
| 24 | ErrorPathAlreadyExists, | |
| 25 | ErrorUnexpected, | |
| 24 | 26 | }; |
| 25 | 27 | |
| 26 | 28 | const char *err_str(int err); |
src/link.cpp+7-3| ... | ... | @@ -48,6 +48,8 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) { |
| 48 | 48 | codegen_set_omit_zigrt(child_gen, true); |
| 49 | 49 | child_gen->want_h_file = false; |
| 50 | 50 | |
| 51 | codegen_set_cache_dir(child_gen, parent_gen->cache_dir); | |
| 52 | ||
| 51 | 53 | codegen_set_is_release(child_gen, parent_gen->is_release_build); |
| 52 | 54 | |
| 53 | 55 | codegen_set_strip(child_gen, parent_gen->strip_debug_symbols); |
| ... | ... | @@ -64,10 +66,12 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) { |
| 64 | 66 | |
| 65 | 67 | codegen_build(child_gen); |
| 66 | 68 | const char *o_ext = target_o_file_ext(&child_gen->zig_target); |
| 67 | Buf *o_out = buf_sprintf("%s%s", oname, o_ext); | |
| 68 | codegen_link(child_gen, buf_ptr(o_out)); | |
| 69 | Buf *o_out_name = buf_sprintf("%s%s", oname, o_ext); | |
| 70 | Buf *output_path = buf_alloc(); | |
| 71 | os_path_join(parent_gen->cache_dir, o_out_name, output_path); | |
| 72 | codegen_link(child_gen, buf_ptr(output_path)); | |
| 69 | 73 | |
| 70 | return o_out; | |
| 74 | return output_path; | |
| 71 | 75 | } |
| 72 | 76 | |
| 73 | 77 | static const char *get_exe_file_extension(CodeGen *g) { |
src/main.cpp+23-3| ... | ... | @@ -29,6 +29,7 @@ static int usage(const char *arg0) { |
| 29 | 29 | " version print version number and exit\n" |
| 30 | 30 | "Compile Options:\n" |
| 31 | 31 | " --assembly [source] add assembly file to build\n" |
| 32 | " --cache-dir [path] override the cache directory\n" | |
| 32 | 33 | " --color [auto|off|on] enable or disable colored error messages\n" |
| 33 | 34 | " --enable-timing-info print timing diagnostics\n" |
| 34 | 35 | " --libc-include-dir [path] directory where libc stdlib.h resides\n" |
| ... | ... | @@ -162,6 +163,7 @@ int main(int argc, char **argv) { |
| 162 | 163 | size_t ver_minor = 0; |
| 163 | 164 | size_t ver_patch = 0; |
| 164 | 165 | bool timing_info = false; |
| 166 | const char *cache_dir = "zig-cache"; | |
| 165 | 167 | |
| 166 | 168 | if (argc >= 2 && strcmp(argv[1], "build") == 0) { |
| 167 | 169 | const char *zig_exe_path = arg0; |
| ... | ... | @@ -180,6 +182,7 @@ int main(int argc, char **argv) { |
| 180 | 182 | ZigList<const char *> args = {0}; |
| 181 | 183 | args.append(zig_exe_path); |
| 182 | 184 | args.append(NULL); // placeholder |
| 185 | args.append(NULL); // placeholder | |
| 183 | 186 | for (int i = 2; i < argc; i += 1) { |
| 184 | 187 | if (strcmp(argv[i], "--debug-build-verbose") == 0) { |
| 185 | 188 | verbose = true; |
| ... | ... | @@ -189,6 +192,9 @@ int main(int argc, char **argv) { |
| 189 | 192 | } else if (i + 1 < argc && strcmp(argv[i], "--build-file") == 0) { |
| 190 | 193 | build_file = argv[i + 1]; |
| 191 | 194 | i += 1; |
| 195 | } else if (i + 1 < argc && strcmp(argv[i], "--cache-dir") == 0) { | |
| 196 | cache_dir = argv[i + 1]; | |
| 197 | i += 1; | |
| 192 | 198 | } else { |
| 193 | 199 | args.append(argv[i]); |
| 194 | 200 | } |
| ... | ... | @@ -205,7 +211,14 @@ int main(int argc, char **argv) { |
| 205 | 211 | Buf build_file_dirname = BUF_INIT; |
| 206 | 212 | os_path_split(&build_file_abs, &build_file_dirname, &build_file_basename); |
| 207 | 213 | |
| 214 | Buf *full_cache_dir = buf_alloc(); | |
| 215 | os_path_resolve(buf_create_from_str("."), buf_create_from_str(cache_dir), full_cache_dir); | |
| 216 | Buf *path_to_build_exe = buf_alloc(); | |
| 217 | os_path_join(full_cache_dir, buf_create_from_str("build"), path_to_build_exe); | |
| 218 | codegen_set_cache_dir(g, full_cache_dir); | |
| 219 | ||
| 208 | 220 | args.items[1] = buf_ptr(&build_file_dirname); |
| 221 | args.items[2] = buf_ptr(full_cache_dir); | |
| 209 | 222 | |
| 210 | 223 | bool build_file_exists; |
| 211 | 224 | if ((err = os_file_exists(&build_file_abs, &build_file_exists))) { |
| ... | ... | @@ -221,6 +234,7 @@ int main(int argc, char **argv) { |
| 221 | 234 | "General Options:\n" |
| 222 | 235 | " --help Print this help and exit\n" |
| 223 | 236 | " --build-file [file] Override path to build.zig\n" |
| 237 | " --cache-dir [path] Override path to cache directory\n" | |
| 224 | 238 | " --verbose Print commands before executing them\n" |
| 225 | 239 | " --debug-build-verbose Print verbose debugging information for the build system itself\n" |
| 226 | 240 | " --prefix [prefix] Override default install prefix\n" |
| ... | ... | @@ -245,13 +259,13 @@ int main(int argc, char **argv) { |
| 245 | 259 | build_pkg->package_table.put(buf_create_from_str("std"), g->std_package); |
| 246 | 260 | g->root_package->package_table.put(buf_create_from_str("@build"), build_pkg); |
| 247 | 261 | codegen_build(g); |
| 248 | codegen_link(g, "build"); | |
| 262 | codegen_link(g, buf_ptr(path_to_build_exe)); | |
| 249 | 263 | |
| 250 | 264 | Termination term; |
| 251 | os_spawn_process("./build", args, &term); | |
| 265 | os_spawn_process(buf_ptr(path_to_build_exe), args, &term); | |
| 252 | 266 | if (term.how != TerminationIdClean || term.code != 0) { |
| 253 | 267 | fprintf(stderr, "\nBuild failed. Use the following command to reproduce the failure:\n"); |
| 254 | fprintf(stderr, "./build"); | |
| 268 | fprintf(stderr, "%s", buf_ptr(path_to_build_exe)); | |
| 255 | 269 | for (size_t i = 0; i < args.length; i += 1) { |
| 256 | 270 | fprintf(stderr, " %s", args.at(i)); |
| 257 | 271 | } |
| ... | ... | @@ -331,6 +345,8 @@ int main(int argc, char **argv) { |
| 331 | 345 | objects.append(argv[i]); |
| 332 | 346 | } else if (strcmp(arg, "--assembly") == 0) { |
| 333 | 347 | asm_files.append(argv[i]); |
| 348 | } else if (strcmp(arg, "--cache-dir") == 0) { | |
| 349 | cache_dir = argv[i]; | |
| 334 | 350 | } else if (strcmp(arg, "--target-arch") == 0) { |
| 335 | 351 | target_arch = argv[i]; |
| 336 | 352 | } else if (strcmp(arg, "--target-os") == 0) { |
| ... | ... | @@ -478,12 +494,16 @@ int main(int argc, char **argv) { |
| 478 | 494 | |
| 479 | 495 | Buf *zig_root_source_file = (cmd == CmdParseH) ? nullptr : in_file_buf; |
| 480 | 496 | |
| 497 | Buf *full_cache_dir = buf_alloc(); | |
| 498 | os_path_resolve(buf_create_from_str("."), buf_create_from_str(cache_dir), full_cache_dir); | |
| 499 | ||
| 481 | 500 | CodeGen *g = codegen_create(zig_root_source_file, target); |
| 482 | 501 | codegen_set_out_name(g, buf_out_name); |
| 483 | 502 | codegen_set_lib_version(g, ver_major, ver_minor, ver_patch); |
| 484 | 503 | codegen_set_is_release(g, is_release_build); |
| 485 | 504 | codegen_set_is_test(g, cmd == CmdTest); |
| 486 | 505 | codegen_set_linker_script(g, linker_script); |
| 506 | codegen_set_cache_dir(g, full_cache_dir); | |
| 487 | 507 | if (each_lib_rpath) |
| 488 | 508 | codegen_set_each_lib_rpath(g, each_lib_rpath); |
| 489 | 509 |
src/os.cpp+48| ... | ... | @@ -723,3 +723,51 @@ double os_get_time(void) { |
| 723 | 723 | return seconds; |
| 724 | 724 | #endif |
| 725 | 725 | } |
| 726 | ||
| 727 | int os_make_path(Buf *path) { | |
| 728 | Buf *resolved_path = buf_alloc(); | |
| 729 | os_path_resolve(buf_create_from_str("."), path, resolved_path); | |
| 730 | ||
| 731 | size_t end_index = buf_len(resolved_path); | |
| 732 | int err; | |
| 733 | while (true) { | |
| 734 | if ((err = os_make_dir(buf_slice(resolved_path, 0, end_index)))) { | |
| 735 | if (err == ErrorPathAlreadyExists) { | |
| 736 | if (end_index == buf_len(resolved_path)) | |
| 737 | return 0; | |
| 738 | } else if (err == ErrorFileNotFound) { | |
| 739 | // march end_index backward until next path component | |
| 740 | while (true) { | |
| 741 | end_index -= 1; | |
| 742 | if (buf_ptr(resolved_path)[end_index] == '/') | |
| 743 | break; | |
| 744 | } | |
| 745 | continue; | |
| 746 | } else { | |
| 747 | return err; | |
| 748 | } | |
| 749 | } | |
| 750 | if (end_index == buf_len(resolved_path)) | |
| 751 | return 0; | |
| 752 | // march end_index forward until next path component | |
| 753 | while (true) { | |
| 754 | end_index += 1; | |
| 755 | if (end_index == buf_len(resolved_path) || buf_ptr(resolved_path)[end_index] == '/') | |
| 756 | break; | |
| 757 | } | |
| 758 | } | |
| 759 | return 0; | |
| 760 | } | |
| 761 | ||
| 762 | int os_make_dir(Buf *path) { | |
| 763 | if (mkdir(buf_ptr(path), 0755) == -1) { | |
| 764 | if (errno == EEXIST) | |
| 765 | return ErrorPathAlreadyExists; | |
| 766 | if (errno == ENOENT) | |
| 767 | return ErrorFileNotFound; | |
| 768 | if (errno == EACCES) | |
| 769 | return ErrorAccess; | |
| 770 | return ErrorUnexpected; | |
| 771 | } | |
| 772 | return 0; | |
| 773 | } |
src/os.hpp+3| ... | ... | @@ -40,6 +40,9 @@ int os_path_real(Buf *rel_path, Buf *out_abs_path); |
| 40 | 40 | void os_path_resolve(Buf *ref_path, Buf *target_path, Buf *out_abs_path); |
| 41 | 41 | bool os_path_is_absolute(Buf *path); |
| 42 | 42 | |
| 43 | int os_make_path(Buf *path); | |
| 44 | int os_make_dir(Buf *path); | |
| 45 | ||
| 43 | 46 | void os_write_file(Buf *full_path, Buf *contents); |
| 44 | 47 | int os_copy_file(Buf *src_path, Buf *dest_path); |
| 45 | 48 |
std/build.zig+8-4| ... | ... | @@ -37,9 +37,10 @@ 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, | |
| 40 | out_dir: []u8, // TODO get rid of this | |
| 41 | 41 | installed_files: List([]const u8), |
| 42 | 42 | build_root: []const u8, |
| 43 | cache_root: []const u8, | |
| 43 | 44 | |
| 44 | 45 | const UserInputOptionsMap = HashMap([]const u8, UserInputOption, mem.hash_slice_u8, mem.eql_slice_u8); |
| 45 | 46 | const AvailableOptionsMap = HashMap([]const u8, AvailableOption, mem.hash_slice_u8, mem.eql_slice_u8); |
| ... | ... | @@ -75,10 +76,13 @@ pub const Builder = struct { |
| 75 | 76 | description: []const u8, |
| 76 | 77 | }; |
| 77 | 78 | |
| 78 | pub fn init(allocator: &Allocator, zig_exe: []const u8, build_root: []const u8) -> Builder { | |
| 79 | pub fn init(allocator: &Allocator, zig_exe: []const u8, build_root: []const u8, | |
| 80 | cache_root: []const u8) -> Builder | |
| 81 | { | |
| 79 | 82 | var self = Builder { |
| 80 | 83 | .zig_exe = zig_exe, |
| 81 | 84 | .build_root = build_root, |
| 85 | .cache_root = cache_root, | |
| 82 | 86 | .verbose = false, |
| 83 | 87 | .invalid_user_input = false, |
| 84 | 88 | .allocator = allocator, |
| ... | ... | @@ -768,7 +772,7 @@ pub const LibExeObjStep = struct { |
| 768 | 772 | explicit_out_path |
| 769 | 773 | } else { |
| 770 | 774 | // TODO make it so we always know where this will be |
| 771 | %%os.path.join(self.builder.allocator, self.builder.out_dir, | |
| 775 | %%os.path.join(self.builder.allocator, self.builder.cache_root, | |
| 772 | 776 | self.builder.fmt("{}{}", obj.name, obj.target.oFileExt())) |
| 773 | 777 | }; |
| 774 | 778 | %%self.object_files.append(path_to_obj); |
| ... | ... | @@ -1217,7 +1221,7 @@ pub const CExecutable = struct { |
| 1217 | 1221 | self.step.dependOn(&obj.step); |
| 1218 | 1222 | |
| 1219 | 1223 | // TODO make it so we always know where this will be |
| 1220 | %%self.object_files.append(%%os.path.join(self.builder.allocator, self.builder.out_dir, | |
| 1224 | %%self.object_files.append(%%os.path.join(self.builder.allocator, self.builder.cache_root, | |
| 1221 | 1225 | self.builder.fmt("{}{}", obj.name, obj.target.oFileExt()))); |
| 1222 | 1226 | |
| 1223 | 1227 | // TODO should be some kind of isolated directory that only has this header in it |
std/special/build_runner.zig+12-1| ... | ... | @@ -32,13 +32,23 @@ pub fn main() -> %void { |
| 32 | 32 | result |
| 33 | 33 | }; |
| 34 | 34 | |
| 35 | const cache_root = { | |
| 36 | if (arg_i >= os.args.count()) { | |
| 37 | %%io.stderr.printf("Expected third argument to be cache root directory path\n"); | |
| 38 | return error.InvalidArgs; | |
| 39 | } | |
| 40 | const result = os.args.at(arg_i); | |
| 41 | arg_i += 1; | |
| 42 | result | |
| 43 | }; | |
| 44 | ||
| 35 | 45 | // TODO use a more general purpose allocator here |
| 36 | 46 | var inc_allocator = %%mem.IncrementingAllocator.init(10 * 1024 * 1024); |
| 37 | 47 | defer inc_allocator.deinit(); |
| 38 | 48 | |
| 39 | 49 | const allocator = &inc_allocator.allocator; |
| 40 | 50 | |
| 41 | var builder = Builder.init(allocator, zig_exe, build_root); | |
| 51 | var builder = Builder.init(allocator, zig_exe, build_root, cache_root); | |
| 42 | 52 | defer builder.deinit(); |
| 43 | 53 | |
| 44 | 54 | var targets = List([]const u8).init(allocator); |
| ... | ... | @@ -113,6 +123,7 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) |
| 113 | 123 | \\General Options: |
| 114 | 124 | \\ --help Print this help and exit |
| 115 | 125 | \\ --build-file [file] Override path to build.zig |
| 126 | \\ --cache-dir [path] Override path to cache directory | |
| 116 | 127 | \\ --verbose Print commands before executing them |
| 117 | 128 | \\ --debug-build-verbose Print verbose debugging information for the build system itself |
| 118 | 129 | \\ --prefix [prefix] Override default install prefix |
test/tests.zig+1-1| ... | ... | @@ -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.out_dir, b.env_map, b.zig_exe, zig_args.toSliceConst()); | |
| 678 | const run_cmd = b.addCommand(b.cache_root, 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); |