libtoolstep

This commit is contained in:
Mitchell Hashimoto
2023-02-14 14:15:34 -08:00
parent 9fcc9ce302
commit d2dd3df86a
2 changed files with 113 additions and 15 deletions

View File

@ -21,6 +21,7 @@ const zlib = @import("pkg/zlib/build.zig");
const tracylib = @import("pkg/tracy/build.zig");
const system_sdk = @import("vendor/mach/libs/glfw/system_sdk.zig");
const WasmTarget = @import("src/os/wasm/target.zig").Target;
const LibtoolStep = @import("src/build/LibtoolStep.zig");
const LipoStep = @import("src/build/LipoStep.zig");
const XCFrameworkStep = @import("src/build/XCFrameworkStep.zig");
@ -122,7 +123,7 @@ pub fn build(b: *std.build.Builder) !void {
exe.install();
// Add the shared dependencies
try addDeps(b, exe, static);
_ = try addDeps(b, exe, static);
}
// App (Mac)
@ -141,7 +142,7 @@ pub fn build(b: *std.build.Builder) !void {
static_lib.install();
static_lib.linkLibC();
static_lib.addOptions("build_options", exe_options);
try addDeps(b, static_lib, true);
_ = try addDeps(b, static_lib, true);
b.default_step.dependOn(&static_lib.step);
}
@ -154,9 +155,19 @@ pub fn build(b: *std.build.Builder) !void {
lib.setTarget(try std.zig.CrossTarget.parse(.{ .arch_os_abi = "aarch64-macos" }));
lib.linkLibC();
lib.addOptions("build_options", exe_options);
try addDeps(b, lib, true);
b.default_step.dependOn(&lib.step);
break :lib lib;
// Create a single static lib with all our dependencies merged
var lib_list = try addDeps(b, lib, true);
try lib_list.append(.{ .generated = &lib.output_path_source });
const libtool = LibtoolStep.create(b, .{
.name = "ghostty",
.out_name = "libghostty-aarch64-fat.a",
.sources = lib_list.items,
});
b.default_step.dependOn(&libtool.step);
break :lib libtool;
};
const static_lib_x86_64 = lib: {
@ -165,16 +176,26 @@ pub fn build(b: *std.build.Builder) !void {
lib.setTarget(try std.zig.CrossTarget.parse(.{ .arch_os_abi = "x86_64-macos" }));
lib.linkLibC();
lib.addOptions("build_options", exe_options);
try addDeps(b, lib, true);
b.default_step.dependOn(&lib.step);
break :lib lib;
// Create a single static lib with all our dependencies merged
var lib_list = try addDeps(b, lib, true);
try lib_list.append(.{ .generated = &lib.output_path_source });
const libtool = LibtoolStep.create(b, .{
.name = "ghostty",
.out_name = "libghostty-x86_64-fat.a",
.sources = lib_list.items,
});
b.default_step.dependOn(&libtool.step);
break :lib libtool;
};
const static_lib_universal = LipoStep.create(b, .{
.name = "ghostty",
.out_name = "libghostty.a",
.input_a = .{ .generated = &static_lib_aarch64.output_path_source },
.input_b = .{ .generated = &static_lib_x86_64.output_path_source },
.input_a = .{ .generated = &static_lib_aarch64.out_path },
.input_b = .{ .generated = &static_lib_x86_64.out_path },
});
static_lib_universal.step.dependOn(&static_lib_aarch64.step);
static_lib_universal.step.dependOn(&static_lib_x86_64.step);
@ -240,7 +261,7 @@ pub fn build(b: *std.build.Builder) !void {
wasm.stack_protector = false;
// Wasm-specific deps
try addDeps(b, wasm, true);
_ = try addDeps(b, wasm, true);
const step = b.step("wasm", "Build the wasm library");
step.dependOn(&wasm.step);
@ -255,7 +276,7 @@ pub fn build(b: *std.build.Builder) !void {
.target = wasm_target,
});
main_test.addOptions("build_options", exe_options);
try addDeps(b, main_test, true);
_ = try addDeps(b, main_test, true);
test_step.dependOn(&main_test.step);
}
@ -299,7 +320,7 @@ pub fn build(b: *std.build.Builder) !void {
main_test_exe.install();
}
main_test.setFilter(test_filter);
try addDeps(b, main_test, true);
_ = try addDeps(b, main_test, true);
main_test.addOptions("build_options", exe_options);
var before = b.addLog("\x1b[" ++ color_map.get("cyan").? ++ "\x1b[" ++ color_map.get("b").? ++ "[{s} tests]" ++ "\x1b[" ++ color_map.get("d").? ++ " ----" ++ "\x1b[0m", .{"ghostty"});
@ -327,7 +348,7 @@ pub fn build(b: *std.build.Builder) !void {
.target = target,
});
try addDeps(b, test_run, true);
_ = try addDeps(b, test_run, true);
// if (pkg.dependencies) |children| {
// test_.packages = std.ArrayList(std.build.Pkg).init(b.allocator);
// try test_.packages.appendSlice(children);
@ -352,12 +373,18 @@ pub fn build(b: *std.build.Builder) !void {
}
}
/// Used to keep track of a list of file sources.
const FileSourceList = std.ArrayList(std.build.FileSource);
/// Adds and links all of the primary dependencies for the exe.
fn addDeps(
b: *std.build.Builder,
step: *std.build.LibExeObjStep,
static: bool,
) !void {
) !FileSourceList {
var static_libs = FileSourceList.init(b.allocator);
errdefer static_libs.deinit();
// Wasm we do manually since it is such a different build.
if (step.target.getCpuArch() == .wasm32) {
// We link this package but its a no-op since Tracy
@ -369,7 +396,7 @@ fn addDeps(
// utf8proc
_ = try utf8proc.link(b, step);
return;
return static_libs;
}
// If we're building a lib we have some different deps
@ -470,6 +497,7 @@ fn addDeps(
},
});
system_sdk.include(b, harfbuzz_step, .{});
try static_libs.append(.{ .generated = &harfbuzz_step.output_path_source });
// Pixman
const pixman_step = try pixman.link(b, step, .{});
@ -522,6 +550,8 @@ fn addDeps(
const imgui_step = try imgui.link(b, step, imgui_opts);
try glfw.link(b, imgui_step, glfw_opts);
}
return static_libs;
}
fn benchSteps(
@ -561,7 +591,7 @@ fn benchSteps(
});
c_exe.setMainPkgPath("./src");
c_exe.install();
try addDeps(b, c_exe, true);
_ = try addDeps(b, c_exe, true);
}
}

