mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-05-25 14:28:32 +00:00
Apple's recent libtool can warn about misaligned 64-bit archive members and silently drop them when merging static libraries. In Ghostty this showed up in the Darwin libtool step that builds libghostty-fat.a. Normalize each input archive by copying it and running ranlib on the copy before handing it to libtool. That rewrites the archive into a layout Apple's linker tools accept without flattening members through the filesystem or changing Ghostty's archive format.
79 lines
2.2 KiB
Zig
79 lines
2.2 KiB
Zig
//! A zig builder step that runs "libtool" against a list of libraries
|
|
//! in order to create a single combined static library.
|
|
const LibtoolStep = @This();
|
|
|
|
const std = @import("std");
|
|
const Step = std.Build.Step;
|
|
const RunStep = std.Build.Step.Run;
|
|
const LazyPath = std.Build.LazyPath;
|
|
|
|
pub const Options = struct {
|
|
/// The name of this step.
|
|
name: []const u8,
|
|
|
|
/// The filename (not the path) of the file to create. This will
|
|
/// be placed in a unique hashed directory. Use out_path to access.
|
|
out_name: []const u8,
|
|
|
|
/// Library files (.a) to combine.
|
|
sources: []LazyPath,
|
|
};
|
|
|
|
/// The step to depend on.
|
|
step: *Step,
|
|
|
|
/// The output file from the libtool run.
|
|
output: LazyPath,
|
|
|
|
/// Run libtool against a list of library files to combine into a single
|
|
/// static library.
|
|
pub fn create(b: *std.Build, opts: Options) *LibtoolStep {
|
|
const self = b.allocator.create(LibtoolStep) catch @panic("OOM");
|
|
|
|
const run_step = RunStep.create(b, b.fmt("libtool {s}", .{opts.name}));
|
|
run_step.addArgs(&.{ "libtool", "-static", "-o" });
|
|
const output = run_step.addOutputFileArg(opts.out_name);
|
|
for (opts.sources, 0..) |source, i| {
|
|
run_step.addFileArg(normalizeArchive(
|
|
b,
|
|
opts.name,
|
|
opts.out_name,
|
|
i,
|
|
source,
|
|
));
|
|
}
|
|
|
|
self.* = .{
|
|
.step = &run_step.step,
|
|
.output = output,
|
|
};
|
|
|
|
return self;
|
|
}
|
|
|
|
fn normalizeArchive(
|
|
b: *std.Build,
|
|
step_name: []const u8,
|
|
out_name: []const u8,
|
|
index: usize,
|
|
source: LazyPath,
|
|
) LazyPath {
|
|
// Newer Xcode libtool can drop 64-bit archive members if the input
|
|
// archive layout doesn't match what it expects. ranlib rewrites the
|
|
// archive without flattening members through the filesystem, so we
|
|
// normalize each source archive first. This is a Zig/toolchain
|
|
// interoperability workaround, not a Ghostty archive format change.
|
|
const run_step = RunStep.create(
|
|
b,
|
|
b.fmt("ranlib {s} #{d}", .{ step_name, index }),
|
|
);
|
|
run_step.addArgs(&.{
|
|
"/bin/sh",
|
|
"-c",
|
|
"/bin/cp \"$1\" \"$2\" && /usr/bin/ranlib \"$2\"",
|
|
"_",
|
|
});
|
|
run_step.addFileArg(source);
|
|
return run_step.addOutputFileArg(b.fmt("{d}-{s}", .{ index, out_name }));
|
|
}
|