From cfea2ea12cf1ef805659ffeae058f03b4639c788 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 13 Mar 2025 21:30:24 -0700 Subject: [PATCH] build: mark most dependencies as lazy Lazy dependencies are only fetched if the build script would actually reach a usage of that dependency at runtime (when the `lazyDependency` function is called). This can save a lot of network traffic, disk uage, and time because we don't have to fetch and build dependencies that we don't actually need. Prior to this commit, Ghostty fetched almost everything for all platforms and configurations all the time. This commit reverses that to fetching almost nothing until it's actually needed. There are very little downsides to doing this[1]. One downside is `zig build --fetch` doesn't fetch lazy dependencies, but we don't rely on this command for packaging and suggest using our custom shell script that downloads a cached list of URLs (`build.zig.zon.txt`). This commit doesn't cover 100% of dependencies, since some provide no benefit to make lazy while the complexity to make them lazy is higher (in code style typically). Conversely, some simple dependencies are marked lazy even if they're almost always needed if they don't introduce any real complexity to the code, because there is very little downside to do so. [1]: https://ziggit.dev/t/lazy-dependencies-best-dependencies/5509/5 --- build.zig.zon | 50 +- pkg/breakpad/build.zig | 104 ++-- pkg/breakpad/build.zig.zon | 1 + pkg/cimgui/build.zig | 8 +- pkg/fontconfig/build.zig | 41 +- pkg/fontconfig/build.zig.zon | 5 +- pkg/freetype/build.zig | 85 ++-- pkg/freetype/build.zig.zon | 1 + pkg/gtk4-layer-shell/build.zig | 11 +- pkg/gtk4-layer-shell/build.zig.zon | 2 + pkg/harfbuzz/build.zig | 33 +- pkg/harfbuzz/build.zig.zon | 1 + pkg/libintl/build.zig | 18 +- pkg/libintl/build.zig.zon | 1 + pkg/libpng/build.zig | 57 ++- pkg/libpng/build.zig.zon | 3 +- pkg/oniguruma/build.zig | 172 +++---- pkg/oniguruma/build.zig.zon | 1 + pkg/sentry/build.zig | 283 +++++------ pkg/sentry/build.zig.zon | 3 +- pkg/utfcpp/build.zig | 17 +- pkg/utfcpp/build.zig.zon | 1 + pkg/wuffs/build.zig | 60 +-- pkg/wuffs/build.zig.zon | 2 + pkg/zlib/build.zig | 42 +- pkg/zlib/build.zig.zon | 1 + src/build/GhosttyResources.zig | 3 +- src/build/SharedDeps.zig | 742 +++++++++++++++++------------ src/build/UnicodeTables.zig | 10 +- 29 files changed, 977 insertions(+), 781 deletions(-) diff --git a/build.zig.zon b/build.zig.zon index 9a14ce919..b01ec4eb7 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -10,30 +10,36 @@ // mitchellh/libxev .url = "https://github.com/mitchellh/libxev/archive/3df9337a9e84450a58a2c4af434ec1a036f7b494.tar.gz", .hash = "libxev-0.0.0-86vtc-ziEgDbLP0vihUn1MhsxNKY4GJEga6BEr7oyHpz", + .lazy = true, }, .vaxis = .{ // rockorager/libvaxis .url = "git+https://github.com/rockorager/libvaxis#1e24e0dfb509e974e1c8713bcd119d0ae032a8c7", .hash = "vaxis-0.1.0-BWNV_MHyCAARemSCSwwc3sA1etNgv7ge0BCIXspX6CZv", + .lazy = true, }, .z2d = .{ // vancluever/z2d .url = "https://github.com/vancluever/z2d/archive/1e89605a624940c310c7a1d81b46a7c5c05919e3.tar.gz", .hash = "z2d-0.6.0-j5P_HvLdCABu-dXpCeRM7Uk4m16vULg1980lMNCQj4_C", + .lazy = true, }, .zig_objc = .{ // mitchellh/zig-objc .url = "https://github.com/mitchellh/zig-objc/archive/3ab0d37c7d6b933d6ded1b3a35b6b60f05590a98.tar.gz", .hash = "zig_objc-0.0.0-Ir_Sp3TyAADEVRTxXlScq3t_uKAM91MYNerZkHfbD0yt", + .lazy = true, }, .zig_js = .{ // mitchellh/zig-js .url = "https://deps.files.ghostty.org/zig_js-12205a66d423259567764fa0fc60c82be35365c21aeb76c5a7dc99698401f4f6fefc.tar.gz", .hash = "N-V-__8AAB9YCQBaZtQjJZVndk-g_GDIK-NTZcIa63bFp9yZ", + .lazy = true, }, .ziglyph = .{ .url = "https://deps.files.ghostty.org/ziglyph-b89d43d1e3fb01b6074bc1f7fc980324b04d26a5.tar.gz", .hash = "ziglyph-0.11.2-AAAAAHPtHwB4Mbzn1KvOV7Wpjo82NYEc_v0WC8oCLrkf", + .lazy = true, }, .zig_wayland = .{ // codeberg ifreund/zig-wayland @@ -44,49 +50,54 @@ // natecraddock/zf .url = "https://github.com/natecraddock/zf/archive/03176fcf23fda543cc02a8675e92c1fe3b1ee2eb.tar.gz", .hash = "zf-0.10.3-OIRy8bKIAACV6JaNNncXA68Nw2BUAD9JVfQdzjyoZQ-J", + .lazy = true, }, .gobject = .{ // https://github.com/jcollie/ghostty-gobject based on zig_gobject // Temporary until we generate them at build time automatically. .url = "https://github.com/jcollie/ghostty-gobject/releases/download/0.14.0-2025-03-11-16-1/ghostty-gobject-0.14.0-2025-03-11-16-1.tar.gz", .hash = "gobject-0.2.0-Skun7H6DlQDWCiNQtdE5TXYcCvx7MyjW01OQe5M_n_jV", + .lazy = true, }, // C libs - .cimgui = .{ .path = "./pkg/cimgui" }, - .fontconfig = .{ .path = "./pkg/fontconfig" }, - .freetype = .{ .path = "./pkg/freetype" }, - .glfw = .{ .path = "./pkg/glfw" }, - .gtk4_layer_shell = .{ .path = "./pkg/gtk4-layer-shell" }, - .harfbuzz = .{ .path = "./pkg/harfbuzz" }, - .highway = .{ .path = "./pkg/highway" }, - .libintl = .{ .path = "./pkg/libintl" }, - .libpng = .{ .path = "./pkg/libpng" }, - .macos = .{ .path = "./pkg/macos" }, - .oniguruma = .{ .path = "./pkg/oniguruma" }, - .opengl = .{ .path = "./pkg/opengl" }, - .sentry = .{ .path = "./pkg/sentry" }, - .simdutf = .{ .path = "./pkg/simdutf" }, - .utfcpp = .{ .path = "./pkg/utfcpp" }, - .wuffs = .{ .path = "./pkg/wuffs" }, - .zlib = .{ .path = "./pkg/zlib" }, + .cimgui = .{ .path = "./pkg/cimgui", .lazy = true }, + .fontconfig = .{ .path = "./pkg/fontconfig", .lazy = true }, + .freetype = .{ .path = "./pkg/freetype", .lazy = true }, + .glfw = .{ .path = "./pkg/glfw", .lazy = true }, + .gtk4_layer_shell = .{ .path = "./pkg/gtk4-layer-shell", .lazy = true }, + .harfbuzz = .{ .path = "./pkg/harfbuzz", .lazy = true }, + .highway = .{ .path = "./pkg/highway", .lazy = true }, + .libintl = .{ .path = "./pkg/libintl", .lazy = true }, + .libpng = .{ .path = "./pkg/libpng", .lazy = true }, + .macos = .{ .path = "./pkg/macos", .lazy = true }, + .oniguruma = .{ .path = "./pkg/oniguruma", .lazy = true }, + .opengl = .{ .path = "./pkg/opengl", .lazy = true }, + .sentry = .{ .path = "./pkg/sentry", .lazy = true }, + .simdutf = .{ .path = "./pkg/simdutf", .lazy = true }, + .utfcpp = .{ .path = "./pkg/utfcpp", .lazy = true }, + .wuffs = .{ .path = "./pkg/wuffs", .lazy = true }, + .zlib = .{ .path = "./pkg/zlib", .lazy = true }, // Shader translation - .glslang = .{ .path = "./pkg/glslang" }, - .spirv_cross = .{ .path = "./pkg/spirv-cross" }, + .glslang = .{ .path = "./pkg/glslang", .lazy = true }, + .spirv_cross = .{ .path = "./pkg/spirv-cross", .lazy = true }, // Wayland .wayland = .{ .url = "https://deps.files.ghostty.org/wayland-9cb3d7aa9dc995ffafdbdef7ab86a949d0fb0e7d.tar.gz", .hash = "N-V-__8AAKrHGAAs2shYq8UkE6bGcR1QJtLTyOE_lcosMn6t", + .lazy = true, }, .wayland_protocols = .{ .url = "https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz", .hash = "N-V-__8AAKw-DAAaV8bOAAGqA0-oD7o-HNIlPFYKRXSPT03S", + .lazy = true, }, .plasma_wayland_protocols = .{ .url = "https://deps.files.ghostty.org/plasma_wayland_protocols-12207e0851c12acdeee0991e893e0132fc87bb763969a585dc16ecca33e88334c566.tar.gz", .hash = "N-V-__8AAKYZBAB-CFHBKs3u4JkeiT4BMvyHu3Y5aaWF3Bbs", + .lazy = true, }, // Other @@ -94,6 +105,7 @@ .iterm2_themes = .{ .url = "https://github.com/mbadolato/iTerm2-Color-Schemes/archive/e21d5ffd19605741d0e3e19d7c5a8c6c25648673.tar.gz", .hash = "N-V-__8AAABBKARxrVb9mEr7T5TUQbbqPiHxdBoOAmsChg2a", + .lazy = true, }, }, } diff --git a/pkg/breakpad/build.zig b/pkg/breakpad/build.zig index a42227e64..e2fdec7ad 100644 --- a/pkg/breakpad/build.zig +++ b/pkg/breakpad/build.zig @@ -4,15 +4,12 @@ pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - const upstream = b.dependency("breakpad", .{}); - const lib = b.addStaticLibrary(.{ .name = "breakpad", .target = target, .optimize = optimize, }); lib.linkLibCpp(); - lib.addIncludePath(upstream.path("src")); lib.addIncludePath(b.path("vendor")); if (target.result.os.tag.isDarwin()) { const apple_sdk = @import("apple_sdk"); @@ -23,66 +20,69 @@ pub fn build(b: *std.Build) !void { defer flags.deinit(); try flags.appendSlice(&.{}); - lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = common, - .flags = flags.items, - }); - - if (target.result.os.tag.isDarwin()) { + if (b.lazyDependency("breakpad", .{})) |upstream| { + lib.addIncludePath(upstream.path("src")); lib.addCSourceFiles(.{ .root = upstream.path(""), - .files = common_apple, - .flags = flags.items, - }); - lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = client_apple, + .files = common, .flags = flags.items, }); - switch (target.result.os.tag) { - .macos => { - lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = common_mac, - .flags = flags.items, - }); - lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = client_mac, - .flags = flags.items, - }); - }, - - .ios => lib.addCSourceFiles(.{ + if (target.result.os.tag.isDarwin()) { + lib.addCSourceFiles(.{ .root = upstream.path(""), - .files = client_ios, + .files = common_apple, .flags = flags.items, - }), + }); + lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = client_apple, + .flags = flags.items, + }); - else => {}, + switch (target.result.os.tag) { + .macos => { + lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = common_mac, + .flags = flags.items, + }); + lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = client_mac, + .flags = flags.items, + }); + }, + + .ios => lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = client_ios, + .flags = flags.items, + }), + + else => {}, + } } - } - if (target.result.os.tag == .linux) { - lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = common_linux, - .flags = flags.items, - }); - lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = client_linux, - .flags = flags.items, - }); - } + if (target.result.os.tag == .linux) { + lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = common_linux, + .flags = flags.items, + }); + lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = client_linux, + .flags = flags.items, + }); + } - lib.installHeadersDirectory( - upstream.path("src"), - "", - .{ .include_extensions = &.{".h"} }, - ); + lib.installHeadersDirectory( + upstream.path("src"), + "", + .{ .include_extensions = &.{".h"} }, + ); + } b.installArtifact(lib); } diff --git a/pkg/breakpad/build.zig.zon b/pkg/breakpad/build.zig.zon index a6c7eda82..0d6c54c93 100644 --- a/pkg/breakpad/build.zig.zon +++ b/pkg/breakpad/build.zig.zon @@ -7,6 +7,7 @@ .breakpad = .{ .url = "https://deps.files.ghostty.org/breakpad-b99f444ba5f6b98cac261cbb391d8766b34a5918.tar.gz", .hash = "N-V-__8AALw2uwF_03u4JRkZwRLc3Y9hakkYV7NKRR9-RIZJ", + .lazy = true, }, .apple_sdk = .{ .path = "../apple-sdk" }, diff --git a/pkg/cimgui/build.zig b/pkg/cimgui/build.zig index 72fa085ea..c76b53966 100644 --- a/pkg/cimgui/build.zig +++ b/pkg/cimgui/build.zig @@ -40,7 +40,13 @@ pub fn build(b: *std.Build) !void { .@"enable-libpng" = true, }); lib.linkLibrary(freetype.artifact("freetype")); - module.addIncludePath(freetype.builder.dependency("freetype", .{}).path("include")); + + if (freetype.builder.lazyDependency( + "freetype", + .{}, + )) |freetype_dep| { + module.addIncludePath(freetype_dep.path("include")); + } } lib.addIncludePath(imgui.path("")); diff --git a/pkg/fontconfig/build.zig b/pkg/fontconfig/build.zig index 96c4ffe4a..77e8df549 100644 --- a/pkg/fontconfig/build.zig +++ b/pkg/fontconfig/build.zig @@ -64,7 +64,6 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu const libxml2_iconv_enabled = options.libxml2_iconv_enabled; const freetype_enabled = options.freetype_enabled; - const upstream = b.dependency("fontconfig", .{}); const lib = b.addStaticLibrary(.{ .name = "fontconfig", .target = target, @@ -75,9 +74,7 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu lib.linkSystemLibrary("pthread"); } - lib.addIncludePath(upstream.path("")); lib.addIncludePath(b.path("override/include")); - module.addIncludePath(upstream.path("")); module.addIncludePath(b.path("override/include")); var flags = std.ArrayList([]const u8).init(b.allocator); @@ -188,11 +185,12 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu if (b.systemIntegrationOption("freetype", .{})) { lib.linkSystemLibrary2("freetype2", dynamic_link_opts); } else { - const freetype_dep = b.dependency( + if (b.lazyDependency( "freetype", .{ .target = target, .optimize = optimize }, - ); - lib.linkLibrary(freetype_dep.artifact("freetype")); + )) |freetype_dep| { + lib.linkLibrary(freetype_dep.artifact("freetype")); + } } } @@ -214,26 +212,31 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu if (b.systemIntegrationOption("libxml2", .{})) { lib.linkSystemLibrary2("libxml-2.0", dynamic_link_opts); } else { - const libxml2_dep = b.dependency("libxml2", .{ + if (b.lazyDependency("libxml2", .{ .target = target, .optimize = optimize, .iconv = libxml2_iconv_enabled, - }); - lib.linkLibrary(libxml2_dep.artifact("xml2")); + })) |libxml2_dep| { + lib.linkLibrary(libxml2_dep.artifact("xml2")); + } } } - lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = srcs, - .flags = flags.items, - }); + if (b.lazyDependency("fontconfig", .{})) |upstream| { + lib.addIncludePath(upstream.path("")); + module.addIncludePath(upstream.path("")); + lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = srcs, + .flags = flags.items, + }); - lib.installHeadersDirectory( - upstream.path("fontconfig"), - "fontconfig", - .{ .include_extensions = &.{".h"} }, - ); + lib.installHeadersDirectory( + upstream.path("fontconfig"), + "fontconfig", + .{ .include_extensions = &.{".h"} }, + ); + } b.installArtifact(lib); diff --git a/pkg/fontconfig/build.zig.zon b/pkg/fontconfig/build.zig.zon index d1d89cf43..b1387b87e 100644 --- a/pkg/fontconfig/build.zig.zon +++ b/pkg/fontconfig/build.zig.zon @@ -7,9 +7,10 @@ .fontconfig = .{ .url = "https://deps.files.ghostty.org/fontconfig-2.14.2.tar.gz", .hash = "N-V-__8AAIrfdwARSa-zMmxWwFuwpXf1T3asIN7s5jqi9c1v", + .lazy = true, }, - .freetype = .{ .path = "../freetype" }, - .libxml2 = .{ .path = "../libxml2" }, + .freetype = .{ .path = "../freetype", .lazy = true }, + .libxml2 = .{ .path = "../libxml2", .lazy = true }, }, } diff --git a/pkg/freetype/build.zig b/pkg/freetype/build.zig index 594788b0c..bfe27e5aa 100644 --- a/pkg/freetype/build.zig +++ b/pkg/freetype/build.zig @@ -61,20 +61,17 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu const libpng_enabled = options.libpng_enabled; - const upstream = b.dependency("freetype", .{}); const lib = b.addStaticLibrary(.{ .name = "freetype", .target = target, .optimize = optimize, }); lib.linkLibC(); - lib.addIncludePath(upstream.path("include")); if (target.result.os.tag.isDarwin()) { const apple_sdk = @import("apple_sdk"); try apple_sdk.addPaths(b, lib.root_module); } - module.addIncludePath(upstream.path("include")); var flags = std.ArrayList([]const u8).init(b.allocator); defer flags.deinit(); try flags.appendSlice(&.{ @@ -114,48 +111,52 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu } } - lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = srcs, - .flags = flags.items, - }); + if (b.lazyDependency("freetype", .{})) |upstream| { + lib.addIncludePath(upstream.path("include")); + module.addIncludePath(upstream.path("include")); + lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = srcs, + .flags = flags.items, + }); - switch (target.result.os.tag) { - .linux => lib.addCSourceFile(.{ - .file = upstream.path("builds/unix/ftsystem.c"), - .flags = flags.items, - }), - .windows => lib.addCSourceFile(.{ - .file = upstream.path("builds/windows/ftsystem.c"), - .flags = flags.items, - }), - else => lib.addCSourceFile(.{ - .file = upstream.path("src/base/ftsystem.c"), - .flags = flags.items, - }), - } - switch (target.result.os.tag) { - .windows => { - lib.addCSourceFile(.{ - .file = upstream.path("builds/windows/ftdebug.c"), + switch (target.result.os.tag) { + .linux => lib.addCSourceFile(.{ + .file = upstream.path("builds/unix/ftsystem.c"), .flags = flags.items, - }); - lib.addWin32ResourceFile(.{ - .file = upstream.path("src/base/ftver.rc"), - }); - }, - else => lib.addCSourceFile(.{ - .file = upstream.path("src/base/ftdebug.c"), - .flags = flags.items, - }), - } + }), + .windows => lib.addCSourceFile(.{ + .file = upstream.path("builds/windows/ftsystem.c"), + .flags = flags.items, + }), + else => lib.addCSourceFile(.{ + .file = upstream.path("src/base/ftsystem.c"), + .flags = flags.items, + }), + } + switch (target.result.os.tag) { + .windows => { + lib.addCSourceFile(.{ + .file = upstream.path("builds/windows/ftdebug.c"), + .flags = flags.items, + }); + lib.addWin32ResourceFile(.{ + .file = upstream.path("src/base/ftver.rc"), + }); + }, + else => lib.addCSourceFile(.{ + .file = upstream.path("src/base/ftdebug.c"), + .flags = flags.items, + }), + } - lib.installHeader(b.path("freetype-zig.h"), "freetype-zig.h"); - lib.installHeadersDirectory( - upstream.path("include"), - "", - .{ .include_extensions = &.{".h"} }, - ); + lib.installHeader(b.path("freetype-zig.h"), "freetype-zig.h"); + lib.installHeadersDirectory( + upstream.path("include"), + "", + .{ .include_extensions = &.{".h"} }, + ); + } b.installArtifact(lib); diff --git a/pkg/freetype/build.zig.zon b/pkg/freetype/build.zig.zon index 20529edff..8ed1516b1 100644 --- a/pkg/freetype/build.zig.zon +++ b/pkg/freetype/build.zig.zon @@ -8,6 +8,7 @@ .freetype = .{ .url = "https://deps.files.ghostty.org/freetype-1220b81f6ecfb3fd222f76cf9106fecfa6554ab07ec7fdc4124b9bb063ae2adf969d.tar.gz", .hash = "N-V-__8AAKLKpwC4H27Ps_0iL3bPkQb-z6ZVSrB-x_3EEkub", + .lazy = true, }, .apple_sdk = .{ .path = "../apple-sdk" }, diff --git a/pkg/gtk4-layer-shell/build.zig b/pkg/gtk4-layer-shell/build.zig index 9ad12d7ab..543faf129 100644 --- a/pkg/gtk4-layer-shell/build.zig +++ b/pkg/gtk4-layer-shell/build.zig @@ -35,14 +35,20 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu const target = options.target; const optimize = options.optimize; - const upstream = b.dependency("gtk4_layer_shell", .{}); - const wayland_protocols = b.dependency("wayland_protocols", .{}); // Shared library const lib = b.addSharedLibrary(.{ .name = "gtk4-layer-shell", .target = target, .optimize = optimize, }); + b.installArtifact(lib); + + // We need to call both lazy dependencies to tell Zig we need both + const upstream_ = b.lazyDependency("gtk4_layer_shell", .{}); + const wayland_protocols_ = b.lazyDependency("wayland_protocols", .{}); + const upstream = upstream_ orelse return lib; + const wayland_protocols = wayland_protocols_ orelse return lib; + lib.linkLibC(); lib.addIncludePath(upstream.path("include")); lib.addIncludePath(upstream.path("src")); @@ -124,6 +130,5 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu }, }); - b.installArtifact(lib); return lib; } diff --git a/pkg/gtk4-layer-shell/build.zig.zon b/pkg/gtk4-layer-shell/build.zig.zon index b9b895524..9329e374f 100644 --- a/pkg/gtk4-layer-shell/build.zig.zon +++ b/pkg/gtk4-layer-shell/build.zig.zon @@ -7,10 +7,12 @@ .gtk4_layer_shell = .{ .url = "https://deps.files.ghostty.org/gtk4-layer-shell-1.1.0.tar.gz", .hash = "N-V-__8AALiNBAA-_0gprYr92CjrMj1I5bqNu0TSJOnjFNSr", + .lazy = true, }, .wayland_protocols = .{ .url = "https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz", .hash = "N-V-__8AAKw-DAAaV8bOAAGqA0-oD7o-HNIlPFYKRXSPT03S", + .lazy = true, }, }, } diff --git a/pkg/harfbuzz/build.zig b/pkg/harfbuzz/build.zig index 4f20ccbfd..d0dd6d01c 100644 --- a/pkg/harfbuzz/build.zig +++ b/pkg/harfbuzz/build.zig @@ -84,7 +84,6 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu .@"enable-libpng" = true, }); - const upstream = b.dependency("harfbuzz", .{}); const lib = b.addStaticLibrary(.{ .name = "harfbuzz", .target = target, @@ -92,8 +91,6 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu }); lib.linkLibC(); lib.linkLibCpp(); - lib.addIncludePath(upstream.path("src")); - module.addIncludePath(upstream.path("src")); if (target.result.os.tag.isDarwin()) { try apple_sdk.addPaths(b, lib.root_module); @@ -133,7 +130,13 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu module.linkSystemLibrary("freetype2", dynamic_link_opts); } else { lib.linkLibrary(freetype.artifact("freetype")); - module.addIncludePath(freetype.builder.dependency("freetype", .{}).path("include")); + + if (freetype.builder.lazyDependency( + "freetype", + .{}, + )) |freetype_dep| { + module.addIncludePath(freetype_dep.path("include")); + } } } @@ -143,15 +146,19 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu module.linkFramework("CoreText", .{}); } - lib.addCSourceFile(.{ - .file = upstream.path("src/harfbuzz.cc"), - .flags = flags.items, - }); - lib.installHeadersDirectory( - upstream.path("src"), - "", - .{ .include_extensions = &.{".h"} }, - ); + if (b.lazyDependency("harfbuzz", .{})) |upstream| { + lib.addIncludePath(upstream.path("src")); + module.addIncludePath(upstream.path("src")); + lib.addCSourceFile(.{ + .file = upstream.path("src/harfbuzz.cc"), + .flags = flags.items, + }); + lib.installHeadersDirectory( + upstream.path("src"), + "", + .{ .include_extensions = &.{".h"} }, + ); + } b.installArtifact(lib); diff --git a/pkg/harfbuzz/build.zig.zon b/pkg/harfbuzz/build.zig.zon index fd6d24025..0422aa65b 100644 --- a/pkg/harfbuzz/build.zig.zon +++ b/pkg/harfbuzz/build.zig.zon @@ -8,6 +8,7 @@ .harfbuzz = .{ .url = "https://deps.files.ghostty.org/harfbuzz-1220b8588f106c996af10249bfa092c6fb2f35fbacb1505ef477a0b04a7dd1063122.tar.gz", .hash = "N-V-__8AAKa0rgW4WI8QbJlq8QJJv6CSxvsvNfussVBe9Heg", + .lazy = true, }, .freetype = .{ .path = "../freetype" }, diff --git a/pkg/libintl/build.zig b/pkg/libintl/build.zig index e10a97cf4..53eb67f16 100644 --- a/pkg/libintl/build.zig +++ b/pkg/libintl/build.zig @@ -22,8 +22,6 @@ pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - const upstream = b.dependency("gettext", .{}); - var flags = std.ArrayList([]const u8).init(b.allocator); defer flags.deinit(); try flags.appendSlice(&.{ @@ -39,19 +37,21 @@ pub fn build(b: *std.Build) !void { }); lib.linkLibC(); lib.addIncludePath(b.path("")); - lib.addIncludePath(upstream.path("gettext-runtime/intl")); - lib.addIncludePath(upstream.path("gettext-runtime/intl/gnulib-lib")); if (target.result.os.tag.isDarwin()) { const apple_sdk = @import("apple_sdk"); try apple_sdk.addPaths(b, lib.root_module); } - lib.addCSourceFiles(.{ - .root = upstream.path("gettext-runtime/intl"), - .files = srcs, - .flags = flags.items, - }); + if (b.lazyDependency("gettext", .{})) |upstream| { + lib.addIncludePath(upstream.path("gettext-runtime/intl")); + lib.addIncludePath(upstream.path("gettext-runtime/intl/gnulib-lib")); + lib.addCSourceFiles(.{ + .root = upstream.path("gettext-runtime/intl"), + .files = srcs, + .flags = flags.items, + }); + } lib.installHeader(b.path("libintl.h"), "libintl.h"); b.installArtifact(lib); diff --git a/pkg/libintl/build.zig.zon b/pkg/libintl/build.zig.zon index 24ee85f43..a32e20098 100644 --- a/pkg/libintl/build.zig.zon +++ b/pkg/libintl/build.zig.zon @@ -7,6 +7,7 @@ .gettext = .{ .url = "https://deps.files.ghostty.org/gettext-0.24.tar.gz", .hash = "N-V-__8AADcZkgn4cMhTUpIz6mShCKyqqB-NBtf_S2bHaTC-", + .lazy = true, }, .apple_sdk = .{ .path = "../apple-sdk" }, diff --git a/pkg/libpng/build.zig b/pkg/libpng/build.zig index c5928a667..d012f2712 100644 --- a/pkg/libpng/build.zig +++ b/pkg/libpng/build.zig @@ -4,8 +4,6 @@ pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - const upstream = b.dependency("libpng", .{}); - const lib = b.addStaticLibrary(.{ .name = "png", .target = target, @@ -31,33 +29,42 @@ pub fn build(b: *std.Build) !void { if (b.systemIntegrationOption("zlib", .{})) { lib.linkSystemLibrary2("zlib", dynamic_link_opts); } else { - const zlib_dep = b.dependency("zlib", .{ .target = target, .optimize = optimize }); - lib.linkLibrary(zlib_dep.artifact("z")); - lib.addIncludePath(upstream.path("")); - lib.addIncludePath(b.path("")); + if (b.lazyDependency( + "zlib", + .{ .target = target, .optimize = optimize }, + )) |zlib_dep| { + lib.linkLibrary(zlib_dep.artifact("z")); + lib.addIncludePath(b.path("")); + } + + if (b.lazyDependency("libpng", .{})) |upstream| { + lib.addIncludePath(upstream.path("")); + } } - var flags = std.ArrayList([]const u8).init(b.allocator); - defer flags.deinit(); - try flags.appendSlice(&.{ - "-DPNG_ARM_NEON_OPT=0", - "-DPNG_POWERPC_VSX_OPT=0", - "-DPNG_INTEL_SSE_OPT=0", - "-DPNG_MIPS_MSA_OPT=0", - }); + if (b.lazyDependency("libpng", .{})) |upstream| { + var flags = std.ArrayList([]const u8).init(b.allocator); + defer flags.deinit(); + try flags.appendSlice(&.{ + "-DPNG_ARM_NEON_OPT=0", + "-DPNG_POWERPC_VSX_OPT=0", + "-DPNG_INTEL_SSE_OPT=0", + "-DPNG_MIPS_MSA_OPT=0", + }); - lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = srcs, - .flags = flags.items, - }); + lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = srcs, + .flags = flags.items, + }); - lib.installHeader(b.path("pnglibconf.h"), "pnglibconf.h"); - lib.installHeadersDirectory( - upstream.path(""), - "", - .{ .include_extensions = &.{".h"} }, - ); + lib.installHeader(b.path("pnglibconf.h"), "pnglibconf.h"); + lib.installHeadersDirectory( + upstream.path(""), + "", + .{ .include_extensions = &.{".h"} }, + ); + } b.installArtifact(lib); } diff --git a/pkg/libpng/build.zig.zon b/pkg/libpng/build.zig.zon index e06703f62..b5153ff74 100644 --- a/pkg/libpng/build.zig.zon +++ b/pkg/libpng/build.zig.zon @@ -8,9 +8,10 @@ .libpng = .{ .url = "https://deps.files.ghostty.org/libpng-1220aa013f0c83da3fb64ea6d327f9173fa008d10e28bc9349eac3463457723b1c66.tar.gz", .hash = "N-V-__8AAJrvXQCqAT8Mg9o_tk6m0yf5Fz-gCNEOKLyTSerD", + .lazy = true, }, - .zlib = .{ .path = "../zlib" }, + .zlib = .{ .path = "../zlib", .lazy = true }, .apple_sdk = .{ .path = "../apple-sdk" }, }, } diff --git a/pkg/oniguruma/build.zig b/pkg/oniguruma/build.zig index 889a04edd..1c93bbf9a 100644 --- a/pkg/oniguruma/build.zig +++ b/pkg/oniguruma/build.zig @@ -57,7 +57,6 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu const target = options.target; const optimize = options.optimize; - const upstream = b.dependency("oniguruma", .{}); const lib = b.addStaticLibrary(.{ .name = "oniguruma", .target = target, @@ -65,98 +64,101 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu }); const t = target.result; lib.linkLibC(); - lib.addIncludePath(upstream.path("src")); - module.addIncludePath(upstream.path("src")); if (target.result.os.tag.isDarwin()) { const apple_sdk = @import("apple_sdk"); try apple_sdk.addPaths(b, lib.root_module); } - lib.addConfigHeader(b.addConfigHeader(.{ - .style = .{ .cmake = upstream.path("src/config.h.cmake.in") }, - }, .{ - .PACKAGE = "oniguruma", - .PACKAGE_VERSION = "6.9.9", - .VERSION = "6.9.9", - .HAVE_ALLOCA = true, - .HAVE_ALLOCA_H = true, - .USE_CRNL_AS_LINE_TERMINATOR = false, - .HAVE_STDINT_H = true, - .HAVE_SYS_TIMES_H = true, - .HAVE_SYS_TIME_H = true, - .HAVE_SYS_TYPES_H = true, - .HAVE_UNISTD_H = true, - .HAVE_INTTYPES_H = true, - .SIZEOF_INT = t.cTypeByteSize(.int), - .SIZEOF_LONG = t.cTypeByteSize(.long), - .SIZEOF_LONG_LONG = t.cTypeByteSize(.longlong), - .SIZEOF_VOIDP = t.ptrBitWidth() / t.cTypeBitSize(.char), - })); + if (b.lazyDependency("oniguruma", .{})) |upstream| { + lib.addIncludePath(upstream.path("src")); + module.addIncludePath(upstream.path("src")); - var flags = std.ArrayList([]const u8).init(b.allocator); - defer flags.deinit(); - try flags.appendSlice(&.{}); - lib.addCSourceFiles(.{ - .root = upstream.path(""), - .flags = flags.items, - .files = &.{ - "src/regerror.c", - "src/regparse.c", - "src/regext.c", - "src/regcomp.c", - "src/regexec.c", - "src/reggnu.c", - "src/regenc.c", - "src/regsyntax.c", - "src/regtrav.c", - "src/regversion.c", - "src/st.c", - "src/onig_init.c", - "src/unicode.c", - "src/ascii.c", - "src/utf8.c", - "src/utf16_be.c", - "src/utf16_le.c", - "src/utf32_be.c", - "src/utf32_le.c", - "src/euc_jp.c", - "src/sjis.c", - "src/iso8859_1.c", - "src/iso8859_2.c", - "src/iso8859_3.c", - "src/iso8859_4.c", - "src/iso8859_5.c", - "src/iso8859_6.c", - "src/iso8859_7.c", - "src/iso8859_8.c", - "src/iso8859_9.c", - "src/iso8859_10.c", - "src/iso8859_11.c", - "src/iso8859_13.c", - "src/iso8859_14.c", - "src/iso8859_15.c", - "src/iso8859_16.c", - "src/euc_tw.c", - "src/euc_kr.c", - "src/big5.c", - "src/gb18030.c", - "src/koi8_r.c", - "src/cp1251.c", - "src/euc_jp_prop.c", - "src/sjis_prop.c", - "src/unicode_unfold_key.c", - "src/unicode_fold1_key.c", - "src/unicode_fold2_key.c", - "src/unicode_fold3_key.c", - }, - }); + lib.addConfigHeader(b.addConfigHeader(.{ + .style = .{ .cmake = upstream.path("src/config.h.cmake.in") }, + }, .{ + .PACKAGE = "oniguruma", + .PACKAGE_VERSION = "6.9.9", + .VERSION = "6.9.9", + .HAVE_ALLOCA = true, + .HAVE_ALLOCA_H = true, + .USE_CRNL_AS_LINE_TERMINATOR = false, + .HAVE_STDINT_H = true, + .HAVE_SYS_TIMES_H = true, + .HAVE_SYS_TIME_H = true, + .HAVE_SYS_TYPES_H = true, + .HAVE_UNISTD_H = true, + .HAVE_INTTYPES_H = true, + .SIZEOF_INT = t.cTypeByteSize(.int), + .SIZEOF_LONG = t.cTypeByteSize(.long), + .SIZEOF_LONG_LONG = t.cTypeByteSize(.longlong), + .SIZEOF_VOIDP = t.ptrBitWidth() / t.cTypeBitSize(.char), + })); - lib.installHeadersDirectory( - upstream.path("src"), - "", - .{ .include_extensions = &.{".h"} }, - ); + var flags = std.ArrayList([]const u8).init(b.allocator); + defer flags.deinit(); + try flags.appendSlice(&.{}); + lib.addCSourceFiles(.{ + .root = upstream.path(""), + .flags = flags.items, + .files = &.{ + "src/regerror.c", + "src/regparse.c", + "src/regext.c", + "src/regcomp.c", + "src/regexec.c", + "src/reggnu.c", + "src/regenc.c", + "src/regsyntax.c", + "src/regtrav.c", + "src/regversion.c", + "src/st.c", + "src/onig_init.c", + "src/unicode.c", + "src/ascii.c", + "src/utf8.c", + "src/utf16_be.c", + "src/utf16_le.c", + "src/utf32_be.c", + "src/utf32_le.c", + "src/euc_jp.c", + "src/sjis.c", + "src/iso8859_1.c", + "src/iso8859_2.c", + "src/iso8859_3.c", + "src/iso8859_4.c", + "src/iso8859_5.c", + "src/iso8859_6.c", + "src/iso8859_7.c", + "src/iso8859_8.c", + "src/iso8859_9.c", + "src/iso8859_10.c", + "src/iso8859_11.c", + "src/iso8859_13.c", + "src/iso8859_14.c", + "src/iso8859_15.c", + "src/iso8859_16.c", + "src/euc_tw.c", + "src/euc_kr.c", + "src/big5.c", + "src/gb18030.c", + "src/koi8_r.c", + "src/cp1251.c", + "src/euc_jp_prop.c", + "src/sjis_prop.c", + "src/unicode_unfold_key.c", + "src/unicode_fold1_key.c", + "src/unicode_fold2_key.c", + "src/unicode_fold3_key.c", + }, + }); + + lib.installHeadersDirectory( + upstream.path("src"), + "", + .{ .include_extensions = &.{".h"} }, + ); + } b.installArtifact(lib); diff --git a/pkg/oniguruma/build.zig.zon b/pkg/oniguruma/build.zig.zon index 7c9075f4e..10ec786cb 100644 --- a/pkg/oniguruma/build.zig.zon +++ b/pkg/oniguruma/build.zig.zon @@ -8,6 +8,7 @@ .oniguruma = .{ .url = "https://deps.files.ghostty.org/oniguruma-1220c15e72eadd0d9085a8af134904d9a0f5dfcbed5f606ad60edc60ebeccd9706bb.tar.gz", .hash = "N-V-__8AAHjwMQDBXnLq3Q2QhaivE0kE2aD138vtX2Bq1g7c", + .lazy = true, }, .apple_sdk = .{ .path = "../apple-sdk" }, diff --git a/pkg/sentry/build.zig b/pkg/sentry/build.zig index 37fd772a9..3c0019710 100644 --- a/pkg/sentry/build.zig +++ b/pkg/sentry/build.zig @@ -6,14 +6,11 @@ pub fn build(b: *std.Build) !void { const backend = b.option(Backend, "backend", "Backend") orelse .inproc; const transport = b.option(Transport, "transport", "Transport") orelse .none; - const upstream = b.dependency("sentry", .{}); - const module = b.addModule("sentry", .{ .root_source_file = b.path("main.zig"), .target = target, .optimize = optimize, }); - module.addIncludePath(upstream.path("include")); const lib = b.addStaticLibrary(.{ .name = "sentry", @@ -21,8 +18,6 @@ pub fn build(b: *std.Build) !void { .optimize = optimize, }); lib.linkLibC(); - lib.addIncludePath(upstream.path("include")); - lib.addIncludePath(upstream.path("src")); if (target.result.os.tag.isDarwin()) { const apple_sdk = @import("apple_sdk"); try apple_sdk.addPaths(b, lib.root_module); @@ -48,162 +43,168 @@ pub fn build(b: *std.Build) !void { .none => {}, } - lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = srcs, - .flags = flags.items, - }); - - // Linux-only - if (target.result.os.tag == .linux) { + if (b.lazyDependency("sentry", .{})) |upstream| { + module.addIncludePath(upstream.path("include")); + lib.addIncludePath(upstream.path("include")); + lib.addIncludePath(upstream.path("src")); lib.addCSourceFiles(.{ .root = upstream.path(""), - .files = &.{ - "vendor/stb_sprintf.c", - }, + .files = srcs, .flags = flags.items, }); - } - // Symbolizer + Unwinder - if (target.result.os.tag == .windows) { - lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = &.{ - "src/sentry_windows_dbghelp.c", - "src/path/sentry_path_windows.c", - "src/symbolizer/sentry_symbolizer_windows.c", - "src/unwinder/sentry_unwinder_dbghelp.c", - }, - .flags = flags.items, - }); - } else { - lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = &.{ - "src/sentry_unix_pageallocator.c", - "src/path/sentry_path_unix.c", - "src/symbolizer/sentry_symbolizer_unix.c", - "src/unwinder/sentry_unwinder_libbacktrace.c", - }, - .flags = flags.items, - }); - } - - // Module finder - switch (target.result.os.tag) { - .windows => lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = &.{ - "src/modulefinder/sentry_modulefinder_windows.c", - }, - .flags = flags.items, - }), - - .macos, .ios => lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = &.{ - "src/modulefinder/sentry_modulefinder_apple.c", - }, - .flags = flags.items, - }), - - .linux => lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = &.{ - "src/modulefinder/sentry_modulefinder_linux.c", - }, - .flags = flags.items, - }), - - .freestanding => {}, - - else => { - std.log.warn("target={} not supported", .{target.result.os.tag}); - return error.UnsupportedTarget; - }, - } - - // Transport - switch (transport) { - .curl => lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = &.{ - "src/transports/sentry_transport_curl.c", - }, - .flags = flags.items, - }), - - .winhttp => lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = &.{ - "src/transports/sentry_transport_winhttp.c", - }, - .flags = flags.items, - }), - - .none => lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = &.{ - "src/transports/sentry_transport_none.c", - }, - .flags = flags.items, - }), - } - - // Backend - switch (backend) { - .crashpad => lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = &.{ - "src/backends/sentry_backend_crashpad.cpp", - }, - .flags = flags.items, - }), - - .breakpad => { + // Linux-only + if (target.result.os.tag == .linux) { lib.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{ - "src/backends/sentry_backend_breakpad.cpp", + "vendor/stb_sprintf.c", }, .flags = flags.items, }); + } - const breakpad_dep = b.dependency("breakpad", .{ - .target = target, - .optimize = optimize, + // Symbolizer + Unwinder + if (target.result.os.tag == .windows) { + lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = &.{ + "src/sentry_windows_dbghelp.c", + "src/path/sentry_path_windows.c", + "src/symbolizer/sentry_symbolizer_windows.c", + "src/unwinder/sentry_unwinder_dbghelp.c", + }, + .flags = flags.items, }); - lib.linkLibrary(breakpad_dep.artifact("breakpad")); + } else { + lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = &.{ + "src/sentry_unix_pageallocator.c", + "src/path/sentry_path_unix.c", + "src/symbolizer/sentry_symbolizer_unix.c", + "src/unwinder/sentry_unwinder_libbacktrace.c", + }, + .flags = flags.items, + }); + } - // We need to add this because Sentry includes some breakpad - // headers that include this vendored file... - lib.addIncludePath(breakpad_dep.path("vendor")); - }, + // Module finder + switch (target.result.os.tag) { + .windows => lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = &.{ + "src/modulefinder/sentry_modulefinder_windows.c", + }, + .flags = flags.items, + }), - .inproc => lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = &.{ - "src/backends/sentry_backend_inproc.c", + .macos, .ios => lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = &.{ + "src/modulefinder/sentry_modulefinder_apple.c", + }, + .flags = flags.items, + }), + + .linux => lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = &.{ + "src/modulefinder/sentry_modulefinder_linux.c", + }, + .flags = flags.items, + }), + + .freestanding => {}, + + else => { + std.log.warn("target={} not supported", .{target.result.os.tag}); + return error.UnsupportedTarget; }, - .flags = flags.items, - }), + } - .none => lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = &.{ - "src/backends/sentry_backend_none.c", + // Transport + switch (transport) { + .curl => lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = &.{ + "src/transports/sentry_transport_curl.c", + }, + .flags = flags.items, + }), + + .winhttp => lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = &.{ + "src/transports/sentry_transport_winhttp.c", + }, + .flags = flags.items, + }), + + .none => lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = &.{ + "src/transports/sentry_transport_none.c", + }, + .flags = flags.items, + }), + } + + // Backend + switch (backend) { + .crashpad => lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = &.{ + "src/backends/sentry_backend_crashpad.cpp", + }, + .flags = flags.items, + }), + + .breakpad => { + lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = &.{ + "src/backends/sentry_backend_breakpad.cpp", + }, + .flags = flags.items, + }); + + if (b.lazyDependency("breakpad", .{ + .target = target, + .optimize = optimize, + })) |breakpad_dep| { + lib.linkLibrary(breakpad_dep.artifact("breakpad")); + + // We need to add this because Sentry includes some breakpad + // headers that include this vendored file... + lib.addIncludePath(breakpad_dep.path("vendor")); + } }, - .flags = flags.items, - }), + + .inproc => lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = &.{ + "src/backends/sentry_backend_inproc.c", + }, + .flags = flags.items, + }), + + .none => lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = &.{ + "src/backends/sentry_backend_none.c", + }, + .flags = flags.items, + }), + } + + lib.installHeadersDirectory( + upstream.path("include"), + "", + .{ .include_extensions = &.{".h"} }, + ); } - lib.installHeadersDirectory( - upstream.path("include"), - "", - .{ .include_extensions = &.{".h"} }, - ); - b.installArtifact(lib); } diff --git a/pkg/sentry/build.zig.zon b/pkg/sentry/build.zig.zon index 96a39f05a..9c8ed0e24 100644 --- a/pkg/sentry/build.zig.zon +++ b/pkg/sentry/build.zig.zon @@ -8,9 +8,10 @@ .sentry = .{ .url = "https://deps.files.ghostty.org/sentry-1220446be831adcca918167647c06c7b825849fa3fba5f22da394667974537a9c77e.tar.gz", .hash = "N-V-__8AAPlZGwBEa-gxrcypGBZ2R8Bse4JYSfo_ul8i2jlG", + .lazy = true, }, .apple_sdk = .{ .path = "../apple-sdk" }, - .breakpad = .{ .path = "../breakpad" }, + .breakpad = .{ .path = "../breakpad", .lazy = true }, }, } diff --git a/pkg/utfcpp/build.zig b/pkg/utfcpp/build.zig index 4720d5323..6b80fec7b 100644 --- a/pkg/utfcpp/build.zig +++ b/pkg/utfcpp/build.zig @@ -4,15 +4,12 @@ pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - const upstream = b.dependency("utfcpp", .{}); - const lib = b.addStaticLibrary(.{ .name = "utfcpp", .target = target, .optimize = optimize, }); lib.linkLibCpp(); - lib.addIncludePath(upstream.path("")); if (target.result.os.tag.isDarwin()) { const apple_sdk = @import("apple_sdk"); @@ -27,11 +24,15 @@ pub fn build(b: *std.Build) !void { .flags = flags.items, .files = &.{"empty.cc"}, }); - lib.installHeadersDirectory( - upstream.path("source"), - "", - .{ .include_extensions = &.{".h"} }, - ); + + if (b.lazyDependency("utfcpp", .{})) |upstream| { + lib.addIncludePath(upstream.path("")); + lib.installHeadersDirectory( + upstream.path("source"), + "", + .{ .include_extensions = &.{".h"} }, + ); + } b.installArtifact(lib); diff --git a/pkg/utfcpp/build.zig.zon b/pkg/utfcpp/build.zig.zon index bd696ac41..eff395a60 100644 --- a/pkg/utfcpp/build.zig.zon +++ b/pkg/utfcpp/build.zig.zon @@ -8,6 +8,7 @@ .utfcpp = .{ .url = "https://deps.files.ghostty.org/utfcpp-1220d4d18426ca72fc2b7e56ce47273149815501d0d2395c2a98c726b31ba931e641.tar.gz", .hash = "N-V-__8AAHffAgDU0YQmynL8K35WzkcnMUmBVQHQ0jlcKpjH", + .lazy = true, }, .apple_sdk = .{ .path = "../apple-sdk" }, diff --git a/pkg/wuffs/build.zig b/pkg/wuffs/build.zig index a98300bd1..d47771c22 100644 --- a/pkg/wuffs/build.zig +++ b/pkg/wuffs/build.zig @@ -4,8 +4,6 @@ pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - const wuffs = b.dependency("wuffs", .{}); - const module = b.addModule("wuffs", .{ .root_source_file = b.path("src/main.zig"), .target = target, @@ -18,6 +16,13 @@ pub fn build(b: *std.Build) !void { try apple_sdk.addPaths(b, module); } + const unit_tests = b.addTest(.{ + .root_source_file = b.path("src/main.zig"), + .target = target, + .optimize = optimize, + }); + unit_tests.linkLibC(); + var flags = std.ArrayList([]const u8).init(b.allocator); defer flags.deinit(); try flags.append("-DWUFFS_IMPLEMENTATION"); @@ -25,36 +30,31 @@ pub fn build(b: *std.Build) !void { try flags.append("-D" ++ key); } - module.addIncludePath(wuffs.path("release/c")); - module.addCSourceFile(.{ - .file = wuffs.path("release/c/wuffs-v0.4.c"), - .flags = flags.items, - }); + if (b.lazyDependency("wuffs", .{})) |wuffs_dep| { + module.addIncludePath(wuffs_dep.path("release/c")); + module.addCSourceFile(.{ + .file = wuffs_dep.path("release/c/wuffs-v0.4.c"), + .flags = flags.items, + }); - const unit_tests = b.addTest(.{ - .root_source_file = b.path("src/main.zig"), - .target = target, - .optimize = optimize, - }); + unit_tests.addIncludePath(wuffs_dep.path("release/c")); + unit_tests.addCSourceFile(.{ + .file = wuffs_dep.path("release/c/wuffs-v0.4.c"), + .flags = flags.items, + }); + } - unit_tests.linkLibC(); - unit_tests.addIncludePath(wuffs.path("release/c")); - unit_tests.addCSourceFile(.{ - .file = wuffs.path("release/c/wuffs-v0.4.c"), - .flags = flags.items, - }); - - const pixels = b.dependency("pixels", .{}); - - inline for (.{ "000000", "FFFFFF" }) |color| { - inline for (.{ "gif", "jpg", "png", "ppm" }) |extension| { - const filename = std.fmt.comptimePrint("1x1#{s}.{s}", .{ color, extension }); - unit_tests.root_module.addAnonymousImport( - filename, - .{ - .root_source_file = pixels.path(filename), - }, - ); + if (b.lazyDependency("pixels", .{})) |pixels_dep| { + inline for (.{ "000000", "FFFFFF" }) |color| { + inline for (.{ "gif", "jpg", "png", "ppm" }) |extension| { + const filename = std.fmt.comptimePrint( + "1x1#{s}.{s}", + .{ color, extension }, + ); + unit_tests.root_module.addAnonymousImport(filename, .{ + .root_source_file = pixels_dep.path(filename), + }); + } } } diff --git a/pkg/wuffs/build.zig.zon b/pkg/wuffs/build.zig.zon index 3e766b635..eb99ba0b0 100644 --- a/pkg/wuffs/build.zig.zon +++ b/pkg/wuffs/build.zig.zon @@ -7,12 +7,14 @@ .wuffs = .{ .url = "https://deps.files.ghostty.org/wuffs-122037b39d577ec2db3fd7b2130e7b69ef6cc1807d68607a7c232c958315d381b5cd.tar.gz", .hash = "N-V-__8AAAzZywE3s51XfsLbP9eyEw57ae9swYB9aGB6fCMs", + .lazy = true, }, // make-github-pseudonymous-again/pixels .pixels = .{ .url = "https://deps.files.ghostty.org/pixels-12207ff340169c7d40c570b4b6a97db614fe47e0d83b5801a932dcd44917424c8806.tar.gz", .hash = "N-V-__8AADYiAAB_80AWnH1AxXC0tql9thT-R-DYO1gBqTLc", + .lazy = true, }, .apple_sdk = .{ .path = "../apple-sdk" }, diff --git a/pkg/zlib/build.zig b/pkg/zlib/build.zig index b58e94980..28ae62424 100644 --- a/pkg/zlib/build.zig +++ b/pkg/zlib/build.zig @@ -4,39 +4,39 @@ pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - const upstream = b.dependency("zlib", .{}); - const lib = b.addStaticLibrary(.{ .name = "z", .target = target, .optimize = optimize, }); lib.linkLibC(); - lib.addIncludePath(upstream.path("")); if (target.result.os.tag.isDarwin()) { const apple_sdk = @import("apple_sdk"); try apple_sdk.addPaths(b, lib.root_module); } - lib.installHeadersDirectory( - upstream.path(""), - "", - .{ .include_extensions = &.{".h"} }, - ); + if (b.lazyDependency("zlib", .{})) |upstream| { + lib.addIncludePath(upstream.path("")); + lib.installHeadersDirectory( + upstream.path(""), + "", + .{ .include_extensions = &.{".h"} }, + ); - var flags = std.ArrayList([]const u8).init(b.allocator); - defer flags.deinit(); - try flags.appendSlice(&.{ - "-DHAVE_SYS_TYPES_H", - "-DHAVE_STDINT_H", - "-DHAVE_STDDEF_H", - "-DZ_HAVE_UNISTD_H", - }); - lib.addCSourceFiles(.{ - .root = upstream.path(""), - .files = srcs, - .flags = flags.items, - }); + var flags = std.ArrayList([]const u8).init(b.allocator); + defer flags.deinit(); + try flags.appendSlice(&.{ + "-DHAVE_SYS_TYPES_H", + "-DHAVE_STDINT_H", + "-DHAVE_STDDEF_H", + "-DZ_HAVE_UNISTD_H", + }); + lib.addCSourceFiles(.{ + .root = upstream.path(""), + .files = srcs, + .flags = flags.items, + }); + } b.installArtifact(lib); } diff --git a/pkg/zlib/build.zig.zon b/pkg/zlib/build.zig.zon index 551d87040..0f75bca75 100644 --- a/pkg/zlib/build.zig.zon +++ b/pkg/zlib/build.zig.zon @@ -8,6 +8,7 @@ .zlib = .{ .url = "https://deps.files.ghostty.org/zlib-1220fed0c74e1019b3ee29edae2051788b080cd96e90d56836eea857b0b966742efb.tar.gz", .hash = "N-V-__8AAB0eQwD-0MdOEBmz7intriBReIsIDNlukNVoNu6o", + .lazy = true, }, .apple_sdk = .{ .path = "../apple-sdk" }, diff --git a/src/build/GhosttyResources.zig b/src/build/GhosttyResources.zig index 912308e46..9d463bf7d 100644 --- a/src/build/GhosttyResources.zig +++ b/src/build/GhosttyResources.zig @@ -90,8 +90,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources { } // Themes - { - const upstream = b.dependency("iterm2_themes", .{}); + if (b.lazyDependency("iterm2_themes", .{})) |upstream| { const install_step = b.addInstallDirectory(.{ .source_dir = upstream.path("ghostty"), .install_dir = .{ .custom = "share" }, diff --git a/src/build/SharedDeps.zig b/src/build/SharedDeps.zig index b9fb93839..88d64ca3c 100644 --- a/src/build/SharedDeps.zig +++ b/src/build/SharedDeps.zig @@ -1,7 +1,6 @@ const SharedDeps = @This(); const std = @import("std"); -const Scanner = @import("zig_wayland").Scanner; const Config = @import("Config.zig"); const HelpStrings = @import("HelpStrings.zig"); const MetallibStep = @import("MetallibStep.zig"); @@ -106,61 +105,72 @@ pub fn add( // Freetype _ = b.systemIntegrationOption("freetype", .{}); // Shows it in help if (self.config.font_backend.hasFreetype()) { - const freetype_dep = b.dependency("freetype", .{ + if (b.lazyDependency("freetype", .{ .target = target, .optimize = optimize, .@"enable-libpng" = true, - }); - step.root_module.addImport("freetype", freetype_dep.module("freetype")); + })) |freetype_dep| { + step.root_module.addImport( + "freetype", + freetype_dep.module("freetype"), + ); - if (b.systemIntegrationOption("freetype", .{})) { - step.linkSystemLibrary2("bzip2", dynamic_link_opts); - step.linkSystemLibrary2("freetype2", dynamic_link_opts); - } else { - step.linkLibrary(freetype_dep.artifact("freetype")); - try static_libs.append(freetype_dep.artifact("freetype").getEmittedBin()); + if (b.systemIntegrationOption("freetype", .{})) { + step.linkSystemLibrary2("bzip2", dynamic_link_opts); + step.linkSystemLibrary2("freetype2", dynamic_link_opts); + } else { + step.linkLibrary(freetype_dep.artifact("freetype")); + try static_libs.append( + freetype_dep.artifact("freetype").getEmittedBin(), + ); + } } } // Harfbuzz _ = b.systemIntegrationOption("harfbuzz", .{}); // Shows it in help if (self.config.font_backend.hasHarfbuzz()) { - const harfbuzz_dep = b.dependency("harfbuzz", .{ + if (b.lazyDependency("harfbuzz", .{ .target = target, .optimize = optimize, .@"enable-freetype" = true, .@"enable-coretext" = self.config.font_backend.hasCoretext(), - }); - - step.root_module.addImport( - "harfbuzz", - harfbuzz_dep.module("harfbuzz"), - ); - if (b.systemIntegrationOption("harfbuzz", .{})) { - step.linkSystemLibrary2("harfbuzz", dynamic_link_opts); - } else { - step.linkLibrary(harfbuzz_dep.artifact("harfbuzz")); - try static_libs.append(harfbuzz_dep.artifact("harfbuzz").getEmittedBin()); + })) |harfbuzz_dep| { + step.root_module.addImport( + "harfbuzz", + harfbuzz_dep.module("harfbuzz"), + ); + if (b.systemIntegrationOption("harfbuzz", .{})) { + step.linkSystemLibrary2("harfbuzz", dynamic_link_opts); + } else { + step.linkLibrary(harfbuzz_dep.artifact("harfbuzz")); + try static_libs.append( + harfbuzz_dep.artifact("harfbuzz").getEmittedBin(), + ); + } } } // Fontconfig _ = b.systemIntegrationOption("fontconfig", .{}); // Shows it in help if (self.config.font_backend.hasFontconfig()) { - const fontconfig_dep = b.dependency("fontconfig", .{ + if (b.lazyDependency("fontconfig", .{ .target = target, .optimize = optimize, - }); - step.root_module.addImport( - "fontconfig", - fontconfig_dep.module("fontconfig"), - ); + })) |fontconfig_dep| { + step.root_module.addImport( + "fontconfig", + fontconfig_dep.module("fontconfig"), + ); - if (b.systemIntegrationOption("fontconfig", .{})) { - step.linkSystemLibrary2("fontconfig", dynamic_link_opts); - } else { - step.linkLibrary(fontconfig_dep.artifact("fontconfig")); - try static_libs.append(fontconfig_dep.artifact("fontconfig").getEmittedBin()); + if (b.systemIntegrationOption("fontconfig", .{})) { + step.linkSystemLibrary2("fontconfig", dynamic_link_opts); + } else { + step.linkLibrary(fontconfig_dep.artifact("fontconfig")); + try static_libs.append( + fontconfig_dep.artifact("fontconfig").getEmittedBin(), + ); + } } } @@ -169,105 +179,142 @@ pub fn add( // libs list if we're not using system integration. The dependencies // will handle linking it. if (!b.systemIntegrationOption("libpng", .{})) { - const libpng_dep = b.dependency("libpng", .{ + if (b.lazyDependency("libpng", .{ .target = target, .optimize = optimize, - }); - step.linkLibrary(libpng_dep.artifact("png")); - try static_libs.append(libpng_dep.artifact("png").getEmittedBin()); + })) |libpng_dep| { + step.linkLibrary(libpng_dep.artifact("png")); + try static_libs.append( + libpng_dep.artifact("png").getEmittedBin(), + ); + } } // Zlib - same as libpng, only used through dependencies. if (!b.systemIntegrationOption("zlib", .{})) { - const zlib_dep = b.dependency("zlib", .{ + if (b.lazyDependency("zlib", .{ .target = target, .optimize = optimize, - }); - step.linkLibrary(zlib_dep.artifact("z")); - try static_libs.append(zlib_dep.artifact("z").getEmittedBin()); + })) |zlib_dep| { + step.linkLibrary(zlib_dep.artifact("z")); + try static_libs.append( + zlib_dep.artifact("z").getEmittedBin(), + ); + } } // Oniguruma - const oniguruma_dep = b.dependency("oniguruma", .{ + if (b.lazyDependency("oniguruma", .{ .target = target, .optimize = optimize, - }); - step.root_module.addImport("oniguruma", oniguruma_dep.module("oniguruma")); - if (b.systemIntegrationOption("oniguruma", .{})) { - step.linkSystemLibrary2("oniguruma", dynamic_link_opts); - } else { - step.linkLibrary(oniguruma_dep.artifact("oniguruma")); - try static_libs.append(oniguruma_dep.artifact("oniguruma").getEmittedBin()); + })) |oniguruma_dep| { + step.root_module.addImport( + "oniguruma", + oniguruma_dep.module("oniguruma"), + ); + if (b.systemIntegrationOption("oniguruma", .{})) { + step.linkSystemLibrary2("oniguruma", dynamic_link_opts); + } else { + step.linkLibrary(oniguruma_dep.artifact("oniguruma")); + try static_libs.append( + oniguruma_dep.artifact("oniguruma").getEmittedBin(), + ); + } } // Glslang - const glslang_dep = b.dependency("glslang", .{ + if (b.lazyDependency("glslang", .{ .target = target, .optimize = optimize, - }); - step.root_module.addImport("glslang", glslang_dep.module("glslang")); - if (b.systemIntegrationOption("glslang", .{})) { - step.linkSystemLibrary2("glslang", dynamic_link_opts); - step.linkSystemLibrary2("glslang-default-resource-limits", dynamic_link_opts); - } else { - step.linkLibrary(glslang_dep.artifact("glslang")); - try static_libs.append(glslang_dep.artifact("glslang").getEmittedBin()); + })) |glslang_dep| { + step.root_module.addImport("glslang", glslang_dep.module("glslang")); + if (b.systemIntegrationOption("glslang", .{})) { + step.linkSystemLibrary2("glslang", dynamic_link_opts); + step.linkSystemLibrary2( + "glslang-default-resource-limits", + dynamic_link_opts, + ); + } else { + step.linkLibrary(glslang_dep.artifact("glslang")); + try static_libs.append( + glslang_dep.artifact("glslang").getEmittedBin(), + ); + } } // Spirv-cross - const spirv_cross_dep = b.dependency("spirv_cross", .{ + if (b.lazyDependency("spirv_cross", .{ .target = target, .optimize = optimize, - }); - step.root_module.addImport("spirv_cross", spirv_cross_dep.module("spirv_cross")); - if (b.systemIntegrationOption("spirv-cross", .{})) { - step.linkSystemLibrary2("spirv-cross", dynamic_link_opts); - } else { - step.linkLibrary(spirv_cross_dep.artifact("spirv_cross")); - try static_libs.append(spirv_cross_dep.artifact("spirv_cross").getEmittedBin()); + })) |spirv_cross_dep| { + step.root_module.addImport( + "spirv_cross", + spirv_cross_dep.module("spirv_cross"), + ); + if (b.systemIntegrationOption("spirv-cross", .{})) { + step.linkSystemLibrary2("spirv-cross", dynamic_link_opts); + } else { + step.linkLibrary(spirv_cross_dep.artifact("spirv_cross")); + try static_libs.append( + spirv_cross_dep.artifact("spirv_cross").getEmittedBin(), + ); + } } // Simdutf if (b.systemIntegrationOption("simdutf", .{})) { step.linkSystemLibrary2("simdutf", dynamic_link_opts); } else { - const simdutf_dep = b.dependency("simdutf", .{ + if (b.lazyDependency("simdutf", .{ .target = target, .optimize = optimize, - }); - step.linkLibrary(simdutf_dep.artifact("simdutf")); - try static_libs.append(simdutf_dep.artifact("simdutf").getEmittedBin()); + })) |simdutf_dep| { + step.linkLibrary(simdutf_dep.artifact("simdutf")); + try static_libs.append( + simdutf_dep.artifact("simdutf").getEmittedBin(), + ); + } } // Sentry if (self.config.sentry) { - const sentry_dep = b.dependency("sentry", .{ + if (b.lazyDependency("sentry", .{ .target = target, .optimize = optimize, .backend = .breakpad, - }); + })) |sentry_dep| { + step.root_module.addImport( + "sentry", + sentry_dep.module("sentry"), + ); + step.linkLibrary(sentry_dep.artifact("sentry")); + try static_libs.append( + sentry_dep.artifact("sentry").getEmittedBin(), + ); - step.root_module.addImport("sentry", sentry_dep.module("sentry")); - - // Sentry - step.linkLibrary(sentry_dep.artifact("sentry")); - try static_libs.append(sentry_dep.artifact("sentry").getEmittedBin()); - - // We also need to include breakpad in the static libs. - const breakpad_dep = sentry_dep.builder.dependency("breakpad", .{ - .target = target, - .optimize = optimize, - }); - try static_libs.append(breakpad_dep.artifact("breakpad").getEmittedBin()); + // We also need to include breakpad in the static libs. + if (sentry_dep.builder.lazyDependency("breakpad", .{ + .target = target, + .optimize = optimize, + })) |breakpad_dep| { + try static_libs.append( + breakpad_dep.artifact("breakpad").getEmittedBin(), + ); + } + } } // Wasm we do manually since it is such a different build. if (step.rootModuleTarget().cpu.arch == .wasm32) { - const js_dep = b.dependency("zig_js", .{ + if (b.lazyDependency("zig_js", .{ .target = target, .optimize = optimize, - }); - step.root_module.addImport("zig-js", js_dep.module("zig-js")); + })) |js_dep| { + step.root_module.addImport( + "zig-js", + js_dep.module("zig-js"), + ); + } return static_libs; } @@ -334,52 +381,72 @@ pub fn add( } // Other dependencies, mostly pure Zig - step.root_module.addImport("opengl", b.dependency( - "opengl", - .{}, - ).module("opengl")); - step.root_module.addImport("vaxis", b.dependency("vaxis", .{ + if (b.lazyDependency("opengl", .{})) |dep| { + step.root_module.addImport("opengl", dep.module("opengl")); + } + if (b.lazyDependency("vaxis", .{})) |dep| { + step.root_module.addImport("vaxis", dep.module("vaxis")); + } + if (b.lazyDependency("wuffs", .{ .target = target, .optimize = optimize, - }).module("vaxis")); - step.root_module.addImport("wuffs", b.dependency("wuffs", .{ + })) |dep| { + step.root_module.addImport("wuffs", dep.module("wuffs")); + } + if (b.lazyDependency("libxev", .{ .target = target, .optimize = optimize, - }).module("wuffs")); - step.root_module.addImport("xev", b.dependency("libxev", .{ + })) |dep| { + step.root_module.addImport("xev", dep.module("xev")); + } + if (b.lazyDependency("z2d", .{})) |dep| { + step.root_module.addImport("z2d", b.addModule("z2d", .{ + .root_source_file = dep.path("src/z2d.zig"), + .target = target, + .optimize = optimize, + })); + } + if (b.lazyDependency("ziglyph", .{ .target = target, .optimize = optimize, - }).module("xev")); - step.root_module.addImport("z2d", b.addModule("z2d", .{ - .root_source_file = b.dependency("z2d", .{}).path("src/z2d.zig"), - .target = target, - .optimize = optimize, - })); - step.root_module.addImport("ziglyph", b.dependency("ziglyph", .{ - .target = target, - .optimize = optimize, - }).module("ziglyph")); - step.root_module.addImport("zf", b.dependency("zf", .{ + })) |dep| { + step.root_module.addImport("ziglyph", dep.module("ziglyph")); + } + if (b.lazyDependency("zf", .{ .target = target, .optimize = optimize, .with_tui = false, - }).module("zf")); + })) |dep| { + step.root_module.addImport("zf", dep.module("zf")); + } // Mac Stuff if (step.rootModuleTarget().os.tag.isDarwin()) { - const objc_dep = b.dependency("zig_objc", .{ + if (b.lazyDependency("zig_objc", .{ .target = target, .optimize = optimize, - }); - const macos_dep = b.dependency("macos", .{ - .target = target, - .optimize = optimize, - }); + })) |objc_dep| { + step.root_module.addImport( + "objc", + objc_dep.module("objc"), + ); + } - step.root_module.addImport("objc", objc_dep.module("objc")); - step.root_module.addImport("macos", macos_dep.module("macos")); - step.linkLibrary(macos_dep.artifact("macos")); - try static_libs.append(macos_dep.artifact("macos").getEmittedBin()); + if (b.lazyDependency("macos", .{ + .target = target, + .optimize = optimize, + })) |macos_dep| { + step.root_module.addImport( + "macos", + macos_dep.module("macos"), + ); + step.linkLibrary( + macos_dep.artifact("macos"), + ); + try static_libs.append( + macos_dep.artifact("macos").getEmittedBin(), + ); + } if (self.config.renderer == .opengl) { step.linkFramework("OpenGL"); @@ -389,38 +456,44 @@ pub fn add( // This is LGPL but since our source code is open source we are // in compliance with the LGPL since end users can modify this // build script to replace the bundled libintl with their own. - const libintl_dep = b.dependency("libintl", .{ + if (b.lazyDependency("libintl", .{ .target = target, .optimize = optimize, - }); - step.linkLibrary(libintl_dep.artifact("intl")); - try static_libs.append(libintl_dep.artifact("intl").getEmittedBin()); + })) |libintl_dep| { + step.linkLibrary(libintl_dep.artifact("intl")); + try static_libs.append( + libintl_dep.artifact("intl").getEmittedBin(), + ); + } } // cimgui - const cimgui_dep = b.dependency("cimgui", .{ + if (b.lazyDependency("cimgui", .{ .target = target, .optimize = optimize, - }); - step.root_module.addImport("cimgui", cimgui_dep.module("cimgui")); - step.linkLibrary(cimgui_dep.artifact("cimgui")); - try static_libs.append(cimgui_dep.artifact("cimgui").getEmittedBin()); + })) |cimgui_dep| { + step.root_module.addImport("cimgui", cimgui_dep.module("cimgui")); + step.linkLibrary(cimgui_dep.artifact("cimgui")); + try static_libs.append(cimgui_dep.artifact("cimgui").getEmittedBin()); + } // Highway - const highway_dep = b.dependency("highway", .{ + if (b.lazyDependency("highway", .{ .target = target, .optimize = optimize, - }); - step.linkLibrary(highway_dep.artifact("highway")); - try static_libs.append(highway_dep.artifact("highway").getEmittedBin()); + })) |highway_dep| { + step.linkLibrary(highway_dep.artifact("highway")); + try static_libs.append(highway_dep.artifact("highway").getEmittedBin()); + } // utfcpp - This is used as a dependency on our hand-written C++ code - const utfcpp_dep = b.dependency("utfcpp", .{ + if (b.lazyDependency("utfcpp", .{ .target = target, .optimize = optimize, - }); - step.linkLibrary(utfcpp_dep.artifact("utfcpp")); - try static_libs.append(utfcpp_dep.artifact("utfcpp").getEmittedBin()); + })) |utfcpp_dep| { + step.linkLibrary(utfcpp_dep.artifact("utfcpp")); + try static_libs.append(utfcpp_dep.artifact("utfcpp").getEmittedBin()); + } // If we're building an exe then we have additional dependencies. if (step.kind != .lib) { @@ -438,181 +511,17 @@ pub fn add( switch (self.config.app_runtime) { .none => {}, - .glfw => { - const glfw_dep = b.dependency("glfw", .{ - .target = target, - .optimize = optimize, - }); + .glfw => if (b.lazyDependency("glfw", .{ + .target = target, + .optimize = optimize, + })) |glfw_dep| { step.root_module.addImport( "glfw", glfw_dep.module("glfw"), ); }, - .gtk => { - const gobject = b.dependency("gobject", .{ - .target = target, - .optimize = optimize, - }); - const gobject_imports = .{ - .{ "adw", "adw1" }, - .{ "gdk", "gdk4" }, - .{ "gio", "gio2" }, - .{ "glib", "glib2" }, - .{ "gobject", "gobject2" }, - .{ "gtk", "gtk4" }, - }; - inline for (gobject_imports) |import| { - const name, const module = import; - step.root_module.addImport(name, gobject.module(module)); - } - - step.linkSystemLibrary2("gtk4", dynamic_link_opts); - step.linkSystemLibrary2("libadwaita-1", dynamic_link_opts); - - if (self.config.x11) { - step.linkSystemLibrary2("X11", dynamic_link_opts); - step.root_module.addImport("gdk_x11", gobject.module("gdkx114")); - } - - if (self.config.wayland) { - const scanner = Scanner.create(b.dependency("zig_wayland", .{}).builder, .{ - .wayland_xml = b.dependency("wayland", .{}).path("protocol/wayland.xml"), - .wayland_protocols = b.dependency("wayland_protocols", .{}).path(""), - }); - - const wayland = b.createModule(.{ .root_source_file = scanner.result }); - - const plasma_wayland_protocols = b.dependency("plasma_wayland_protocols", .{ - .target = target, - .optimize = optimize, - }); - - // FIXME: replace with `zxdg_decoration_v1` once GTK merges https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/6398 - scanner.addCustomProtocol(plasma_wayland_protocols.path("src/protocols/blur.xml")); - scanner.addCustomProtocol(plasma_wayland_protocols.path("src/protocols/server-decoration.xml")); - scanner.addCustomProtocol(plasma_wayland_protocols.path("src/protocols/slide.xml")); - - scanner.generate("wl_compositor", 1); - scanner.generate("org_kde_kwin_blur_manager", 1); - scanner.generate("org_kde_kwin_server_decoration_manager", 1); - scanner.generate("org_kde_kwin_slide_manager", 1); - - step.root_module.addImport("wayland", wayland); - step.root_module.addImport("gdk_wayland", gobject.module("gdkwayland4")); - - const gtk4_layer_shell = b.dependency("gtk4_layer_shell", .{ - .target = target, - .optimize = optimize, - }); - const layer_shell_module = gtk4_layer_shell.module("gtk4-layer-shell"); - layer_shell_module.addImport("gtk", gobject.module("gtk4")); - step.root_module.addImport("gtk4-layer-shell", layer_shell_module); - - // IMPORTANT: gtk4-layer-shell must be linked BEFORE - // wayland-client, as it relies on shimming libwayland's APIs. - if (b.systemIntegrationOption("gtk4-layer-shell", .{})) { - step.linkSystemLibrary2("gtk4-layer-shell-0", dynamic_link_opts); - } else { - // gtk4-layer-shell *must* be dynamically linked, - // so we don't add it as a static library - step.linkLibrary(gtk4_layer_shell.artifact("gtk4-layer-shell")); - } - - step.linkSystemLibrary2("wayland-client", dynamic_link_opts); - } - - { - const gresource = @import("../apprt/gtk/gresource.zig"); - - const gresource_xml = gresource_xml: { - const generate_gresource_xml = b.addExecutable(.{ - .name = "generate_gresource_xml", - .root_source_file = b.path("src/apprt/gtk/gresource.zig"), - .target = b.graph.host, - }); - - const generate = b.addRunArtifact(generate_gresource_xml); - - const gtk_blueprint_compiler = b.addExecutable(.{ - .name = "gtk_blueprint_compiler", - .root_source_file = b.path("src/apprt/gtk/blueprint_compiler.zig"), - .target = b.graph.host, - }); - gtk_blueprint_compiler.linkSystemLibrary2("gtk4", dynamic_link_opts); - gtk_blueprint_compiler.linkSystemLibrary2("libadwaita-1", dynamic_link_opts); - gtk_blueprint_compiler.linkLibC(); - - for (gresource.blueprint_files) |blueprint_file| { - const blueprint_compiler = b.addRunArtifact(gtk_blueprint_compiler); - blueprint_compiler.addArgs(&.{ - b.fmt("{d}", .{blueprint_file.major}), - b.fmt("{d}", .{blueprint_file.minor}), - }); - const ui_file = blueprint_compiler.addOutputFileArg(b.fmt( - "{d}.{d}/{s}.ui", - .{ - blueprint_file.major, - blueprint_file.minor, - blueprint_file.name, - }, - )); - blueprint_compiler.addFileArg(b.path(b.fmt( - "src/apprt/gtk/ui/{d}.{d}/{s}.blp", - .{ - blueprint_file.major, - blueprint_file.minor, - blueprint_file.name, - }, - ))); - generate.addFileArg(ui_file); - } - - break :gresource_xml generate.captureStdOut(); - }; - - { - const gtk_builder_check = b.addExecutable(.{ - .name = "gtk_builder_check", - .root_source_file = b.path("src/apprt/gtk/builder_check.zig"), - .target = b.graph.host, - }); - gtk_builder_check.root_module.addOptions("build_options", self.options); - gtk_builder_check.root_module.addImport("gtk", gobject.module("gtk4")); - gtk_builder_check.root_module.addImport("adw", gobject.module("adw1")); - - for (gresource.dependencies) |pathname| { - const extension = std.fs.path.extension(pathname); - if (!std.mem.eql(u8, extension, ".ui")) continue; - const check = b.addRunArtifact(gtk_builder_check); - check.addFileArg(b.path(pathname)); - step.step.dependOn(&check.step); - } - } - - const generate_resources_c = b.addSystemCommand(&.{ - "glib-compile-resources", - "--c-name", - "ghostty", - "--generate-source", - "--target", - }); - const ghostty_resources_c = generate_resources_c.addOutputFileArg("ghostty_resources.c"); - generate_resources_c.addFileArg(gresource_xml); - step.addCSourceFile(.{ .file = ghostty_resources_c, .flags = &.{} }); - - const generate_resources_h = b.addSystemCommand(&.{ - "glib-compile-resources", - "--c-name", - "ghostty", - "--generate-header", - "--target", - }); - const ghostty_resources_h = generate_resources_h.addOutputFileArg("ghostty_resources.h"); - generate_resources_h.addFileArg(gresource_xml); - step.addIncludePath(ghostty_resources_h.dirname()); - } - }, + .gtk => try self.addGTK(step), } } @@ -623,6 +532,231 @@ pub fn add( return static_libs; } +/// Setup the dependencies for the GTK apprt build. The GTK apprt +/// is particularly involved compared to others so we pull this out +/// into a dedicated function. +fn addGTK( + self: *const SharedDeps, + step: *std.Build.Step.Compile, +) !void { + const b = step.step.owner; + const target = step.root_module.resolved_target.?; + const optimize = step.root_module.optimize.?; + + const gobject_ = b.lazyDependency("gobject", .{ + .target = target, + .optimize = optimize, + }); + if (gobject_) |gobject| { + const gobject_imports = .{ + .{ "adw", "adw1" }, + .{ "gdk", "gdk4" }, + .{ "gio", "gio2" }, + .{ "glib", "glib2" }, + .{ "gobject", "gobject2" }, + .{ "gtk", "gtk4" }, + }; + inline for (gobject_imports) |import| { + const name, const module = import; + step.root_module.addImport(name, gobject.module(module)); + } + } + + step.linkSystemLibrary2("gtk4", dynamic_link_opts); + step.linkSystemLibrary2("libadwaita-1", dynamic_link_opts); + + if (self.config.x11) { + step.linkSystemLibrary2("X11", dynamic_link_opts); + if (gobject_) |gobject| { + step.root_module.addImport( + "gdk_x11", + gobject.module("gdkx114"), + ); + } + } + + if (self.config.wayland) wayland: { + // These need to be all be called to note that we need them. + const wayland_dep_ = b.lazyDependency("wayland", .{}); + const wayland_protocols_dep_ = b.lazyDependency( + "wayland_protocols", + .{}, + ); + const plasma_wayland_protocols_dep_ = b.lazyDependency( + "plasma_wayland_protocols", + .{}, + ); + + // Unwrap or return, there are no more dependencies below. + const wayland_dep = wayland_dep_ orelse break :wayland; + const wayland_protocols_dep = wayland_protocols_dep_ orelse break :wayland; + const plasma_wayland_protocols_dep = plasma_wayland_protocols_dep_ orelse break :wayland; + + // Note that zig_wayland cannot be lazy because lazy dependencies + // can't be imported since they don't exist and imports are + // resolved at compile time of the build. + const zig_wayland_dep = b.dependency("zig_wayland", .{}); + const Scanner = @import("zig_wayland").Scanner; + const scanner = Scanner.create(zig_wayland_dep.builder, .{ + .wayland_xml = wayland_dep.path("protocol/wayland.xml"), + .wayland_protocols = wayland_protocols_dep.path(""), + }); + + // FIXME: replace with `zxdg_decoration_v1` once GTK merges https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/6398 + scanner.addCustomProtocol( + plasma_wayland_protocols_dep.path("src/protocols/blur.xml"), + ); + scanner.addCustomProtocol( + plasma_wayland_protocols_dep.path("src/protocols/server-decoration.xml"), + ); + scanner.addCustomProtocol( + plasma_wayland_protocols_dep.path("src/protocols/slide.xml"), + ); + + scanner.generate("wl_compositor", 1); + scanner.generate("org_kde_kwin_blur_manager", 1); + scanner.generate("org_kde_kwin_server_decoration_manager", 1); + scanner.generate("org_kde_kwin_slide_manager", 1); + + step.root_module.addImport("wayland", b.createModule(.{ + .root_source_file = scanner.result, + })); + if (gobject_) |gobject| step.root_module.addImport( + "gdk_wayland", + gobject.module("gdkwayland4"), + ); + + if (b.lazyDependency("gtk4_layer_shell", .{ + .target = target, + .optimize = optimize, + })) |gtk4_layer_shell| { + const layer_shell_module = gtk4_layer_shell.module("gtk4-layer-shell"); + if (gobject_) |gobject| layer_shell_module.addImport( + "gtk", + gobject.module("gtk4"), + ); + step.root_module.addImport( + "gtk4-layer-shell", + layer_shell_module, + ); + + // IMPORTANT: gtk4-layer-shell must be linked BEFORE + // wayland-client, as it relies on shimming libwayland's APIs. + if (b.systemIntegrationOption("gtk4-layer-shell", .{})) { + step.linkSystemLibrary2( + "gtk4-layer-shell-0", + dynamic_link_opts, + ); + } else { + // gtk4-layer-shell *must* be dynamically linked, + // so we don't add it as a static library + step.linkLibrary(gtk4_layer_shell.artifact("gtk4-layer-shell")); + } + } + + step.linkSystemLibrary2("wayland-client", dynamic_link_opts); + } + + { + const gresource = @import("../apprt/gtk/gresource.zig"); + + const gresource_xml = gresource_xml: { + const generate_gresource_xml = b.addExecutable(.{ + .name = "generate_gresource_xml", + .root_source_file = b.path("src/apprt/gtk/gresource.zig"), + .target = b.graph.host, + }); + + const generate = b.addRunArtifact(generate_gresource_xml); + + const gtk_blueprint_compiler = b.addExecutable(.{ + .name = "gtk_blueprint_compiler", + .root_source_file = b.path("src/apprt/gtk/blueprint_compiler.zig"), + .target = b.graph.host, + }); + gtk_blueprint_compiler.linkSystemLibrary2("gtk4", dynamic_link_opts); + gtk_blueprint_compiler.linkSystemLibrary2("libadwaita-1", dynamic_link_opts); + gtk_blueprint_compiler.linkLibC(); + + for (gresource.blueprint_files) |blueprint_file| { + const blueprint_compiler = b.addRunArtifact(gtk_blueprint_compiler); + blueprint_compiler.addArgs(&.{ + b.fmt("{d}", .{blueprint_file.major}), + b.fmt("{d}", .{blueprint_file.minor}), + }); + const ui_file = blueprint_compiler.addOutputFileArg(b.fmt( + "{d}.{d}/{s}.ui", + .{ + blueprint_file.major, + blueprint_file.minor, + blueprint_file.name, + }, + )); + blueprint_compiler.addFileArg(b.path(b.fmt( + "src/apprt/gtk/ui/{d}.{d}/{s}.blp", + .{ + blueprint_file.major, + blueprint_file.minor, + blueprint_file.name, + }, + ))); + generate.addFileArg(ui_file); + } + + break :gresource_xml generate.captureStdOut(); + }; + + { + const gtk_builder_check = b.addExecutable(.{ + .name = "gtk_builder_check", + .root_source_file = b.path("src/apprt/gtk/builder_check.zig"), + .target = b.graph.host, + }); + gtk_builder_check.root_module.addOptions("build_options", self.options); + if (gobject_) |gobject| { + gtk_builder_check.root_module.addImport( + "gtk", + gobject.module("gtk4"), + ); + gtk_builder_check.root_module.addImport( + "adw", + gobject.module("adw1"), + ); + } + + for (gresource.dependencies) |pathname| { + const extension = std.fs.path.extension(pathname); + if (!std.mem.eql(u8, extension, ".ui")) continue; + const check = b.addRunArtifact(gtk_builder_check); + check.addFileArg(b.path(pathname)); + step.step.dependOn(&check.step); + } + } + + const generate_resources_c = b.addSystemCommand(&.{ + "glib-compile-resources", + "--c-name", + "ghostty", + "--generate-source", + "--target", + }); + const ghostty_resources_c = generate_resources_c.addOutputFileArg("ghostty_resources.c"); + generate_resources_c.addFileArg(gresource_xml); + step.addCSourceFile(.{ .file = ghostty_resources_c, .flags = &.{} }); + + const generate_resources_h = b.addSystemCommand(&.{ + "glib-compile-resources", + "--c-name", + "ghostty", + "--generate-header", + "--target", + }); + const ghostty_resources_h = generate_resources_h.addOutputFileArg("ghostty_resources.h"); + generate_resources_h.addFileArg(gresource_xml); + step.addIncludePath(ghostty_resources_h.dirname()); + } +} + // For dynamic linking, we prefer dynamic linking and to search by // mode first. Mode first will search all paths for a dynamic library // before falling back to static. diff --git a/src/build/UnicodeTables.zig b/src/build/UnicodeTables.zig index d50ec3099..58af17a6e 100644 --- a/src/build/UnicodeTables.zig +++ b/src/build/UnicodeTables.zig @@ -16,10 +16,14 @@ pub fn init(b: *std.Build) !UnicodeTables { .target = b.graph.host, }); - const ziglyph_dep = b.dependency("ziglyph", .{ + if (b.lazyDependency("ziglyph", .{ .target = b.graph.host, - }); - exe.root_module.addImport("ziglyph", ziglyph_dep.module("ziglyph")); + })) |ziglyph_dep| { + exe.root_module.addImport( + "ziglyph", + ziglyph_dep.module("ziglyph"), + ); + } const run = b.addRunArtifact(exe); return .{