lots of broken stuff

This commit is contained in:
Mitchell Hashimoto
2023-02-14 13:56:43 -08:00
parent 4dd4bbf7e0
commit 8b80e65928
6 changed files with 132 additions and 72 deletions

View File

@ -140,6 +140,8 @@ pub fn build(b: *std.build.Builder) !void {
static_lib.setTarget(target); static_lib.setTarget(target);
static_lib.install(); static_lib.install();
static_lib.linkLibC(); static_lib.linkLibC();
static_lib.addOptions("build_options", exe_options);
try addDeps(b, static_lib, true);
b.default_step.dependOn(&static_lib.step); b.default_step.dependOn(&static_lib.step);
} }
@ -150,8 +152,9 @@ pub fn build(b: *std.build.Builder) !void {
const lib = b.addStaticLibrary("ghostty", "src/main_c.zig"); const lib = b.addStaticLibrary("ghostty", "src/main_c.zig");
lib.setBuildMode(mode); lib.setBuildMode(mode);
lib.setTarget(try std.zig.CrossTarget.parse(.{ .arch_os_abi = "aarch64-macos" })); lib.setTarget(try std.zig.CrossTarget.parse(.{ .arch_os_abi = "aarch64-macos" }));
lib.install();
lib.linkLibC(); lib.linkLibC();
lib.addOptions("build_options", exe_options);
try addDeps(b, lib, true);
b.default_step.dependOn(&lib.step); b.default_step.dependOn(&lib.step);
break :lib lib; break :lib lib;
}; };
@ -160,8 +163,9 @@ pub fn build(b: *std.build.Builder) !void {
const lib = b.addStaticLibrary("ghostty", "src/main_c.zig"); const lib = b.addStaticLibrary("ghostty", "src/main_c.zig");
lib.setBuildMode(mode); lib.setBuildMode(mode);
lib.setTarget(try std.zig.CrossTarget.parse(.{ .arch_os_abi = "x86_64-macos" })); lib.setTarget(try std.zig.CrossTarget.parse(.{ .arch_os_abi = "x86_64-macos" }));
lib.install();
lib.linkLibC(); lib.linkLibC();
lib.addOptions("build_options", exe_options);
try addDeps(b, lib, true);
b.default_step.dependOn(&lib.step); b.default_step.dependOn(&lib.step);
break :lib lib; break :lib lib;
}; };
@ -368,12 +372,18 @@ fn addDeps(
return; return;
} }
// If we're building a lib we have some different deps
const lib = step.kind == .lib;
// We always require the system SDK so that our system headers are available.
// This makes things like `os/log.h` available for cross-compiling.
system_sdk.include(b, step, .{});
// We always need the Zig packages // We always need the Zig packages
if (enable_fontconfig) step.addModule("fontconfig", fontconfig.module(b)); if (enable_fontconfig) step.addModule("fontconfig", fontconfig.module(b));
step.addModule("freetype", freetype.module(b)); step.addModule("freetype", freetype.module(b));
step.addModule("harfbuzz", harfbuzz.module(b)); step.addModule("harfbuzz", harfbuzz.module(b));
step.addModule("imgui", imgui.module(b)); step.addModule("imgui", imgui.module(b));
step.addModule("glfw", glfw.module(b));
step.addModule("xev", libxev.module(b)); step.addModule("xev", libxev.module(b));
step.addModule("pixman", pixman.module(b)); step.addModule("pixman", pixman.module(b));
step.addModule("stb_image_resize", stb_image_resize.module(b)); step.addModule("stb_image_resize", stb_image_resize.module(b));
@ -386,10 +396,6 @@ fn addDeps(
_ = try macos.link(b, step, .{}); _ = try macos.link(b, step, .{});
} }
// We always statically compile glad
step.addIncludePath("vendor/glad/include/");
step.addCSourceFile("vendor/glad/src/gl.c", &.{});
// Tracy // Tracy
step.addModule("tracy", tracylib.module(b)); step.addModule("tracy", tracylib.module(b));
if (tracy) { if (tracy) {
@ -403,13 +409,6 @@ fn addDeps(
// utf8proc // utf8proc
_ = try utf8proc.link(b, step); _ = try utf8proc.link(b, step);
// Glfw
const glfw_opts: glfw.Options = .{
.metal = step.target.isDarwin(),
.opengl = false,
};
try glfw.link(b, step, glfw_opts);
// Imgui, we have to do this later since we need some information // Imgui, we have to do this later since we need some information
const imgui_backends = if (step.target.isDarwin()) const imgui_backends = if (step.target.isDarwin())
&[_][]const u8{ "glfw", "opengl3", "metal" } &[_][]const u8{ "glfw", "opengl3", "metal" }
@ -505,9 +504,24 @@ fn addDeps(
imgui_opts.freetype.include = &freetype.include_paths; imgui_opts.freetype.include = &freetype.include_paths;
} }
// Imgui if (!lib) {
const imgui_step = try imgui.link(b, step, imgui_opts); step.addModule("glfw", glfw.module(b));
try glfw.link(b, imgui_step, glfw_opts);
// We always statically compile glad
step.addIncludePath("vendor/glad/include/");
step.addCSourceFile("vendor/glad/src/gl.c", &.{});
// Glfw
const glfw_opts: glfw.Options = .{
.metal = step.target.isDarwin(),
.opengl = false,
};
try glfw.link(b, step, glfw_opts);
// Imgui
const imgui_step = try imgui.link(b, step, imgui_opts);
try glfw.link(b, imgui_step, glfw_opts);
}
} }
fn benchSteps( fn benchSteps(

View File

@ -7,7 +7,9 @@ extern "C" {
#include <stdint.h> #include <stdint.h>
uint64_t ghostty_hello(void); #define GHOSTTY_SUCCESS 0
int ghostty_init(void);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -3,11 +3,13 @@ import GhosttyKit
@main @main
struct GhosttyApp: App { struct GhosttyApp: App {
@State private var num = ghostty_hello() init() {
assert(ghostty_init() == GHOSTTY_SUCCESS, "ghostty failed to initialize");
}
var body: some Scene { var body: some Scene {
WindowGroup { WindowGroup {
Text(String(num)).font(.largeTitle) Text("Hello!").font(.largeTitle)
} }
} }
} }

View File

@ -5,6 +5,7 @@ const App = @This();
const std = @import("std"); const std = @import("std");
const builtin = @import("builtin"); const builtin = @import("builtin");
const assert = std.debug.assert;
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const apprt = @import("apprt.zig"); const apprt = @import("apprt.zig");
const Window = @import("Window.zig"); const Window = @import("Window.zig");
@ -273,8 +274,7 @@ pub const Wasm = if (!builtin.target.isWasm()) struct {} else struct {
const alloc = wasm.alloc; const alloc = wasm.alloc;
// export fn app_new(config: *Config) ?*App { // export fn app_new(config: *Config) ?*App {
// return app_new_(config) catch |err| { // return app_new_(config) catch |err| { log.err("error initializing app err={}", .{err});
// log.err("error initializing app err={}", .{err});
// return null; // return null;
// }; // };
// } // }
@ -295,3 +295,15 @@ pub const Wasm = if (!builtin.target.isWasm()) struct {} else struct {
// } // }
// } // }
}; };
pub const CAPI = struct {
const ProcessState = @import("main.zig").ProcessState;
var state: ?ProcessState = null;
export fn ghostty_init() c_int {
assert(state == null);
state = undefined;
ProcessState.init(&state.?);
return 0;
}
};

View File

@ -16,58 +16,88 @@ const App = @import("App.zig");
const cli_args = @import("cli_args.zig"); const cli_args = @import("cli_args.zig");
const Config = @import("config.zig").Config; const Config = @import("config.zig").Config;
pub fn main() !void { /// ProcessState represents the global process state. There should only
// Output some debug information right away /// be one of these at any given moment. This is extracted into a dedicated
std.log.info("dependency harfbuzz={s}", .{harfbuzz.versionString()}); /// struct because it is reused by main and the static C lib.
if (options.fontconfig) { ///
std.log.info("dependency fontconfig={d}", .{fontconfig.version()}); /// ProcessState.init should be one of the first things ever called
} /// when using Ghostty. Ghostty calls this for you so this is more of a note
std.log.info("renderer={}", .{renderer.Renderer}); /// for maintainers.
std.log.info("libxev backend={}", .{xev.backend}); pub const ProcessState = struct {
// First things first, we fix our file descriptors
internal_os.fixMaxFiles();
// We need to make sure the process locale is set properly. Locale
// affects a lot of behaviors in a shell.
internal_os.ensureLocale();
const GPA = std.heap.GeneralPurposeAllocator(.{}); const GPA = std.heap.GeneralPurposeAllocator(.{});
var gpa: ?GPA = gpa: {
// Use the libc allocator if it is available beacuse it is WAY
// faster than GPA. We only do this in release modes so that we
// can get easy memory leak detection in debug modes.
if (builtin.link_libc) {
if (switch (builtin.mode) {
.ReleaseSafe, .ReleaseFast => true,
// We also use it if we can detect we're running under gpa: ?GPA,
// Valgrind since Valgrind only instruments the C allocator alloc: std.mem.Allocator,
else => std.valgrind.runningOnValgrind() > 0,
}) break :gpa null; pub fn init(self: *ProcessState) void {
// Output some debug information right away
std.log.info("dependency harfbuzz={s}", .{harfbuzz.versionString()});
if (options.fontconfig) {
std.log.info("dependency fontconfig={d}", .{fontconfig.version()});
} }
std.log.info("renderer={}", .{renderer.Renderer});
std.log.info("libxev backend={}", .{xev.backend});
break :gpa GPA{}; // First things first, we fix our file descriptors
}; internal_os.fixMaxFiles();
defer if (gpa) |*value| {
// We want to ensure that we deinit the GPA because this is
// the point at which it will output if there were safety violations.
_ = value.deinit();
};
const alloc = alloc: { // We need to make sure the process locale is set properly. Locale
const base = if (gpa) |*value| // affects a lot of behaviors in a shell.
value.allocator() internal_os.ensureLocale();
else if (builtin.link_libc)
std.heap.c_allocator
else
unreachable;
// If we're tracing, wrap the allocator // Initialize ourself to nothing so we don't have any extra state.
if (!tracy.enabled) break :alloc base; self.* = .{
var tracy_alloc = tracy.allocator(base, null); .gpa = null,
break :alloc tracy_alloc.allocator(); .alloc = undefined,
}; };
errdefer self.deinit();
self.gpa = gpa: {
// Use the libc allocator if it is available beacuse it is WAY
// faster than GPA. We only do this in release modes so that we
// can get easy memory leak detection in debug modes.
if (builtin.link_libc) {
if (switch (builtin.mode) {
.ReleaseSafe, .ReleaseFast => true,
// We also use it if we can detect we're running under
// Valgrind since Valgrind only instruments the C allocator
else => std.valgrind.runningOnValgrind() > 0,
}) break :gpa null;
}
break :gpa GPA{};
};
self.alloc = alloc: {
const base = if (self.gpa) |*value|
value.allocator()
else if (builtin.link_libc)
std.heap.c_allocator
else
unreachable;
// If we're tracing, wrap the allocator
if (!tracy.enabled) break :alloc base;
var tracy_alloc = tracy.allocator(base, null);
break :alloc tracy_alloc.allocator();
};
}
pub fn deinit(self: *ProcessState) void {
if (self.gpa) |*value| {
// We want to ensure that we deinit the GPA because this is
// the point at which it will output if there were safety violations.
_ = value.deinit();
}
}
};
pub fn main() !void {
var state: ProcessState = undefined;
ProcessState.init(&state);
defer state.deinit();
const alloc = state.alloc;
// Try reading our config // Try reading our config
var config = try Config.default(alloc); var config = try Config.default(alloc);

View File

@ -4,8 +4,8 @@
// support). // support).
const std = @import("std"); const std = @import("std");
const builtin = @import("builtin"); const builtin = @import("builtin");
const main = @import("main.zig");
// We're just testing right now. pub usingnamespace @import("App.zig").CAPI;
export fn ghostty_hello() u64 {
return 42; pub const std_options = main.std_options;
}