authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-10-17 22:08:39-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-10-17 22:08:39-04:00
loge42d86b657c2fae093fb2545e8b4b85614a0c906
treee7b0f9f6f509e34edeb2226569b2ae78d34cfb5a
parent17aa8c3ee29fae4bfbd6acc91eed8d229f627c32
parent2d5b2bf1c986d037ef965bf8c9b4d8dfd5967478
signaturelock-open Commit is signed but in an unrecognized format.

Merge branch 'lun-4-progress-take-2'

closes #3362

15 files changed, 543 insertions(+), 102 deletions(-)

lib/std/fmt.zig+10-3
...@@ -1055,14 +1055,21 @@ const BufPrintContext = struct {...@@ -1055,14 +1055,21 @@ const BufPrintContext = struct {
1055};1055};
10561056
1057fn bufPrintWrite(context: *BufPrintContext, bytes: []const u8) !void {1057fn 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 mem.copy(u8, context.remaining, bytes);1062 mem.copy(u8, context.remaining, bytes);
1060 context.remaining = context.remaining[bytes.len..];1063 context.remaining = context.remaining[bytes.len..];
1061}1064}
10621065
1063pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) ![]u8 {1066pub 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};
1070pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) BufPrintError![]u8 {
1064 var context = BufPrintContext{ .remaining = buf };1071 var context = BufPrintContext{ .remaining = buf };
1065 try format(&context, error{BufferTooSmall}, bufPrintWrite, fmt, args);1072 try format(&context, BufPrintError, bufPrintWrite, fmt, args);
1066 return buf[0 .. buf.len - context.remaining.len];1073 return buf[0 .. buf.len - context.remaining.len];
1067}1074}
10681075
lib/std/progress.zig created+258
...@@ -0,0 +1,258 @@
1const std = @import("std");
2const testing = std.testing;
3const 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`
10pub 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
212test "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,28 +2,33 @@ const std = @import("std");
2const io = std.io;2const io = std.io;
3const builtin = @import("builtin");3const builtin = @import("builtin");
4const test_fn_list = builtin.test_functions;4const test_fn_list = builtin.test_functions;
5const warn = std.debug.warn;
65
7pub fn main() !void {6pub fn main() anyerror!void {
8 var ok_count: usize = 0;7 var ok_count: usize = 0;
9 var skip_count: usize = 0;8 var skip_count: usize = 0;
10 for (test_fn_list) |test_fn, i| {9 var progress = std.Progress{};
11 warn("{}/{} {}...", i + 1, test_fn_list.len, test_fn.name);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 };
1214
15 for (test_fn_list) |test_fn, i| {
16 var test_node = root_node.start(test_fn.name, null);
17 test_node.activate();
13 if (test_fn.func()) |_| {18 if (test_fn.func()) |_| {
14 ok_count += 1;19 ok_count += 1;
15 warn("OK\n");20 test_node.end();
16 } else |err| switch (err) {21 } else |err| switch (err) {
17 error.SkipZigTest => {22 error.SkipZigTest => {
18 skip_count += 1;23 skip_count += 1;
19 warn("SKIP\n");24 test_node.end();
25 progress.log("{}...SKIP\n", test_fn.name);
20 },26 },
21 else => return err,27 else => return err,
22 }28 }
23 }29 }
24 if (ok_count == test_fn_list.len) {30 root_node.end();
25 warn("All tests passed.\n");31 if (ok_count != test_fn_list.len) {
26 } else {32 progress.log("{} passed; {} skipped.\n", ok_count, skip_count);
27 warn("{} 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,20 +6,21 @@ pub const BufMap = @import("buf_map.zig").BufMap;
6pub const BufSet = @import("buf_set.zig").BufSet;6pub const BufSet = @import("buf_set.zig").BufSet;
7pub const Buffer = @import("buffer.zig").Buffer;7pub const Buffer = @import("buffer.zig").Buffer;
8pub const BufferOutStream = @import("io.zig").BufferOutStream;8pub const BufferOutStream = @import("io.zig").BufferOutStream;
9pub const ChildProcess = @import("child_process.zig").ChildProcess;
9pub const DynLib = @import("dynamic_library.zig").DynLib;10pub const DynLib = @import("dynamic_library.zig").DynLib;
10pub const HashMap = @import("hash_map.zig").HashMap;11pub const HashMap = @import("hash_map.zig").HashMap;
11pub const Mutex = @import("mutex.zig").Mutex;12pub const Mutex = @import("mutex.zig").Mutex;
12pub const PackedIntArrayEndian = @import("packed_int_array.zig").PackedIntArrayEndian;
13pub const PackedIntArray = @import("packed_int_array.zig").PackedIntArray;13pub const PackedIntArray = @import("packed_int_array.zig").PackedIntArray;
14pub const PackedIntSliceEndian = @import("packed_int_array.zig").PackedIntSliceEndian;14pub const PackedIntArrayEndian = @import("packed_int_array.zig").PackedIntArrayEndian;
15pub const PackedIntSlice = @import("packed_int_array.zig").PackedIntSlice;15pub const PackedIntSlice = @import("packed_int_array.zig").PackedIntSlice;
16pub const PackedIntSliceEndian = @import("packed_int_array.zig").PackedIntSliceEndian;
16pub const PriorityQueue = @import("priority_queue.zig").PriorityQueue;17pub const PriorityQueue = @import("priority_queue.zig").PriorityQueue;
17pub const SinglyLinkedList = @import("linked_list.zig").SinglyLinkedList;18pub const Progress = @import("progress.zig").Progress;
18pub const StaticallyInitializedMutex = @import("statically_initialized_mutex.zig").StaticallyInitializedMutex;
19pub const SegmentedList = @import("segmented_list.zig").SegmentedList;19pub const SegmentedList = @import("segmented_list.zig").SegmentedList;
20pub const SinglyLinkedList = @import("linked_list.zig").SinglyLinkedList;
20pub const SpinLock = @import("spinlock.zig").SpinLock;21pub const SpinLock = @import("spinlock.zig").SpinLock;
22pub const StaticallyInitializedMutex = @import("statically_initialized_mutex.zig").StaticallyInitializedMutex;
21pub const StringHashMap = @import("hash_map.zig").StringHashMap;23pub const StringHashMap = @import("hash_map.zig").StringHashMap;
22pub const ChildProcess = @import("child_process.zig").ChildProcess;
23pub const TailQueue = @import("linked_list.zig").TailQueue;24pub const TailQueue = @import("linked_list.zig").TailQueue;
24pub const Thread = @import("thread.zig").Thread;25pub const Thread = @import("thread.zig").Thread;
2526
src-self-hosted/stage1.zig+59
...@@ -456,3 +456,62 @@ export fn stage2_attach_segfault_handler() void {...@@ -456,3 +456,62 @@ export fn stage2_attach_segfault_handler() void {
456 std.debug.attachSegfaultHandler();456 std.debug.attachSegfaultHandler();
457 }457 }
458}458}
459
460// ABI warning
461export 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
468export fn stage2_progress_destroy(progress: *std.Progress) void {
469 std.heap.c_allocator.destroy(progress);
470}
471
472// ABI warning
473export 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
486export fn stage2_progress_disable_tty(progress: *std.Progress) void {
487 progress.terminal = null;
488}
489
490// ABI warning
491export 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
507export 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
515export 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,6 +2010,8 @@ struct CodeGen {
20102010
2011 ZigFn *largest_frame_fn;2011 ZigFn *largest_frame_fn;
20122012
2013 Stage2ProgressNode *progress_node;
2014
2013 WantPIC want_pic;2015 WantPIC want_pic;
2014 WantStackCheck want_stack_check;2016 WantStackCheck want_stack_check;
2015 CacheHash cache_hash;2017 CacheHash cache_hash;
src/codegen.cpp+45-6
...@@ -7610,7 +7610,7 @@ static void zig_llvm_emit_output(CodeGen *g) {...@@ -7610,7 +7610,7 @@ static void zig_llvm_emit_output(CodeGen *g) {
7610 if (g->bundle_compiler_rt && (g->out_type == OutTypeObj ||7610 if (g->bundle_compiler_rt && (g->out_type == OutTypeObj ||
7611 (g->out_type == OutTypeLib && !g->is_dynamic)))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 break;7615 break;
76167616
...@@ -9453,7 +9453,7 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose...@@ -9453,7 +9453,7 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose
9453}9453}
94549454
9455// returns true if it was a cache miss9455// returns true if it was a cache miss
9456static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) {9456static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file, Stage2ProgressNode *parent_prog_node) {
9457 Error err;9457 Error err;
94589458
9459 Buf *artifact_dir;9459 Buf *artifact_dir;
...@@ -9464,6 +9464,10 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) {...@@ -9464,6 +9464,10 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) {
9464 Buf *c_source_file = buf_create_from_str(c_file->source_path);9464 Buf *c_source_file = buf_create_from_str(c_file->source_path);
9465 Buf *c_source_basename = buf_alloc();9465 Buf *c_source_basename = buf_alloc();
9466 os_path_split(c_source_file, nullptr, c_source_basename);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 Buf *final_o_basename = buf_alloc();9471 Buf *final_o_basename = buf_alloc();
9468 os_path_extname(c_source_basename, final_o_basename, nullptr);9472 os_path_extname(c_source_basename, final_o_basename, nullptr);
9469 buf_append_str(final_o_basename, target_o_file_ext(g->zig_target));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,6 +9584,8 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) {
95809584
9581 g->link_objects.append(o_final_path);9585 g->link_objects.append(o_final_path);
9582 g->caches_to_release.append(cache_hash);9586 g->caches_to_release.append(cache_hash);
9587
9588 stage2_progress_end(child_prog_node);
9583}9589}
95849590
9585// returns true if we had any cache misses9591// returns true if we had any cache misses
...@@ -9596,11 +9602,16 @@ static void gen_c_objects(CodeGen *g) {...@@ -9596,11 +9602,16 @@ static void gen_c_objects(CodeGen *g) {
9596 }9602 }
95979603
9598 codegen_add_time_event(g, "Compile C Code");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);
95999608
9600 for (size_t c_file_i = 0; c_file_i < g->c_source_files.length; c_file_i += 1) {9609 for (size_t c_file_i = 0; c_file_i < g->c_source_files.length; c_file_i += 1) {
9601 CFile *c_file = g->c_source_files.at(c_file_i);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}
96059616
9606void codegen_add_object(CodeGen *g, Buf *object_path) {9617void codegen_add_object(CodeGen *g, Buf *object_path) {
...@@ -10320,6 +10331,10 @@ void codegen_build_and_link(CodeGen *g) {...@@ -10320,6 +10331,10 @@ void codegen_build_and_link(CodeGen *g) {
10320 init(g);10331 init(g);
1032110332
10322 codegen_add_time_event(g, "Semantic Analysis");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;
1032310338
10324 gen_root_source(g);10339 gen_root_source(g);
1032510340
...@@ -10343,13 +10358,31 @@ void codegen_build_and_link(CodeGen *g) {...@@ -10343,13 +10358,31 @@ void codegen_build_and_link(CodeGen *g) {
1034310358
10344 if (need_llvm_module(g)) {10359 if (need_llvm_module(g)) {
10345 codegen_add_time_event(g, "Code Generation");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 }
1034610367
10347 do_code_gen(g);10368 do_code_gen(g);
10348 codegen_add_time_event(g, "LLVM Emit Output");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 zig_llvm_emit_output(g);10376 zig_llvm_emit_output(g);
1035010377
10351 if (!g->disable_gen_h && (g->out_type == OutTypeObj || g->out_type == OutTypeLib)) {10378 if (!g->disable_gen_h && (g->out_type == OutTypeObj || g->out_type == OutTypeLib)) {
10352 codegen_add_time_event(g, "Generate .h");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 gen_h_file(g);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,10 +10479,15 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c
10446}10479}
1044710480
10448CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType out_type,10481CodeGen *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 CodeGen *child_gen = codegen_create(nullptr, root_src_path, parent_gen->zig_target, out_type,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 child_gen->disable_gen_h = true;10491 child_gen->disable_gen_h = true;
10454 child_gen->want_stack_check = WantStackCheckDisabled;10492 child_gen->want_stack_check = WantStackCheckDisabled;
10455 child_gen->verbose_tokenize = parent_gen->verbose_tokenize;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,9 +10516,10 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o
1047810516
10479CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,10517CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,
10480 OutType out_type, BuildMode build_mode, Buf *override_lib_dir,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 CodeGen *g = allocate<CodeGen>(1);10521 CodeGen *g = allocate<CodeGen>(1);
10522 g->progress_node = progress_node;
1048410523
10485 codegen_add_time_event(g, "Initialize");10524 codegen_add_time_event(g, "Initialize");
1048610525
src/codegen.hpp+3-3
...@@ -18,10 +18,10 @@...@@ -18,10 +18,10 @@
1818
19CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,19CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,
20 OutType out_type, BuildMode build_mode, Buf *zig_lib_dir,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);
2222
23CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType out_type,23CodeGen *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);
2525
26void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);26void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);
27void codegen_set_llvm_argv(CodeGen *codegen, const char **args, size_t len);27void 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,7 +46,7 @@ void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patc
46void codegen_add_time_event(CodeGen *g, const char *name);46void codegen_add_time_event(CodeGen *g, const char *name);
47void codegen_print_timing_report(CodeGen *g, FILE *f);47void codegen_print_timing_report(CodeGen *g, FILE *f);
48void codegen_link(CodeGen *g);48void codegen_link(CodeGen *g);
49void zig_link_add_compiler_rt(CodeGen *g);49void zig_link_add_compiler_rt(CodeGen *g, Stage2ProgressNode *progress_node);
50void codegen_build_and_link(CodeGen *g);50void codegen_build_and_link(CodeGen *g);
5151
52ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const char *root_src_path,52ZigPackage *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,7 +169,7 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo
169}169}
170170
171Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, const ZigTarget *target,171Error 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 Error err;174 Error err;
175175
...@@ -332,8 +332,7 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con...@@ -332,8 +332,7 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con
332 return err;332 return err;
333 }333 }
334334
335 CodeGen *child_gen = create_child_codegen(g, zig_file_path, OutTypeLib, nullptr);335 CodeGen *child_gen = create_child_codegen(g, zig_file_path, OutTypeLib, nullptr, lib->name, progress_node);
336 codegen_set_out_name(child_gen, buf_create_from_str(lib->name));
337 codegen_set_lib_version(child_gen, lib->sover, 0, 0);336 codegen_set_lib_version(child_gen, lib->sover, 0, 0);
338 child_gen->is_dynamic = true;337 child_gen->is_dynamic = true;
339 child_gen->is_dummy_so = true;338 child_gen->is_dummy_so = true;
src/glibc.hpp+1-1
...@@ -41,7 +41,7 @@ struct ZigGLibCAbi {...@@ -41,7 +41,7 @@ struct ZigGLibCAbi {
4141
42Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbose);42Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbose);
43Error glibc_build_dummies_and_maps(CodeGen *codegen, const ZigGLibCAbi *glibc_abi, const ZigTarget *target,43Error 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);
4545
46// returns ErrorUnknownABI when glibc is not the native libc46// returns ErrorUnknownABI when glibc is not the native libc
47Error glibc_detect_native_version(ZigGLibCVersion *glibc_ver);47Error glibc_detect_native_version(ZigGLibCVersion *glibc_ver);
src/link.cpp+76-66
...@@ -594,11 +594,13 @@ struct LinkJob {...@@ -594,11 +594,13 @@ struct LinkJob {
594 ZigList<const char *> args;594 ZigList<const char *> args;
595 bool link_in_crt;595 bool link_in_crt;
596 HashMap<Buf *, bool, buf_hash, buf_eql_buf> rpath_table;596 HashMap<Buf *, bool, buf_hash, buf_eql_buf> rpath_table;
597 Stage2ProgressNode *build_dep_prog_node;
597};598};
598599
599static const char *build_libc_object(CodeGen *parent_gen, const char *name, CFile *c_file) {600static 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 Stage2ProgressNode *progress_node)
601 codegen_set_out_name(child_gen, buf_create_from_str(name));602{
603 CodeGen *child_gen = create_child_codegen(parent_gen, nullptr, OutTypeObj, nullptr, name, progress_node);
602 ZigList<CFile *> c_source_files = {0};604 ZigList<CFile *> c_source_files = {0};
603 c_source_files.append(c_file);605 c_source_files.append(c_file);
604 child_gen->c_source_files = c_source_files;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,9 +624,8 @@ static const char *path_from_libunwind(CodeGen *g, const char *subpath) {
622 return path_from_zig_lib(g, "libunwind", subpath);624 return path_from_zig_lib(g, "libunwind", subpath);
623}625}
624626
625static const char *build_libunwind(CodeGen *parent) {627static const char *build_libunwind(CodeGen *parent, Stage2ProgressNode *progress_node) {
626 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);628 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "unwind", progress_node);
627 codegen_set_out_name(child_gen, buf_create_from_str("unwind"));
628 LinkLib *new_link_lib = codegen_add_link_lib(child_gen, buf_create_from_str("c"));629 LinkLib *new_link_lib = codegen_add_link_lib(child_gen, buf_create_from_str("c"));
629 new_link_lib->provided_explicitly = false;630 new_link_lib->provided_explicitly = false;
630 enum SrcKind {631 enum SrcKind {
...@@ -1017,9 +1018,8 @@ static bool is_musl_arch_name(const char *name) {...@@ -1017,9 +1018,8 @@ static bool is_musl_arch_name(const char *name) {
1017 return false;1018 return false;
1018}1019}
10191020
1020static const char *build_musl(CodeGen *parent) {1021static const char *build_musl(CodeGen *parent, Stage2ProgressNode *progress_node) {
1021 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);1022 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "c", progress_node);
1022 codegen_set_out_name(child_gen, buf_create_from_str("c"));
10231023
1024 // When there is a src/<arch>/foo.* then it should substitute for src/foo.*1024 // When there is a src/<arch>/foo.* then it should substitute for src/foo.*
1025 // Even a .s file can substitute for a .c file.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,7 +1175,7 @@ static void add_mingwex_os_dep(CodeGen *parent, CodeGen *child_gen, const char *
1175 child_gen->c_source_files.append(c_file);1175 child_gen->c_source_files.append(c_file);
1176}1176}
11771177
1178static const char *get_libc_crt_file(CodeGen *parent, const char *file) {1178static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2ProgressNode *progress_node) {
1179 if (parent->libc == nullptr && parent->zig_target->os == OsWindows) {1179 if (parent->libc == nullptr && parent->zig_target->os == OsWindows) {
1180 if (strcmp(file, "crt2.o") == 0) {1180 if (strcmp(file, "crt2.o") == 0) {
1181 CFile *c_file = allocate<CFile>(1);1181 CFile *c_file = allocate<CFile>(1);
...@@ -1188,7 +1188,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {...@@ -1188,7 +1188,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
1188 //c_file->args.append("-DUNICODE");1188 //c_file->args.append("-DUNICODE");
1189 //c_file->args.append("-D_UNICODE");1189 //c_file->args.append("-D_UNICODE");
1190 //c_file->args.append("-DWPRFLAG=1");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 } else if (strcmp(file, "dllcrt2.o") == 0) {1192 } else if (strcmp(file, "dllcrt2.o") == 0) {
1193 CFile *c_file = allocate<CFile>(1);1193 CFile *c_file = allocate<CFile>(1);
1194 c_file->source_path = buf_ptr(buf_sprintf(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,10 +1196,9 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
1196 mingw_add_cc_args(parent, c_file);1196 mingw_add_cc_args(parent, c_file);
1197 c_file->args.append("-U__CRTDLL__");1197 c_file->args.append("-U__CRTDLL__");
1198 c_file->args.append("-D__MSVCRT__");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 } else if (strcmp(file, "mingw32.lib") == 0) {1200 } else if (strcmp(file, "mingw32.lib") == 0) {
1201 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);1201 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "mingw32", progress_node);
1202 codegen_set_out_name(child_gen, buf_create_from_str("mingw32"));
12031202
1204 static const char *deps[] = {1203 static const char *deps[] = {
1205 "mingw" OS_SEP "crt" OS_SEP "crt0_c.c",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,8 +1255,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
1256 codegen_build_and_link(child_gen);1255 codegen_build_and_link(child_gen);
1257 return buf_ptr(&child_gen->output_file_path);1256 return buf_ptr(&child_gen->output_file_path);
1258 } else if (strcmp(file, "msvcrt-os.lib") == 0) {1257 } else if (strcmp(file, "msvcrt-os.lib") == 0) {
1259 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);1258 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "msvcrt-os", progress_node);
1260 codegen_set_out_name(child_gen, buf_create_from_str("msvcrt-os"));
12611259
1262 for (size_t i = 0; i < array_length(msvcrt_common_src); i += 1) {1260 for (size_t i = 0; i < array_length(msvcrt_common_src); i += 1) {
1263 add_msvcrt_os_dep(parent, child_gen, msvcrt_common_src[i]);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,8 +1272,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
1274 codegen_build_and_link(child_gen);1272 codegen_build_and_link(child_gen);
1275 return buf_ptr(&child_gen->output_file_path);1273 return buf_ptr(&child_gen->output_file_path);
1276 } else if (strcmp(file, "mingwex.lib") == 0) {1274 } else if (strcmp(file, "mingwex.lib") == 0) {
1277 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);1275 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "mingwex", progress_node);
1278 codegen_set_out_name(child_gen, buf_create_from_str("mingwex"));
12791276
1280 for (size_t i = 0; i < array_length(mingwex_generic_src); i += 1) {1277 for (size_t i = 0; i < array_length(mingwex_generic_src); i += 1) {
1281 add_mingwex_os_dep(parent, child_gen, mingwex_generic_src[i]);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,7 +1315,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
1318 c_file->args.append("-DASSEMBLER");1315 c_file->args.append("-DASSEMBLER");
1319 c_file->args.append("-g");1316 c_file->args.append("-g");
1320 c_file->args.append("-Wa,--noexecstack");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 } else if (strcmp(file, "crtn.o") == 0) {1319 } else if (strcmp(file, "crtn.o") == 0) {
1323 CFile *c_file = allocate<CFile>(1);1320 CFile *c_file = allocate<CFile>(1);
1324 c_file->source_path = glibc_start_asm_path(parent, "crtn.S");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,7 +1326,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
1329 c_file->args.append("-DASSEMBLER");1326 c_file->args.append("-DASSEMBLER");
1330 c_file->args.append("-g");1327 c_file->args.append("-g");
1331 c_file->args.append("-Wa,--noexecstack");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 } else if (strcmp(file, "start.os") == 0) {1330 } else if (strcmp(file, "start.os") == 0) {
1334 CFile *c_file = allocate<CFile>(1);1331 CFile *c_file = allocate<CFile>(1);
1335 c_file->source_path = glibc_start_asm_path(parent, "start.S");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,7 +1344,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
1347 c_file->args.append("-DASSEMBLER");1344 c_file->args.append("-DASSEMBLER");
1348 c_file->args.append("-g");1345 c_file->args.append("-g");
1349 c_file->args.append("-Wa,--noexecstack");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 } else if (strcmp(file, "abi-note.o") == 0) {1348 } else if (strcmp(file, "abi-note.o") == 0) {
1352 CFile *c_file = allocate<CFile>(1);1349 CFile *c_file = allocate<CFile>(1);
1353 c_file->source_path = path_from_libc(parent, "glibc" OS_SEP "csu" OS_SEP "abi-note.S");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,19 +1357,17 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
1360 c_file->args.append("-DASSEMBLER");1357 c_file->args.append("-DASSEMBLER");
1361 c_file->args.append("-g");1358 c_file->args.append("-g");
1362 c_file->args.append("-Wa,--noexecstack");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 } else if (strcmp(file, "Scrt1.o") == 0) {1361 } else if (strcmp(file, "Scrt1.o") == 0) {
1365 const char *start_os = get_libc_crt_file(parent, "start.os");1362 const char *start_os = get_libc_crt_file(parent, "start.os", progress_node);
1366 const char *abi_note_o = get_libc_crt_file(parent, "abi-note.o");1363 const char *abi_note_o = get_libc_crt_file(parent, "abi-note.o", progress_node);
1367 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeObj, nullptr);1364 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeObj, nullptr, "Scrt1", progress_node);
1368 codegen_set_out_name(child_gen, buf_create_from_str("Scrt1"));
1369 codegen_add_object(child_gen, buf_create_from_str(start_os));1365 codegen_add_object(child_gen, buf_create_from_str(start_os));
1370 codegen_add_object(child_gen, buf_create_from_str(abi_note_o));1366 codegen_add_object(child_gen, buf_create_from_str(abi_note_o));
1371 codegen_build_and_link(child_gen);1367 codegen_build_and_link(child_gen);
1372 return buf_ptr(&child_gen->output_file_path);1368 return buf_ptr(&child_gen->output_file_path);
1373 } else if (strcmp(file, "libc_nonshared.a") == 0) {1369 } else if (strcmp(file, "libc_nonshared.a") == 0) {
1374 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);1370 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "c_nonshared", progress_node);
1375 codegen_set_out_name(child_gen, buf_create_from_str("c_nonshared"));
1376 {1371 {
1377 CFile *c_file = allocate<CFile>(1);1372 CFile *c_file = allocate<CFile>(1);
1378 c_file->source_path = path_from_libc(parent, "glibc" OS_SEP "csu" OS_SEP "elf-init.c");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,7 +1396,8 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
1401 c_file->args.append("-DPIC");1396 c_file->args.append("-DPIC");
1402 c_file->args.append("-DLIBC_NONSHARED=1");1397 c_file->args.append("-DLIBC_NONSHARED=1");
1403 c_file->args.append("-DTOP_NAMESPACE=glibc");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 static const struct {1402 static const struct {
1407 const char *name;1403 const char *name;
...@@ -1445,7 +1441,8 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {...@@ -1445,7 +1441,8 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
1445 c_file->args.append("-DPIC");1441 c_file->args.append("-DPIC");
1446 c_file->args.append("-DLIBC_NONSHARED=1");1442 c_file->args.append("-DLIBC_NONSHARED=1");
1447 c_file->args.append("-DTOP_NAMESPACE=glibc");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 codegen_build_and_link(child_gen);1447 codegen_build_and_link(child_gen);
1451 return buf_ptr(&child_gen->output_file_path);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,20 +1455,20 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
1458 c_file->source_path = musl_start_asm_path(parent, "crti.s");1455 c_file->source_path = musl_start_asm_path(parent, "crti.s");
1459 musl_add_cc_args(parent, c_file, false);1456 musl_add_cc_args(parent, c_file, false);
1460 c_file->args.append("-Qunused-arguments");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 } else if (strcmp(file, "crtn.o") == 0) {1459 } else if (strcmp(file, "crtn.o") == 0) {
1463 CFile *c_file = allocate<CFile>(1);1460 CFile *c_file = allocate<CFile>(1);
1464 c_file->source_path = musl_start_asm_path(parent, "crtn.s");1461 c_file->source_path = musl_start_asm_path(parent, "crtn.s");
1465 c_file->args.append("-Qunused-arguments");1462 c_file->args.append("-Qunused-arguments");
1466 musl_add_cc_args(parent, c_file, false);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 } else if (strcmp(file, "crt1.o") == 0) {1465 } else if (strcmp(file, "crt1.o") == 0) {
1469 CFile *c_file = allocate<CFile>(1);1466 CFile *c_file = allocate<CFile>(1);
1470 c_file->source_path = path_from_libc(parent, "musl" OS_SEP "crt" OS_SEP "crt1.c");1467 c_file->source_path = path_from_libc(parent, "musl" OS_SEP "crt" OS_SEP "crt1.c");
1471 musl_add_cc_args(parent, c_file, false);1468 musl_add_cc_args(parent, c_file, false);
1472 c_file->args.append("-fno-stack-protector");1469 c_file->args.append("-fno-stack-protector");
1473 c_file->args.append("-DCRT");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 } else if (strcmp(file, "Scrt1.o") == 0) {1472 } else if (strcmp(file, "Scrt1.o") == 0) {
1476 CFile *c_file = allocate<CFile>(1);1473 CFile *c_file = allocate<CFile>(1);
1477 c_file->source_path = path_from_libc(parent, "musl" OS_SEP "crt" OS_SEP "Scrt1.c");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,7 +1476,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
1479 c_file->args.append("-fPIC");1476 c_file->args.append("-fPIC");
1480 c_file->args.append("-fno-stack-protector");1477 c_file->args.append("-fno-stack-protector");
1481 c_file->args.append("-DCRT");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 } else {1480 } else {
1484 zig_unreachable();1481 zig_unreachable();
1485 }1482 }
...@@ -1491,10 +1488,11 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {...@@ -1491,10 +1488,11 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
1491 }1488 }
1492}1489}
14931490
1494static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path, OutType child_out_type) {1491static 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,1492 Stage2ProgressNode *progress_node)
1496 parent_gen->libc);1493{
1497 codegen_set_out_name(child_gen, buf_create_from_str(aname));1494 CodeGen *child_gen = create_child_codegen(parent_gen, full_path, child_out_type, parent_gen->libc, aname,
1495 progress_node);
14981496
1499 // This is so that compiler_rt and libc.zig libraries know whether they1497 // This is so that compiler_rt and libc.zig libraries know whether they
1500 // will eventually be linked with libc. They make different decisions1498 // 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,18 +1509,18 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path,
1511 return &child_gen->output_file_path;1509 return &child_gen->output_file_path;
1512}1510}
15131511
1514static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type) {1512static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type, Stage2ProgressNode *progress_node) {
1515 Buf *full_path = buf_alloc();1513 Buf *full_path = buf_alloc();
1516 os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("compiler_rt.zig"), full_path);1514 os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("compiler_rt.zig"), full_path);
15171515
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}
15201518
1521static Buf *build_c(CodeGen *parent_gen, OutType child_out_type) {1519static Buf *build_c(CodeGen *parent_gen, OutType child_out_type, Stage2ProgressNode *progress_node) {
1522 Buf *full_path = buf_alloc();1520 Buf *full_path = buf_alloc();
1523 os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("c.zig"), full_path);1521 os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("c.zig"), full_path);
15241522
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}
15271525
1528static const char *get_darwin_arch_string(const ZigTarget *t) {1526static const char *get_darwin_arch_string(const ZigTarget *t) {
...@@ -1616,7 +1614,7 @@ static void add_glibc_libs(LinkJob *lj) {...@@ -1616,7 +1614,7 @@ static void add_glibc_libs(LinkJob *lj) {
16161614
1617 Buf *artifact_dir;1615 Buf *artifact_dir;
1618 if ((err = glibc_build_dummies_and_maps(lj->codegen, glibc_abi, lj->codegen->zig_target,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 fprintf(stderr, "%s\n", err_str(err));1619 fprintf(stderr, "%s\n", err_str(err));
1622 exit(1);1620 exit(1);
...@@ -1692,9 +1690,9 @@ static void construct_linker_job_elf(LinkJob *lj) {...@@ -1692,9 +1690,9 @@ static void construct_linker_job_elf(LinkJob *lj) {
1692 } else {1690 } else {
1693 crt1o = "Scrt1.o";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 if (target_libc_needs_crti_crtn(g->zig_target)) {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 }
17001698
...@@ -1759,11 +1757,11 @@ static void construct_linker_job_elf(LinkJob *lj) {...@@ -1759,11 +1757,11 @@ static void construct_linker_job_elf(LinkJob *lj) {
17591757
1760 if (!g->is_dummy_so && (g->out_type == OutTypeExe || is_dyn_lib)) {1758 if (!g->is_dummy_so && (g->out_type == OutTypeExe || is_dyn_lib)) {
1761 if (g->libc_link_lib == nullptr) {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 lj->args.append(buf_ptr(libc_a_path));1761 lj->args.append(buf_ptr(libc_a_path));
1764 }1762 }
17651763
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 lj->args.append(buf_ptr(compiler_rt_o_path));1765 lj->args.append(buf_ptr(compiler_rt_o_path));
1768 }1766 }
17691767
...@@ -1823,15 +1821,15 @@ static void construct_linker_job_elf(LinkJob *lj) {...@@ -1823,15 +1821,15 @@ static void construct_linker_job_elf(LinkJob *lj) {
1823 }1821 }
1824 } else if (target_is_glibc(g->zig_target)) {1822 } else if (target_is_glibc(g->zig_target)) {
1825 if (target_supports_libunwind(g->zig_target)) {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 add_glibc_libs(lj);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 } else if (target_is_musl(g->zig_target)) {1828 } else if (target_is_musl(g->zig_target)) {
1831 if (target_supports_libunwind(g->zig_target)) {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 } else {1833 } else {
1836 zig_unreachable();1834 zig_unreachable();
1837 }1835 }
...@@ -1840,9 +1838,9 @@ static void construct_linker_job_elf(LinkJob *lj) {...@@ -1840,9 +1838,9 @@ static void construct_linker_job_elf(LinkJob *lj) {
1840 // crt end1838 // crt end
1841 if (lj->link_in_crt) {1839 if (lj->link_in_crt) {
1842 if (target_is_android(g->zig_target)) {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 } else if (target_libc_needs_crti_crtn(g->zig_target)) {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 }
18481846
...@@ -1887,10 +1885,10 @@ static void construct_linker_job_wasm(LinkJob *lj) {...@@ -1887,10 +1885,10 @@ static void construct_linker_job_wasm(LinkJob *lj) {
1887 }1885 }
18881886
1889 if (g->out_type != OutTypeObj) {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 lj->args.append(buf_ptr(libc_o_path));1889 lj->args.append(buf_ptr(libc_o_path));
18921890
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 lj->args.append(buf_ptr(compiler_rt_o_path));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,14 +2168,14 @@ static void add_mingw_link_args(LinkJob *lj, bool is_library) {
2170 }2168 }
21712169
2172 if (is_dll) {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 } else {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 }
21772175
2178 lj->args.append(get_libc_crt_file(g, "mingw32.lib"));2176 lj->args.append(get_libc_crt_file(g, "mingw32.lib", lj->build_dep_prog_node));
2179 lj->args.append(get_libc_crt_file(g, "mingwex.lib"));2177 lj->args.append(get_libc_crt_file(g, "mingwex.lib", lj->build_dep_prog_node));
2180 lj->args.append(get_libc_crt_file(g, "msvcrt-os.lib"));2178 lj->args.append(get_libc_crt_file(g, "msvcrt-os.lib", lj->build_dep_prog_node));
21812179
2182 for (size_t def_i = 0; def_i < array_length(mingw_def_list); def_i += 1) {2180 for (size_t def_i = 0; def_i < array_length(mingw_def_list); def_i += 1) {
2183 const char *name = mingw_def_list[def_i].name;2181 const char *name = mingw_def_list[def_i].name;
...@@ -2319,12 +2317,12 @@ static void construct_linker_job_coff(LinkJob *lj) {...@@ -2319,12 +2317,12 @@ static void construct_linker_job_coff(LinkJob *lj) {
23192317
2320 if (g->out_type == OutTypeExe || (g->out_type == OutTypeLib && g->is_dynamic)) {2318 if (g->out_type == OutTypeExe || (g->out_type == OutTypeLib && g->is_dynamic)) {
2321 if (g->libc_link_lib == nullptr && !g->is_dummy_so) {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 lj->args.append(buf_ptr(libc_a_path));2321 lj->args.append(buf_ptr(libc_a_path));
2324 }2322 }
23252323
2326 // msvc compiler_rt is missing some stuff, so we still build it and rely on weak linkage2324 // 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 lj->args.append(buf_ptr(compiler_rt_o_path));2326 lj->args.append(buf_ptr(compiler_rt_o_path));
2329 }2327 }
23302328
...@@ -2563,7 +2561,7 @@ static void construct_linker_job_macho(LinkJob *lj) {...@@ -2563,7 +2561,7 @@ static void construct_linker_job_macho(LinkJob *lj) {
25632561
2564 // compiler_rt on darwin is missing some stuff, so we still build it and rely on LinkOnce2562 // compiler_rt on darwin is missing some stuff, so we still build it and rely on LinkOnce
2565 if (g->out_type == OutTypeExe || is_dyn_lib) {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 lj->args.append(buf_ptr(compiler_rt_o_path));2565 lj->args.append(buf_ptr(compiler_rt_o_path));
2568 }2566 }
25692567
...@@ -2621,16 +2619,22 @@ static void construct_linker_job(LinkJob *lj) {...@@ -2621,16 +2619,22 @@ static void construct_linker_job(LinkJob *lj) {
2621 }2619 }
2622}2620}
26232621
2624void zig_link_add_compiler_rt(CodeGen *g) {2622void zig_link_add_compiler_rt(CodeGen *g, Stage2ProgressNode *progress_node) {
2625 Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj);2623 Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj, progress_node);
2626 g->link_objects.append(compiler_rt_o_path);2624 g->link_objects.append(compiler_rt_o_path);
2627}2625}
26282626
2629void codegen_link(CodeGen *g) {2627void codegen_link(CodeGen *g) {
2630 codegen_add_time_event(g, "Build Dependencies");2628 codegen_add_time_event(g, "Build Dependencies");
2631
2632 LinkJob lj = {0};2629 LinkJob lj = {0};
26332630
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 // even though we're calling LLD as a library it thinks the first2638 // even though we're calling LLD as a library it thinks the first
2635 // argument is its own exe name2639 // argument is its own exe name
2636 lj.args.append("lld");2640 lj.args.append("lld");
...@@ -2656,6 +2660,12 @@ void codegen_link(CodeGen *g) {...@@ -2656,6 +2660,12 @@ void codegen_link(CodeGen *g) {
2656 }2660 }
2657 ZigLLVM_OSType os_type = get_llvm_os_type(g->zig_target->os);2661 ZigLLVM_OSType os_type = get_llvm_os_type(g->zig_target->os);
2658 codegen_add_time_event(g, "LLVM Link");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 if (g->verbose_link) {2669 if (g->verbose_link) {
2660 fprintf(stderr, "ar rcs %s", buf_ptr(&g->output_file_path));2670 fprintf(stderr, "ar rcs %s", buf_ptr(&g->output_file_path));
2661 for (size_t i = 0; i < file_names.length; i += 1) {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,9 +587,10 @@ int main(int argc, char **argv) {
587 Buf *cache_dir_buf = buf_create_from_str(cache_dir);587 Buf *cache_dir_buf = buf_create_from_str(cache_dir);
588 full_cache_dir = os_path_resolve(&cache_dir_buf, 1);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);
590591
591 CodeGen *g = codegen_create(main_pkg_path, build_runner_path, &target, OutTypeExe,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 g->valgrind_support = valgrind_support;594 g->valgrind_support = valgrind_support;
594 g->enable_time_report = timing_info;595 g->enable_time_report = timing_info;
595 codegen_set_out_name(g, buf_create_from_str("build"));596 codegen_set_out_name(g, buf_create_from_str("build"));
...@@ -963,6 +964,10 @@ int main(int argc, char **argv) {...@@ -963,6 +964,10 @@ int main(int argc, char **argv) {
963 return EXIT_FAILURE;964 return EXIT_FAILURE;
964 }965 }
965966
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 init_all_targets();971 init_all_targets();
967972
968 ZigTarget target;973 ZigTarget target;
...@@ -1034,17 +1039,19 @@ int main(int argc, char **argv) {...@@ -1034,17 +1039,19 @@ int main(int argc, char **argv) {
1034 ZigLibCInstallation libc;1039 ZigLibCInstallation libc;
1035 if ((err = zig_libc_parse(&libc, buf_create_from_str(in_file), &target, true)))1040 if ((err = zig_libc_parse(&libc, buf_create_from_str(in_file), &target, true)))
1036 return EXIT_FAILURE;1041 return EXIT_FAILURE;
1042 stage2_progress_end(root_progress_node);
1037 return EXIT_SUCCESS;1043 return EXIT_SUCCESS;
1038 }1044 }
1039 ZigLibCInstallation libc;1045 ZigLibCInstallation libc;
1040 if ((err = zig_libc_find_native(&libc, true)))1046 if ((err = zig_libc_find_native(&libc, true)))
1041 return EXIT_FAILURE;1047 return EXIT_FAILURE;
1042 zig_libc_render(&libc, stdout);1048 zig_libc_render(&libc, stdout);
1049 stage2_progress_end(root_progress_node);
1043 return EXIT_SUCCESS;1050 return EXIT_SUCCESS;
1044 }1051 }
1045 case CmdBuiltin: {1052 case CmdBuiltin: {
1046 CodeGen *g = codegen_create(main_pkg_path, nullptr, &target,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 codegen_set_strip(g, strip);1055 codegen_set_strip(g, strip);
1049 for (size_t i = 0; i < link_libs.length; i += 1) {1056 for (size_t i = 0; i < link_libs.length; i += 1) {
1050 LinkLib *link_lib = codegen_add_link_lib(g, buf_create_from_str(link_libs.at(i)));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,6 +1067,7 @@ int main(int argc, char **argv) {
1060 fprintf(stderr, "unable to write to stdout: %s\n", strerror(ferror(stdout)));1067 fprintf(stderr, "unable to write to stdout: %s\n", strerror(ferror(stdout)));
1061 return EXIT_FAILURE;1068 return EXIT_FAILURE;
1062 }1069 }
1070 stage2_progress_end(root_progress_node);
1063 return EXIT_SUCCESS;1071 return EXIT_SUCCESS;
1064 }1072 }
1065 case CmdRun:1073 case CmdRun:
...@@ -1148,7 +1156,7 @@ int main(int argc, char **argv) {...@@ -1148,7 +1156,7 @@ int main(int argc, char **argv) {
1148 cache_dir_buf = buf_create_from_str(cache_dir);1156 cache_dir_buf = buf_create_from_str(cache_dir);
1149 }1157 }
1150 CodeGen *g = codegen_create(main_pkg_path, zig_root_source_file, &target, out_type, build_mode,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 if (llvm_argv.length >= 2) codegen_set_llvm_argv(g, llvm_argv.items + 1, llvm_argv.length - 2);1160 if (llvm_argv.length >= 2) codegen_set_llvm_argv(g, llvm_argv.items + 1, llvm_argv.length - 2);
1153 g->valgrind_support = valgrind_support;1161 g->valgrind_support = valgrind_support;
1154 g->want_pic = want_pic;1162 g->want_pic = want_pic;
...@@ -1276,6 +1284,7 @@ int main(int argc, char **argv) {...@@ -1276,6 +1284,7 @@ int main(int argc, char **argv) {
1276 if (printf("%s\n", buf_ptr(&g->output_file_path)) < 0)1284 if (printf("%s\n", buf_ptr(&g->output_file_path)) < 0)
1277 return EXIT_FAILURE;1285 return EXIT_FAILURE;
1278 }1286 }
1287 stage2_progress_end(root_progress_node);
1279 return EXIT_SUCCESS;1288 return EXIT_SUCCESS;
1280 } else {1289 } else {
1281 zig_unreachable();1290 zig_unreachable();
...@@ -1284,6 +1293,7 @@ int main(int argc, char **argv) {...@@ -1284,6 +1293,7 @@ int main(int argc, char **argv) {
1284 codegen_translate_c(g, in_file_buf, stdout, cmd == CmdTranslateCUserland);1293 codegen_translate_c(g, in_file_buf, stdout, cmd == CmdTranslateCUserland);
1285 if (timing_info)1294 if (timing_info)
1286 codegen_print_timing_report(g, stderr);1295 codegen_print_timing_report(g, stderr);
1296 stage2_progress_end(root_progress_node);
1287 return EXIT_SUCCESS;1297 return EXIT_SUCCESS;
1288 } else if (cmd == CmdTest) {1298 } else if (cmd == CmdTest) {
1289 codegen_set_emit_file_type(g, emit_file_type);1299 codegen_set_emit_file_type(g, emit_file_type);
...@@ -1338,6 +1348,7 @@ int main(int argc, char **argv) {...@@ -1338,6 +1348,7 @@ int main(int argc, char **argv) {
1338 fprintf(stderr, "\nTests failed. Use the following command to reproduce the failure:\n");1348 fprintf(stderr, "\nTests failed. Use the following command to reproduce the failure:\n");
1339 fprintf(stderr, "%s\n", buf_ptr(test_exe_path));1349 fprintf(stderr, "%s\n", buf_ptr(test_exe_path));
1340 }1350 }
1351 stage2_progress_end(root_progress_node);
1341 return (term.how == TerminationIdClean) ? term.code : -1;1352 return (term.how == TerminationIdClean) ? term.code : -1;
1342 } else {1353 } else {
1343 zig_unreachable();1354 zig_unreachable();
src/userland.cpp+29
...@@ -59,3 +59,32 @@ stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self) {...@@ -59,3 +59,32 @@ stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self) {
59 const char *msg = "stage0 called stage2_DepTokenizer_next";59 const char *msg = "stage0 called stage2_DepTokenizer_next";
60 stage2_panic(msg, strlen(msg));60 stage2_panic(msg, strlen(msg));
61}61}
62
63
64struct Stage2Progress {
65 int trash;
66};
67
68struct Stage2ProgressNode {
69 int trash;
70};
71
72Stage2Progress *stage2_progress_create(void) {
73 return nullptr;
74}
75
76void stage2_progress_destroy(Stage2Progress *progress) {}
77
78Stage2ProgressNode *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}
83Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node,
84 const char *name_ptr, size_t name_len, size_t estimated_total_items)
85{
86 return nullptr;
87}
88void stage2_progress_end(Stage2ProgressNode *node) {}
89void stage2_progress_complete_one(Stage2ProgressNode *node) {}
90void 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,4 +156,25 @@ ZIG_EXTERN_C void stage2_DepTokenizer_deinit(stage2_DepTokenizer *self);
156// ABI warning156// ABI warning
157ZIG_EXTERN_C stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self);157ZIG_EXTERN_C stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self);
158158
159// ABI warning
160struct Stage2Progress;
161// ABI warning
162struct Stage2ProgressNode;
163// ABI warning
164ZIG_EXTERN_C Stage2Progress *stage2_progress_create(void);
165// ABI warning
166ZIG_EXTERN_C void stage2_progress_disable_tty(Stage2Progress *progress);
167// ABI warning
168ZIG_EXTERN_C void stage2_progress_destroy(Stage2Progress *progress);
169// ABI warning
170ZIG_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
173ZIG_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
176ZIG_EXTERN_C void stage2_progress_end(Stage2ProgressNode *node);
177// ABI warning
178ZIG_EXTERN_C void stage2_progress_complete_one(Stage2ProgressNode *node);
179
159#endif180#endif
test/cli.zig+2-2
...@@ -87,7 +87,7 @@ fn exec(cwd: []const u8, argv: []const []const u8) !ChildProcess.ExecResult {...@@ -87,7 +87,7 @@ fn exec(cwd: []const u8, argv: []const []const u8) !ChildProcess.ExecResult {
87fn testZigInitLib(zig_exe: []const u8, dir_path: []const u8) !void {87fn testZigInitLib(zig_exe: []const u8, dir_path: []const u8) !void {
88 _ = try exec(dir_path, [_][]const u8{ zig_exe, "init-lib" });88 _ = try exec(dir_path, [_][]const u8{ zig_exe, "init-lib" });
89 const test_result = try exec(dir_path, [_][]const u8{ zig_exe, "build", "test" });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}
9292
93fn testZigInitExe(zig_exe: []const u8, dir_path: []const u8) !void {93fn 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,6 +136,6 @@ fn testMissingOutputPath(zig_exe: []const u8, dir_path: []const u8) !void {
136 const output_path = try fs.path.join(a, [_][]const u8{ "does", "not", "exist" });136 const output_path = try fs.path.join(a, [_][]const u8{ "does", "not", "exist" });
137 const source_path = try fs.path.join(a, [_][]const u8{ "src", "main.zig" });137 const source_path = try fs.path.join(a, [_][]const u8{ "src", "main.zig" });
138 _ = try exec(dir_path, [_][]const u8{138 _ = try exec(dir_path, [_][]const u8{
139 zig_exe, "build-exe", source_path, "--output-dir", output_path139 zig_exe, "build-exe", source_path, "--output-dir", output_path,
140 });140 });
141}141}