From 800fa99ff27b317bff789cd0b29a5707663521b6 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 19 Sep 2025 15:12:20 -0700 Subject: [PATCH] build: move apprt, font, renderer enums to dedicated files This reduces the surface area of files we depend on for builds. --- src/apprt.zig | 25 +-------- src/apprt/runtime.zig | 29 +++++++++++ src/build/Config.zig | 36 ++++++------- src/build_config.zig | 2 +- src/font/backend.zig | 110 +++++++++++++++++++++++++++++++++++++++ src/font/main.zig | 110 +-------------------------------------- src/renderer.zig | 23 +------- src/renderer/backend.zig | 23 ++++++++ 8 files changed, 184 insertions(+), 174 deletions(-) create mode 100644 src/apprt/runtime.zig create mode 100644 src/font/backend.zig create mode 100644 src/renderer/backend.zig diff --git a/src/apprt.zig b/src/apprt.zig index ccb1251a2..947f29050 100644 --- a/src/apprt.zig +++ b/src/apprt.zig @@ -23,6 +23,7 @@ pub const embedded = @import("apprt/embedded.zig"); pub const surface = @import("apprt/surface.zig"); pub const Action = action.Action; +pub const Runtime = @import("apprt/runtime.zig").Runtime; pub const Target = action.Target; pub const ContentScale = structs.ContentScale; @@ -51,30 +52,6 @@ pub const runtime = switch (build_config.artifact) { pub const App = runtime.App; pub const Surface = runtime.Surface; -/// Runtime is the runtime to use for Ghostty. All runtimes do not provide -/// equivalent feature sets. -pub const Runtime = enum { - /// Will not produce an executable at all when `zig build` is called. - /// This is only useful if you're only interested in the lib only (macOS). - none, - - /// GTK4. Rich windowed application. This uses a full GObject-based - /// approach to building the application. - gtk, - - pub fn default(target: std.Target) Runtime { - return switch (target.os.tag) { - // The Linux and FreeBSD default is GTK because it is a full - // featured application. - .linux, .freebsd => .gtk, - // Otherwise, we do NONE so we don't create an exe and we create - // libghostty. On macOS, Xcode is used to build the app that links - // to libghostty. - else => .none, - }; - } -}; - test { _ = Runtime; _ = runtime; diff --git a/src/apprt/runtime.zig b/src/apprt/runtime.zig new file mode 100644 index 000000000..1be503536 --- /dev/null +++ b/src/apprt/runtime.zig @@ -0,0 +1,29 @@ +const std = @import("std"); + +/// Runtime is the runtime to use for Ghostty. All runtimes do not provide +/// equivalent feature sets. +pub const Runtime = enum { + /// Will not produce an executable at all when `zig build` is called. + /// This is only useful if you're only interested in the lib only (macOS). + none, + + /// GTK4. Rich windowed application. This uses a full GObject-based + /// approach to building the application. + gtk, + + pub fn default(target: std.Target) Runtime { + return switch (target.os.tag) { + // The Linux and FreeBSD default is GTK because it is a full + // featured application. + .linux, .freebsd => .gtk, + // Otherwise, we do NONE so we don't create an exe and we create + // libghostty. On macOS, Xcode is used to build the app that links + // to libghostty. + else => .none, + }; + } +}; + +test { + _ = Runtime; +} diff --git a/src/build/Config.zig b/src/build/Config.zig index 296a6a3b4..d1b7aa81f 100644 --- a/src/build/Config.zig +++ b/src/build/Config.zig @@ -5,9 +5,9 @@ const Config = @This(); const std = @import("std"); const builtin = @import("builtin"); -const apprt = @import("../apprt.zig"); -const font = @import("../font/main.zig"); -const rendererpkg = @import("../renderer.zig"); +const ApprtRuntime = @import("../apprt/runtime.zig").Runtime; +const FontBackend = @import("../font/backend.zig").Backend; +const RendererBackend = @import("../renderer/backend.zig").Backend; const Command = @import("../Command.zig"); const XCFramework = @import("GhosttyXCFramework.zig"); const WasmTarget = @import("../os/wasm/target.zig").Target; @@ -29,9 +29,9 @@ xcframework_target: XCFramework.Target = .universal, wasm_target: WasmTarget, /// Comptime interfaces -app_runtime: apprt.Runtime = .none, -renderer: rendererpkg.Impl = .opengl, -font_backend: font.Backend = .freetype, +app_runtime: ApprtRuntime = .none, +renderer: RendererBackend = .opengl, +font_backend: FontBackend = .freetype, /// Feature flags x11: bool = false, @@ -126,22 +126,22 @@ pub fn init(b: *std.Build) !Config { //--------------------------------------------------------------- // Comptime Interfaces config.font_backend = b.option( - font.Backend, + FontBackend, "font-backend", "The font backend to use for discovery and rasterization.", - ) orelse font.Backend.default(target.result, wasm_target); + ) orelse FontBackend.default(target.result, wasm_target); config.app_runtime = b.option( - apprt.Runtime, + ApprtRuntime, "app-runtime", "The app runtime to use. Not all values supported on all platforms.", - ) orelse apprt.Runtime.default(target.result); + ) orelse ApprtRuntime.default(target.result); config.renderer = b.option( - rendererpkg.Impl, + RendererBackend, "renderer", "The app runtime to use. Not all values supported on all platforms.", - ) orelse rendererpkg.Impl.default(target.result, wasm_target); + ) orelse RendererBackend.default(target.result, wasm_target); //--------------------------------------------------------------- // Feature Flags @@ -446,9 +446,9 @@ pub fn addOptions(self: *const Config, step: *std.Build.Step.Options) !void { step.addOption(bool, "wayland", self.wayland); step.addOption(bool, "sentry", self.sentry); step.addOption(bool, "i18n", self.i18n); - step.addOption(apprt.Runtime, "app_runtime", self.app_runtime); - step.addOption(font.Backend, "font_backend", self.font_backend); - step.addOption(rendererpkg.Impl, "renderer", self.renderer); + step.addOption(ApprtRuntime, "app_runtime", self.app_runtime); + step.addOption(FontBackend, "font_backend", self.font_backend); + step.addOption(RendererBackend, "renderer", self.renderer); step.addOption(ExeEntrypoint, "exe_entrypoint", self.exe_entrypoint); step.addOption(WasmTarget, "wasm_target", self.wasm_target); step.addOption(bool, "wasm_shared", self.wasm_shared); @@ -503,9 +503,9 @@ pub fn fromOptions() Config { .version = options.app_version, .flatpak = options.flatpak, - .app_runtime = std.meta.stringToEnum(apprt.Runtime, @tagName(options.app_runtime)).?, - .font_backend = std.meta.stringToEnum(font.Backend, @tagName(options.font_backend)).?, - .renderer = std.meta.stringToEnum(rendererpkg.Impl, @tagName(options.renderer)).?, + .app_runtime = std.meta.stringToEnum(ApprtRuntime, @tagName(options.app_runtime)).?, + .font_backend = std.meta.stringToEnum(FontBackend, @tagName(options.font_backend)).?, + .renderer = std.meta.stringToEnum(RendererBackend, @tagName(options.renderer)).?, .exe_entrypoint = std.meta.stringToEnum(ExeEntrypoint, @tagName(options.exe_entrypoint)).?, .wasm_target = std.meta.stringToEnum(WasmTarget, @tagName(options.wasm_target)).?, .wasm_shared = options.wasm_shared, diff --git a/src/build_config.zig b/src/build_config.zig index 903197717..ebd14bfe8 100644 --- a/src/build_config.zig +++ b/src/build_config.zig @@ -40,7 +40,7 @@ pub const exe_entrypoint = config.exe_entrypoint; pub const flatpak = options.flatpak; pub const app_runtime: apprt.Runtime = config.app_runtime; pub const font_backend: font.Backend = config.font_backend; -pub const renderer: rendererpkg.Impl = config.renderer; +pub const renderer: rendererpkg.Backend = config.renderer; pub const i18n: bool = config.i18n; /// The bundle ID for the app. This is used in many places and is currently diff --git a/src/font/backend.zig b/src/font/backend.zig new file mode 100644 index 000000000..37b3189b6 --- /dev/null +++ b/src/font/backend.zig @@ -0,0 +1,110 @@ +const std = @import("std"); + +pub const Backend = enum { + const WasmTarget = @import("../os/wasm/target.zig").Target; + + /// FreeType for font rendering with no font discovery enabled. + freetype, + + /// Fontconfig for font discovery and FreeType for font rendering. + fontconfig_freetype, + + /// CoreText for font discovery, rendering, and shaping (macOS). + coretext, + + /// CoreText for font discovery, FreeType for rendering, and + /// HarfBuzz for shaping (macOS). + coretext_freetype, + + /// CoreText for font discovery and rendering, HarfBuzz for shaping + coretext_harfbuzz, + + /// CoreText for font discovery and rendering, no shaping. + coretext_noshape, + + /// Use the browser font system and the Canvas API (wasm). This limits + /// the available fonts to browser fonts (anything Canvas natively + /// supports). + web_canvas, + + /// Returns the default backend for a build environment. This is + /// meant to be called at comptime by the build.zig script. To get the + /// backend look at build_options. + pub fn default( + target: std.Target, + wasm_target: WasmTarget, + ) Backend { + if (target.cpu.arch == .wasm32) { + return switch (wasm_target) { + .browser => .web_canvas, + }; + } + + // macOS also supports "coretext_freetype" but there is no scenario + // that is the default. It is only used by people who want to + // self-compile Ghostty and prefer the freetype aesthetic. + return if (target.os.tag.isDarwin()) .coretext else .fontconfig_freetype; + } + + // All the functions below can be called at comptime or runtime to + // determine if we have a certain dependency. + + pub fn hasFreetype(self: Backend) bool { + return switch (self) { + .freetype, + .fontconfig_freetype, + .coretext_freetype, + => true, + + .coretext, + .coretext_harfbuzz, + .coretext_noshape, + .web_canvas, + => false, + }; + } + + pub fn hasCoretext(self: Backend) bool { + return switch (self) { + .coretext, + .coretext_freetype, + .coretext_harfbuzz, + .coretext_noshape, + => true, + + .freetype, + .fontconfig_freetype, + .web_canvas, + => false, + }; + } + + pub fn hasFontconfig(self: Backend) bool { + return switch (self) { + .fontconfig_freetype => true, + + .freetype, + .coretext, + .coretext_freetype, + .coretext_harfbuzz, + .coretext_noshape, + .web_canvas, + => false, + }; + } + + pub fn hasHarfbuzz(self: Backend) bool { + return switch (self) { + .freetype, + .fontconfig_freetype, + .coretext_freetype, + .coretext_harfbuzz, + => true, + + .coretext, + .coretext_noshape, + .web_canvas, + => false, + }; + } +}; diff --git a/src/font/main.zig b/src/font/main.zig index 782b3e388..a8522afe1 100644 --- a/src/font/main.zig +++ b/src/font/main.zig @@ -5,6 +5,7 @@ const build_config = @import("../build_config.zig"); const library = @import("library.zig"); pub const Atlas = @import("Atlas.zig"); +pub const Backend = @import("backend.zig").Backend; pub const discovery = @import("discovery.zig"); pub const embedded = @import("embedded.zig"); pub const face = @import("face.zig"); @@ -48,115 +49,6 @@ pub const options: struct { .backend = if (builtin.target.cpu.arch.isWasm()) .web_canvas else build_config.font_backend, }; -pub const Backend = enum { - const WasmTarget = @import("../os/wasm/target.zig").Target; - - /// FreeType for font rendering with no font discovery enabled. - freetype, - - /// Fontconfig for font discovery and FreeType for font rendering. - fontconfig_freetype, - - /// CoreText for font discovery, rendering, and shaping (macOS). - coretext, - - /// CoreText for font discovery, FreeType for rendering, and - /// HarfBuzz for shaping (macOS). - coretext_freetype, - - /// CoreText for font discovery and rendering, HarfBuzz for shaping - coretext_harfbuzz, - - /// CoreText for font discovery and rendering, no shaping. - coretext_noshape, - - /// Use the browser font system and the Canvas API (wasm). This limits - /// the available fonts to browser fonts (anything Canvas natively - /// supports). - web_canvas, - - /// Returns the default backend for a build environment. This is - /// meant to be called at comptime by the build.zig script. To get the - /// backend look at build_options. - pub fn default( - target: std.Target, - wasm_target: WasmTarget, - ) Backend { - if (target.cpu.arch == .wasm32) { - return switch (wasm_target) { - .browser => .web_canvas, - }; - } - - // macOS also supports "coretext_freetype" but there is no scenario - // that is the default. It is only used by people who want to - // self-compile Ghostty and prefer the freetype aesthetic. - return if (target.os.tag.isDarwin()) .coretext else .fontconfig_freetype; - } - - // All the functions below can be called at comptime or runtime to - // determine if we have a certain dependency. - - pub fn hasFreetype(self: Backend) bool { - return switch (self) { - .freetype, - .fontconfig_freetype, - .coretext_freetype, - => true, - - .coretext, - .coretext_harfbuzz, - .coretext_noshape, - .web_canvas, - => false, - }; - } - - pub fn hasCoretext(self: Backend) bool { - return switch (self) { - .coretext, - .coretext_freetype, - .coretext_harfbuzz, - .coretext_noshape, - => true, - - .freetype, - .fontconfig_freetype, - .web_canvas, - => false, - }; - } - - pub fn hasFontconfig(self: Backend) bool { - return switch (self) { - .fontconfig_freetype => true, - - .freetype, - .coretext, - .coretext_freetype, - .coretext_harfbuzz, - .coretext_noshape, - .web_canvas, - => false, - }; - } - - pub fn hasHarfbuzz(self: Backend) bool { - return switch (self) { - .freetype, - .fontconfig_freetype, - .coretext_freetype, - .coretext_harfbuzz, - => true, - - .coretext, - .coretext_noshape, - .web_canvas, - => false, - }; - } -}; - /// The styles that a family can take. pub const Style = enum(u3) { regular = 0, diff --git a/src/renderer.zig b/src/renderer.zig index e3ed070b6..f09f717c4 100644 --- a/src/renderer.zig +++ b/src/renderer.zig @@ -10,12 +10,12 @@ const std = @import("std"); const builtin = @import("builtin"); const build_config = @import("build_config.zig"); -const WasmTarget = @import("os/wasm/target.zig").Target; const cursor = @import("renderer/cursor.zig"); const message = @import("renderer/message.zig"); const size = @import("renderer/size.zig"); pub const shadertoy = @import("renderer/shadertoy.zig"); +pub const Backend = @import("renderer/backend.zig").Backend; pub const GenericRenderer = @import("renderer/generic.zig").Renderer; pub const Metal = @import("renderer/Metal.zig"); pub const OpenGL = @import("renderer/OpenGL.zig"); @@ -33,27 +33,6 @@ pub const GridSize = size.GridSize; pub const Padding = size.Padding; pub const cursorStyle = cursor.style; -/// Possible implementations, used for build options. -pub const Impl = enum { - opengl, - metal, - webgl, - - pub fn default( - target: std.Target, - wasm_target: WasmTarget, - ) Impl { - if (target.cpu.arch == .wasm32) { - return switch (wasm_target) { - .browser => .webgl, - }; - } - - if (target.os.tag.isDarwin()) return .metal; - return .opengl; - } -}; - /// The implementation to use for the renderer. This is comptime chosen /// so that every build has exactly one renderer implementation. pub const Renderer = switch (build_config.renderer) { diff --git a/src/renderer/backend.zig b/src/renderer/backend.zig new file mode 100644 index 000000000..942e1f0ff --- /dev/null +++ b/src/renderer/backend.zig @@ -0,0 +1,23 @@ +const std = @import("std"); +const WasmTarget = @import("../os/wasm/target.zig").Target; + +/// Possible implementations, used for build options. +pub const Backend = enum { + opengl, + metal, + webgl, + + pub fn default( + target: std.Target, + wasm_target: WasmTarget, + ) Backend { + if (target.cpu.arch == .wasm32) { + return switch (wasm_target) { + .browser => .webgl, + }; + } + + if (target.os.tag.isDarwin()) return .metal; + return .opengl; + } +}; -- 2.51.2