This commit is contained in:
agra
2026-03-02 09:49:43 +02:00
parent f763765ea2
commit ba9c4d69ce
6 changed files with 460 additions and 103 deletions

View File

@@ -19,6 +19,8 @@ pub const TargetConfig = struct {
linker: ?[]const u8 = null,
/// Sysroot for cross-compilation (passed as --sysroot to linker).
sysroot: ?[]const u8 = null,
/// Extra flags passed through to the linker (e.g. Emscripten -s flags).
extra_link_flags: []const []const u8 = &.{},
pub const OptLevel = enum {
none,
@@ -51,6 +53,16 @@ pub const TargetConfig = struct {
return self.tripleContains("windows") or self.tripleContains("win32");
}
/// Check if target triple indicates WebAssembly (wasm32 or wasm64).
pub fn isWasm(self: TargetConfig) bool {
return self.tripleHasPrefix("wasm32", "wasm64");
}
/// Check if target triple indicates Emscripten (contains "emscripten").
pub fn isEmscripten(self: TargetConfig) bool {
return self.tripleContains("emscripten");
}
fn tripleHasPrefix(self: TargetConfig, prefix1: []const u8, prefix2: []const u8) bool {
if (self.triple) |t| {
const span = std.mem.span(t);
@@ -139,7 +151,28 @@ pub fn runJITFromObject(obj_buf: c.LLVMMemoryBufferRef) !u8 {
pub fn link(allocator: std.mem.Allocator, io: std.Io, output_obj: []const u8, extra_objects: []const []const u8, output_bin: []const u8, libraries: []const []const u8, target_config: TargetConfig) !void {
var argv = std.ArrayList([]const u8).empty;
if (target_config.isWindows()) {
if (target_config.isEmscripten()) {
// Emscripten: use emcc as the linker/driver
const linker = target_config.linker orelse "emcc";
try argv.appendSlice(allocator, &.{ linker, output_obj, "-o", output_bin });
for (extra_objects) |eo| try argv.append(allocator, eo);
if (target_config.sysroot) |sr| {
try argv.append(allocator, try std.fmt.allocPrint(allocator, "--sysroot={s}", .{sr}));
}
for (target_config.lib_paths) |lp| {
try argv.append(allocator, try std.fmt.allocPrint(allocator, "-L{s}", .{lp}));
}
for (libraries) |lib| {
try argv.append(allocator, try std.fmt.allocPrint(allocator, "-l{s}", .{lib}));
}
// Extra linker flags (e.g. -sUSE_SDL=2, -sUSE_WEBGL2=1, --preload-file)
for (target_config.extra_link_flags) |flag| {
try argv.append(allocator, flag);
}
} else if (target_config.isWindows()) {
// Windows: MSVC-style linker flags
const linker = target_config.linker orelse "link.exe";
try argv.appendSlice(allocator, &.{ linker, output_obj });
@@ -176,6 +209,11 @@ pub fn link(allocator: std.mem.Allocator, io: std.Io, output_obj: []const u8, ex
for (libraries) |lib| {
try argv.append(allocator, try std.fmt.allocPrint(allocator, "-l{s}", .{lib}));
}
// Extra linker flags
for (target_config.extra_link_flags) |flag| {
try argv.append(allocator, flag);
}
}
const argv_slice = try argv.toOwnedSlice(allocator);