fixes
This commit is contained in:
@@ -270,6 +270,74 @@ pub fn link(allocator: std.mem.Allocator, io: std.Io, output_obj: []const u8, ex
|
||||
if (result.exited != 0) return error.LinkError;
|
||||
}
|
||||
|
||||
/// After emcc produces HTML output, inject cache-busting hashes into the
|
||||
/// generated <script> tag and add Module.locateFile for .wasm/.data files.
|
||||
pub fn postProcessWasmHtml(allocator: std.mem.Allocator, io: std.Io, html_path: []const u8) void {
|
||||
const base = if (std.mem.endsWith(u8, html_path, ".html"))
|
||||
html_path[0 .. html_path.len - 5]
|
||||
else
|
||||
return;
|
||||
|
||||
// Hash build output contents (.js + .wasm + optional .data)
|
||||
var hash: u64 = 0;
|
||||
const exts = [_][]const u8{ ".js", ".wasm", ".data" };
|
||||
for (exts) |ext| {
|
||||
const path = std.fmt.allocPrint(allocator, "{s}{s}", .{ base, ext }) catch continue;
|
||||
if (std.Io.Dir.readFileAlloc(.cwd(), io, path, allocator, .limited(64 * 1024 * 1024))) |data| {
|
||||
hash = std.hash.Wyhash.hash(hash, data);
|
||||
} else |_| {}
|
||||
}
|
||||
|
||||
const hash_hex = std.fmt.allocPrint(allocator, "{x:0>8}", .{@as(u32, @truncate(hash))}) catch return;
|
||||
|
||||
// Read the final HTML produced by emcc
|
||||
const html = std.Io.Dir.readFileAlloc(.cwd(), io, html_path, allocator, .limited(10 * 1024 * 1024)) catch return;
|
||||
|
||||
var out = std.ArrayList(u8).empty;
|
||||
var pos: usize = 0;
|
||||
var injected_locateFile = false;
|
||||
|
||||
// Find emcc's generated script tag: <script ...src="*.js"></script>
|
||||
// Inject ?v=HASH into the src and prepend a Module.locateFile script.
|
||||
while (std.mem.indexOfPos(u8, html, pos, "src=\"")) |src_start| {
|
||||
const val_start = src_start + 5; // past src="
|
||||
const val_end = std.mem.indexOfPos(u8, html, val_start, "\"") orelse break;
|
||||
const src_val = html[val_start..val_end];
|
||||
|
||||
if (!std.mem.endsWith(u8, src_val, ".js")) {
|
||||
// Not a .js src — skip past this attribute and keep searching
|
||||
pos = val_end + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find the opening < of this tag to inject locateFile before it
|
||||
const tag_start = if (std.mem.lastIndexOf(u8, html[pos..src_start], "<")) |off| pos + off else src_start;
|
||||
|
||||
// Copy everything up to the tag start
|
||||
out.appendSlice(allocator, html[pos..tag_start]) catch return;
|
||||
|
||||
// Inject Module.locateFile once, before the first .js script tag
|
||||
if (!injected_locateFile) {
|
||||
out.appendSlice(allocator, "<script>Module.locateFile=function(p){return p+'?v=") catch return;
|
||||
out.appendSlice(allocator, hash_hex) catch return;
|
||||
out.appendSlice(allocator, "'}</script>\n") catch return;
|
||||
injected_locateFile = true;
|
||||
}
|
||||
|
||||
// Copy tag up to the closing quote of src, inserting ?v=HASH
|
||||
out.appendSlice(allocator, html[tag_start..val_end]) catch return;
|
||||
out.appendSlice(allocator, "?v=") catch return;
|
||||
out.appendSlice(allocator, hash_hex) catch return;
|
||||
|
||||
pos = val_end;
|
||||
}
|
||||
// Copy remaining HTML
|
||||
out.appendSlice(allocator, html[pos..]) catch return;
|
||||
|
||||
const final = out.toOwnedSlice(allocator) catch return;
|
||||
std.Io.Dir.writeFile(.cwd(), io, .{ .sub_path = html_path, .data = final }) catch {};
|
||||
}
|
||||
|
||||
/// Common library paths for the host OS, computed at comptime.
|
||||
pub const host_lib_paths = blk: {
|
||||
const builtin = @import("builtin");
|
||||
|
||||
Reference in New Issue
Block a user