can specify a wasm target in build

This commit is contained in:
Mitchell Hashimoto
2022-12-31 08:53:11 -08:00
parent 1093cf5254
commit ce490e21ea
11 changed files with 69 additions and 3 deletions

View File

@ -19,6 +19,7 @@ const utf8proc = @import("pkg/utf8proc/build.zig");
const zlib = @import("pkg/zlib/build.zig");
const tracylib = @import("pkg/tracy/build.zig");
const system_sdk = @import("vendor/mach/libs/glfw/system_sdk.zig");
const WasmTarget = @import("src/os/wasm/target.zig").Target;
// Build options, see the build options help for more info.
var tracy: bool = false;
@ -134,6 +135,11 @@ pub fn build(b: *std.build.Builder) !void {
const wasm_shared: bool = true;
exe_options.addOption(bool, "wasm_shared", wasm_shared);
// We want to support alternate wasm targets in the future (i.e.
// server side) so we have this now although its hardcoded.
const wasm_specific_target: WasmTarget = .browser;
exe_options.addOption(WasmTarget, "wasm_target", wasm_specific_target);
const wasm = b.addSharedLibrary(
"ghostty-wasm",
"src/main_wasm.zig",

View File

@ -77,6 +77,7 @@ fetch(url.href).then(response =>
const config_str = makeStr("font-family = monospace");
config_load_string(config, config_str.ptr, config_str.len);
config_finalize(config);
free(config_str.ptr);
// Create our atlas
// const atlas = atlas_new(512, 0 /* greyscale */);

View File

@ -266,3 +266,32 @@ pub const Message = union(enum) {
font_size: ?font.face.DesiredSize = null,
};
};
// Wasm API.
pub const Wasm = if (!builtin.target.isWasm()) struct {} else struct {
const wasm = @import("os/wasm.zig");
const alloc = wasm.alloc;
// export fn app_new(config: *Config) ?*App {
// return app_new_(config) catch |err| {
// log.err("error initializing app err={}", .{err});
// return null;
// };
// }
//
// fn app_new_(config: *Config) !*App {
// const app = try App.create(alloc, config);
// errdefer app.destroy();
//
// const result = try alloc.create(App);
// result.* = app;
// return result;
// }
//
// export fn app_free(ptr: ?*App) void {
// if (ptr) |v| {
// v.destroy();
// alloc.destroy(v);
// }
// }
};

View File

@ -3,6 +3,7 @@
const DevMode = @This();
const std = @import("std");
const builtin = @import("builtin");
const imgui = @import("imgui");
const Allocator = std.mem.Allocator;
const assert = std.debug.assert;
@ -14,7 +15,7 @@ const Config = @import("config.zig").Config;
/// If this is false, the rest of the terminal will be compiled without
/// dev mode support at all.
pub const enabled = true;
pub const enabled = !builtin.target.isWasm();
/// The global DevMode instance that can be used app-wide. Assume all functions
/// are NOT thread-safe unless otherwise noted.

View File

@ -12,13 +12,16 @@ const builtin = @import("builtin");
pub usingnamespace @import("apprt/structs.zig");
pub const glfw = @import("apprt/glfw.zig");
pub const browser = @import("apprt/browser.zig");
pub const Window = @import("apprt/Window.zig");
/// The implementation to use for the app runtime. This is comptime chosen
/// so that every build has exactly one application runtime implementation.
/// Note: it is very rare to use Runtime directly; most usage will use
/// Window or something.
pub const runtime = switch (builtin.os.tag) {
pub const runtime = if (builtin.target.isWasm())
browser
else switch (builtin.os.tag) {
else => glfw,
};

2
src/apprt/browser.zig Normal file
View File

@ -0,0 +1,2 @@
pub const App = struct {};
pub const Window = struct {};

View File

@ -8,6 +8,7 @@ pub usingnamespace @import("os/wasm/log.zig");
pub usingnamespace @import("font/main.zig");
pub usingnamespace @import("terminal/main.zig");
pub usingnamespace @import("config.zig").Wasm;
pub usingnamespace @import("App.zig").Wasm;
// Set our log level. We try to get as much logging as possible but in
// ReleaseSmall mode where we're optimizing for space, we elevate the

View File

@ -2,6 +2,7 @@
const std = @import("std");
const builtin = @import("builtin");
const options = @import("build_options");
const Target = @import("wasm/target.zig").Target;
comptime {
if (!builtin.target.isWasm()) {
@ -13,6 +14,16 @@ comptime {
/// in JS will be backed by a SharedArrayBuffer and some behaviors change.
pub const shared_mem = options.wasm_shared;
/// Our specific target platform.
pub const target: ?Target = if (!builtin.target.isWasm()) null else target: {
const result = @intToEnum(Target, @enumToInt(options.wasm_target));
// This maybe isn't necessary but I don't know if enums without a specific
// tag type and value are guaranteed to be the same between build.zig
// compilation and our own source compilation so I have this just in case.
std.debug.assert(std.mem.eql(u8, @tagName(result), @tagName(options.wasm_target)));
break :target result;
};
/// The allocator to use in wasm environments.
///
/// The return values of this should NOT be sent to the host environment

6
src/os/wasm/target.zig Normal file
View File

@ -0,0 +1,6 @@
/// The wasm target platform. This is used to toggle certain features
/// on and off since the standard triple target is often not specific
/// enough (i.e. we can't tell wasm32-freestanding is for browser or not).
pub const Target = enum {
browser,
};

View File

@ -14,13 +14,17 @@ pub usingnamespace @import("renderer/message.zig");
pub usingnamespace @import("renderer/size.zig");
pub const Metal = @import("renderer/Metal.zig");
pub const OpenGL = @import("renderer/OpenGL.zig");
pub const WebGL = @import("renderer/WebGL.zig");
pub const Options = @import("renderer/Options.zig");
pub const Thread = @import("renderer/Thread.zig");
pub const State = @import("renderer/State.zig");
/// The implementation to use for the renderer. This is comptime chosen
/// so that every build has exactly one renderer implementation.
pub const Renderer = switch (builtin.os.tag) {
const wasm = @import("os/wasm.zig");
pub const Renderer = if (wasm.target) |target| switch (target) {
.browser => WebGL,
} else switch (builtin.os.tag) {
.macos => Metal,
else => OpenGL,
};

2
src/renderer/WebGL.zig Normal file
View File

@ -0,0 +1,2 @@
//! Renderer implementation for WebGL in the browser.
pub const WebGL = @This();