| author | |
| committer | |
| log | e42d86b657c2fae093fb2545e8b4b85614a0c906 |
| tree | e7b0f9f6f509e34edeb2226569b2ae78d34cfb5a |
| parent | 17aa8c3ee29fae4bfbd6acc91eed8d229f627c32 |
| parent | 2d5b2bf1c986d037ef965bf8c9b4d8dfd5967478 |
| signature |
closes #336215 files changed, 543 insertions(+), 102 deletions(-)
lib/std/fmt.zig+10-3| ... | ... | @@ -1055,14 +1055,21 @@ const BufPrintContext = struct { |
| 1055 | 1055 | }; |
| 1056 | 1056 | |
| 1057 | 1057 | fn bufPrintWrite(context: *BufPrintContext, bytes: []const u8) !void { |
| 1058 | if (context.remaining.len < bytes.len) return error.BufferTooSmall; | |
| 1058 | if (context.remaining.len < bytes.len) { | |
| 1059 | mem.copy(u8, context.remaining, bytes[0..context.remaining.len]); | |
| 1060 | return error.BufferTooSmall; | |
| 1061 | } | |
| 1059 | 1062 | mem.copy(u8, context.remaining, bytes); |
| 1060 | 1063 | context.remaining = context.remaining[bytes.len..]; |
| 1061 | 1064 | } |
| 1062 | 1065 | |
| 1063 | pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) ![]u8 { | |
| 1066 | pub const BufPrintError = error{ | |
| 1067 | /// As much as possible was written to the buffer, but it was too small to fit all the printed bytes. | |
| 1068 | BufferTooSmall, | |
| 1069 | }; | |
| 1070 | pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) BufPrintError![]u8 { | |
| 1064 | 1071 | var context = BufPrintContext{ .remaining = buf }; |
| 1065 | try format(&context, error{BufferTooSmall}, bufPrintWrite, fmt, args); | |
| 1072 | try format(&context, BufPrintError, bufPrintWrite, fmt, args); | |
| 1066 | 1073 | return buf[0 .. buf.len - context.remaining.len]; |
| 1067 | 1074 | } |
| 1068 | 1075 |
lib/std/progress.zig created+258| ... | ... | @@ -0,0 +1,258 @@ |
| 1 | const std = @import("std"); | |
| 2 | const testing = std.testing; | |
| 3 | const assert = std.debug.assert; | |
| 4 | ||
| 5 | /// This API is non-allocating and non-fallible. The tradeoff is that users of | |
| 6 | /// this API must provide the storage for each `Progress.Node`. | |
| 7 | /// Initialize the struct directly, overriding these fields as desired: | |
| 8 | /// * `refresh_rate_ms` | |
| 9 | /// * `initial_delay_ms` | |
| 10 | pub const Progress = struct { | |
| 11 | /// `null` if the current node (and its children) should | |
| 12 | /// not print on update() | |
| 13 | terminal: ?std.fs.File = undefined, | |
| 14 | ||
| 15 | root: Node = undefined, | |
| 16 | ||
| 17 | /// Keeps track of how much time has passed since the beginning. | |
| 18 | /// Used to compare with `initial_delay_ms` and `refresh_rate_ms`. | |
| 19 | timer: std.time.Timer = undefined, | |
| 20 | ||
| 21 | /// When the previous refresh was written to the terminal. | |
| 22 | /// Used to compare with `refresh_rate_ms`. | |
| 23 | prev_refresh_timestamp: u64 = undefined, | |
| 24 | ||
| 25 | /// This buffer represents the maximum number of bytes written to the terminal | |
| 26 | /// with each refresh. | |
| 27 | output_buffer: [100]u8 = undefined, | |
| 28 | ||
| 29 | /// How many nanoseconds between writing updates to the terminal. | |
| 30 | refresh_rate_ns: u64 = 50 * std.time.millisecond, | |
| 31 | ||
| 32 | /// How many nanoseconds to keep the output hidden | |
| 33 | initial_delay_ns: u64 = 500 * std.time.millisecond, | |
| 34 | ||
| 35 | done: bool = true, | |
| 36 | ||
| 37 | /// Keeps track of how many columns in the terminal have been output, so that | |
| 38 | /// we can move the cursor back later. | |
| 39 | columns_written: usize = undefined, | |
| 40 | ||
| 41 | /// Represents one unit of progress. Each node can have children nodes, or | |
| 42 | /// one can use integers with `update`. | |
| 43 | pub const Node = struct { | |
| 44 | context: *Progress, | |
| 45 | parent: ?*Node, | |
| 46 | completed_items: usize, | |
| 47 | name: []const u8, | |
| 48 | recently_updated_child: ?*Node = null, | |
| 49 | ||
| 50 | /// This field may be updated freely. | |
| 51 | estimated_total_items: ?usize, | |
| 52 | ||
| 53 | /// Create a new child progress node. | |
| 54 | /// Call `Node.end` when done. | |
| 55 | /// TODO solve https://github.com/ziglang/zig/issues/2765 and then change this | |
| 56 | /// API to set `self.parent.recently_updated_child` with the return value. | |
| 57 | /// Until that is fixed you probably want to call `activate` on the return value. | |
| 58 | pub fn start(self: *Node, name: []const u8, estimated_total_items: ?usize) Node { | |
| 59 | return Node{ | |
| 60 | .context = self.context, | |
| 61 | .parent = self, | |
| 62 | .completed_items = 0, | |
| 63 | .name = name, | |
| 64 | .estimated_total_items = estimated_total_items, | |
| 65 | }; | |
| 66 | } | |
| 67 | ||
| 68 | /// This is the same as calling `start` and then `end` on the returned `Node`. | |
| 69 | pub fn completeOne(self: *Node) void { | |
| 70 | if (self.parent) |parent| parent.recently_updated_child = self; | |
| 71 | self.completed_items += 1; | |
| 72 | self.context.maybeRefresh(); | |
| 73 | } | |
| 74 | ||
| 75 | pub fn end(self: *Node) void { | |
| 76 | self.context.maybeRefresh(); | |
| 77 | if (self.parent) |parent| { | |
| 78 | if (parent.recently_updated_child) |parent_child| { | |
| 79 | if (parent_child == self) { | |
| 80 | parent.recently_updated_child = null; | |
| 81 | } | |
| 82 | } | |
| 83 | parent.completeOne(); | |
| 84 | } else { | |
| 85 | self.context.done = true; | |
| 86 | self.context.refresh(); | |
| 87 | } | |
| 88 | } | |
| 89 | ||
| 90 | /// Tell the parent node that this node is actively being worked on. | |
| 91 | pub fn activate(self: *Node) void { | |
| 92 | if (self.parent) |parent| parent.recently_updated_child = self; | |
| 93 | } | |
| 94 | }; | |
| 95 | ||
| 96 | /// Create a new progress node. | |
| 97 | /// Call `Node.end` when done. | |
| 98 | /// TODO solve https://github.com/ziglang/zig/issues/2765 and then change this | |
| 99 | /// API to return Progress rather than accept it as a parameter. | |
| 100 | pub fn start(self: *Progress, name: []const u8, estimated_total_items: ?usize) !*Node { | |
| 101 | if (std.io.getStdErr()) |stderr| { | |
| 102 | self.terminal = if (stderr.supportsAnsiEscapeCodes()) stderr else null; | |
| 103 | } else |_| { | |
| 104 | self.terminal = null; | |
| 105 | } | |
| 106 | self.root = Node{ | |
| 107 | .context = self, | |
| 108 | .parent = null, | |
| 109 | .completed_items = 0, | |
| 110 | .name = name, | |
| 111 | .estimated_total_items = estimated_total_items, | |
| 112 | }; | |
| 113 | self.columns_written = 0; | |
| 114 | self.prev_refresh_timestamp = 0; | |
| 115 | self.timer = try std.time.Timer.start(); | |
| 116 | self.done = false; | |
| 117 | return &self.root; | |
| 118 | } | |
| 119 | ||
| 120 | /// Updates the terminal if enough time has passed since last update. | |
| 121 | pub fn maybeRefresh(self: *Progress) void { | |
| 122 | const now = self.timer.read(); | |
| 123 | if (now < self.initial_delay_ns) return; | |
| 124 | if (now - self.prev_refresh_timestamp < self.refresh_rate_ns) return; | |
| 125 | self.refresh(); | |
| 126 | } | |
| 127 | ||
| 128 | /// Updates the terminal and resets `self.next_refresh_timestamp`. | |
| 129 | pub fn refresh(self: *Progress) void { | |
| 130 | const file = self.terminal orelse return; | |
| 131 | ||
| 132 | const prev_columns_written = self.columns_written; | |
| 133 | var end: usize = 0; | |
| 134 | if (self.columns_written > 0) { | |
| 135 | // restore cursor position | |
| 136 | end += (std.fmt.bufPrint(self.output_buffer[end..], "\x1b[{}D", self.columns_written) catch unreachable).len; | |
| 137 | self.columns_written = 0; | |
| 138 | ||
| 139 | // clear rest of line | |
| 140 | end += (std.fmt.bufPrint(self.output_buffer[end..], "\x1b[0K") catch unreachable).len; | |
| 141 | } | |
| 142 | ||
| 143 | if (!self.done) { | |
| 144 | var need_ellipse = false; | |
| 145 | var maybe_node: ?*Node = &self.root; | |
| 146 | while (maybe_node) |node| { | |
| 147 | if (need_ellipse) { | |
| 148 | self.bufWrite(&end, "..."); | |
| 149 | } | |
| 150 | need_ellipse = false; | |
| 151 | if (node.name.len != 0 or node.estimated_total_items != null) { | |
| 152 | if (node.name.len != 0) { | |
| 153 | self.bufWrite(&end, "{}", node.name); | |
| 154 | need_ellipse = true; | |
| 155 | } | |
| 156 | if (node.estimated_total_items) |total| { | |
| 157 | if (need_ellipse) self.bufWrite(&end, " "); | |
| 158 | self.bufWrite(&end, "[{}/{}] ", node.completed_items, total); | |
| 159 | need_ellipse = false; | |
| 160 | } else if (node.completed_items != 0) { | |
| 161 | if (need_ellipse) self.bufWrite(&end, " "); | |
| 162 | self.bufWrite(&end, "[{}] ", node.completed_items); | |
| 163 | need_ellipse = false; | |
| 164 | } | |
| 165 | } | |
| 166 | maybe_node = node.recently_updated_child; | |
| 167 | } | |
| 168 | if (need_ellipse) { | |
| 169 | self.bufWrite(&end, "..."); | |
| 170 | } | |
| 171 | } | |
| 172 | ||
| 173 | _ = file.write(self.output_buffer[0..end]) catch |e| { | |
| 174 | // Stop trying to write to this file once it errors. | |
| 175 | self.terminal = null; | |
| 176 | }; | |
| 177 | self.prev_refresh_timestamp = self.timer.read(); | |
| 178 | } | |
| 179 | ||
| 180 | pub fn log(self: *Progress, comptime format: []const u8, args: ...) void { | |
| 181 | const file = self.terminal orelse return; | |
| 182 | self.refresh(); | |
| 183 | file.outStream().stream.print(format, args) catch { | |
| 184 | self.terminal = null; | |
| 185 | return; | |
| 186 | }; | |
| 187 | self.columns_written = 0; | |
| 188 | } | |
| 189 | ||
| 190 | fn bufWrite(self: *Progress, end: *usize, comptime format: []const u8, args: ...) void { | |
| 191 | if (std.fmt.bufPrint(self.output_buffer[end.*..], format, args)) |written| { | |
| 192 | const amt = written.len; | |
| 193 | end.* += amt; | |
| 194 | self.columns_written += amt; | |
| 195 | } else |err| switch (err) { | |
| 196 | error.BufferTooSmall => { | |
| 197 | self.columns_written += self.output_buffer.len - end.*; | |
| 198 | end.* = self.output_buffer.len; | |
| 199 | }, | |
| 200 | } | |
| 201 | const bytes_needed_for_esc_codes_at_end = 11; | |
| 202 | const max_end = self.output_buffer.len - bytes_needed_for_esc_codes_at_end; | |
| 203 | if (end.* > max_end) { | |
| 204 | const suffix = "..."; | |
| 205 | self.columns_written = self.columns_written - (end.* - max_end) + suffix.len; | |
| 206 | std.mem.copy(u8, self.output_buffer[max_end..], suffix); | |
| 207 | end.* = max_end + suffix.len; | |
| 208 | } | |
| 209 | } | |
| 210 | }; | |
| 211 | ||
| 212 | test "basic functionality" { | |
| 213 | var disable = true; | |
| 214 | if (disable) { | |
| 215 | // This test is disabled because it uses time.sleep() and is therefore slow. It also | |
| 216 | // prints bogus progress data to stderr. | |
| 217 | return error.SkipZigTest; | |
| 218 | } | |
| 219 | var progress = Progress{}; | |
| 220 | const root_node = try progress.start("", 100); | |
| 221 | defer root_node.end(); | |
| 222 | ||
| 223 | const sub_task_names = [_][]const u8{ | |
| 224 | "reticulating splines", | |
| 225 | "adjusting shoes", | |
| 226 | "climbing towers", | |
| 227 | "pouring juice", | |
| 228 | }; | |
| 229 | var next_sub_task: usize = 0; | |
| 230 | ||
| 231 | var i: usize = 0; | |
| 232 | while (i < 100) : (i += 1) { | |
| 233 | var node = root_node.start(sub_task_names[next_sub_task], 5); | |
| 234 | node.activate(); | |
| 235 | next_sub_task = (next_sub_task + 1) % sub_task_names.len; | |
| 236 | ||
| 237 | node.completeOne(); | |
| 238 | std.time.sleep(5 * std.time.millisecond); | |
| 239 | node.completeOne(); | |
| 240 | node.completeOne(); | |
| 241 | std.time.sleep(5 * std.time.millisecond); | |
| 242 | node.completeOne(); | |
| 243 | node.completeOne(); | |
| 244 | std.time.sleep(5 * std.time.millisecond); | |
| 245 | ||
| 246 | node.end(); | |
| 247 | ||
| 248 | std.time.sleep(5 * std.time.millisecond); | |
| 249 | } | |
| 250 | { | |
| 251 | var node = root_node.start("this is a really long name designed to activate the truncation code. let's find out if it works", null); | |
| 252 | node.activate(); | |
| 253 | std.time.sleep(10 * std.time.millisecond); | |
| 254 | progress.refresh(); | |
| 255 | std.time.sleep(10 * std.time.millisecond); | |
| 256 | node.end(); | |
| 257 | } | |
| 258 | } |
lib/std/special/test_runner.zig+15-10| ... | ... | @@ -2,28 +2,33 @@ const std = @import("std"); |
| 2 | 2 | const io = std.io; |
| 3 | 3 | const builtin = @import("builtin"); |
| 4 | 4 | const test_fn_list = builtin.test_functions; |
| 5 | const warn = std.debug.warn; | |
| 6 | 5 | |
| 7 | pub fn main() !void { | |
| 6 | pub fn main() anyerror!void { | |
| 8 | 7 | var ok_count: usize = 0; |
| 9 | 8 | var skip_count: usize = 0; |
| 10 | for (test_fn_list) |test_fn, i| { | |
| 11 | warn("{}/{} {}...", i + 1, test_fn_list.len, test_fn.name); | |
| 9 | var progress = std.Progress{}; | |
| 10 | const root_node = progress.start("Test", test_fn_list.len) catch |err| switch (err) { | |
| 11 | // TODO still run tests in this case | |
| 12 | error.TimerUnsupported => @panic("timer unsupported"), | |
| 13 | }; | |
| 12 | 14 | |
| 15 | for (test_fn_list) |test_fn, i| { | |
| 16 | var test_node = root_node.start(test_fn.name, null); | |
| 17 | test_node.activate(); | |
| 13 | 18 | if (test_fn.func()) |_| { |
| 14 | 19 | ok_count += 1; |
| 15 | warn("OK\n"); | |
| 20 | test_node.end(); | |
| 16 | 21 | } else |err| switch (err) { |
| 17 | 22 | error.SkipZigTest => { |
| 18 | 23 | skip_count += 1; |
| 19 | warn("SKIP\n"); | |
| 24 | test_node.end(); | |
| 25 | progress.log("{}...SKIP\n", test_fn.name); | |
| 20 | 26 | }, |
| 21 | 27 | else => return err, |
| 22 | 28 | } |
| 23 | 29 | } |
| 24 | if (ok_count == test_fn_list.len) { | |
| 25 | warn("All tests passed.\n"); | |
| 26 | } else { | |
| 27 | warn("{} passed; {} skipped.\n", ok_count, skip_count); | |
| 30 | root_node.end(); | |
| 31 | if (ok_count != test_fn_list.len) { | |
| 32 | progress.log("{} passed; {} skipped.\n", ok_count, skip_count); | |
| 28 | 33 | } |
| 29 | 34 | } |
lib/std/std.zig+6-5| ... | ... | @@ -6,20 +6,21 @@ pub const BufMap = @import("buf_map.zig").BufMap; |
| 6 | 6 | pub const BufSet = @import("buf_set.zig").BufSet; |
| 7 | 7 | pub const Buffer = @import("buffer.zig").Buffer; |
| 8 | 8 | pub const BufferOutStream = @import("io.zig").BufferOutStream; |
| 9 | pub const ChildProcess = @import("child_process.zig").ChildProcess; | |
| 9 | 10 | pub const DynLib = @import("dynamic_library.zig").DynLib; |
| 10 | 11 | pub const HashMap = @import("hash_map.zig").HashMap; |
| 11 | 12 | pub const Mutex = @import("mutex.zig").Mutex; |
| 12 | pub const PackedIntArrayEndian = @import("packed_int_array.zig").PackedIntArrayEndian; | |
| 13 | 13 | pub const PackedIntArray = @import("packed_int_array.zig").PackedIntArray; |
| 14 | pub const PackedIntSliceEndian = @import("packed_int_array.zig").PackedIntSliceEndian; | |
| 14 | pub const PackedIntArrayEndian = @import("packed_int_array.zig").PackedIntArrayEndian; | |
| 15 | 15 | pub const PackedIntSlice = @import("packed_int_array.zig").PackedIntSlice; |
| 16 | pub const PackedIntSliceEndian = @import("packed_int_array.zig").PackedIntSliceEndian; | |
| 16 | 17 | pub const PriorityQueue = @import("priority_queue.zig").PriorityQueue; |
| 17 | pub const SinglyLinkedList = @import("linked_list.zig").SinglyLinkedList; | |
| 18 | pub const StaticallyInitializedMutex = @import("statically_initialized_mutex.zig").StaticallyInitializedMutex; | |
| 18 | pub const Progress = @import("progress.zig").Progress; | |
| 19 | 19 | pub const SegmentedList = @import("segmented_list.zig").SegmentedList; |
| 20 | pub const SinglyLinkedList = @import("linked_list.zig").SinglyLinkedList; | |
| 20 | 21 | pub const SpinLock = @import("spinlock.zig").SpinLock; |
| 22 | pub const StaticallyInitializedMutex = @import("statically_initialized_mutex.zig").StaticallyInitializedMutex; | |
| 21 | 23 | pub const StringHashMap = @import("hash_map.zig").StringHashMap; |
| 22 | pub const ChildProcess = @import("child_process.zig").ChildProcess; | |
| 23 | 24 | pub const TailQueue = @import("linked_list.zig").TailQueue; |
| 24 | 25 | pub const Thread = @import("thread.zig").Thread; |
| 25 | 26 |
src-self-hosted/stage1.zig+59| ... | ... | @@ -456,3 +456,62 @@ export fn stage2_attach_segfault_handler() void { |
| 456 | 456 | std.debug.attachSegfaultHandler(); |
| 457 | 457 | } |
| 458 | 458 | } |
| 459 | ||
| 460 | // ABI warning | |
| 461 | export fn stage2_progress_create() *std.Progress { | |
| 462 | const ptr = std.heap.c_allocator.create(std.Progress) catch @panic("out of memory"); | |
| 463 | ptr.* = std.Progress{}; | |
| 464 | return ptr; | |
| 465 | } | |
| 466 | ||
| 467 | // ABI warning | |
| 468 | export fn stage2_progress_destroy(progress: *std.Progress) void { | |
| 469 | std.heap.c_allocator.destroy(progress); | |
| 470 | } | |
| 471 | ||
| 472 | // ABI warning | |
| 473 | export fn stage2_progress_start_root( | |
| 474 | progress: *std.Progress, | |
| 475 | name_ptr: [*]const u8, | |
| 476 | name_len: usize, | |
| 477 | estimated_total_items: usize, | |
| 478 | ) *std.Progress.Node { | |
| 479 | return progress.start( | |
| 480 | name_ptr[0..name_len], | |
| 481 | if (estimated_total_items == 0) null else estimated_total_items, | |
| 482 | ) catch @panic("timer unsupported"); | |
| 483 | } | |
| 484 | ||
| 485 | // ABI warning | |
| 486 | export fn stage2_progress_disable_tty(progress: *std.Progress) void { | |
| 487 | progress.terminal = null; | |
| 488 | } | |
| 489 | ||
| 490 | // ABI warning | |
| 491 | export fn stage2_progress_start( | |
| 492 | node: *std.Progress.Node, | |
| 493 | name_ptr: [*]const u8, | |
| 494 | name_len: usize, | |
| 495 | estimated_total_items: usize, | |
| 496 | ) *std.Progress.Node { | |
| 497 | const child_node = std.heap.c_allocator.create(std.Progress.Node) catch @panic("out of memory"); | |
| 498 | child_node.* = node.start( | |
| 499 | name_ptr[0..name_len], | |
| 500 | if (estimated_total_items == 0) null else estimated_total_items, | |
| 501 | ); | |
| 502 | child_node.activate(); | |
| 503 | return child_node; | |
| 504 | } | |
| 505 | ||
| 506 | // ABI warning | |
| 507 | export fn stage2_progress_end(node: *std.Progress.Node) void { | |
| 508 | node.end(); | |
| 509 | if (&node.context.root != node) { | |
| 510 | std.heap.c_allocator.destroy(node); | |
| 511 | } | |
| 512 | } | |
| 513 | ||
| 514 | // ABI warning | |
| 515 | export fn stage2_progress_complete_one(node: *std.Progress.Node) void { | |
| 516 | node.completeOne(); | |
| 517 | } |
src/all_types.hpp+2| ... | ... | @@ -2010,6 +2010,8 @@ struct CodeGen { |
| 2010 | 2010 | |
| 2011 | 2011 | ZigFn *largest_frame_fn; |
| 2012 | 2012 | |
| 2013 | Stage2ProgressNode *progress_node; | |
| 2014 | ||
| 2013 | 2015 | WantPIC want_pic; |
| 2014 | 2016 | WantStackCheck want_stack_check; |
| 2015 | 2017 | CacheHash cache_hash; |
src/codegen.cpp+45-6| ... | ... | @@ -7610,7 +7610,7 @@ static void zig_llvm_emit_output(CodeGen *g) { |
| 7610 | 7610 | if (g->bundle_compiler_rt && (g->out_type == OutTypeObj || |
| 7611 | 7611 | (g->out_type == OutTypeLib && !g->is_dynamic))) |
| 7612 | 7612 | { |
| 7613 | zig_link_add_compiler_rt(g); | |
| 7613 | zig_link_add_compiler_rt(g, g->progress_node); | |
| 7614 | 7614 | } |
| 7615 | 7615 | break; |
| 7616 | 7616 | |
| ... | ... | @@ -9453,7 +9453,7 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose |
| 9453 | 9453 | } |
| 9454 | 9454 | |
| 9455 | 9455 | // returns true if it was a cache miss |
| 9456 | static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) { | |
| 9456 | static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file, Stage2ProgressNode *parent_prog_node) { | |
| 9457 | 9457 | Error err; |
| 9458 | 9458 | |
| 9459 | 9459 | Buf *artifact_dir; |
| ... | ... | @@ -9464,6 +9464,10 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) { |
| 9464 | 9464 | Buf *c_source_file = buf_create_from_str(c_file->source_path); |
| 9465 | 9465 | Buf *c_source_basename = buf_alloc(); |
| 9466 | 9466 | os_path_split(c_source_file, nullptr, c_source_basename); |
| 9467 | ||
| 9468 | Stage2ProgressNode *child_prog_node = stage2_progress_start(parent_prog_node, buf_ptr(c_source_basename), | |
| 9469 | buf_len(c_source_basename), 0); | |
| 9470 | ||
| 9467 | 9471 | Buf *final_o_basename = buf_alloc(); |
| 9468 | 9472 | os_path_extname(c_source_basename, final_o_basename, nullptr); |
| 9469 | 9473 | buf_append_str(final_o_basename, target_o_file_ext(g->zig_target)); |
| ... | ... | @@ -9580,6 +9584,8 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) { |
| 9580 | 9584 | |
| 9581 | 9585 | g->link_objects.append(o_final_path); |
| 9582 | 9586 | g->caches_to_release.append(cache_hash); |
| 9587 | ||
| 9588 | stage2_progress_end(child_prog_node); | |
| 9583 | 9589 | } |
| 9584 | 9590 | |
| 9585 | 9591 | // returns true if we had any cache misses |
| ... | ... | @@ -9596,11 +9602,16 @@ static void gen_c_objects(CodeGen *g) { |
| 9596 | 9602 | } |
| 9597 | 9603 | |
| 9598 | 9604 | codegen_add_time_event(g, "Compile C Code"); |
| 9605 | const char *c_prog_name = "compiling C objects"; | |
| 9606 | Stage2ProgressNode *c_prog_node = stage2_progress_start(g->progress_node, c_prog_name, strlen(c_prog_name), | |
| 9607 | g->c_source_files.length); | |
| 9599 | 9608 | |
| 9600 | 9609 | for (size_t c_file_i = 0; c_file_i < g->c_source_files.length; c_file_i += 1) { |
| 9601 | 9610 | CFile *c_file = g->c_source_files.at(c_file_i); |
| 9602 | gen_c_object(g, self_exe_path, c_file); | |
| 9611 | gen_c_object(g, self_exe_path, c_file, c_prog_node); | |
| 9603 | 9612 | } |
| 9613 | ||
| 9614 | stage2_progress_end(c_prog_node); | |
| 9604 | 9615 | } |
| 9605 | 9616 | |
| 9606 | 9617 | void codegen_add_object(CodeGen *g, Buf *object_path) { |
| ... | ... | @@ -10320,6 +10331,10 @@ void codegen_build_and_link(CodeGen *g) { |
| 10320 | 10331 | init(g); |
| 10321 | 10332 | |
| 10322 | 10333 | codegen_add_time_event(g, "Semantic Analysis"); |
| 10334 | const char *progress_name = "Semantic Analysis"; | |
| 10335 | Stage2ProgressNode *child_progress_node = stage2_progress_start(g->progress_node, | |
| 10336 | progress_name, strlen(progress_name), 0); | |
| 10337 | (void)child_progress_node; | |
| 10323 | 10338 | |
| 10324 | 10339 | gen_root_source(g); |
| 10325 | 10340 | |
| ... | ... | @@ -10343,13 +10358,31 @@ void codegen_build_and_link(CodeGen *g) { |
| 10343 | 10358 | |
| 10344 | 10359 | if (need_llvm_module(g)) { |
| 10345 | 10360 | codegen_add_time_event(g, "Code Generation"); |
| 10361 | { | |
| 10362 | const char *progress_name = "Code Generation"; | |
| 10363 | Stage2ProgressNode *child_progress_node = stage2_progress_start(g->progress_node, | |
| 10364 | progress_name, strlen(progress_name), 0); | |
| 10365 | (void)child_progress_node; | |
| 10366 | } | |
| 10346 | 10367 | |
| 10347 | 10368 | do_code_gen(g); |
| 10348 | 10369 | codegen_add_time_event(g, "LLVM Emit Output"); |
| 10370 | { | |
| 10371 | const char *progress_name = "LLVM Emit Output"; | |
| 10372 | Stage2ProgressNode *child_progress_node = stage2_progress_start(g->progress_node, | |
| 10373 | progress_name, strlen(progress_name), 0); | |
| 10374 | (void)child_progress_node; | |
| 10375 | } | |
| 10349 | 10376 | zig_llvm_emit_output(g); |
| 10350 | 10377 | |
| 10351 | 10378 | if (!g->disable_gen_h && (g->out_type == OutTypeObj || g->out_type == OutTypeLib)) { |
| 10352 | 10379 | codegen_add_time_event(g, "Generate .h"); |
| 10380 | { | |
| 10381 | const char *progress_name = "Generate .h"; | |
| 10382 | Stage2ProgressNode *child_progress_node = stage2_progress_start(g->progress_node, | |
| 10383 | progress_name, strlen(progress_name), 0); | |
| 10384 | (void)child_progress_node; | |
| 10385 | } | |
| 10353 | 10386 | gen_h_file(g); |
| 10354 | 10387 | } |
| 10355 | 10388 | } |
| ... | ... | @@ -10446,10 +10479,15 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c |
| 10446 | 10479 | } |
| 10447 | 10480 | |
| 10448 | 10481 | CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType out_type, |
| 10449 | ZigLibCInstallation *libc) | |
| 10482 | ZigLibCInstallation *libc, const char *name, Stage2ProgressNode *parent_progress_node) | |
| 10450 | 10483 | { |
| 10484 | Stage2ProgressNode *child_progress_node = stage2_progress_start( | |
| 10485 | parent_progress_node ? parent_progress_node : parent_gen->progress_node, | |
| 10486 | name, strlen(name), 0); | |
| 10487 | ||
| 10451 | 10488 | CodeGen *child_gen = codegen_create(nullptr, root_src_path, parent_gen->zig_target, out_type, |
| 10452 | parent_gen->build_mode, parent_gen->zig_lib_dir, libc, get_stage1_cache_path(), false); | |
| 10489 | parent_gen->build_mode, parent_gen->zig_lib_dir, libc, get_stage1_cache_path(), false, child_progress_node); | |
| 10490 | child_gen->root_out_name = buf_create_from_str(name); | |
| 10453 | 10491 | child_gen->disable_gen_h = true; |
| 10454 | 10492 | child_gen->want_stack_check = WantStackCheckDisabled; |
| 10455 | 10493 | child_gen->verbose_tokenize = parent_gen->verbose_tokenize; |
| ... | ... | @@ -10478,9 +10516,10 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o |
| 10478 | 10516 | |
| 10479 | 10517 | CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target, |
| 10480 | 10518 | OutType out_type, BuildMode build_mode, Buf *override_lib_dir, |
| 10481 | ZigLibCInstallation *libc, Buf *cache_dir, bool is_test_build) | |
| 10519 | ZigLibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node) | |
| 10482 | 10520 | { |
| 10483 | 10521 | CodeGen *g = allocate<CodeGen>(1); |
| 10522 | g->progress_node = progress_node; | |
| 10484 | 10523 | |
| 10485 | 10524 | codegen_add_time_event(g, "Initialize"); |
| 10486 | 10525 |
src/codegen.hpp+3-3| ... | ... | @@ -18,10 +18,10 @@ |
| 18 | 18 | |
| 19 | 19 | CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target, |
| 20 | 20 | OutType out_type, BuildMode build_mode, Buf *zig_lib_dir, |
| 21 | ZigLibCInstallation *libc, Buf *cache_dir, bool is_test_build); | |
| 21 | ZigLibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node); | |
| 22 | 22 | |
| 23 | 23 | CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType out_type, |
| 24 | ZigLibCInstallation *libc); | |
| 24 | ZigLibCInstallation *libc, const char *name, Stage2ProgressNode *progress_node); | |
| 25 | 25 | |
| 26 | 26 | void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len); |
| 27 | 27 | void codegen_set_llvm_argv(CodeGen *codegen, const char **args, size_t len); |
| ... | ... | @@ -46,7 +46,7 @@ void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patc |
| 46 | 46 | void codegen_add_time_event(CodeGen *g, const char *name); |
| 47 | 47 | void codegen_print_timing_report(CodeGen *g, FILE *f); |
| 48 | 48 | void codegen_link(CodeGen *g); |
| 49 | void zig_link_add_compiler_rt(CodeGen *g); | |
| 49 | void zig_link_add_compiler_rt(CodeGen *g, Stage2ProgressNode *progress_node); | |
| 50 | 50 | void codegen_build_and_link(CodeGen *g); |
| 51 | 51 | |
| 52 | 52 | ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const char *root_src_path, |
src/glibc.cpp+2-3| ... | ... | @@ -169,7 +169,7 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo |
| 169 | 169 | } |
| 170 | 170 | |
| 171 | 171 | Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, const ZigTarget *target, |
| 172 | Buf **out_dir, bool verbose) | |
| 172 | Buf **out_dir, bool verbose, Stage2ProgressNode *progress_node) | |
| 173 | 173 | { |
| 174 | 174 | Error err; |
| 175 | 175 | |
| ... | ... | @@ -332,8 +332,7 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con |
| 332 | 332 | return err; |
| 333 | 333 | } |
| 334 | 334 | |
| 335 | CodeGen *child_gen = create_child_codegen(g, zig_file_path, OutTypeLib, nullptr); | |
| 336 | codegen_set_out_name(child_gen, buf_create_from_str(lib->name)); | |
| 335 | CodeGen *child_gen = create_child_codegen(g, zig_file_path, OutTypeLib, nullptr, lib->name, progress_node); | |
| 337 | 336 | codegen_set_lib_version(child_gen, lib->sover, 0, 0); |
| 338 | 337 | child_gen->is_dynamic = true; |
| 339 | 338 | child_gen->is_dummy_so = true; |
src/glibc.hpp+1-1| ... | ... | @@ -41,7 +41,7 @@ struct ZigGLibCAbi { |
| 41 | 41 | |
| 42 | 42 | Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbose); |
| 43 | 43 | Error glibc_build_dummies_and_maps(CodeGen *codegen, const ZigGLibCAbi *glibc_abi, const ZigTarget *target, |
| 44 | Buf **out_dir, bool verbose); | |
| 44 | Buf **out_dir, bool verbose, Stage2ProgressNode *progress_node); | |
| 45 | 45 | |
| 46 | 46 | // returns ErrorUnknownABI when glibc is not the native libc |
| 47 | 47 | Error glibc_detect_native_version(ZigGLibCVersion *glibc_ver); |
src/link.cpp+76-66| ... | ... | @@ -594,11 +594,13 @@ struct LinkJob { |
| 594 | 594 | ZigList<const char *> args; |
| 595 | 595 | bool link_in_crt; |
| 596 | 596 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> rpath_table; |
| 597 | Stage2ProgressNode *build_dep_prog_node; | |
| 597 | 598 | }; |
| 598 | 599 | |
| 599 | static const char *build_libc_object(CodeGen *parent_gen, const char *name, CFile *c_file) { | |
| 600 | CodeGen *child_gen = create_child_codegen(parent_gen, nullptr, OutTypeObj, nullptr); | |
| 601 | codegen_set_out_name(child_gen, buf_create_from_str(name)); | |
| 600 | static const char *build_libc_object(CodeGen *parent_gen, const char *name, CFile *c_file, | |
| 601 | Stage2ProgressNode *progress_node) | |
| 602 | { | |
| 603 | CodeGen *child_gen = create_child_codegen(parent_gen, nullptr, OutTypeObj, nullptr, name, progress_node); | |
| 602 | 604 | ZigList<CFile *> c_source_files = {0}; |
| 603 | 605 | c_source_files.append(c_file); |
| 604 | 606 | child_gen->c_source_files = c_source_files; |
| ... | ... | @@ -622,9 +624,8 @@ static const char *path_from_libunwind(CodeGen *g, const char *subpath) { |
| 622 | 624 | return path_from_zig_lib(g, "libunwind", subpath); |
| 623 | 625 | } |
| 624 | 626 | |
| 625 | static const char *build_libunwind(CodeGen *parent) { | |
| 626 | CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr); | |
| 627 | codegen_set_out_name(child_gen, buf_create_from_str("unwind")); | |
| 627 | static const char *build_libunwind(CodeGen *parent, Stage2ProgressNode *progress_node) { | |
| 628 | CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "unwind", progress_node); | |
| 628 | 629 | LinkLib *new_link_lib = codegen_add_link_lib(child_gen, buf_create_from_str("c")); |
| 629 | 630 | new_link_lib->provided_explicitly = false; |
| 630 | 631 | enum SrcKind { |
| ... | ... | @@ -1017,9 +1018,8 @@ static bool is_musl_arch_name(const char *name) { |
| 1017 | 1018 | return false; |
| 1018 | 1019 | } |
| 1019 | 1020 | |
| 1020 | static const char *build_musl(CodeGen *parent) { | |
| 1021 | CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr); | |
| 1022 | codegen_set_out_name(child_gen, buf_create_from_str("c")); | |
| 1021 | static const char *build_musl(CodeGen *parent, Stage2ProgressNode *progress_node) { | |
| 1022 | CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "c", progress_node); | |
| 1023 | 1023 | |
| 1024 | 1024 | // When there is a src/<arch>/foo.* then it should substitute for src/foo.* |
| 1025 | 1025 | // Even a .s file can substitute for a .c file. |
| ... | ... | @@ -1175,7 +1175,7 @@ static void add_mingwex_os_dep(CodeGen *parent, CodeGen *child_gen, const char * |
| 1175 | 1175 | child_gen->c_source_files.append(c_file); |
| 1176 | 1176 | } |
| 1177 | 1177 | |
| 1178 | static const char *get_libc_crt_file(CodeGen *parent, const char *file) { | |
| 1178 | static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2ProgressNode *progress_node) { | |
| 1179 | 1179 | if (parent->libc == nullptr && parent->zig_target->os == OsWindows) { |
| 1180 | 1180 | if (strcmp(file, "crt2.o") == 0) { |
| 1181 | 1181 | CFile *c_file = allocate<CFile>(1); |
| ... | ... | @@ -1188,7 +1188,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) { |
| 1188 | 1188 | //c_file->args.append("-DUNICODE"); |
| 1189 | 1189 | //c_file->args.append("-D_UNICODE"); |
| 1190 | 1190 | //c_file->args.append("-DWPRFLAG=1"); |
| 1191 | return build_libc_object(parent, "crt2", c_file); | |
| 1191 | return build_libc_object(parent, "crt2", c_file, progress_node); | |
| 1192 | 1192 | } else if (strcmp(file, "dllcrt2.o") == 0) { |
| 1193 | 1193 | CFile *c_file = allocate<CFile>(1); |
| 1194 | 1194 | c_file->source_path = buf_ptr(buf_sprintf( |
| ... | ... | @@ -1196,10 +1196,9 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) { |
| 1196 | 1196 | mingw_add_cc_args(parent, c_file); |
| 1197 | 1197 | c_file->args.append("-U__CRTDLL__"); |
| 1198 | 1198 | c_file->args.append("-D__MSVCRT__"); |
| 1199 | return build_libc_object(parent, "dllcrt2", c_file); | |
| 1199 | return build_libc_object(parent, "dllcrt2", c_file, progress_node); | |
| 1200 | 1200 | } else if (strcmp(file, "mingw32.lib") == 0) { |
| 1201 | CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr); | |
| 1202 | codegen_set_out_name(child_gen, buf_create_from_str("mingw32")); | |
| 1201 | CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "mingw32", progress_node); | |
| 1203 | 1202 | |
| 1204 | 1203 | static const char *deps[] = { |
| 1205 | 1204 | "mingw" OS_SEP "crt" OS_SEP "crt0_c.c", |
| ... | ... | @@ -1256,8 +1255,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) { |
| 1256 | 1255 | codegen_build_and_link(child_gen); |
| 1257 | 1256 | return buf_ptr(&child_gen->output_file_path); |
| 1258 | 1257 | } else if (strcmp(file, "msvcrt-os.lib") == 0) { |
| 1259 | CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr); | |
| 1260 | codegen_set_out_name(child_gen, buf_create_from_str("msvcrt-os")); | |
| 1258 | CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "msvcrt-os", progress_node); | |
| 1261 | 1259 | |
| 1262 | 1260 | for (size_t i = 0; i < array_length(msvcrt_common_src); i += 1) { |
| 1263 | 1261 | add_msvcrt_os_dep(parent, child_gen, msvcrt_common_src[i]); |
| ... | ... | @@ -1274,8 +1272,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) { |
| 1274 | 1272 | codegen_build_and_link(child_gen); |
| 1275 | 1273 | return buf_ptr(&child_gen->output_file_path); |
| 1276 | 1274 | } else if (strcmp(file, "mingwex.lib") == 0) { |
| 1277 | CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr); | |
| 1278 | codegen_set_out_name(child_gen, buf_create_from_str("mingwex")); | |
| 1275 | CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "mingwex", progress_node); | |
| 1279 | 1276 | |
| 1280 | 1277 | for (size_t i = 0; i < array_length(mingwex_generic_src); i += 1) { |
| 1281 | 1278 | add_mingwex_os_dep(parent, child_gen, mingwex_generic_src[i]); |
| ... | ... | @@ -1318,7 +1315,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) { |
| 1318 | 1315 | c_file->args.append("-DASSEMBLER"); |
| 1319 | 1316 | c_file->args.append("-g"); |
| 1320 | 1317 | c_file->args.append("-Wa,--noexecstack"); |
| 1321 | return build_libc_object(parent, "crti", c_file); | |
| 1318 | return build_libc_object(parent, "crti", c_file, progress_node); | |
| 1322 | 1319 | } else if (strcmp(file, "crtn.o") == 0) { |
| 1323 | 1320 | CFile *c_file = allocate<CFile>(1); |
| 1324 | 1321 | c_file->source_path = glibc_start_asm_path(parent, "crtn.S"); |
| ... | ... | @@ -1329,7 +1326,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) { |
| 1329 | 1326 | c_file->args.append("-DASSEMBLER"); |
| 1330 | 1327 | c_file->args.append("-g"); |
| 1331 | 1328 | c_file->args.append("-Wa,--noexecstack"); |
| 1332 | return build_libc_object(parent, "crtn", c_file); | |
| 1329 | return build_libc_object(parent, "crtn", c_file, progress_node); | |
| 1333 | 1330 | } else if (strcmp(file, "start.os") == 0) { |
| 1334 | 1331 | CFile *c_file = allocate<CFile>(1); |
| 1335 | 1332 | c_file->source_path = glibc_start_asm_path(parent, "start.S"); |
| ... | ... | @@ -1347,7 +1344,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) { |
| 1347 | 1344 | c_file->args.append("-DASSEMBLER"); |
| 1348 | 1345 | c_file->args.append("-g"); |
| 1349 | 1346 | c_file->args.append("-Wa,--noexecstack"); |
| 1350 | return build_libc_object(parent, "start", c_file); | |
| 1347 | return build_libc_object(parent, "start", c_file, progress_node); | |
| 1351 | 1348 | } else if (strcmp(file, "abi-note.o") == 0) { |
| 1352 | 1349 | CFile *c_file = allocate<CFile>(1); |
| 1353 | 1350 | c_file->source_path = path_from_libc(parent, "glibc" OS_SEP "csu" OS_SEP "abi-note.S"); |
| ... | ... | @@ -1360,19 +1357,17 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) { |
| 1360 | 1357 | c_file->args.append("-DASSEMBLER"); |
| 1361 | 1358 | c_file->args.append("-g"); |
| 1362 | 1359 | c_file->args.append("-Wa,--noexecstack"); |
| 1363 | return build_libc_object(parent, "abi-note", c_file); | |
| 1360 | return build_libc_object(parent, "abi-note", c_file, progress_node); | |
| 1364 | 1361 | } else if (strcmp(file, "Scrt1.o") == 0) { |
| 1365 | const char *start_os = get_libc_crt_file(parent, "start.os"); | |
| 1366 | const char *abi_note_o = get_libc_crt_file(parent, "abi-note.o"); | |
| 1367 | CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeObj, nullptr); | |
| 1368 | codegen_set_out_name(child_gen, buf_create_from_str("Scrt1")); | |
| 1362 | const char *start_os = get_libc_crt_file(parent, "start.os", progress_node); | |
| 1363 | const char *abi_note_o = get_libc_crt_file(parent, "abi-note.o", progress_node); | |
| 1364 | CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeObj, nullptr, "Scrt1", progress_node); | |
| 1369 | 1365 | codegen_add_object(child_gen, buf_create_from_str(start_os)); |
| 1370 | 1366 | codegen_add_object(child_gen, buf_create_from_str(abi_note_o)); |
| 1371 | 1367 | codegen_build_and_link(child_gen); |
| 1372 | 1368 | return buf_ptr(&child_gen->output_file_path); |
| 1373 | 1369 | } else if (strcmp(file, "libc_nonshared.a") == 0) { |
| 1374 | CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr); | |
| 1375 | codegen_set_out_name(child_gen, buf_create_from_str("c_nonshared")); | |
| 1370 | CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "c_nonshared", progress_node); | |
| 1376 | 1371 | { |
| 1377 | 1372 | CFile *c_file = allocate<CFile>(1); |
| 1378 | 1373 | c_file->source_path = path_from_libc(parent, "glibc" OS_SEP "csu" OS_SEP "elf-init.c"); |
| ... | ... | @@ -1401,7 +1396,8 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) { |
| 1401 | 1396 | c_file->args.append("-DPIC"); |
| 1402 | 1397 | c_file->args.append("-DLIBC_NONSHARED=1"); |
| 1403 | 1398 | c_file->args.append("-DTOP_NAMESPACE=glibc"); |
| 1404 | codegen_add_object(child_gen, buf_create_from_str(build_libc_object(parent, "elf-init", c_file))); | |
| 1399 | codegen_add_object(child_gen, buf_create_from_str( | |
| 1400 | build_libc_object(parent, "elf-init", c_file, progress_node))); | |
| 1405 | 1401 | } |
| 1406 | 1402 | static const struct { |
| 1407 | 1403 | const char *name; |
| ... | ... | @@ -1445,7 +1441,8 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) { |
| 1445 | 1441 | c_file->args.append("-DPIC"); |
| 1446 | 1442 | c_file->args.append("-DLIBC_NONSHARED=1"); |
| 1447 | 1443 | c_file->args.append("-DTOP_NAMESPACE=glibc"); |
| 1448 | codegen_add_object(child_gen, buf_create_from_str(build_libc_object(parent, deps[i].name, c_file))); | |
| 1444 | codegen_add_object(child_gen, buf_create_from_str( | |
| 1445 | build_libc_object(parent, deps[i].name, c_file, progress_node))); | |
| 1449 | 1446 | } |
| 1450 | 1447 | codegen_build_and_link(child_gen); |
| 1451 | 1448 | return buf_ptr(&child_gen->output_file_path); |
| ... | ... | @@ -1458,20 +1455,20 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) { |
| 1458 | 1455 | c_file->source_path = musl_start_asm_path(parent, "crti.s"); |
| 1459 | 1456 | musl_add_cc_args(parent, c_file, false); |
| 1460 | 1457 | c_file->args.append("-Qunused-arguments"); |
| 1461 | return build_libc_object(parent, "crti", c_file); | |
| 1458 | return build_libc_object(parent, "crti", c_file, progress_node); | |
| 1462 | 1459 | } else if (strcmp(file, "crtn.o") == 0) { |
| 1463 | 1460 | CFile *c_file = allocate<CFile>(1); |
| 1464 | 1461 | c_file->source_path = musl_start_asm_path(parent, "crtn.s"); |
| 1465 | 1462 | c_file->args.append("-Qunused-arguments"); |
| 1466 | 1463 | musl_add_cc_args(parent, c_file, false); |
| 1467 | return build_libc_object(parent, "crtn", c_file); | |
| 1464 | return build_libc_object(parent, "crtn", c_file, progress_node); | |
| 1468 | 1465 | } else if (strcmp(file, "crt1.o") == 0) { |
| 1469 | 1466 | CFile *c_file = allocate<CFile>(1); |
| 1470 | 1467 | c_file->source_path = path_from_libc(parent, "musl" OS_SEP "crt" OS_SEP "crt1.c"); |
| 1471 | 1468 | musl_add_cc_args(parent, c_file, false); |
| 1472 | 1469 | c_file->args.append("-fno-stack-protector"); |
| 1473 | 1470 | c_file->args.append("-DCRT"); |
| 1474 | return build_libc_object(parent, "crt1", c_file); | |
| 1471 | return build_libc_object(parent, "crt1", c_file, progress_node); | |
| 1475 | 1472 | } else if (strcmp(file, "Scrt1.o") == 0) { |
| 1476 | 1473 | CFile *c_file = allocate<CFile>(1); |
| 1477 | 1474 | c_file->source_path = path_from_libc(parent, "musl" OS_SEP "crt" OS_SEP "Scrt1.c"); |
| ... | ... | @@ -1479,7 +1476,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) { |
| 1479 | 1476 | c_file->args.append("-fPIC"); |
| 1480 | 1477 | c_file->args.append("-fno-stack-protector"); |
| 1481 | 1478 | c_file->args.append("-DCRT"); |
| 1482 | return build_libc_object(parent, "Scrt1", c_file); | |
| 1479 | return build_libc_object(parent, "Scrt1", c_file, progress_node); | |
| 1483 | 1480 | } else { |
| 1484 | 1481 | zig_unreachable(); |
| 1485 | 1482 | } |
| ... | ... | @@ -1491,10 +1488,11 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) { |
| 1491 | 1488 | } |
| 1492 | 1489 | } |
| 1493 | 1490 | |
| 1494 | static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path, OutType child_out_type) { | |
| 1495 | CodeGen *child_gen = create_child_codegen(parent_gen, full_path, child_out_type, | |
| 1496 | parent_gen->libc); | |
| 1497 | codegen_set_out_name(child_gen, buf_create_from_str(aname)); | |
| 1491 | static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path, OutType child_out_type, | |
| 1492 | Stage2ProgressNode *progress_node) | |
| 1493 | { | |
| 1494 | CodeGen *child_gen = create_child_codegen(parent_gen, full_path, child_out_type, parent_gen->libc, aname, | |
| 1495 | progress_node); | |
| 1498 | 1496 | |
| 1499 | 1497 | // This is so that compiler_rt and libc.zig libraries know whether they |
| 1500 | 1498 | // will eventually be linked with libc. They make different decisions |
| ... | ... | @@ -1511,18 +1509,18 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path, |
| 1511 | 1509 | return &child_gen->output_file_path; |
| 1512 | 1510 | } |
| 1513 | 1511 | |
| 1514 | static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type) { | |
| 1512 | static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type, Stage2ProgressNode *progress_node) { | |
| 1515 | 1513 | Buf *full_path = buf_alloc(); |
| 1516 | 1514 | os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("compiler_rt.zig"), full_path); |
| 1517 | 1515 | |
| 1518 | return build_a_raw(parent_gen, "compiler_rt", full_path, child_out_type); | |
| 1516 | return build_a_raw(parent_gen, "compiler_rt", full_path, child_out_type, progress_node); | |
| 1519 | 1517 | } |
| 1520 | 1518 | |
| 1521 | static Buf *build_c(CodeGen *parent_gen, OutType child_out_type) { | |
| 1519 | static Buf *build_c(CodeGen *parent_gen, OutType child_out_type, Stage2ProgressNode *progress_node) { | |
| 1522 | 1520 | Buf *full_path = buf_alloc(); |
| 1523 | 1521 | os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("c.zig"), full_path); |
| 1524 | 1522 | |
| 1525 | return build_a_raw(parent_gen, "c", full_path, child_out_type); | |
| 1523 | return build_a_raw(parent_gen, "c", full_path, child_out_type, progress_node); | |
| 1526 | 1524 | } |
| 1527 | 1525 | |
| 1528 | 1526 | static const char *get_darwin_arch_string(const ZigTarget *t) { |
| ... | ... | @@ -1616,7 +1614,7 @@ static void add_glibc_libs(LinkJob *lj) { |
| 1616 | 1614 | |
| 1617 | 1615 | Buf *artifact_dir; |
| 1618 | 1616 | if ((err = glibc_build_dummies_and_maps(lj->codegen, glibc_abi, lj->codegen->zig_target, |
| 1619 | &artifact_dir, true))) | |
| 1617 | &artifact_dir, true, lj->build_dep_prog_node))) | |
| 1620 | 1618 | { |
| 1621 | 1619 | fprintf(stderr, "%s\n", err_str(err)); |
| 1622 | 1620 | exit(1); |
| ... | ... | @@ -1692,9 +1690,9 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 1692 | 1690 | } else { |
| 1693 | 1691 | crt1o = "Scrt1.o"; |
| 1694 | 1692 | } |
| 1695 | lj->args.append(get_libc_crt_file(g, crt1o)); | |
| 1693 | lj->args.append(get_libc_crt_file(g, crt1o, lj->build_dep_prog_node)); | |
| 1696 | 1694 | if (target_libc_needs_crti_crtn(g->zig_target)) { |
| 1697 | lj->args.append(get_libc_crt_file(g, "crti.o")); | |
| 1695 | lj->args.append(get_libc_crt_file(g, "crti.o", lj->build_dep_prog_node)); | |
| 1698 | 1696 | } |
| 1699 | 1697 | } |
| 1700 | 1698 | |
| ... | ... | @@ -1759,11 +1757,11 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 1759 | 1757 | |
| 1760 | 1758 | if (!g->is_dummy_so && (g->out_type == OutTypeExe || is_dyn_lib)) { |
| 1761 | 1759 | if (g->libc_link_lib == nullptr) { |
| 1762 | Buf *libc_a_path = build_c(g, OutTypeLib); | |
| 1760 | Buf *libc_a_path = build_c(g, OutTypeLib, lj->build_dep_prog_node); | |
| 1763 | 1761 | lj->args.append(buf_ptr(libc_a_path)); |
| 1764 | 1762 | } |
| 1765 | 1763 | |
| 1766 | Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib); | |
| 1764 | Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib, lj->build_dep_prog_node); | |
| 1767 | 1765 | lj->args.append(buf_ptr(compiler_rt_o_path)); |
| 1768 | 1766 | } |
| 1769 | 1767 | |
| ... | ... | @@ -1823,15 +1821,15 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 1823 | 1821 | } |
| 1824 | 1822 | } else if (target_is_glibc(g->zig_target)) { |
| 1825 | 1823 | if (target_supports_libunwind(g->zig_target)) { |
| 1826 | lj->args.append(build_libunwind(g)); | |
| 1824 | lj->args.append(build_libunwind(g, lj->build_dep_prog_node)); | |
| 1827 | 1825 | } |
| 1828 | 1826 | add_glibc_libs(lj); |
| 1829 | lj->args.append(get_libc_crt_file(g, "libc_nonshared.a")); | |
| 1827 | lj->args.append(get_libc_crt_file(g, "libc_nonshared.a", lj->build_dep_prog_node)); | |
| 1830 | 1828 | } else if (target_is_musl(g->zig_target)) { |
| 1831 | 1829 | if (target_supports_libunwind(g->zig_target)) { |
| 1832 | lj->args.append(build_libunwind(g)); | |
| 1830 | lj->args.append(build_libunwind(g, lj->build_dep_prog_node)); | |
| 1833 | 1831 | } |
| 1834 | lj->args.append(build_musl(g)); | |
| 1832 | lj->args.append(build_musl(g, lj->build_dep_prog_node)); | |
| 1835 | 1833 | } else { |
| 1836 | 1834 | zig_unreachable(); |
| 1837 | 1835 | } |
| ... | ... | @@ -1840,9 +1838,9 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 1840 | 1838 | // crt end |
| 1841 | 1839 | if (lj->link_in_crt) { |
| 1842 | 1840 | if (target_is_android(g->zig_target)) { |
| 1843 | lj->args.append(get_libc_crt_file(g, "crtend_android.o")); | |
| 1841 | lj->args.append(get_libc_crt_file(g, "crtend_android.o", lj->build_dep_prog_node)); | |
| 1844 | 1842 | } else if (target_libc_needs_crti_crtn(g->zig_target)) { |
| 1845 | lj->args.append(get_libc_crt_file(g, "crtn.o")); | |
| 1843 | lj->args.append(get_libc_crt_file(g, "crtn.o", lj->build_dep_prog_node)); | |
| 1846 | 1844 | } |
| 1847 | 1845 | } |
| 1848 | 1846 | |
| ... | ... | @@ -1887,10 +1885,10 @@ static void construct_linker_job_wasm(LinkJob *lj) { |
| 1887 | 1885 | } |
| 1888 | 1886 | |
| 1889 | 1887 | if (g->out_type != OutTypeObj) { |
| 1890 | Buf *libc_o_path = build_c(g, OutTypeObj); | |
| 1888 | Buf *libc_o_path = build_c(g, OutTypeObj, lj->build_dep_prog_node); | |
| 1891 | 1889 | lj->args.append(buf_ptr(libc_o_path)); |
| 1892 | 1890 | |
| 1893 | Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj); | |
| 1891 | Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj, lj->build_dep_prog_node); | |
| 1894 | 1892 | lj->args.append(buf_ptr(compiler_rt_o_path)); |
| 1895 | 1893 | } |
| 1896 | 1894 | } |
| ... | ... | @@ -2170,14 +2168,14 @@ static void add_mingw_link_args(LinkJob *lj, bool is_library) { |
| 2170 | 2168 | } |
| 2171 | 2169 | |
| 2172 | 2170 | if (is_dll) { |
| 2173 | lj->args.append(get_libc_crt_file(g, "dllcrt2.o")); | |
| 2171 | lj->args.append(get_libc_crt_file(g, "dllcrt2.o", lj->build_dep_prog_node)); | |
| 2174 | 2172 | } else { |
| 2175 | lj->args.append(get_libc_crt_file(g, "crt2.o")); | |
| 2173 | lj->args.append(get_libc_crt_file(g, "crt2.o", lj->build_dep_prog_node)); | |
| 2176 | 2174 | } |
| 2177 | 2175 | |
| 2178 | lj->args.append(get_libc_crt_file(g, "mingw32.lib")); | |
| 2179 | lj->args.append(get_libc_crt_file(g, "mingwex.lib")); | |
| 2180 | lj->args.append(get_libc_crt_file(g, "msvcrt-os.lib")); | |
| 2176 | lj->args.append(get_libc_crt_file(g, "mingw32.lib", lj->build_dep_prog_node)); | |
| 2177 | lj->args.append(get_libc_crt_file(g, "mingwex.lib", lj->build_dep_prog_node)); | |
| 2178 | lj->args.append(get_libc_crt_file(g, "msvcrt-os.lib", lj->build_dep_prog_node)); | |
| 2181 | 2179 | |
| 2182 | 2180 | for (size_t def_i = 0; def_i < array_length(mingw_def_list); def_i += 1) { |
| 2183 | 2181 | const char *name = mingw_def_list[def_i].name; |
| ... | ... | @@ -2319,12 +2317,12 @@ static void construct_linker_job_coff(LinkJob *lj) { |
| 2319 | 2317 | |
| 2320 | 2318 | if (g->out_type == OutTypeExe || (g->out_type == OutTypeLib && g->is_dynamic)) { |
| 2321 | 2319 | if (g->libc_link_lib == nullptr && !g->is_dummy_so) { |
| 2322 | Buf *libc_a_path = build_c(g, OutTypeLib); | |
| 2320 | Buf *libc_a_path = build_c(g, OutTypeLib, lj->build_dep_prog_node); | |
| 2323 | 2321 | lj->args.append(buf_ptr(libc_a_path)); |
| 2324 | 2322 | } |
| 2325 | 2323 | |
| 2326 | 2324 | // msvc compiler_rt is missing some stuff, so we still build it and rely on weak linkage |
| 2327 | Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib); | |
| 2325 | Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib, lj->build_dep_prog_node); | |
| 2328 | 2326 | lj->args.append(buf_ptr(compiler_rt_o_path)); |
| 2329 | 2327 | } |
| 2330 | 2328 | |
| ... | ... | @@ -2563,7 +2561,7 @@ static void construct_linker_job_macho(LinkJob *lj) { |
| 2563 | 2561 | |
| 2564 | 2562 | // compiler_rt on darwin is missing some stuff, so we still build it and rely on LinkOnce |
| 2565 | 2563 | if (g->out_type == OutTypeExe || is_dyn_lib) { |
| 2566 | Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib); | |
| 2564 | Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib, lj->build_dep_prog_node); | |
| 2567 | 2565 | lj->args.append(buf_ptr(compiler_rt_o_path)); |
| 2568 | 2566 | } |
| 2569 | 2567 | |
| ... | ... | @@ -2621,16 +2619,22 @@ static void construct_linker_job(LinkJob *lj) { |
| 2621 | 2619 | } |
| 2622 | 2620 | } |
| 2623 | 2621 | |
| 2624 | void zig_link_add_compiler_rt(CodeGen *g) { | |
| 2625 | Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj); | |
| 2622 | void zig_link_add_compiler_rt(CodeGen *g, Stage2ProgressNode *progress_node) { | |
| 2623 | Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj, progress_node); | |
| 2626 | 2624 | g->link_objects.append(compiler_rt_o_path); |
| 2627 | 2625 | } |
| 2628 | 2626 | |
| 2629 | 2627 | void codegen_link(CodeGen *g) { |
| 2630 | 2628 | codegen_add_time_event(g, "Build Dependencies"); |
| 2631 | ||
| 2632 | 2629 | LinkJob lj = {0}; |
| 2633 | 2630 | |
| 2631 | { | |
| 2632 | const char *progress_name = "Build Dependencies"; | |
| 2633 | lj.build_dep_prog_node = stage2_progress_start(g->progress_node, | |
| 2634 | progress_name, strlen(progress_name), 0); | |
| 2635 | } | |
| 2636 | ||
| 2637 | ||
| 2634 | 2638 | // even though we're calling LLD as a library it thinks the first |
| 2635 | 2639 | // argument is its own exe name |
| 2636 | 2640 | lj.args.append("lld"); |
| ... | ... | @@ -2656,6 +2660,12 @@ void codegen_link(CodeGen *g) { |
| 2656 | 2660 | } |
| 2657 | 2661 | ZigLLVM_OSType os_type = get_llvm_os_type(g->zig_target->os); |
| 2658 | 2662 | codegen_add_time_event(g, "LLVM Link"); |
| 2663 | { | |
| 2664 | const char *progress_name = "linking"; | |
| 2665 | Stage2ProgressNode *child_progress_node = stage2_progress_start(g->progress_node, | |
| 2666 | progress_name, strlen(progress_name), 0); | |
| 2667 | (void)child_progress_node; | |
| 2668 | } | |
| 2659 | 2669 | if (g->verbose_link) { |
| 2660 | 2670 | fprintf(stderr, "ar rcs %s", buf_ptr(&g->output_file_path)); |
| 2661 | 2671 | for (size_t i = 0; i < file_names.length; i += 1) { |
src/main.cpp+14-3| ... | ... | @@ -587,9 +587,10 @@ int main(int argc, char **argv) { |
| 587 | 587 | Buf *cache_dir_buf = buf_create_from_str(cache_dir); |
| 588 | 588 | full_cache_dir = os_path_resolve(&cache_dir_buf, 1); |
| 589 | 589 | } |
| 590 | Stage2ProgressNode *root_progress_node = stage2_progress_start_root(stage2_progress_create(), "", 0, 0); | |
| 590 | 591 | |
| 591 | 592 | CodeGen *g = codegen_create(main_pkg_path, build_runner_path, &target, OutTypeExe, |
| 592 | BuildModeDebug, override_lib_dir, nullptr, &full_cache_dir, false); | |
| 593 | BuildModeDebug, override_lib_dir, nullptr, &full_cache_dir, false, root_progress_node); | |
| 593 | 594 | g->valgrind_support = valgrind_support; |
| 594 | 595 | g->enable_time_report = timing_info; |
| 595 | 596 | codegen_set_out_name(g, buf_create_from_str("build")); |
| ... | ... | @@ -963,6 +964,10 @@ int main(int argc, char **argv) { |
| 963 | 964 | return EXIT_FAILURE; |
| 964 | 965 | } |
| 965 | 966 | |
| 967 | Stage2Progress *progress = stage2_progress_create(); | |
| 968 | Stage2ProgressNode *root_progress_node = stage2_progress_start_root(progress, "", 0, 0); | |
| 969 | if (color == ErrColorOff) stage2_progress_disable_tty(progress); | |
| 970 | ||
| 966 | 971 | init_all_targets(); |
| 967 | 972 | |
| 968 | 973 | ZigTarget target; |
| ... | ... | @@ -1034,17 +1039,19 @@ int main(int argc, char **argv) { |
| 1034 | 1039 | ZigLibCInstallation libc; |
| 1035 | 1040 | if ((err = zig_libc_parse(&libc, buf_create_from_str(in_file), &target, true))) |
| 1036 | 1041 | return EXIT_FAILURE; |
| 1042 | stage2_progress_end(root_progress_node); | |
| 1037 | 1043 | return EXIT_SUCCESS; |
| 1038 | 1044 | } |
| 1039 | 1045 | ZigLibCInstallation libc; |
| 1040 | 1046 | if ((err = zig_libc_find_native(&libc, true))) |
| 1041 | 1047 | return EXIT_FAILURE; |
| 1042 | 1048 | zig_libc_render(&libc, stdout); |
| 1049 | stage2_progress_end(root_progress_node); | |
| 1043 | 1050 | return EXIT_SUCCESS; |
| 1044 | 1051 | } |
| 1045 | 1052 | case CmdBuiltin: { |
| 1046 | 1053 | CodeGen *g = codegen_create(main_pkg_path, nullptr, &target, |
| 1047 | out_type, build_mode, override_lib_dir, nullptr, nullptr, false); | |
| 1054 | out_type, build_mode, override_lib_dir, nullptr, nullptr, false, root_progress_node); | |
| 1048 | 1055 | codegen_set_strip(g, strip); |
| 1049 | 1056 | for (size_t i = 0; i < link_libs.length; i += 1) { |
| 1050 | 1057 | LinkLib *link_lib = codegen_add_link_lib(g, buf_create_from_str(link_libs.at(i))); |
| ... | ... | @@ -1060,6 +1067,7 @@ int main(int argc, char **argv) { |
| 1060 | 1067 | fprintf(stderr, "unable to write to stdout: %s\n", strerror(ferror(stdout))); |
| 1061 | 1068 | return EXIT_FAILURE; |
| 1062 | 1069 | } |
| 1070 | stage2_progress_end(root_progress_node); | |
| 1063 | 1071 | return EXIT_SUCCESS; |
| 1064 | 1072 | } |
| 1065 | 1073 | case CmdRun: |
| ... | ... | @@ -1148,7 +1156,7 @@ int main(int argc, char **argv) { |
| 1148 | 1156 | cache_dir_buf = buf_create_from_str(cache_dir); |
| 1149 | 1157 | } |
| 1150 | 1158 | CodeGen *g = codegen_create(main_pkg_path, zig_root_source_file, &target, out_type, build_mode, |
| 1151 | override_lib_dir, libc, cache_dir_buf, cmd == CmdTest); | |
| 1159 | override_lib_dir, libc, cache_dir_buf, cmd == CmdTest, root_progress_node); | |
| 1152 | 1160 | if (llvm_argv.length >= 2) codegen_set_llvm_argv(g, llvm_argv.items + 1, llvm_argv.length - 2); |
| 1153 | 1161 | g->valgrind_support = valgrind_support; |
| 1154 | 1162 | g->want_pic = want_pic; |
| ... | ... | @@ -1276,6 +1284,7 @@ int main(int argc, char **argv) { |
| 1276 | 1284 | if (printf("%s\n", buf_ptr(&g->output_file_path)) < 0) |
| 1277 | 1285 | return EXIT_FAILURE; |
| 1278 | 1286 | } |
| 1287 | stage2_progress_end(root_progress_node); | |
| 1279 | 1288 | return EXIT_SUCCESS; |
| 1280 | 1289 | } else { |
| 1281 | 1290 | zig_unreachable(); |
| ... | ... | @@ -1284,6 +1293,7 @@ int main(int argc, char **argv) { |
| 1284 | 1293 | codegen_translate_c(g, in_file_buf, stdout, cmd == CmdTranslateCUserland); |
| 1285 | 1294 | if (timing_info) |
| 1286 | 1295 | codegen_print_timing_report(g, stderr); |
| 1296 | stage2_progress_end(root_progress_node); | |
| 1287 | 1297 | return EXIT_SUCCESS; |
| 1288 | 1298 | } else if (cmd == CmdTest) { |
| 1289 | 1299 | codegen_set_emit_file_type(g, emit_file_type); |
| ... | ... | @@ -1338,6 +1348,7 @@ int main(int argc, char **argv) { |
| 1338 | 1348 | fprintf(stderr, "\nTests failed. Use the following command to reproduce the failure:\n"); |
| 1339 | 1349 | fprintf(stderr, "%s\n", buf_ptr(test_exe_path)); |
| 1340 | 1350 | } |
| 1351 | stage2_progress_end(root_progress_node); | |
| 1341 | 1352 | return (term.how == TerminationIdClean) ? term.code : -1; |
| 1342 | 1353 | } else { |
| 1343 | 1354 | zig_unreachable(); |
src/userland.cpp+29| ... | ... | @@ -59,3 +59,32 @@ stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self) { |
| 59 | 59 | const char *msg = "stage0 called stage2_DepTokenizer_next"; |
| 60 | 60 | stage2_panic(msg, strlen(msg)); |
| 61 | 61 | } |
| 62 | ||
| 63 | ||
| 64 | struct Stage2Progress { | |
| 65 | int trash; | |
| 66 | }; | |
| 67 | ||
| 68 | struct Stage2ProgressNode { | |
| 69 | int trash; | |
| 70 | }; | |
| 71 | ||
| 72 | Stage2Progress *stage2_progress_create(void) { | |
| 73 | return nullptr; | |
| 74 | } | |
| 75 | ||
| 76 | void stage2_progress_destroy(Stage2Progress *progress) {} | |
| 77 | ||
| 78 | Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress, | |
| 79 | const char *name_ptr, size_t name_len, size_t estimated_total_items) | |
| 80 | { | |
| 81 | return nullptr; | |
| 82 | } | |
| 83 | Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node, | |
| 84 | const char *name_ptr, size_t name_len, size_t estimated_total_items) | |
| 85 | { | |
| 86 | return nullptr; | |
| 87 | } | |
| 88 | void stage2_progress_end(Stage2ProgressNode *node) {} | |
| 89 | void stage2_progress_complete_one(Stage2ProgressNode *node) {} | |
| 90 | void stage2_progress_disable_tty(Stage2Progress *progress) {} |
src/userland.h+21| ... | ... | @@ -156,4 +156,25 @@ ZIG_EXTERN_C void stage2_DepTokenizer_deinit(stage2_DepTokenizer *self); |
| 156 | 156 | // ABI warning |
| 157 | 157 | ZIG_EXTERN_C stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self); |
| 158 | 158 | |
| 159 | // ABI warning | |
| 160 | struct Stage2Progress; | |
| 161 | // ABI warning | |
| 162 | struct Stage2ProgressNode; | |
| 163 | // ABI warning | |
| 164 | ZIG_EXTERN_C Stage2Progress *stage2_progress_create(void); | |
| 165 | // ABI warning | |
| 166 | ZIG_EXTERN_C void stage2_progress_disable_tty(Stage2Progress *progress); | |
| 167 | // ABI warning | |
| 168 | ZIG_EXTERN_C void stage2_progress_destroy(Stage2Progress *progress); | |
| 169 | // ABI warning | |
| 170 | ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress, | |
| 171 | const char *name_ptr, size_t name_len, size_t estimated_total_items); | |
| 172 | // ABI warning | |
| 173 | ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node, | |
| 174 | const char *name_ptr, size_t name_len, size_t estimated_total_items); | |
| 175 | // ABI warning | |
| 176 | ZIG_EXTERN_C void stage2_progress_end(Stage2ProgressNode *node); | |
| 177 | // ABI warning | |
| 178 | ZIG_EXTERN_C void stage2_progress_complete_one(Stage2ProgressNode *node); | |
| 179 | ||
| 159 | 180 | #endif |
test/cli.zig+2-2| ... | ... | @@ -87,7 +87,7 @@ fn exec(cwd: []const u8, argv: []const []const u8) !ChildProcess.ExecResult { |
| 87 | 87 | fn testZigInitLib(zig_exe: []const u8, dir_path: []const u8) !void { |
| 88 | 88 | _ = try exec(dir_path, [_][]const u8{ zig_exe, "init-lib" }); |
| 89 | 89 | const test_result = try exec(dir_path, [_][]const u8{ zig_exe, "build", "test" }); |
| 90 | testing.expect(std.mem.endsWith(u8, test_result.stderr, "All tests passed.\n")); | |
| 90 | testing.expect(std.mem.eql(u8, test_result.stderr, "")); | |
| 91 | 91 | } |
| 92 | 92 | |
| 93 | 93 | fn testZigInitExe(zig_exe: []const u8, dir_path: []const u8) !void { |
| ... | ... | @@ -136,6 +136,6 @@ fn testMissingOutputPath(zig_exe: []const u8, dir_path: []const u8) !void { |
| 136 | 136 | const output_path = try fs.path.join(a, [_][]const u8{ "does", "not", "exist" }); |
| 137 | 137 | const source_path = try fs.path.join(a, [_][]const u8{ "src", "main.zig" }); |
| 138 | 138 | _ = try exec(dir_path, [_][]const u8{ |
| 139 | zig_exe, "build-exe", source_path, "--output-dir", output_path | |
| 139 | zig_exe, "build-exe", source_path, "--output-dir", output_path, | |
| 140 | 140 | }); |
| 141 | 141 | } |