From 7fdf5ed9d1dd433e4657b670b7831cec6e3d41ca Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Thu, 24 Sep 2026 12:56:04 -0300 Subject: Build MuPDF against the FreeType the gui links, not the slim one it bundles MuPDF compiled its own FreeType 2.13.3 (FREETYPE_SRC, trimmed by scripts/freetype's slimftmodules.h and slimftoptions.h) into libmupdf.a, and the gui also links the freetype package, 2.14.3 in its full configuration. The two define the same 312 symbols, and a linker handed both keeps one of each: the gui's MuPDF ran the package's FreeType compiled against the slim headers, while the tty ran the slim one. Now there is one. mupdf.zig takes the build's freetype artifact, links it (its headers come with it) and no longer compiles FREETYPE_SRC or puts the slim headers on the include path. The shared artifact is built at c_optimize, as MuPDF is, so a Debug gui's glyph atlas now uses a ReleaseFast FreeType too; one artifact cannot be both. The tty gains the full FreeType's extra modules, which FT_Add_Default_Modules registers whether or not a PDF needs them. MuPDF asks nothing of FreeType the full configuration lacks: every page of docs/design.pdf, docs/9p.pdf and docs/registry.pdf renders bit for bit as before, at 144 and at 300 dpi. Co-Authored-By: Claude Opus 5.5 (1M context) --- build.zig | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'build.zig') diff --git a/build.zig b/build.zig index 2c8a8858..3b57fff6 100644 --- a/build.zig +++ b/build.zig @@ -418,12 +418,22 @@ pub fn build(b: *std.Build) void { .root_source_file = b.path("src/c_heap.zig"), }); + // One FreeType in a binary: the gui's glyph atlas links it and MuPDF is + // built against it (see mupdf.zig). At c_optimize with the rest of the + // vendored C, since MuPDF rasterizes a PDF's text through it. + const freetype: ?*std.Build.Step.Compile = if (freestanding_core) null else b.dependency("freetype", .{ + .target = target, + .optimize = c_optimize, + .@"enable-libpng" = false, + }).artifact("freetype"); + if (enable_mupdf) { if (b.lazyDependency("mupdf", .{})) |mupdf_dep| { const mupdf = mupdf_build.add(b, io, mupdf_dep, .{ .target = target, .optimize = c_optimize, .jpx = enable_jpx, + .freetype = freetype.?, }); const mupdf_mod = b.createModule(.{ .target = target, @@ -647,12 +657,7 @@ pub fn build(b: *std.Build) void { gm.linkLibrary(sdl_lib); gm.addIncludePath(dep.path("include")); } - const freetype_dep = b.dependency("freetype", .{ - .target = target, - .optimize = optimize, - .@"enable-libpng" = false, - }); - gm.linkLibrary(freetype_dep.artifact("freetype")); + gm.linkLibrary(freetype.?); // HarfBuzz from source, like FreeType: its FreeType integration // (HAVE_FREETYPE, hb-ft) links the freetype artifact above, so the two // share one FreeType. The flags are the ones Ghostty builds it with, @@ -669,7 +674,7 @@ pub fn build(b: *std.Build) void { .link_libcpp = true, }), }); - harfbuzz.root_module.linkLibrary(freetype_dep.artifact("freetype")); + harfbuzz.root_module.linkLibrary(freetype.?); harfbuzz.root_module.addIncludePath(upstream.path("src")); harfbuzz.root_module.addCSourceFile(.{ .file = upstream.path("src/harfbuzz.cc"), -- cgit v1.3