mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 09:16:11 +03:00
windows: initial support for zig build test
Makes progress getting "zig build test" to work on windows. Mostly fixed issues around build configuration and added some branches throughout the Zig code to return/throw errors for unimplemented parts. I also added an initial implementation for getting the home dir.
This commit is contained in:
10
build.zig
10
build.zig
@ -329,7 +329,7 @@ pub fn build(b: *std.Build) !void {
|
|||||||
// Convert to termcap source format if thats helpful to people and
|
// Convert to termcap source format if thats helpful to people and
|
||||||
// install it. The resulting value here is the termcap source in case
|
// install it. The resulting value here is the termcap source in case
|
||||||
// that is used for other commands.
|
// that is used for other commands.
|
||||||
{
|
if (!target.isWindows()) {
|
||||||
const run_step = RunStep.create(b, "infotocap");
|
const run_step = RunStep.create(b, "infotocap");
|
||||||
run_step.addArg("infotocap");
|
run_step.addArg("infotocap");
|
||||||
run_step.addFileSourceArg(src_source);
|
run_step.addFileSourceArg(src_source);
|
||||||
@ -349,7 +349,7 @@ pub fn build(b: *std.Build) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compile the terminfo source into a terminfo database
|
// Compile the terminfo source into a terminfo database
|
||||||
{
|
if (!target.isWindows()) {
|
||||||
const run_step = RunStep.create(b, "tic");
|
const run_step = RunStep.create(b, "tic");
|
||||||
run_step.addArgs(&.{ "tic", "-x", "-o" });
|
run_step.addArgs(&.{ "tic", "-x", "-o" });
|
||||||
const path = run_step.addOutputFileArg("terminfo");
|
const path = run_step.addOutputFileArg("terminfo");
|
||||||
@ -799,7 +799,11 @@ fn addDeps(
|
|||||||
b,
|
b,
|
||||||
step.target,
|
step.target,
|
||||||
step.optimize,
|
step.optimize,
|
||||||
.{ .lzma = false, .zlib = false },
|
.{
|
||||||
|
.lzma = false,
|
||||||
|
.zlib = false,
|
||||||
|
.iconv = !step.target.isWindows(),
|
||||||
|
},
|
||||||
);
|
);
|
||||||
libxml2_lib.link(step);
|
libxml2_lib.link(step);
|
||||||
|
|
||||||
|
@ -99,15 +99,9 @@ pub fn buildFontconfig(
|
|||||||
"-DHAVE_STDLIB_H",
|
"-DHAVE_STDLIB_H",
|
||||||
"-DHAVE_STRING_H",
|
"-DHAVE_STRING_H",
|
||||||
"-DHAVE_UNISTD_H",
|
"-DHAVE_UNISTD_H",
|
||||||
"-DHAVE_SYS_STATVFS_H",
|
|
||||||
"-DHAVE_SYS_VFS_H",
|
|
||||||
"-DHAVE_SYS_STATFS_H",
|
|
||||||
"-DHAVE_SYS_PARAM_H",
|
"-DHAVE_SYS_PARAM_H",
|
||||||
"-DHAVE_SYS_MOUNT_H",
|
|
||||||
|
|
||||||
"-DHAVE_LINK",
|
|
||||||
"-DHAVE_MKSTEMP",
|
"-DHAVE_MKSTEMP",
|
||||||
"-DHAVE_MKOSTEMP",
|
|
||||||
"-DHAVE__MKTEMP_S",
|
"-DHAVE__MKTEMP_S",
|
||||||
"-DHAVE_MKDTEMP",
|
"-DHAVE_MKDTEMP",
|
||||||
"-DHAVE_GETOPT",
|
"-DHAVE_GETOPT",
|
||||||
@ -115,15 +109,9 @@ pub fn buildFontconfig(
|
|||||||
//"-DHAVE_GETPROGNAME",
|
//"-DHAVE_GETPROGNAME",
|
||||||
//"-DHAVE_GETEXECNAME",
|
//"-DHAVE_GETEXECNAME",
|
||||||
"-DHAVE_RAND",
|
"-DHAVE_RAND",
|
||||||
"-DHAVE_RANDOM",
|
|
||||||
"-DHAVE_LRAND48",
|
|
||||||
//"-DHAVE_RANDOM_R",
|
//"-DHAVE_RANDOM_R",
|
||||||
"-DHAVE_RAND_R",
|
|
||||||
"-DHAVE_READLINK",
|
|
||||||
"-DHAVE_FSTATVFS",
|
"-DHAVE_FSTATVFS",
|
||||||
"-DHAVE_FSTATFS",
|
"-DHAVE_FSTATFS",
|
||||||
"-DHAVE_LSTAT",
|
|
||||||
"-DHAVE_MMAP",
|
|
||||||
"-DHAVE_VPRINTF",
|
"-DHAVE_VPRINTF",
|
||||||
|
|
||||||
"-DHAVE_FT_GET_BDF_PROPERTY",
|
"-DHAVE_FT_GET_BDF_PROPERTY",
|
||||||
@ -175,8 +163,27 @@ pub fn buildFontconfig(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!target.isWindows()) {
|
if (target.isWindows()) {
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(&.{
|
||||||
|
"-DFC_CACHEDIR=\"LOCAL_APPDATA_FONTCONFIG_CACHE\"",
|
||||||
|
"-DFC_TEMPLATEDIR=\"c:/share/fontconfig/conf.avail\"",
|
||||||
|
"-DCONFIGDIR=\"c:/etc/fonts/conf.d\"",
|
||||||
|
"-DFC_DEFAULT_FONTS=\"\\t<dir>WINDOWSFONTDIR</dir>\\n\\t<dir>WINDOWSUSERFONTDIR</dir>\\n\"",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
try flags.appendSlice(&.{
|
||||||
|
"-DHAVE_SYS_STATVFS_H",
|
||||||
|
"-DHAVE_SYS_VFS_H",
|
||||||
|
"-DHAVE_SYS_STATFS_H",
|
||||||
|
"-DHAVE_SYS_MOUNT_H",
|
||||||
|
"-DHAVE_LINK",
|
||||||
|
"-DHAVE_MKOSTEMP",
|
||||||
|
"-DHAVE_RANDOM",
|
||||||
|
"-DHAVE_LRAND48",
|
||||||
|
"-DHAVE_RAND_R",
|
||||||
|
"-DHAVE_READLINK",
|
||||||
|
"-DHAVE_LSTAT",
|
||||||
|
"-DHAVE_MMAP",
|
||||||
"-DHAVE_PTHREAD",
|
"-DHAVE_PTHREAD",
|
||||||
|
|
||||||
"-DFC_CACHEDIR=\"/var/cache/fontconfig\"",
|
"-DFC_CACHEDIR=\"/var/cache/fontconfig\"",
|
||||||
|
@ -117,7 +117,6 @@ pub fn buildFreetype(
|
|||||||
.windows => {
|
.windows => {
|
||||||
lib.addCSourceFiles(&.{
|
lib.addCSourceFiles(&.{
|
||||||
root ++ "builds/windows/ftdebug.c",
|
root ++ "builds/windows/ftdebug.c",
|
||||||
root ++ "src/base/ftver.c",
|
|
||||||
}, flags.items);
|
}, flags.items);
|
||||||
},
|
},
|
||||||
else => lib.addCSourceFile(.{
|
else => lib.addCSourceFile(.{
|
||||||
|
@ -81,13 +81,17 @@ pub fn buildHarfbuzz(
|
|||||||
defer flags.deinit();
|
defer flags.deinit();
|
||||||
|
|
||||||
try flags.appendSlice(&.{
|
try flags.appendSlice(&.{
|
||||||
"-DHAVE_UNISTD_H",
|
|
||||||
"-DHAVE_SYS_MMAN_H",
|
|
||||||
"-DHAVE_STDBOOL_H",
|
"-DHAVE_STDBOOL_H",
|
||||||
|
|
||||||
// We always have pthread
|
|
||||||
"-DHAVE_PTHREAD=1",
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!step.target.isWindows()) {
|
||||||
|
try flags.appendSlice(&.{
|
||||||
|
"-DHAVE_UNISTD_H",
|
||||||
|
"-DHAVE_SYS_MMAN_H",
|
||||||
|
"-DHAVE_PTHREAD=1",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (opt.freetype.enabled) try flags.appendSlice(&.{
|
if (opt.freetype.enabled) try flags.appendSlice(&.{
|
||||||
"-DHAVE_FREETYPE=1",
|
"-DHAVE_FREETYPE=1",
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ pub fn buildLib(
|
|||||||
|
|
||||||
// Compile
|
// Compile
|
||||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||||
|
try flags.append("-DUTF8PROC_EXPORTS");
|
||||||
defer flags.deinit();
|
defer flags.deinit();
|
||||||
|
|
||||||
// C files
|
// C files
|
||||||
|
@ -122,6 +122,9 @@ pub fn start(self: *Command, alloc: Allocator) !void {
|
|||||||
else
|
else
|
||||||
@compileError("missing env vars");
|
@compileError("missing env vars");
|
||||||
|
|
||||||
|
if (builtin.os.tag == .windows)
|
||||||
|
@panic("start not implemented on windows");
|
||||||
|
|
||||||
// Fork
|
// Fork
|
||||||
const pid = try std.os.fork();
|
const pid = try std.os.fork();
|
||||||
if (pid != 0) {
|
if (pid != 0) {
|
||||||
@ -187,6 +190,9 @@ fn setupFd(src: File.Handle, target: i32) !void {
|
|||||||
|
|
||||||
/// Wait for the command to exit and return information about how it exited.
|
/// Wait for the command to exit and return information about how it exited.
|
||||||
pub fn wait(self: Command, block: bool) !Exit {
|
pub fn wait(self: Command, block: bool) !Exit {
|
||||||
|
if (builtin.os.tag == .windows)
|
||||||
|
@panic("wait not implemented on windows");
|
||||||
|
|
||||||
const res = if (block) std.os.waitpid(self.pid.?, 0) else res: {
|
const res = if (block) std.os.waitpid(self.pid.?, 0) else res: {
|
||||||
// We specify NOHANG because its not our fault if the process we launch
|
// We specify NOHANG because its not our fault if the process we launch
|
||||||
// for the tty doesn't properly waitpid its children. We don't want
|
// for the tty doesn't properly waitpid its children. We don't want
|
||||||
@ -255,7 +261,7 @@ pub fn expandPath(alloc: Allocator, cmd: []const u8) !?[]u8 {
|
|||||||
};
|
};
|
||||||
defer f.close();
|
defer f.close();
|
||||||
const stat = try f.stat();
|
const stat = try f.stat();
|
||||||
if (stat.kind != .directory and stat.mode & 0o0111 != 0) {
|
if (stat.kind != .directory and isExecutable(stat.mode)) {
|
||||||
return try alloc.dupe(u8, full_path);
|
return try alloc.dupe(u8, full_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,6 +271,11 @@ pub fn expandPath(alloc: Allocator, cmd: []const u8) !?[]u8 {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn isExecutable(mode: std.fs.File.Mode) bool {
|
||||||
|
if (builtin.os.tag == .windows) return true;
|
||||||
|
return mode & 0o0111 != 0;
|
||||||
|
}
|
||||||
|
|
||||||
test "expandPath: env" {
|
test "expandPath: env" {
|
||||||
const path = (try expandPath(testing.allocator, "env")).?;
|
const path = (try expandPath(testing.allocator, "env")).?;
|
||||||
defer testing.allocator.free(path);
|
defer testing.allocator.free(path);
|
||||||
|
@ -13,6 +13,7 @@ const c = switch (builtin.os.tag) {
|
|||||||
@cInclude("sys/ioctl.h"); // ioctl and constants
|
@cInclude("sys/ioctl.h"); // ioctl and constants
|
||||||
@cInclude("util.h"); // openpty()
|
@cInclude("util.h"); // openpty()
|
||||||
}),
|
}),
|
||||||
|
.windows => { },
|
||||||
else => @cImport({
|
else => @cImport({
|
||||||
@cInclude("sys/ioctl.h"); // ioctl and constants
|
@cInclude("sys/ioctl.h"); // ioctl and constants
|
||||||
@cInclude("pty.h");
|
@cInclude("pty.h");
|
||||||
@ -45,6 +46,8 @@ slave: fd_t,
|
|||||||
|
|
||||||
/// Open a new PTY with the given initial size.
|
/// Open a new PTY with the given initial size.
|
||||||
pub fn open(size: winsize) !Pty {
|
pub fn open(size: winsize) !Pty {
|
||||||
|
if (builtin.os.tag == .windows) return error.NotImplementedOnWindows;
|
||||||
|
|
||||||
// Need to copy so that it becomes non-const.
|
// Need to copy so that it becomes non-const.
|
||||||
var sizeCopy = size;
|
var sizeCopy = size;
|
||||||
|
|
||||||
@ -86,6 +89,8 @@ pub fn deinit(self: *Pty) void {
|
|||||||
|
|
||||||
/// Return the size of the pty.
|
/// Return the size of the pty.
|
||||||
pub fn getSize(self: Pty) !winsize {
|
pub fn getSize(self: Pty) !winsize {
|
||||||
|
if (builtin.os.tag == .windows) return error.NotImplementedOnWindows;
|
||||||
|
|
||||||
var ws: winsize = undefined;
|
var ws: winsize = undefined;
|
||||||
if (c.ioctl(self.master, TIOCGWINSZ, @intFromPtr(&ws)) < 0)
|
if (c.ioctl(self.master, TIOCGWINSZ, @intFromPtr(&ws)) < 0)
|
||||||
return error.IoctlFailed;
|
return error.IoctlFailed;
|
||||||
@ -95,6 +100,7 @@ pub fn getSize(self: Pty) !winsize {
|
|||||||
|
|
||||||
/// Set the size of the pty.
|
/// Set the size of the pty.
|
||||||
pub fn setSize(self: Pty, size: winsize) !void {
|
pub fn setSize(self: Pty, size: winsize) !void {
|
||||||
|
if (builtin.os.tag == .windows) return error.NotImplementedOnWindows;
|
||||||
if (c.ioctl(self.master, TIOCSWINSZ, @intFromPtr(&size)) < 0)
|
if (c.ioctl(self.master, TIOCSWINSZ, @intFromPtr(&size)) < 0)
|
||||||
return error.IoctlFailed;
|
return error.IoctlFailed;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ const Error = error{
|
|||||||
pub inline fn home(buf: []u8) !?[]u8 {
|
pub inline fn home(buf: []u8) !?[]u8 {
|
||||||
return switch (builtin.os.tag) {
|
return switch (builtin.os.tag) {
|
||||||
inline .linux, .macos => try homeUnix(buf),
|
inline .linux, .macos => try homeUnix(buf),
|
||||||
|
.windows => try homeWindows(buf),
|
||||||
else => @compileError("unimplemented"),
|
else => @compileError("unimplemented"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -77,6 +78,36 @@ fn homeUnix(buf: []u8) !?[]u8 {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn homeWindows(buf: []u8) !?[]u8 {
|
||||||
|
const drive_len = blk: {
|
||||||
|
var fba_instance = std.heap.FixedBufferAllocator.init(buf);
|
||||||
|
const fba = fba_instance.allocator();
|
||||||
|
const drive = std.process.getEnvVarOwned(fba, "HOMEDRIVE") catch |err| switch (err) {
|
||||||
|
error.OutOfMemory => return Error.BufferTooSmall,
|
||||||
|
error.InvalidUtf8,
|
||||||
|
error.EnvironmentVariableNotFound => return null,
|
||||||
|
};
|
||||||
|
// could shift the contents if this ever happens
|
||||||
|
if (drive.ptr != buf.ptr) @panic("codebug");
|
||||||
|
break :blk drive.len;
|
||||||
|
};
|
||||||
|
|
||||||
|
const path_len = blk: {
|
||||||
|
const path_buf = buf[drive_len..];
|
||||||
|
var fba_instance = std.heap.FixedBufferAllocator.init(buf[drive_len..]);
|
||||||
|
const fba = fba_instance.allocator();
|
||||||
|
const homepath = std.process.getEnvVarOwned(fba, "HOMEPATH") catch |err| switch (err) {
|
||||||
|
error.OutOfMemory => return Error.BufferTooSmall,
|
||||||
|
error.InvalidUtf8,
|
||||||
|
error.EnvironmentVariableNotFound => return null,
|
||||||
|
};
|
||||||
|
// could shift the contents if this ever happens
|
||||||
|
if (homepath.ptr != path_buf.ptr) @panic("codebug");
|
||||||
|
break :blk homepath.len;
|
||||||
|
};
|
||||||
|
return buf[0 .. drive_len + path_len];
|
||||||
|
}
|
||||||
|
|
||||||
fn trimSpace(input: []const u8) []const u8 {
|
fn trimSpace(input: []const u8) []const u8 {
|
||||||
return std.mem.trim(u8, input, " \n\t");
|
return std.mem.trim(u8, input, " \n\t");
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ comptime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Used to determine the default shell and directory on Unixes.
|
/// Used to determine the default shell and directory on Unixes.
|
||||||
const c = @cImport({
|
const c = if (builtin.os.tag == .windows) { } else @cImport({
|
||||||
@cInclude("sys/types.h");
|
@cInclude("sys/types.h");
|
||||||
@cInclude("unistd.h");
|
@cInclude("unistd.h");
|
||||||
@cInclude("pwd.h");
|
@cInclude("pwd.h");
|
||||||
@ -30,6 +30,8 @@ pub const Entry = struct {
|
|||||||
|
|
||||||
/// Get the passwd entry for the currently executing user.
|
/// Get the passwd entry for the currently executing user.
|
||||||
pub fn get(alloc: Allocator) !Entry {
|
pub fn get(alloc: Allocator) !Entry {
|
||||||
|
if (builtin.os.tag == .windows) @panic("todo: windows");
|
||||||
|
|
||||||
var buf: [1024]u8 = undefined;
|
var buf: [1024]u8 = undefined;
|
||||||
var pw: c.struct_passwd = undefined;
|
var pw: c.struct_passwd = undefined;
|
||||||
var pw_ptr: ?*c.struct_passwd = null;
|
var pw_ptr: ?*c.struct_passwd = null;
|
||||||
|
Reference in New Issue
Block a user