68
src/build/LibtoolStep.zig Normal file
View File

@ -0,0 +1,68 @@
//! A zig builder step that runs "lipo" on two binaries to create
//! a universal binary.
const LibtoolStep = @This();
const std = @import("std");
const Step = std.build.Step;
const FileSource = std.build.FileSource;
const GeneratedFile = std.build.GeneratedFile;
pub const Options = struct {
/// The name of the xcframework to create.
name: []const u8,
/// The filename (not the path) of the file to create.
out_name: []const u8,
/// Library file (dylib, a) to package.
sources: []FileSource,
};
step: Step,
builder: *std.build.Builder,
/// Resulting binary
out_path: GeneratedFile,
/// See Options
name: []const u8,
out_name: []const u8,
sources: []FileSource,
pub fn create(builder: *std.build.Builder, opts: Options) *LibtoolStep {
const self = builder.allocator.create(LibtoolStep) catch @panic("OOM");
self.* = .{
.step = Step.init(.custom, builder.fmt("lipo {s}", .{opts.name}), builder.allocator, make),
.builder = builder,
.name = opts.name,
.out_path = .{ .step = &self.step },
.out_name = opts.out_name,
.sources = opts.sources,
};
return self;
}
fn make(step: *Step) !void {
const self = @fieldParentPtr(LibtoolStep, "step", step);
// TODO: use the zig cache system when it is in the stdlib
// https://github.com/ziglang/zig/pull/14571
const output_path = self.builder.pathJoin(&.{
self.builder.cache_root, self.out_name,
});
// We use a RunStep here to ease our configuration.
{
const run = std.build.RunStep.create(self.builder, self.builder.fmt(
"libtool {s}",
.{self.name},
));
run.addArgs(&.{ "libtool", "-static", "-o", output_path });
for (self.sources) |source| {
run.addArg(source.getPath(self.builder));
}
try run.step.make();
}
self.out_path.path = output_path;
}