diff options
Diffstat (limited to 'build.zig')
| -rw-r--r-- | build.zig | 61 |
1 files changed, 61 insertions, 0 deletions
@@ -1,4 +1,5 @@ const std = @import("std"); +const mupdf_build = @import("mupdf.zig"); const snap_build = @import("build/snap.zig"); pub const Platform = enum { tty, gui, web }; @@ -27,6 +28,7 @@ pub fn build(b: *std.Build) void { const static = b.option(bool, "static", "statically link") orelse false; const dump_path = b.option([]const u8, "dump", "dump .zon embedded into the web shell (-Dplatform=web)"); const is_web = platform == .web; + const enable_mupdf = b.option(bool, "mupdf", "native PDF rendering with MuPDF (AGPL/commercial; native default on, web off; -Dmupdf=false disables)") orelse !is_web; const is_web_target = target.result.cpu.arch == .wasm32 and target.result.os.tag == .freestanding; // wasm: size is the budget const optimize = if (is_web) .ReleaseSmall else requested_optimize; @@ -47,6 +49,9 @@ pub fn build(b: *std.Build) void { // The browser shell is a freestanding wasm core plus ordinary web files. // JavaScript owns the loop and IO; HTML/CSS own rendering. const web_step = b.step("web", "build the DOM browser shell into zig-out/web (-Dplatform=web -Dtarget=wasm32-freestanding -Ddump=<dump.zon>)"); + const mupdf_check = b.step("mupdf-check", "compile, link, render, and search docs/design.pdf with MuPDF"); + if (!enable_mupdf) + mupdf_check.dependOn(&b.addFail("mupdf-check is unavailable with -Dmupdf=false").step); // Web LOOK has a tiny read-only source filesystem. Generate one Zig module // on the host from every tracked .zig path + its current working-tree @@ -74,6 +79,7 @@ pub fn build(b: *std.Build) void { if (is_web and !is_web_target) return failBuild(b, web_step, "-Dplatform=web requires -Dtarget=wasm32-freestanding"); if (!is_web and (is_web_target or target.result.os.tag == .emscripten)) return failBuild(b, web_step, "wasm browser targets require -Dplatform=web"); if (platform == .web and dump_path == null) return failBuild(b, web_step, "-Dplatform=web requires -Ddump=<dump.zon> (the browser has no ptys; state replays from an embedded dump)"); + if (enable_mupdf and is_web) return failBuild(b, web_step, "-Dmupdf=true is supported only by the native tty/Kitty and gui/SDL backends"); // build-time IO: slurps the grammars' highlights.scm queries, and reads // vendor/themes to find the theme sources @@ -151,6 +157,7 @@ pub fn build(b: *std.Build) void { opts.addOption(bool, "syntax_full_grammars", tree_sitter_grammars == .full); opts.addOption(bool, "enable_tracy", tracy != null); opts.addOption(bool, "zls_backend", zls_backend); + opts.addOption(bool, "mupdf", enable_mupdf); // Which ZLS is compiled in, for `SPC l i`. Kept next to the dependency it // names: the .zon pins a commit, and a status screen that cannot say WHICH // analyser answered is not worth opening. @@ -332,6 +339,44 @@ pub fn build(b: *std.Build) void { root_mod.addImport("mvzr", mvzr_mod); hx_core_mod.addImport("mvzr", mvzr_mod); + // MuPDF is the default native PDF engine, but remains a genuinely optional + // dependency: with -Dmupdf=false (and by default on web), the lazy source + // archive is not fetched, compiled, linked, or exposed to runtime code. + // mupdf.zig mirrors the 1.27.0 Makefile source graph with Zig's C compiler + // and deliberately enables only the PDF document handler for this first + // integration. + if (enable_mupdf) { + if (b.lazyDependency("mupdf", .{})) |mupdf_dep| { + const mupdf = mupdf_build.add(b, io, mupdf_dep, .{ + .target = target, + .optimize = c_optimize, + }); + const mupdf_mod = b.createModule(.{ + .target = target, + .optimize = optimize, + .root_source_file = b.path("src/pdf.zig"), + .link_libc = true, + }); + mupdf.linkTo(mupdf_mod); + mupdf_mod.addIncludePath(b.path("src")); + mupdf_mod.addCSourceFile(.{ + .file = b.path("src/pdf_bridge.c"), + .flags = &.{"-std=gnu11"}, + }); + root_mod.addImport("mupdf", mupdf_mod); + hx_core_mod.addImport("mupdf", mupdf_mod); + // Compile the @cImport + exception bridge and exercise the Zig + // wrapper's stride-aware RGB-to-RGBA boundary alongside the C + // end-to-end document probe below. + const mupdf_test = b.addTest(.{ .root_module = mupdf_mod }); + mupdf_check.dependOn(&b.addRunArtifact(mupdf_test).step); + mupdf_check.dependOn(mupdf_build.addProbe(b, mupdf, .{ + .target = target, + .pdf = b.path("docs/design.pdf"), + })); + } + } + // ghostty-vt and vaxis both depend on uucode, but Zig forbids one source // file in two modules — build a single uucode (our config, unpacked tables) // and hand it to both. Same trick as the prototype; see uucode_config.zig. @@ -583,6 +628,22 @@ pub fn build(b: *std.Build) void { run_image_harness.has_side_effects = true; b.step("image-harness", "exercise native Kitty/SDL image rendering end to end").dependOn(&run_image_harness.step); + // The PDF arm uses the same native-pixel observer but a generated, + // searchable two-page document. Keep it a distinct opt-in step: the + // ordinary image harness stays identical when MuPDF is disabled, and + // asking for PDF coverage without the feature gets an explicit error. + const pdf_harness_step = b.step("pdf-harness", "exercise PDF rendering, page replacement, and search Look end to end"); + if (enable_mupdf) { + const run_pdf_harness = b.addRunArtifact(image_harness); + run_pdf_harness.addArtifactArg(exe); + run_pdf_harness.addArg(if (platform == .gui) "gui" else "tty"); + run_pdf_harness.addArg("pdf"); + run_pdf_harness.has_side_effects = true; + pdf_harness_step.dependOn(&run_pdf_harness.step); + } else { + pdf_harness_step.dependOn(&b.addFail("pdf-harness is unavailable with -Dmupdf=false").step); + } + // helix differential harness: drive the sans-IO core headlessly over // JSON-Lines cases, one contract result line per case on stdout — // the pardes half of the pardes-vs-helix diff (helix's hx-harness on |
