From 89f9dd7848111b28287a70388d610d66227a53f4 Mon Sep 17 00:00:00 2001 From: "Jeffrey C. Ollie" Date: Tue, 3 Mar 2026 14:40:00 -0600 Subject: [PATCH] build: link to the system FontConfig by default on non-macOS systems Because of the global shared state that FontConfig maintains, FontConfig must be linked dynamically to the same system FontConfig shared library that GTK uses. Ghostty's default has been changed to always link to the system FontConfig library on non-macOS systems. If that is overridden (by specifying `-fno-sys=fontconfig` during the build) Ghostty may crash when trying to locate glyphs that are not available in the default font. Fixes #10432 --- HACKING.md | 9 +++++++++ src/build/Config.zig | 14 +++++++++++++- src/build/SharedDeps.zig | 7 +++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/HACKING.md b/HACKING.md index 7ba584881..d69bcd0f8 100644 --- a/HACKING.md +++ b/HACKING.md @@ -38,6 +38,15 @@ here: | `zig build dist` | Builds a source tarball | | `zig build distcheck` | Builds and validates a source tarball | +## FontConfig and GTK + +Because of the global shared state that FontConfig maintains, FontConfig must +be linked dynamically to the same system FontConfig shared library that GTK +uses. Ghostty's default has been changed to always link to the system FontConfig +library. If that is overridden (by specifying `-fno-sys=fontconfig` during the +build) Ghostty may crash when trying to locate glyphs that are not available in +the default font. + ## Extra Dependencies Building Ghostty from a Git checkout on Linux requires some additional diff --git a/src/build/Config.zig b/src/build/Config.zig index 3a8a4e0c7..aded6007d 100644 --- a/src/build/Config.zig +++ b/src/build/Config.zig @@ -424,6 +424,19 @@ pub fn init(b: *std.Build, appVersion: []const u8) !Config { // show up properly in `--help`. { + // These should default to `true` except on macOS because linking them + // to Ghostty statically when GTK is dynamically linked to them can + // cause crashes. + for (&[_][]const u8{ + "fontconfig", + }) |dep| { + _ = b.systemIntegrationOption( + dep, + .{ + .default = if (target.result.os.tag.isDarwin()) false else true, + }, + ); + } // These dependencies we want to default false if we're on macOS. // On macOS we don't want to use system libraries because we // generally want a fat binary. This can be overridden with the @@ -431,7 +444,6 @@ pub fn init(b: *std.Build, appVersion: []const u8) !Config { for (&[_][]const u8{ "freetype", "harfbuzz", - "fontconfig", "libpng", "zlib", "oniguruma", diff --git a/src/build/SharedDeps.zig b/src/build/SharedDeps.zig index 9276c9914..821677128 100644 --- a/src/build/SharedDeps.zig +++ b/src/build/SharedDeps.zig @@ -200,6 +200,13 @@ pub fn add( if (b.systemIntegrationOption("fontconfig", .{})) { step.linkSystemLibrary2("fontconfig", dynamic_link_opts); } else { + if (self.config.app_runtime == .gtk) + std.debug.print( + \\WARNING: Statically linking FontConfig when using the GTK app runtime is known + \\to cause crashes! It is HIGHLY recommended that Ghostty be dynamically linked + \\to the system FontConfig library. + \\ + , .{}); step.linkLibrary(fontconfig_dep.artifact("fontconfig")); try static_libs.append( b.allocator,