mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-05-25 14:28:32 +00:00
cmake: add ghostty_vt_add_target() for cross-compilation
Add a ghostty_vt_add_target() CMake function that lets downstream projects build libghostty-vt for a specific Zig target triple. The function encapsulates zig discovery, build-type-to-optimize mapping, the zig build invocation, and output path conventions so consumers do not need to duplicate any of that logic. It creates named IMPORTED targets (e.g. ghostty-vt-static-linux-amd64) that work alongside the existing native ghostty-vt and ghostty-vt-static targets. The build-type mapping is factored into a shared _GHOSTTY_ZIG_OPT_FLAG variable used by both the native build and the new function. The static library targets now propagate c++ as a link dependency on non-Windows platforms, fixing link failures when consumers use static linking with the default SIMD-enabled build. A new example/c-vt-cmake-cross/ demonstrates end-to-end cross- compilation using zig cc as the C compiler, auto-detecting a cross target based on the host OS.
This commit is contained in:
@@ -279,10 +279,9 @@ fn initLib(
|
||||
|
||||
// For static libraries with vendored SIMD dependencies, combine
|
||||
// all archives into a single fat archive so consumers only need
|
||||
// to link one file. Skip on Windows where ar/libtool aren't available.
|
||||
// to link one file.
|
||||
if (kind == .static and
|
||||
zig.simd_libs.items.len > 0 and
|
||||
target.result.os.tag != .windows)
|
||||
zig.simd_libs.items.len > 0)
|
||||
{
|
||||
var sources: SharedDeps.LazyPathList = .empty;
|
||||
try sources.append(b.allocator, lib.getEmittedBin());
|
||||
@@ -329,26 +328,17 @@ fn combineArchives(
|
||||
return .{ .step = libtool.step, .output = libtool.output };
|
||||
}
|
||||
|
||||
// On non-Darwin, use an MRI script with ar -M to combine archives
|
||||
// directly without extracting. This avoids issues with ar x
|
||||
// producing full-path member names and read-only permissions.
|
||||
const run = RunStep.create(b, "combine-archives ghostty-vt");
|
||||
run.addArgs(&.{
|
||||
"/bin/sh", "-c",
|
||||
\\set -e
|
||||
\\out="$1"; shift
|
||||
\\script="CREATE $out"
|
||||
\\for a in "$@"; do
|
||||
\\ script="$script
|
||||
\\ADDLIB $a"
|
||||
\\done
|
||||
\\script="$script
|
||||
\\SAVE
|
||||
\\END"
|
||||
\\echo "$script" | ar -M
|
||||
,
|
||||
"_",
|
||||
// On non-Darwin, use a build tool that generates an MRI script and
|
||||
// pipes it to `zig ar -M`. This works on all platforms including
|
||||
// Windows (the previous /bin/sh approach did not).
|
||||
const tool = b.addExecutable(.{
|
||||
.name = "combine_archives",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/build/combine_archives.zig"),
|
||||
.target = b.graph.host,
|
||||
}),
|
||||
});
|
||||
const run = b.addRunArtifact(tool);
|
||||
const output = run.addOutputFileArg("libghostty-vt.a");
|
||||
for (sources) |source| run.addFileArg(source);
|
||||
|
||||
|
||||
54
src/build/combine_archives.zig
Normal file
54
src/build/combine_archives.zig
Normal file
@@ -0,0 +1,54 @@
|
||||
//! Build tool that combines multiple static archives into a single fat
|
||||
//! archive using an MRI script piped to `zig ar -M`.
|
||||
//!
|
||||
//! MRI scripts require stdin piping (`ar -M < script`), which can't be
|
||||
//! expressed as a single command in the zig build system's RunStep. The
|
||||
//! previous approach used `/bin/sh -c` to do the piping, but that isn't
|
||||
//! available on Windows. This tool handles both the script generation
|
||||
//! and the piping in a single cross-platform executable.
|
||||
//!
|
||||
//! Usage: combine_archives <output.a> <input1.a> [input2.a ...]
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init;
|
||||
const alloc = gpa.allocator();
|
||||
|
||||
const args = try std.process.argsAlloc(alloc);
|
||||
if (args.len < 3) {
|
||||
std.log.err("usage: combine_archives <output> <input...>", .{});
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
const output_path = args[1];
|
||||
const inputs = args[2..];
|
||||
|
||||
// Build the MRI script.
|
||||
var script: std.ArrayListUnmanaged(u8) = .empty;
|
||||
try script.appendSlice(alloc, "CREATE ");
|
||||
try script.appendSlice(alloc, output_path);
|
||||
try script.append(alloc, '\n');
|
||||
for (inputs) |input| {
|
||||
try script.appendSlice(alloc, "ADDLIB ");
|
||||
try script.appendSlice(alloc, input);
|
||||
try script.append(alloc, '\n');
|
||||
}
|
||||
try script.appendSlice(alloc, "SAVE\nEND\n");
|
||||
|
||||
var child: std.process.Child = .init(&.{ "zig", "ar", "-M" }, alloc);
|
||||
child.stdin_behavior = .Pipe;
|
||||
child.stdout_behavior = .Inherit;
|
||||
child.stderr_behavior = .Inherit;
|
||||
|
||||
try child.spawn();
|
||||
try child.stdin.?.writeAll(script.items);
|
||||
child.stdin.?.close();
|
||||
child.stdin = null;
|
||||
|
||||
const term = try child.wait();
|
||||
if (term.Exited != 0) {
|
||||
std.log.err("zig ar -M exited with code {d}", .{term.Exited});
|
||||
std.process.exit(1);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user