| author | |
| committer | |
| log | 299991019dddb2acd076d4b2698a4fd6a7a6ae94 |
| tree | 340707c9bf119b7e3cbb5b425cf6b3de533b15fa |
| parent | a73c7bcaf997fddd3aa746104e930cef8b08a934 |
| signature |
13 files changed, 464 insertions(+), 167 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+212-77| ... | ... | @@ -1,107 +1,242 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 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 | /// Keeps track of how many columns in the terminal have been output, so that | |
| 30 | /// we can move the cursor back later. | |
| 31 | columns_written: usize = undefined, | |
| 32 | ||
| 33 | /// How many nanoseconds between writing updates to the terminal. | |
| 34 | refresh_rate_ns: u64 = 50 * std.time.millisecond, | |
| 35 | ||
| 36 | /// How many nanoseconds to keep the output hidden | |
| 37 | initial_delay_ns: u64 = 500 * std.time.millisecond, | |
| 38 | ||
| 39 | done: bool = true, | |
| 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 | } | |
| 3 | 67 | |
| 4 | pub const PrintConfig = struct { | |
| 5 | /// If the current node (and its children) should | |
| 6 | /// print to stderr on update() | |
| 7 | flag: bool = false, | |
| 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 | } | |
| 8 | 74 | |
| 9 | /// If all output should be suppressed instead | |
| 10 | /// serves the same practical purpose as `flag` but supposed to be used | |
| 11 | /// by separate parts of the user program. | |
| 12 | suppress: bool = false, | |
| 13 | }; | |
| 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 | } | |
| 14 | 89 | |
| 15 | pub const ProgressNode = struct { | |
| 16 | completed_items: usize = 0, | |
| 17 | total_items: usize, | |
| 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 | }; | |
| 18 | 95 | |
| 19 | print_config: PrintConfig, | |
| 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 | const is_term = stderr.isTty(); | |
| 103 | self.terminal = if (is_term) stderr else null; | |
| 104 | } else |_| { | |
| 105 | self.terminal = null; | |
| 106 | } | |
| 107 | self.root = Node{ | |
| 108 | .context = self, | |
| 109 | .parent = null, | |
| 110 | .completed_items = 0, | |
| 111 | .name = name, | |
| 112 | .estimated_total_items = estimated_total_items, | |
| 113 | }; | |
| 114 | self.prev_refresh_timestamp = 0; | |
| 115 | self.columns_written = 0; | |
| 116 | self.timer = try std.time.Timer.start(); | |
| 117 | self.done = false; | |
| 118 | return &self.root; | |
| 119 | } | |
| 20 | 120 | |
| 21 | // TODO maybe instead of keeping a prefix field, we could | |
| 22 | // select the proper prefix at the time of update(), and if we're not | |
| 23 | // in a terminal, we use warn("/r{}", lots_of_whitespace). | |
| 24 | prefix: []const u8, | |
| 121 | /// Updates the terminal if enough time has passed since last update. | |
| 122 | pub fn maybeRefresh(self: *Progress) void { | |
| 123 | const now = self.timer.read(); | |
| 124 | if (now < self.initial_delay_ns) return; | |
| 125 | if (now - self.prev_refresh_timestamp < self.refresh_rate_ns) return; | |
| 126 | self.refresh(); | |
| 127 | } | |
| 25 | 128 | |
| 26 | /// Create a new progress node. | |
| 27 | pub fn start( | |
| 28 | parent_opt: ?ProgressNode, | |
| 29 | total_items_opt: ?usize, | |
| 30 | ) !ProgressNode { | |
| 31 | ||
| 32 | // inherit the last set print "configuration" from the parent node | |
| 33 | var print_config = PrintConfig{}; | |
| 34 | if (parent_opt) |parent| { | |
| 35 | print_config = parent.print_config; | |
| 129 | /// Updates the terminal and resets `self.next_refresh_timestamp`. | |
| 130 | pub fn refresh(self: *Progress) void { | |
| 131 | const file = self.terminal orelse return; | |
| 132 | ||
| 133 | const prev_columns_written = self.columns_written; | |
| 134 | var end: usize = 0; | |
| 135 | if (self.columns_written > 0) { | |
| 136 | end += (std.fmt.bufPrint(self.output_buffer[end..], "\x1b[{}D", self.columns_written) catch unreachable).len; | |
| 137 | self.columns_written = 0; | |
| 36 | 138 | } |
| 37 | 139 | |
| 38 | var stderr = try std.io.getStdErr(); | |
| 39 | const is_term = std.os.isatty(stderr.handle); | |
| 140 | if (!self.done) { | |
| 141 | self.bufWriteNode(self.root, &end); | |
| 142 | self.bufWrite(&end, "..."); | |
| 143 | } | |
| 40 | 144 | |
| 41 | // if we're in a terminal, use vt100 escape codes | |
| 42 | // for the progress. | |
| 43 | var prefix: []const u8 = undefined; | |
| 44 | if (is_term) { | |
| 45 | prefix = "\x21[2K\r"; | |
| 46 | } else { | |
| 47 | prefix = "\n"; | |
| 145 | if (prev_columns_written > self.columns_written) { | |
| 146 | const amt = prev_columns_written - self.columns_written; | |
| 147 | std.mem.set(u8, self.output_buffer[end .. end + amt], ' '); | |
| 148 | end += amt; | |
| 149 | end += (std.fmt.bufPrint(self.output_buffer[end..], "\x1b[{}D", amt) catch unreachable).len; | |
| 48 | 150 | } |
| 49 | 151 | |
| 50 | return ProgressNode{ | |
| 51 | .total_items = total_items_opt orelse 0, | |
| 52 | .print_config = print_config, | |
| 53 | .prefix = prefix, | |
| 152 | _ = file.write(self.output_buffer[0..end]) catch |e| { | |
| 153 | // Stop trying to write to this file once it errors. | |
| 154 | self.terminal = null; | |
| 54 | 155 | }; |
| 156 | self.prev_refresh_timestamp = self.timer.read(); | |
| 55 | 157 | } |
| 56 | 158 | |
| 57 | /// Signal an update on the progress node. | |
| 58 | /// The user of this function is supposed to modify | |
| 59 | /// ProgressNode.PrintConfig.flag when update() is supposed to print. | |
| 60 | pub fn update( | |
| 61 | self: *ProgressNode, | |
| 62 | current_action: ?[]const u8, | |
| 63 | items_done_opt: ?usize, | |
| 64 | ) void { | |
| 65 | if (items_done_opt) |items_done| { | |
| 66 | self.completed_items = items_done; | |
| 67 | ||
| 68 | if (items_done > self.total_items) { | |
| 69 | self.total_items = items_done; | |
| 159 | fn bufWriteNode(self: *Progress, node: Node, end: *usize) void { | |
| 160 | if (node.name.len != 0 or node.estimated_total_items != null) { | |
| 161 | if (node.name.len != 0) { | |
| 162 | self.bufWrite(end, "{}", node.name); | |
| 163 | if (node.recently_updated_child != null or node.estimated_total_items != null or | |
| 164 | node.completed_items != 0) | |
| 165 | { | |
| 166 | self.bufWrite(end, "..."); | |
| 167 | } | |
| 168 | } | |
| 169 | if (node.estimated_total_items) |total| { | |
| 170 | self.bufWrite(end, "[{}/{}] ", node.completed_items, total); | |
| 171 | } else if (node.completed_items != 0) { | |
| 172 | self.bufWrite(end, "[{}] ", node.completed_items); | |
| 70 | 173 | } |
| 71 | 174 | } |
| 72 | ||
| 73 | var cfg = self.print_config; | |
| 74 | if (cfg.flag and !cfg.suppress and current_action != null) { | |
| 75 | std.debug.warn( | |
| 76 | "{}[{}/{}] {}", | |
| 77 | self.prefix, | |
| 78 | self.completed_items, | |
| 79 | self.total_items, | |
| 80 | current_action, | |
| 81 | ); | |
| 175 | if (node.recently_updated_child) |child| { | |
| 176 | self.bufWriteNode(child.*, end); | |
| 82 | 177 | } |
| 83 | 178 | } |
| 84 | 179 | |
| 85 | pub fn end(self: *ProgressNode) void { | |
| 86 | if (!self.print_config.flag) return; | |
| 87 | ||
| 88 | // TODO emoji? | |
| 89 | std.debug.warn("\n[V] done!"); | |
| 180 | fn bufWrite(self: *Progress, end: *usize, comptime format: []const u8, args: ...) void { | |
| 181 | if (std.fmt.bufPrint(self.output_buffer[end.*..], format, args)) |written| { | |
| 182 | const amt = written.len; | |
| 183 | end.* += amt; | |
| 184 | self.columns_written += amt; | |
| 185 | } else |err| switch (err) { | |
| 186 | error.BufferTooSmall => { | |
| 187 | self.columns_written += self.output_buffer.len - end.*; | |
| 188 | end.* = self.output_buffer.len; | |
| 189 | }, | |
| 190 | } | |
| 191 | const bytes_needed_for_esc_codes_at_end = 11; | |
| 192 | const max_end = self.output_buffer.len - bytes_needed_for_esc_codes_at_end; | |
| 193 | if (end.* > max_end) { | |
| 194 | const suffix = "..."; | |
| 195 | self.columns_written = self.columns_written - (end.* - max_end) + suffix.len; | |
| 196 | std.mem.copy(u8, self.output_buffer[max_end..], suffix); | |
| 197 | end.* = max_end + suffix.len; | |
| 198 | } | |
| 90 | 199 | } |
| 91 | 200 | }; |
| 92 | 201 | |
| 93 | 202 | test "basic functionality" { |
| 94 | var node = try ProgressNode.start(null, 100); | |
| 95 | ||
| 96 | var buf: [100]u8 = undefined; | |
| 203 | var progress = Progress{}; | |
| 204 | const root_node = try progress.start("", 100); | |
| 205 | defer root_node.end(); | |
| 206 | ||
| 207 | const sub_task_names = [_][]const u8{ | |
| 208 | "reticulating splines", | |
| 209 | "adjusting shoes", | |
| 210 | "climbing towers", | |
| 211 | "pouring juice", | |
| 212 | }; | |
| 213 | var next_sub_task: usize = 0; | |
| 97 | 214 | |
| 98 | 215 | var i: usize = 0; |
| 99 | while (i < 100) : (i += 6) { | |
| 100 | if (i > 50) node.print_config.flag = true; | |
| 101 | const msg = try std.fmt.bufPrint(buf[0..], "action at i={}", i); | |
| 102 | node.update(msg, i); | |
| 216 | while (i < 100) : (i += 1) { | |
| 217 | var node = root_node.start(sub_task_names[next_sub_task], 5); | |
| 218 | node.activate(); | |
| 219 | next_sub_task = (next_sub_task + 1) % sub_task_names.len; | |
| 220 | ||
| 221 | node.completeOne(); | |
| 222 | std.time.sleep(5 * std.time.millisecond); | |
| 223 | node.completeOne(); | |
| 224 | node.completeOne(); | |
| 225 | std.time.sleep(5 * std.time.millisecond); | |
| 226 | node.completeOne(); | |
| 227 | node.completeOne(); | |
| 228 | std.time.sleep(5 * std.time.millisecond); | |
| 229 | ||
| 230 | node.end(); | |
| 231 | ||
| 232 | std.time.sleep(5 * std.time.millisecond); | |
| 233 | } | |
| 234 | { | |
| 235 | 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); | |
| 236 | node.activate(); | |
| 103 | 237 | std.time.sleep(10 * std.time.millisecond); |
| 238 | progress.maybeRefresh(); | |
| 239 | std.time.sleep(10 * std.time.millisecond); | |
| 240 | node.end(); | |
| 104 | 241 | } |
| 105 | ||
| 106 | node.end(); | |
| 107 | 242 | } |
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+49| ... | ... | @@ -456,3 +456,52 @@ 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(progress: *std.Progress, name_ptr: [*]const u8, name_len: usize, estimated_total_items: usize) *std.Progress.Node { | |
| 474 | return progress.start( | |
| 475 | name_ptr[0..name_len], | |
| 476 | if (estimated_total_items == 0) null else estimated_total_items, | |
| 477 | ) catch @panic("timer unsupported"); | |
| 478 | } | |
| 479 | ||
| 480 | // ABI warning | |
| 481 | export fn stage2_progress_start( | |
| 482 | node: *std.Progress.Node, | |
| 483 | name_ptr: [*]const u8, | |
| 484 | name_len: usize, | |
| 485 | estimated_total_items: usize, | |
| 486 | ) *std.Progress.Node { | |
| 487 | const child_node = std.heap.c_allocator.create(std.Progress.Node) catch @panic("out of memory"); | |
| 488 | child_node.* = node.start( | |
| 489 | name_ptr[0..name_len], | |
| 490 | if (estimated_total_items == 0) null else estimated_total_items, | |
| 491 | ); | |
| 492 | child_node.activate(); | |
| 493 | return child_node; | |
| 494 | } | |
| 495 | ||
| 496 | // ABI warning | |
| 497 | export fn stage2_progress_end(node: *std.Progress.Node) void { | |
| 498 | node.end(); | |
| 499 | if (&node.context.root != node) { | |
| 500 | std.heap.c_allocator.destroy(node); | |
| 501 | } | |
| 502 | } | |
| 503 | ||
| 504 | // ABI warning | |
| 505 | export fn stage2_progress_complete_one(node: *std.Progress.Node) void { | |
| 506 | node.completeOne(); | |
| 507 | } |
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 *child_progress_node) | |
| 10450 | 10483 | { |
| 10484 | if (!child_progress_node) { | |
| 10485 | child_progress_node = stage2_progress_start(parent_gen->progress_node, name, strlen(name), 0); | |
| 10486 | } | |
| 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+11-3| ... | ... | @@ -506,6 +506,8 @@ int main(int argc, char **argv) { |
| 506 | 506 | ZigList<const char *> llvm_argv = {0}; |
| 507 | 507 | llvm_argv.append("zig (LLVM option parsing)"); |
| 508 | 508 | |
| 509 | Stage2ProgressNode *root_progress_node = stage2_progress_start_root(stage2_progress_create(), "", 0, 0); | |
| 510 | ||
| 509 | 511 | if (argc >= 2 && strcmp(argv[1], "build") == 0) { |
| 510 | 512 | Buf zig_exe_path_buf = BUF_INIT; |
| 511 | 513 | if ((err = os_self_exe_path(&zig_exe_path_buf))) { |
| ... | ... | @@ -589,7 +591,7 @@ int main(int argc, char **argv) { |
| 589 | 591 | } |
| 590 | 592 | |
| 591 | 593 | CodeGen *g = codegen_create(main_pkg_path, build_runner_path, &target, OutTypeExe, |
| 592 | BuildModeDebug, override_lib_dir, nullptr, &full_cache_dir, false); | |
| 594 | BuildModeDebug, override_lib_dir, nullptr, &full_cache_dir, false, root_progress_node); | |
| 593 | 595 | g->valgrind_support = valgrind_support; |
| 594 | 596 | g->enable_time_report = timing_info; |
| 595 | 597 | codegen_set_out_name(g, buf_create_from_str("build")); |
| ... | ... | @@ -1034,17 +1036,19 @@ int main(int argc, char **argv) { |
| 1034 | 1036 | ZigLibCInstallation libc; |
| 1035 | 1037 | if ((err = zig_libc_parse(&libc, buf_create_from_str(in_file), &target, true))) |
| 1036 | 1038 | return EXIT_FAILURE; |
| 1039 | stage2_progress_end(root_progress_node); | |
| 1037 | 1040 | return EXIT_SUCCESS; |
| 1038 | 1041 | } |
| 1039 | 1042 | ZigLibCInstallation libc; |
| 1040 | 1043 | if ((err = zig_libc_find_native(&libc, true))) |
| 1041 | 1044 | return EXIT_FAILURE; |
| 1042 | 1045 | zig_libc_render(&libc, stdout); |
| 1046 | stage2_progress_end(root_progress_node); | |
| 1043 | 1047 | return EXIT_SUCCESS; |
| 1044 | 1048 | } |
| 1045 | 1049 | case CmdBuiltin: { |
| 1046 | 1050 | CodeGen *g = codegen_create(main_pkg_path, nullptr, &target, |
| 1047 | out_type, build_mode, override_lib_dir, nullptr, nullptr, false); | |
| 1051 | out_type, build_mode, override_lib_dir, nullptr, nullptr, false, root_progress_node); | |
| 1048 | 1052 | codegen_set_strip(g, strip); |
| 1049 | 1053 | for (size_t i = 0; i < link_libs.length; i += 1) { |
| 1050 | 1054 | LinkLib *link_lib = codegen_add_link_lib(g, buf_create_from_str(link_libs.at(i))); |
| ... | ... | @@ -1060,6 +1064,7 @@ int main(int argc, char **argv) { |
| 1060 | 1064 | fprintf(stderr, "unable to write to stdout: %s\n", strerror(ferror(stdout))); |
| 1061 | 1065 | return EXIT_FAILURE; |
| 1062 | 1066 | } |
| 1067 | stage2_progress_end(root_progress_node); | |
| 1063 | 1068 | return EXIT_SUCCESS; |
| 1064 | 1069 | } |
| 1065 | 1070 | case CmdRun: |
| ... | ... | @@ -1148,7 +1153,7 @@ int main(int argc, char **argv) { |
| 1148 | 1153 | cache_dir_buf = buf_create_from_str(cache_dir); |
| 1149 | 1154 | } |
| 1150 | 1155 | 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); | |
| 1156 | override_lib_dir, libc, cache_dir_buf, cmd == CmdTest, root_progress_node); | |
| 1152 | 1157 | if (llvm_argv.length >= 2) codegen_set_llvm_argv(g, llvm_argv.items + 1, llvm_argv.length - 2); |
| 1153 | 1158 | g->valgrind_support = valgrind_support; |
| 1154 | 1159 | g->want_pic = want_pic; |
| ... | ... | @@ -1276,6 +1281,7 @@ int main(int argc, char **argv) { |
| 1276 | 1281 | if (printf("%s\n", buf_ptr(&g->output_file_path)) < 0) |
| 1277 | 1282 | return EXIT_FAILURE; |
| 1278 | 1283 | } |
| 1284 | stage2_progress_end(root_progress_node); | |
| 1279 | 1285 | return EXIT_SUCCESS; |
| 1280 | 1286 | } else { |
| 1281 | 1287 | zig_unreachable(); |
| ... | ... | @@ -1284,6 +1290,7 @@ int main(int argc, char **argv) { |
| 1284 | 1290 | codegen_translate_c(g, in_file_buf, stdout, cmd == CmdTranslateCUserland); |
| 1285 | 1291 | if (timing_info) |
| 1286 | 1292 | codegen_print_timing_report(g, stderr); |
| 1293 | stage2_progress_end(root_progress_node); | |
| 1287 | 1294 | return EXIT_SUCCESS; |
| 1288 | 1295 | } else if (cmd == CmdTest) { |
| 1289 | 1296 | codegen_set_emit_file_type(g, emit_file_type); |
| ... | ... | @@ -1338,6 +1345,7 @@ int main(int argc, char **argv) { |
| 1338 | 1345 | fprintf(stderr, "\nTests failed. Use the following command to reproduce the failure:\n"); |
| 1339 | 1346 | fprintf(stderr, "%s\n", buf_ptr(test_exe_path)); |
| 1340 | 1347 | } |
| 1348 | stage2_progress_end(root_progress_node); | |
| 1341 | 1349 | return (term.how == TerminationIdClean) ? term.code : -1; |
| 1342 | 1350 | } else { |
| 1343 | 1351 | zig_unreachable(); |
src/userland.cpp+28| ... | ... | @@ -59,3 +59,31 @@ 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) {} |
src/userland.h+19| ... | ... | @@ -156,4 +156,23 @@ 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_destroy(Stage2Progress *progress); | |
| 167 | // ABI warning | |
| 168 | ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress, | |
| 169 | const char *name_ptr, size_t name_len, size_t estimated_total_items); | |
| 170 | // ABI warning | |
| 171 | ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node, | |
| 172 | const char *name_ptr, size_t name_len, size_t estimated_total_items); | |
| 173 | // ABI warning | |
| 174 | ZIG_EXTERN_C void stage2_progress_end(Stage2ProgressNode *node); | |
| 175 | // ABI warning | |
| 176 | ZIG_EXTERN_C void stage2_progress_complete_one(Stage2ProgressNode *node); | |
| 177 | ||
| 159 | 178 | #endif |