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
This commit is contained in:
Mitchell Hashimoto 2025-03-13 21:30:24 -07:00
parent 234b804872
commit cfea2ea12c
No known key found for this signature in database
GPG Key ID: 523D5DC389D273BC
29 changed files with 977 additions and 781 deletions

View File

@ -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,
},
},
}

View File

@ -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);
}

View File

@ -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" },

View File

@ -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(""));

View File

@ -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);

View File

@ -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 },
},
}

View File

@ -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);

View File

@ -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" },

View File

@ -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;
}

View File

@ -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,
},
},
}

View File

@ -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);

View File

@ -8,6 +8,7 @@
.harfbuzz = .{
.url = "https://deps.files.ghostty.org/harfbuzz-1220b8588f106c996af10249bfa092c6fb2f35fbacb1505ef477a0b04a7dd1063122.tar.gz",
.hash = "N-V-__8AAKa0rgW4WI8QbJlq8QJJv6CSxvsvNfussVBe9Heg",
.lazy = true,
},
.freetype = .{ .path = "../freetype" },

View File

@ -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);

View File

@ -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" },

View File

@ -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);
}

View File

@ -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" },
},
}

View File

@ -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);

View File

@ -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" },

View File

@ -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);
}

View File

@ -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 },
},
}

View File

@ -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);

View File

@ -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" },

View File

@ -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),
});
}
}
}

View File

@ -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" },

View File

@ -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);
}

View File

@ -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" },

View File

@ -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" },

View File

@ -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.

View File

@ -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 .{