mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-18 01:36:08 +03:00
apprt/gtk-ng: gresource creation, resource registration in Application
This commit is contained in:
172
src/apprt/gtk-ng/build/blueprint.zig
Normal file
172
src/apprt/gtk-ng/build/blueprint.zig
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
//! Compiles a blueprint file using `blueprint-compiler`. This performs
|
||||||
|
//! additional checks to ensure that various minimum versions are met.
|
||||||
|
//!
|
||||||
|
//! Usage: blueprint.zig <major> <minor> <output> <input>
|
||||||
|
//!
|
||||||
|
//! Example: blueprint.zig 1 5 output.ui input.blp
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub const c = @cImport({
|
||||||
|
@cInclude("adwaita.h");
|
||||||
|
});
|
||||||
|
|
||||||
|
const adwaita_version = std.SemanticVersion{
|
||||||
|
.major = c.ADW_MAJOR_VERSION,
|
||||||
|
.minor = c.ADW_MINOR_VERSION,
|
||||||
|
.patch = c.ADW_MICRO_VERSION,
|
||||||
|
};
|
||||||
|
const required_blueprint_version = std.SemanticVersion{
|
||||||
|
.major = 0,
|
||||||
|
.minor = 16,
|
||||||
|
.patch = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
var debug_allocator: std.heap.DebugAllocator(.{}) = .init;
|
||||||
|
defer _ = debug_allocator.deinit();
|
||||||
|
const alloc = debug_allocator.allocator();
|
||||||
|
|
||||||
|
// Get our args
|
||||||
|
var it = try std.process.argsWithAllocator(alloc);
|
||||||
|
defer it.deinit();
|
||||||
|
_ = it.next(); // Skip argv0
|
||||||
|
const arg_major = it.next() orelse return error.NoMajorVersion;
|
||||||
|
const arg_minor = it.next() orelse return error.NoMinorVersion;
|
||||||
|
const output = it.next() orelse return error.NoOutput;
|
||||||
|
const input = it.next() orelse return error.NoInput;
|
||||||
|
|
||||||
|
const required_adwaita_version = std.SemanticVersion{
|
||||||
|
.major = try std.fmt.parseUnsigned(u8, arg_major, 10),
|
||||||
|
.minor = try std.fmt.parseUnsigned(u8, arg_minor, 10),
|
||||||
|
.patch = 0,
|
||||||
|
};
|
||||||
|
if (adwaita_version.order(required_adwaita_version) == .lt) {
|
||||||
|
std.debug.print(
|
||||||
|
\\`libadwaita` is too old.
|
||||||
|
\\
|
||||||
|
\\Ghostty requires a version {} or newer of `libadwaita` to
|
||||||
|
\\compile this blueprint. Please install it, ensure that it is
|
||||||
|
\\available on your PATH, and then retry building Ghostty.
|
||||||
|
, .{required_adwaita_version});
|
||||||
|
std.posix.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version checks
|
||||||
|
{
|
||||||
|
var stdout: std.ArrayListUnmanaged(u8) = .empty;
|
||||||
|
defer stdout.deinit(alloc);
|
||||||
|
var stderr: std.ArrayListUnmanaged(u8) = .empty;
|
||||||
|
defer stderr.deinit(alloc);
|
||||||
|
|
||||||
|
var blueprint_compiler = std.process.Child.init(
|
||||||
|
&.{
|
||||||
|
"blueprint-compiler",
|
||||||
|
"--version",
|
||||||
|
},
|
||||||
|
alloc,
|
||||||
|
);
|
||||||
|
blueprint_compiler.stdout_behavior = .Pipe;
|
||||||
|
blueprint_compiler.stderr_behavior = .Pipe;
|
||||||
|
try blueprint_compiler.spawn();
|
||||||
|
try blueprint_compiler.collectOutput(
|
||||||
|
alloc,
|
||||||
|
&stdout,
|
||||||
|
&stderr,
|
||||||
|
std.math.maxInt(u16),
|
||||||
|
);
|
||||||
|
const term = blueprint_compiler.wait() catch |err| switch (err) {
|
||||||
|
error.FileNotFound => {
|
||||||
|
std.debug.print(
|
||||||
|
\\`blueprint-compiler` not found.
|
||||||
|
\\
|
||||||
|
\\Ghostty requires version {} or newer of
|
||||||
|
\\`blueprint-compiler` as a build-time dependency starting
|
||||||
|
\\from version 1.2. Please install it, ensure that it is
|
||||||
|
\\available on your PATH, and then retry building Ghostty.
|
||||||
|
\\
|
||||||
|
, .{required_blueprint_version});
|
||||||
|
std.posix.exit(1);
|
||||||
|
},
|
||||||
|
else => return err,
|
||||||
|
};
|
||||||
|
switch (term) {
|
||||||
|
.Exited => |rc| if (rc != 0) std.process.exit(1),
|
||||||
|
else => std.process.exit(1),
|
||||||
|
}
|
||||||
|
|
||||||
|
const version = try std.SemanticVersion.parse(std.mem.trim(
|
||||||
|
u8,
|
||||||
|
stdout.items,
|
||||||
|
&std.ascii.whitespace,
|
||||||
|
));
|
||||||
|
if (version.order(required_blueprint_version) == .lt) {
|
||||||
|
std.debug.print(
|
||||||
|
\\`blueprint-compiler` is the wrong version.
|
||||||
|
\\
|
||||||
|
\\Ghostty requires version {} or newer of
|
||||||
|
\\`blueprint-compiler` as a build-time dependency starting
|
||||||
|
\\from version 1.2. Please install it, ensure that it is
|
||||||
|
\\available on your PATH, and then retry building Ghostty.
|
||||||
|
\\
|
||||||
|
, .{required_blueprint_version});
|
||||||
|
std.posix.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compilation
|
||||||
|
{
|
||||||
|
var stdout: std.ArrayListUnmanaged(u8) = .empty;
|
||||||
|
defer stdout.deinit(alloc);
|
||||||
|
var stderr: std.ArrayListUnmanaged(u8) = .empty;
|
||||||
|
defer stderr.deinit(alloc);
|
||||||
|
|
||||||
|
var blueprint_compiler = std.process.Child.init(
|
||||||
|
&.{
|
||||||
|
"blueprint-compiler",
|
||||||
|
"compile",
|
||||||
|
"--output",
|
||||||
|
output,
|
||||||
|
input,
|
||||||
|
},
|
||||||
|
alloc,
|
||||||
|
);
|
||||||
|
blueprint_compiler.stdout_behavior = .Pipe;
|
||||||
|
blueprint_compiler.stderr_behavior = .Pipe;
|
||||||
|
try blueprint_compiler.spawn();
|
||||||
|
try blueprint_compiler.collectOutput(
|
||||||
|
alloc,
|
||||||
|
&stdout,
|
||||||
|
&stderr,
|
||||||
|
std.math.maxInt(u16),
|
||||||
|
);
|
||||||
|
const term = blueprint_compiler.wait() catch |err| switch (err) {
|
||||||
|
error.FileNotFound => {
|
||||||
|
std.debug.print(
|
||||||
|
\\`blueprint-compiler` not found.
|
||||||
|
\\
|
||||||
|
\\Ghostty requires version {} or newer of
|
||||||
|
\\`blueprint-compiler` as a build-time dependency starting
|
||||||
|
\\from version 1.2. Please install it, ensure that it is
|
||||||
|
\\available on your PATH, and then retry building Ghostty.
|
||||||
|
\\
|
||||||
|
, .{required_blueprint_version});
|
||||||
|
std.posix.exit(1);
|
||||||
|
},
|
||||||
|
else => return err,
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (term) {
|
||||||
|
.Exited => |rc| {
|
||||||
|
if (rc != 0) {
|
||||||
|
std.debug.print("{s}", .{stderr.items});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
std.debug.print("{s}", .{stderr.items});
|
||||||
|
std.process.exit(1);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
182
src/apprt/gtk-ng/build/gresource.zig
Normal file
182
src/apprt/gtk-ng/build/gresource.zig
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
//! This file contains a binary helper that builds our gresource XML
|
||||||
|
//! file that we can then use with `glib-compile-resources`.
|
||||||
|
//!
|
||||||
|
//! This binary is expected to be run from the Ghostty source root.
|
||||||
|
//! Litmus test: `src/apprt/gtk` should exist relative to the pwd.
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
|
/// Prefix/appid for the gresource file.
|
||||||
|
pub const prefix = "/com/mitchellh/ghostty";
|
||||||
|
pub const app_id = "com.mitchellh.ghostty";
|
||||||
|
|
||||||
|
/// The path to the Blueprint files. The folder structure is expected to be
|
||||||
|
/// `{version}/{name}.blp` where `version` is the major and minor
|
||||||
|
/// minimum adwaita version.
|
||||||
|
pub const ui_path = "src/apprt/gtk-ng/ui";
|
||||||
|
|
||||||
|
/// The possible icon sizes we'll embed into the gresource file.
|
||||||
|
/// If any size doesn't exist then it will be an error. We could
|
||||||
|
/// infer this completely from available files but we wouldn't be
|
||||||
|
/// able to error when they don't exist that way.
|
||||||
|
pub const icon_sizes: []const comptime_int = &.{ 16, 32, 128, 256, 512, 1024 };
|
||||||
|
|
||||||
|
/// The blueprint files that we will embed into the gresource file.
|
||||||
|
/// We can't look these up at runtime [easily] because we require the
|
||||||
|
/// compiled UI files as input. We can refactor this lator to maybe do
|
||||||
|
/// all of this automatically and ensure we have the right dependencies
|
||||||
|
/// setup in the build system.
|
||||||
|
///
|
||||||
|
/// These will be asserted to exist at runtime.
|
||||||
|
pub const blueprints: []const struct {
|
||||||
|
major: u16,
|
||||||
|
minor: u16,
|
||||||
|
name: []const u8,
|
||||||
|
} = &.{
|
||||||
|
.{ .major = 1, .minor = 5, .name = "window" },
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The list of filepaths that we depend on. Used for the build
|
||||||
|
/// system to have proper caching.
|
||||||
|
pub const file_inputs = deps: {
|
||||||
|
const total = (icon_sizes.len * 2) + blueprints.len;
|
||||||
|
var deps: [total][]const u8 = undefined;
|
||||||
|
var index: usize = 0;
|
||||||
|
for (icon_sizes) |size| {
|
||||||
|
deps[index] = std.fmt.comptimePrint("images/icons/icon_{d}.png", .{size});
|
||||||
|
deps[index + 1] = std.fmt.comptimePrint("images/icons/icon_{d}@2x.png", .{size});
|
||||||
|
index += 2;
|
||||||
|
}
|
||||||
|
for (blueprints) |bp| {
|
||||||
|
deps[index] = std.fmt.comptimePrint("{s}/{d}.{d}/{s}.blp", .{
|
||||||
|
ui_path,
|
||||||
|
bp.major,
|
||||||
|
bp.minor,
|
||||||
|
bp.name,
|
||||||
|
});
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
break :deps deps;
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
var debug_allocator: std.heap.DebugAllocator(.{}) = .init;
|
||||||
|
defer _ = debug_allocator.deinit();
|
||||||
|
const alloc = debug_allocator.allocator();
|
||||||
|
|
||||||
|
// Collect the UI files that are passed in as arguments.
|
||||||
|
var ui_files: std.ArrayListUnmanaged([]const u8) = .empty;
|
||||||
|
defer {
|
||||||
|
for (ui_files.items) |item| alloc.free(item);
|
||||||
|
ui_files.deinit(alloc);
|
||||||
|
}
|
||||||
|
var it = try std.process.argsWithAllocator(alloc);
|
||||||
|
defer it.deinit();
|
||||||
|
while (it.next()) |arg| {
|
||||||
|
if (!std.mem.endsWith(u8, arg, ".ui")) continue;
|
||||||
|
try ui_files.append(
|
||||||
|
alloc,
|
||||||
|
try alloc.dupe(u8, arg),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const writer = std.io.getStdOut().writer();
|
||||||
|
try writer.writeAll(
|
||||||
|
\\<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
\\<gresources>
|
||||||
|
\\
|
||||||
|
);
|
||||||
|
|
||||||
|
try genIcons(writer);
|
||||||
|
try genUi(alloc, writer, &ui_files);
|
||||||
|
|
||||||
|
try writer.writeAll(
|
||||||
|
\\</gresources>
|
||||||
|
\\
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate the icon resources. This works by looking up all the icons
|
||||||
|
/// specified by `icon_sizes` in `images/icons/`. They are asserted to exist
|
||||||
|
/// by trying to access the file.
|
||||||
|
fn genIcons(writer: anytype) !void {
|
||||||
|
try writer.print(
|
||||||
|
\\ <gresource prefix="{s}/icons">
|
||||||
|
\\
|
||||||
|
, .{prefix});
|
||||||
|
|
||||||
|
const cwd = std.fs.cwd();
|
||||||
|
inline for (icon_sizes) |size| {
|
||||||
|
// 1x
|
||||||
|
{
|
||||||
|
const alias = std.fmt.comptimePrint("{d}x{d}", .{ size, size });
|
||||||
|
const source = std.fmt.comptimePrint("images/icons/icon_{d}.png", .{size});
|
||||||
|
try cwd.access(source, .{});
|
||||||
|
try writer.print(
|
||||||
|
\\ <file alias="{s}/apps/{s}.png">{s}</file>
|
||||||
|
\\
|
||||||
|
,
|
||||||
|
.{ alias, app_id, source },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2x
|
||||||
|
{
|
||||||
|
const alias = std.fmt.comptimePrint("{d}x{d}@2", .{ size, size });
|
||||||
|
const source = std.fmt.comptimePrint("images/icons/icon_{d}@2x.png", .{size});
|
||||||
|
try cwd.access(source, .{});
|
||||||
|
try writer.print(
|
||||||
|
\\ <file alias="{s}/apps/{s}.png">{s}</file>
|
||||||
|
\\
|
||||||
|
,
|
||||||
|
.{ alias, app_id, source },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try writer.writeAll(
|
||||||
|
\\ </gresource>
|
||||||
|
\\
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate all the UI resources. This works by looking up all the
|
||||||
|
/// blueprint files in `${ui_path}/{major}.{minor}/{name}.blp` and
|
||||||
|
/// assuming these will be
|
||||||
|
fn genUi(
|
||||||
|
alloc: Allocator,
|
||||||
|
writer: anytype,
|
||||||
|
files: *const std.ArrayListUnmanaged([]const u8),
|
||||||
|
) !void {
|
||||||
|
try writer.print(
|
||||||
|
\\ <gresource prefix="{s}/ui">
|
||||||
|
\\
|
||||||
|
, .{prefix});
|
||||||
|
|
||||||
|
for (files.items) |ui_file| {
|
||||||
|
for (blueprints) |bp| {
|
||||||
|
const expected = try std.fmt.allocPrint(
|
||||||
|
alloc,
|
||||||
|
"/{d}.{d}/{s}.ui",
|
||||||
|
.{ bp.major, bp.minor, bp.name },
|
||||||
|
);
|
||||||
|
defer alloc.free(expected);
|
||||||
|
if (!std.mem.endsWith(u8, ui_file, expected)) continue;
|
||||||
|
try writer.print(
|
||||||
|
" <file compressed=\"true\" preprocess=\"xml-stripblanks\" alias=\"{d}.{d}/{s}.ui\">{s}</file>\n",
|
||||||
|
.{ bp.major, bp.minor, bp.name, ui_file },
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// The for loop never broke which means it didn't find
|
||||||
|
// a matching blueprint for this input.
|
||||||
|
return error.BlueprintNotFound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try writer.writeAll(
|
||||||
|
\\ </gresource>
|
||||||
|
\\
|
||||||
|
);
|
||||||
|
}
|
@ -100,11 +100,20 @@ pub const GhosttyApplication = extern struct {
|
|||||||
single_instance,
|
single_instance,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Initialize the app.
|
||||||
const self = gobject.ext.newInstance(Self, .{
|
const self = gobject.ext.newInstance(Self, .{
|
||||||
.application_id = app_id.ptr,
|
.application_id = app_id.ptr,
|
||||||
.flags = app_flags,
|
.flags = app_flags,
|
||||||
|
|
||||||
|
// Force the resource path to a known value so it doesn't depend
|
||||||
|
// on the app id (which changes between debug/release and can be
|
||||||
|
// user-configured) and force it to load in compiled resources.
|
||||||
|
.resource_base_path = "/com/mitchellh/ghostty",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Setup our private state. More setup is done in the init
|
||||||
|
// callback that GObject calls, but we can't pass this data through
|
||||||
|
// to there (and we don't need it there directly) so this is here.
|
||||||
const priv = self.private();
|
const priv = self.private();
|
||||||
priv.core_app = core_app;
|
priv.core_app = core_app;
|
||||||
priv.config = config;
|
priv.config = config;
|
||||||
@ -275,6 +284,23 @@ pub const GhosttyApplication = extern struct {
|
|||||||
pub const Instance = Self;
|
pub const Instance = Self;
|
||||||
|
|
||||||
fn init(class: *Class) callconv(.C) void {
|
fn init(class: *Class) callconv(.C) void {
|
||||||
|
// Register our compiled resources exactly once.
|
||||||
|
{
|
||||||
|
const c = @cImport({
|
||||||
|
// generated header files
|
||||||
|
@cInclude("ghostty_resources.h");
|
||||||
|
});
|
||||||
|
if (c.ghostty_get_resource()) |ptr| {
|
||||||
|
gio.resourcesRegister(@ptrCast(@alignCast(ptr)));
|
||||||
|
} else {
|
||||||
|
// If we fail to load resources then things will
|
||||||
|
// probably look really bad but it shouldn't stop our
|
||||||
|
// app from loading.
|
||||||
|
log.warn("unable to load resources", .{});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Virtual methods
|
||||||
gio.Application.virtual_methods.activate.implement(class, &activate);
|
gio.Application.virtual_methods.activate.implement(class, &activate);
|
||||||
gio.Application.virtual_methods.startup.implement(class, &startup);
|
gio.Application.virtual_methods.startup.implement(class, &startup);
|
||||||
gobject.Object.virtual_methods.finalize.implement(class, &finalize);
|
gobject.Object.virtual_methods.finalize.implement(class, &finalize);
|
||||||
|
8
src/apprt/gtk-ng/ui/1.5/window.blp
Normal file
8
src/apprt/gtk-ng/ui/1.5/window.blp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
using Gtk 4.0;
|
||||||
|
using Adw 1;
|
||||||
|
|
||||||
|
Adw.Window {
|
||||||
|
Label {
|
||||||
|
label: "Hello";
|
||||||
|
}
|
||||||
|
}
|
@ -8,8 +8,6 @@ const UnicodeTables = @import("UnicodeTables.zig");
|
|||||||
const GhosttyFrameData = @import("GhosttyFrameData.zig");
|
const GhosttyFrameData = @import("GhosttyFrameData.zig");
|
||||||
const DistResource = @import("GhosttyDist.zig").Resource;
|
const DistResource = @import("GhosttyDist.zig").Resource;
|
||||||
|
|
||||||
const gresource = @import("../apprt/gtk/gresource.zig");
|
|
||||||
|
|
||||||
config: *const Config,
|
config: *const Config,
|
||||||
|
|
||||||
options: *std.Build.Step.Options,
|
options: *std.Build.Step.Options,
|
||||||
@ -688,6 +686,107 @@ fn addGtkNg(
|
|||||||
|
|
||||||
step.linkSystemLibrary2("wayland-client", dynamic_link_opts);
|
step.linkSystemLibrary2("wayland-client", dynamic_link_opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Get our gresource c/h files and add them to our build.
|
||||||
|
const dist = gtkNgDistResources(b);
|
||||||
|
step.addCSourceFile(.{ .file = dist.resources_c.path(b), .flags = &.{} });
|
||||||
|
step.addIncludePath(dist.resources_h.path(b).dirname());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates the resources that can be prebuilt for our dist build.
|
||||||
|
pub fn gtkNgDistResources(
|
||||||
|
b: *std.Build,
|
||||||
|
) struct {
|
||||||
|
resources_c: DistResource,
|
||||||
|
resources_h: DistResource,
|
||||||
|
} {
|
||||||
|
const gresource = @import("../apprt/gtk-ng/build/gresource.zig");
|
||||||
|
const gresource_xml = gresource_xml: {
|
||||||
|
const xml_exe = b.addExecutable(.{
|
||||||
|
.name = "generate_gresource_xml",
|
||||||
|
.root_source_file = b.path("src/apprt/gtk-ng/build/gresource.zig"),
|
||||||
|
.target = b.graph.host,
|
||||||
|
});
|
||||||
|
const xml_run = b.addRunArtifact(xml_exe);
|
||||||
|
|
||||||
|
// Run our blueprint compiler across all of our blueprint files.
|
||||||
|
const blueprint_exe = b.addExecutable(.{
|
||||||
|
.name = "gtk_blueprint_compiler",
|
||||||
|
.root_source_file = b.path("src/apprt/gtk-ng/build/blueprint.zig"),
|
||||||
|
.target = b.graph.host,
|
||||||
|
});
|
||||||
|
blueprint_exe.linkLibC();
|
||||||
|
blueprint_exe.linkSystemLibrary2("gtk4", dynamic_link_opts);
|
||||||
|
blueprint_exe.linkSystemLibrary2("libadwaita-1", dynamic_link_opts);
|
||||||
|
|
||||||
|
for (gresource.blueprints) |bp| {
|
||||||
|
const blueprint_run = b.addRunArtifact(blueprint_exe);
|
||||||
|
blueprint_run.addArgs(&.{
|
||||||
|
b.fmt("{d}", .{bp.major}),
|
||||||
|
b.fmt("{d}", .{bp.minor}),
|
||||||
|
});
|
||||||
|
const ui_file = blueprint_run.addOutputFileArg(b.fmt(
|
||||||
|
"{d}.{d}/{s}.ui",
|
||||||
|
.{
|
||||||
|
bp.major,
|
||||||
|
bp.minor,
|
||||||
|
bp.name,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
blueprint_run.addFileArg(b.path(b.fmt(
|
||||||
|
"{s}/{d}.{d}/{s}.blp",
|
||||||
|
.{
|
||||||
|
gresource.ui_path,
|
||||||
|
bp.major,
|
||||||
|
bp.minor,
|
||||||
|
bp.name,
|
||||||
|
},
|
||||||
|
)));
|
||||||
|
|
||||||
|
xml_run.addFileArg(ui_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
break :gresource_xml xml_run.captureStdOut();
|
||||||
|
};
|
||||||
|
|
||||||
|
const generate_c = b.addSystemCommand(&.{
|
||||||
|
"glib-compile-resources",
|
||||||
|
"--c-name",
|
||||||
|
"ghostty",
|
||||||
|
"--generate-source",
|
||||||
|
"--target",
|
||||||
|
});
|
||||||
|
const resources_c = generate_c.addOutputFileArg("ghostty_resources.c");
|
||||||
|
generate_c.addFileArg(gresource_xml);
|
||||||
|
for (gresource.file_inputs) |path| {
|
||||||
|
generate_c.addFileInput(b.path(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
const generate_h = b.addSystemCommand(&.{
|
||||||
|
"glib-compile-resources",
|
||||||
|
"--c-name",
|
||||||
|
"ghostty",
|
||||||
|
"--generate-header",
|
||||||
|
"--target",
|
||||||
|
});
|
||||||
|
const resources_h = generate_h.addOutputFileArg("ghostty_resources.h");
|
||||||
|
generate_h.addFileArg(gresource_xml);
|
||||||
|
for (gresource.file_inputs) |path| {
|
||||||
|
generate_h.addFileInput(b.path(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.resources_c = .{
|
||||||
|
.dist = "src/apprt/gtk-ng/ghostty_resources.c",
|
||||||
|
.generated = resources_c,
|
||||||
|
},
|
||||||
|
.resources_h = .{
|
||||||
|
.dist = "src/apprt/gtk-ng/ghostty_resources.h",
|
||||||
|
.generated = resources_h,
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Setup the dependencies for the GTK apprt build. The GTK apprt
|
/// Setup the dependencies for the GTK apprt build. The GTK apprt
|
||||||
@ -832,6 +931,8 @@ pub fn gtkDistResources(
|
|||||||
resources_c: DistResource,
|
resources_c: DistResource,
|
||||||
resources_h: DistResource,
|
resources_h: DistResource,
|
||||||
} {
|
} {
|
||||||
|
const gresource = @import("../apprt/gtk/gresource.zig");
|
||||||
|
|
||||||
const gresource_xml = gresource_xml: {
|
const gresource_xml = gresource_xml: {
|
||||||
const xml_exe = b.addExecutable(.{
|
const xml_exe = b.addExecutable(.{
|
||||||
.name = "generate_gresource_xml",
|
.name = "generate_gresource_xml",
|
||||||
|
Reference in New Issue
Block a user