Skip to content

Commit dffc8c4

Browse files
authored
Merge pull request ziglang#21115 from Snektron/build-system-asm
compilation and build system fixes
2 parents 7071d1b + 8099939 commit dffc8c4

31 files changed

+337
-319
lines changed

lib/compiler/objcopy.zig

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,10 @@ fn cmdObjCopy(
201201
if (seen_update) fatal("zig objcopy only supports 1 update for now", .{});
202202
seen_update = true;
203203

204-
try server.serveEmitBinPath(output, .{
205-
.flags = .{ .cache_hit = false },
206-
});
204+
// The build system already knows what the output is at this point, we
205+
// only need to communicate that the process has finished.
206+
// Use the empty error bundle to indicate that the update is done.
207+
try server.serveErrorBundle(std.zig.ErrorBundle.empty);
207208
},
208209
else => fatal("unsupported message: {s}", .{@tagName(hdr.tag)}),
209210
}

lib/std/Build.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2373,7 +2373,7 @@ pub const LazyPath = union(enum) {
23732373
// basis for not traversing up too many directories.
23742374

23752375
var file_path: Cache.Path = .{
2376-
.root_dir = gen.file.step.owner.build_root,
2376+
.root_dir = Cache.Directory.cwd(),
23772377
.sub_path = gen.file.path orelse {
23782378
std.debug.lockStdErr();
23792379
const stderr = std.io.getStdErr();

lib/std/Build/Cache.zig

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -896,8 +896,8 @@ pub const Manifest = struct {
896896
}
897897
}
898898

899-
/// Returns a hex encoded hash of the inputs.
900-
pub fn final(self: *Manifest) HexDigest {
899+
/// Returns a binary hash of the inputs.
900+
pub fn finalBin(self: *Manifest) BinDigest {
901901
assert(self.manifest_file != null);
902902

903903
// We don't close the manifest file yet, because we want to
@@ -908,7 +908,12 @@ pub const Manifest = struct {
908908

909909
var bin_digest: BinDigest = undefined;
910910
self.hash.hasher.final(&bin_digest);
911+
return bin_digest;
912+
}
911913

914+
/// Returns a hex encoded hash of the inputs.
915+
pub fn final(self: *Manifest) HexDigest {
916+
const bin_digest = self.finalBin();
912917
return binToHex(bin_digest);
913918
}
914919

lib/std/Build/Fuzz.zig

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,15 @@ pub fn start(
100100
}
101101

102102
fn rebuildTestsWorkerRun(run: *Step.Run, ttyconf: std.io.tty.Config, parent_prog_node: std.Progress.Node) void {
103+
rebuildTestsWorkerRunFallible(run, ttyconf, parent_prog_node) catch |err| {
104+
const compile = run.producer.?;
105+
log.err("step '{s}': failed to rebuild in fuzz mode: {s}", .{
106+
compile.step.name, @errorName(err),
107+
});
108+
};
109+
}
110+
111+
fn rebuildTestsWorkerRunFallible(run: *Step.Run, ttyconf: std.io.tty.Config, parent_prog_node: std.Progress.Node) !void {
103112
const gpa = run.step.owner.allocator;
104113
const stderr = std.io.getStdErr();
105114

@@ -121,14 +130,9 @@ fn rebuildTestsWorkerRun(run: *Step.Run, ttyconf: std.io.tty.Config, parent_prog
121130

122131
const rebuilt_bin_path = result catch |err| switch (err) {
123132
error.MakeFailed => return,
124-
else => {
125-
log.err("step '{s}': failed to rebuild in fuzz mode: {s}", .{
126-
compile.step.name, @errorName(err),
127-
});
128-
return;
129-
},
133+
else => |other| return other,
130134
};
131-
run.rebuilt_executable = rebuilt_bin_path;
135+
run.rebuilt_executable = try rebuilt_bin_path.join(gpa, compile.out_filename);
132136
}
133137

134138
fn fuzzWorkerRun(

lib/std/Build/Fuzz/WebServer.zig

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ const Coverage = std.debug.Coverage;
88
const abi = std.Build.Fuzz.abi;
99
const log = std.log;
1010
const assert = std.debug.assert;
11+
const Cache = std.Build.Cache;
12+
const Path = Cache.Path;
1113

1214
const WebServer = @This();
1315

@@ -31,6 +33,10 @@ coverage_mutex: std.Thread.Mutex,
3133
/// Signaled when `coverage_files` changes.
3234
coverage_condition: std.Thread.Condition,
3335

36+
const fuzzer_bin_name = "fuzzer";
37+
const fuzzer_arch_os_abi = "wasm32-freestanding";
38+
const fuzzer_cpu_features = "baseline+atomics+bulk_memory+multivalue+mutable_globals+nontrapping_fptoint+reference_types+sign_ext";
39+
3440
const CoverageMap = struct {
3541
mapped_memory: []align(std.mem.page_size) const u8,
3642
coverage: Coverage,
@@ -181,9 +187,18 @@ fn serveWasm(
181187

182188
// Do the compilation every request, so that the user can edit the files
183189
// and see the changes without restarting the server.
184-
const wasm_binary_path = try buildWasmBinary(ws, arena, optimize_mode);
190+
const wasm_base_path = try buildWasmBinary(ws, arena, optimize_mode);
191+
const bin_name = try std.zig.binNameAlloc(arena, .{
192+
.root_name = fuzzer_bin_name,
193+
.target = std.zig.system.resolveTargetQuery(std.Build.parseTargetQuery(.{
194+
.arch_os_abi = fuzzer_arch_os_abi,
195+
.cpu_features = fuzzer_cpu_features,
196+
}) catch unreachable) catch unreachable,
197+
.output_mode = .Exe,
198+
});
185199
// std.http.Server does not have a sendfile API yet.
186-
const file_contents = try std.fs.cwd().readFileAlloc(gpa, wasm_binary_path, 10 * 1024 * 1024);
200+
const bin_path = try wasm_base_path.join(arena, bin_name);
201+
const file_contents = try bin_path.root_dir.handle.readFileAlloc(gpa, bin_path.sub_path, 10 * 1024 * 1024);
187202
defer gpa.free(file_contents);
188203
try request.respond(file_contents, .{
189204
.extra_headers = &.{
@@ -197,7 +212,7 @@ fn buildWasmBinary(
197212
ws: *WebServer,
198213
arena: Allocator,
199214
optimize_mode: std.builtin.OptimizeMode,
200-
) ![]const u8 {
215+
) !Path {
201216
const gpa = ws.gpa;
202217

203218
const main_src_path: Build.Cache.Path = .{
@@ -219,11 +234,11 @@ fn buildWasmBinary(
219234
ws.zig_exe_path, "build-exe", //
220235
"-fno-entry", //
221236
"-O", @tagName(optimize_mode), //
222-
"-target", "wasm32-freestanding", //
223-
"-mcpu", "baseline+atomics+bulk_memory+multivalue+mutable_globals+nontrapping_fptoint+reference_types+sign_ext", //
237+
"-target", fuzzer_arch_os_abi, //
238+
"-mcpu", fuzzer_cpu_features, //
224239
"--cache-dir", ws.global_cache_directory.path orelse ".", //
225240
"--global-cache-dir", ws.global_cache_directory.path orelse ".", //
226-
"--name", "fuzzer", //
241+
"--name", fuzzer_bin_name, //
227242
"-rdynamic", //
228243
"-fsingle-threaded", //
229244
"--dep", "Walk", //
@@ -251,7 +266,7 @@ fn buildWasmBinary(
251266
try sendMessage(child.stdin.?, .exit);
252267

253268
const Header = std.zig.Server.Message.Header;
254-
var result: ?[]const u8 = null;
269+
var result: ?Path = null;
255270
var result_error_bundle = std.zig.ErrorBundle.empty;
256271

257272
const stdout = poller.fifo(.stdout);
@@ -288,13 +303,17 @@ fn buildWasmBinary(
288303
.extra = extra_array,
289304
};
290305
},
291-
.emit_bin_path => {
292-
const EbpHdr = std.zig.Server.Message.EmitBinPath;
306+
.emit_digest => {
307+
const EbpHdr = std.zig.Server.Message.EmitDigest;
293308
const ebp_hdr = @as(*align(1) const EbpHdr, @ptrCast(body));
294309
if (!ebp_hdr.flags.cache_hit) {
295310
log.info("source changes detected; rebuilt wasm component", .{});
296311
}
297-
result = try arena.dupe(u8, body[@sizeOf(EbpHdr)..]);
312+
const digest = body[@sizeOf(EbpHdr)..][0..Cache.bin_digest_len];
313+
result = Path{
314+
.root_dir = ws.global_cache_directory,
315+
.sub_path = try arena.dupe(u8, "o" ++ std.fs.path.sep_str ++ Cache.binToHex(digest.*)),
316+
};
298317
},
299318
else => {}, // ignore other messages
300319
}
@@ -568,10 +587,7 @@ fn prepareTables(
568587
};
569588
errdefer gop.value_ptr.coverage.deinit(gpa);
570589

571-
const rebuilt_exe_path: Build.Cache.Path = .{
572-
.root_dir = Build.Cache.Directory.cwd(),
573-
.sub_path = run_step.rebuilt_executable.?,
574-
};
590+
const rebuilt_exe_path = run_step.rebuilt_executable.?;
575591
var debug_info = std.debug.Info.load(gpa, rebuilt_exe_path, &gop.value_ptr.coverage) catch |err| {
576592
log.err("step '{s}': failed to load debug information for '{}': {s}", .{
577593
run_step.step.name, rebuilt_exe_path, @errorName(err),

lib/std/Build/Step.zig

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,8 @@ const Build = std.Build;
317317
const Allocator = std.mem.Allocator;
318318
const assert = std.debug.assert;
319319
const builtin = @import("builtin");
320+
const Cache = Build.Cache;
321+
const Path = Cache.Path;
320322

321323
pub fn evalChildProcess(s: *Step, argv: []const []const u8) ![]u8 {
322324
const run_result = try captureChildProcess(s, std.Progress.Node.none, argv);
@@ -373,7 +375,7 @@ pub fn evalZigProcess(
373375
argv: []const []const u8,
374376
prog_node: std.Progress.Node,
375377
watch: bool,
376-
) !?[]const u8 {
378+
) !?Path {
377379
if (s.getZigProcess()) |zp| update: {
378380
assert(watch);
379381
if (std.Progress.have_ipc) if (zp.progress_ipc_fd) |fd| prog_node.setIpcFd(fd);
@@ -477,7 +479,7 @@ pub fn evalZigProcess(
477479
return result;
478480
}
479481

480-
fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool) !?[]const u8 {
482+
fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool) !?Path {
481483
const b = s.owner;
482484
const arena = b.allocator;
483485

@@ -487,7 +489,7 @@ fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool) !?[]const u8 {
487489
if (!watch) try sendMessage(zp.child.stdin.?, .exit);
488490

489491
const Header = std.zig.Server.Message.Header;
490-
var result: ?[]const u8 = null;
492+
var result: ?Path = null;
491493

492494
const stdout = zp.poller.fifo(.stdout);
493495

@@ -531,16 +533,15 @@ fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool) !?[]const u8 {
531533
break;
532534
}
533535
},
534-
.emit_bin_path => {
535-
const EbpHdr = std.zig.Server.Message.EmitBinPath;
536+
.emit_digest => {
537+
const EbpHdr = std.zig.Server.Message.EmitDigest;
536538
const ebp_hdr = @as(*align(1) const EbpHdr, @ptrCast(body));
537539
s.result_cached = ebp_hdr.flags.cache_hit;
538-
result = try arena.dupe(u8, body[@sizeOf(EbpHdr)..]);
539-
if (watch) {
540-
// This message indicates the end of the update.
541-
stdout.discard(body.len);
542-
break;
543-
}
540+
const digest = body[@sizeOf(EbpHdr)..][0..Cache.bin_digest_len];
541+
result = Path{
542+
.root_dir = b.cache_root,
543+
.sub_path = try arena.dupe(u8, "o" ++ std.fs.path.sep_str ++ Cache.binToHex(digest.*)),
544+
};
544545
},
545546
.file_system_inputs => {
546547
s.clearWatchInputs();

lib/std/Build/Step/Compile.zig

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const Module = std.Build.Module;
1717
const InstallDir = std.Build.InstallDir;
1818
const GeneratedFile = std.Build.GeneratedFile;
1919
const Compile = @This();
20+
const Path = std.Build.Cache.Path;
2021

2122
pub const base_id: Step.Id = .compile;
2223

@@ -1765,7 +1766,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
17651766

17661767
const zig_args = try getZigArgs(compile, false);
17671768

1768-
const maybe_output_bin_path = step.evalZigProcess(
1769+
const maybe_output_dir = step.evalZigProcess(
17691770
zig_args,
17701771
options.progress_node,
17711772
(b.graph.incremental == true) and options.watch,
@@ -1779,53 +1780,51 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
17791780
};
17801781

17811782
// Update generated files
1782-
if (maybe_output_bin_path) |output_bin_path| {
1783-
const output_dir = fs.path.dirname(output_bin_path).?;
1784-
1783+
if (maybe_output_dir) |output_dir| {
17851784
if (compile.emit_directory) |lp| {
1786-
lp.path = output_dir;
1785+
lp.path = b.fmt("{}", .{output_dir});
17871786
}
17881787

17891788
// -femit-bin[=path] (default) Output machine code
17901789
if (compile.generated_bin) |bin| {
1791-
bin.path = b.pathJoin(&.{ output_dir, compile.out_filename });
1790+
bin.path = output_dir.joinString(b.allocator, compile.out_filename) catch @panic("OOM");
17921791
}
17931792

1794-
const sep = std.fs.path.sep;
1793+
const sep = std.fs.path.sep_str;
17951794

17961795
// output PDB if someone requested it
17971796
if (compile.generated_pdb) |pdb| {
1798-
pdb.path = b.fmt("{s}{c}{s}.pdb", .{ output_dir, sep, compile.name });
1797+
pdb.path = b.fmt("{}" ++ sep ++ "{s}.pdb", .{ output_dir, compile.name });
17991798
}
18001799

18011800
// -femit-implib[=path] (default) Produce an import .lib when building a Windows DLL
18021801
if (compile.generated_implib) |implib| {
1803-
implib.path = b.fmt("{s}{c}{s}.lib", .{ output_dir, sep, compile.name });
1802+
implib.path = b.fmt("{}" ++ sep ++ "{s}.lib", .{ output_dir, compile.name });
18041803
}
18051804

18061805
// -femit-h[=path] Generate a C header file (.h)
18071806
if (compile.generated_h) |lp| {
1808-
lp.path = b.fmt("{s}{c}{s}.h", .{ output_dir, sep, compile.name });
1807+
lp.path = b.fmt("{}" ++ sep ++ "{s}.h", .{ output_dir, compile.name });
18091808
}
18101809

18111810
// -femit-docs[=path] Create a docs/ dir with html documentation
18121811
if (compile.generated_docs) |generated_docs| {
1813-
generated_docs.path = b.pathJoin(&.{ output_dir, "docs" });
1812+
generated_docs.path = output_dir.joinString(b.allocator, "docs") catch @panic("OOM");
18141813
}
18151814

18161815
// -femit-asm[=path] Output .s (assembly code)
18171816
if (compile.generated_asm) |lp| {
1818-
lp.path = b.fmt("{s}{c}{s}.s", .{ output_dir, sep, compile.name });
1817+
lp.path = b.fmt("{}" ++ sep ++ "{s}.s", .{ output_dir, compile.name });
18191818
}
18201819

18211820
// -femit-llvm-ir[=path] Produce a .ll file with optimized LLVM IR (requires LLVM extensions)
18221821
if (compile.generated_llvm_ir) |lp| {
1823-
lp.path = b.fmt("{s}{c}{s}.ll", .{ output_dir, sep, compile.name });
1822+
lp.path = b.fmt("{}" ++ sep ++ "{s}.ll", .{ output_dir, compile.name });
18241823
}
18251824

18261825
// -femit-llvm-bc[=path] Produce an optimized LLVM module as a .bc file (requires LLVM extensions)
18271826
if (compile.generated_llvm_bc) |lp| {
1828-
lp.path = b.fmt("{s}{c}{s}.bc", .{ output_dir, sep, compile.name });
1827+
lp.path = b.fmt("{}" ++ sep ++ "{s}.bc", .{ output_dir, compile.name });
18291828
}
18301829
}
18311830

@@ -1841,7 +1840,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
18411840
}
18421841
}
18431842

1844-
pub fn rebuildInFuzzMode(c: *Compile, progress_node: std.Progress.Node) ![]const u8 {
1843+
pub fn rebuildInFuzzMode(c: *Compile, progress_node: std.Progress.Node) !Path {
18451844
const gpa = c.step.owner.allocator;
18461845

18471846
c.step.result_error_msgs.clearRetainingCapacity();

0 commit comments

Comments
 (0)