move libuv into pkg

This commit is contained in:
Mitchell Hashimoto
2022-08-16 17:47:44 -07:00
parent f7d55ce334
commit b2192ea8f7
23 changed files with 293 additions and 249 deletions

140
build.zig
View File

@ -4,7 +4,7 @@ const Builder = std.build.Builder;
const LibExeObjStep = std.build.LibExeObjStep; const LibExeObjStep = std.build.LibExeObjStep;
const glfw = @import("vendor/mach/glfw/build.zig"); const glfw = @import("vendor/mach/glfw/build.zig");
const ft = @import("src/freetype/build.zig"); const ft = @import("src/freetype/build.zig");
const uv = @import("src/libuv/build.zig"); const libuv = @import("pkg/libuv/build.zig");
const tracylib = @import("src/tracy/build.zig"); const tracylib = @import("src/tracy/build.zig");
const system_sdk = @import("vendor/mach/glfw/system_sdk.zig"); const system_sdk = @import("vendor/mach/glfw/system_sdk.zig");
@ -33,50 +33,34 @@ pub fn build(b: *std.build.Builder) !void {
"Name of the conformance app to run with 'run' option.", "Name of the conformance app to run with 'run' option.",
); );
const exe = b.addExecutable("ghostty", "src/main.zig");
// Exe
{
const exe_options = b.addOptions(); const exe_options = b.addOptions();
exe_options.addOption(bool, "tracy_enabled", tracy); exe_options.addOption(bool, "tracy_enabled", tracy);
const exe = b.addExecutable("ghostty", "src/main.zig");
exe.setTarget(target); exe.setTarget(target);
exe.setBuildMode(mode); exe.setBuildMode(mode);
exe.addOptions("build_options", exe_options); exe.addOptions("build_options", exe_options);
exe.install(); exe.install();
exe.addIncludeDir("src/");
exe.addCSourceFile("src/gb_math.c", &.{}); // Add the shared dependencies
exe.addPackagePath("glfw", "vendor/mach/glfw/src/main.zig"); try addDeps(b, exe);
glfw.link(b, exe, .{
.metal = false,
.opengl = false, // Found at runtime
});
// Tracy // Tracy
if (tracy) try tracylib.link(b, exe, target); if (tracy) try tracylib.link(b, exe, target);
}
// GLAD // Run
exe.addIncludeDir("vendor/glad/include/"); {
exe.addCSourceFile("vendor/glad/src/gl.c", &.{});
const ftlib = try ft.create(b, target, mode, .{});
ftlib.link(exe);
const libuv = try uv.create(b, target, mode);
system_sdk.include(b, libuv.step, .{});
libuv.link(exe);
// stb if we need it
// exe.addIncludeDir("vendor/stb");
// exe.addCSourceFile("src/stb/stb.c", &.{});
// Conformance apps
var conformance_exes = try conformanceSteps(b, target, mode);
defer conformance_exes.deinit();
// Build our run step, which runs the main app by default, but will // Build our run step, which runs the main app by default, but will
// run a conformance app if `-Dconformance` is set. // run a conformance app if `-Dconformance` is set.
const run_exe = if (conformance) |name| const run_exe = if (conformance) |name| blk: {
conformance_exes.get(name) orelse return error.InvalidConformance var conformance_exes = try conformanceSteps(b, target, mode);
else defer conformance_exes.deinit();
exe; break :blk conformance_exes.get(name) orelse return error.InvalidConformance;
} else exe;
const run_cmd = run_exe.run(); const run_cmd = run_exe.run();
run_cmd.step.dependOn(&run_exe.step); run_cmd.step.dependOn(&run_exe.step);
if (b.args) |args| { if (b.args) |args| {
@ -85,16 +69,80 @@ pub fn build(b: *std.build.Builder) !void {
const run_step = b.step("run", "Run the app"); const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step); run_step.dependOn(&run_cmd.step);
}
// Tests // Tests
{
const test_step = b.step("test", "Run all tests"); const test_step = b.step("test", "Run all tests");
const lib_tests = b.addTest("src/main.zig"); var test_bin_ = b.option([]const u8, "test-bin", "Emit bin to");
ftlib.link(lib_tests); var test_filter = b.option([]const u8, "test-filter", "Filter for test");
libuv.link(lib_tests);
lib_tests.setTarget(target); const main_test = b.addTest("src/main.zig");
lib_tests.addIncludeDir("vendor/glad/include/"); {
lib_tests.addCSourceFile("vendor/glad/src/gl.c", &.{}); main_test.setFilter(test_filter);
test_step.dependOn(&lib_tests.step); if (test_bin_) |test_bin| {
main_test.name = std.fs.path.basename(test_bin);
if (std.fs.path.dirname(test_bin)) |dir| main_test.setOutputDir(dir);
}
main_test.setTarget(target);
try addDeps(b, main_test);
var before = b.addLog("\x1b[" ++ color_map.get("cyan").? ++ "\x1b[" ++ color_map.get("b").? ++ "[{s} tests]" ++ "\x1b[" ++ color_map.get("d").? ++ " ----" ++ "\x1b[0m", .{"ghostty"});
var after = b.addLog("\x1b[" ++ color_map.get("d").? ++ "---\n\n" ++ "\x1b[0m", .{});
test_step.dependOn(&before.step);
test_step.dependOn(&main_test.step);
test_step.dependOn(&after.step);
}
// Named package dependencies don't have their tests run by reference,
// so we iterate through them here. We're only interested in dependencies
// we wrote (are in the "pkg/" directory).
for (main_test.packages.items) |pkg_| {
const pkg: std.build.Pkg = pkg_;
if (std.mem.eql(u8, pkg.name, "glfw")) continue;
var test_ = b.addTestSource(pkg.source);
test_.setTarget(target);
try addDeps(b, test_);
if (pkg.dependencies) |children| {
test_.packages = std.ArrayList(std.build.Pkg).init(b.allocator);
try test_.packages.appendSlice(children);
}
var before = b.addLog("\x1b[" ++ color_map.get("cyan").? ++ "\x1b[" ++ color_map.get("b").? ++ "[{s} tests]" ++ "\x1b[" ++ color_map.get("d").? ++ " ----" ++ "\x1b[0m", .{pkg.name});
var after = b.addLog("\x1b[" ++ color_map.get("d").? ++ "---\n\n" ++ "\x1b[0m", .{});
test_step.dependOn(&before.step);
test_step.dependOn(&test_.step);
test_step.dependOn(&after.step);
}
}
}
/// Adds and links all of the primary dependencies for the exe.
fn addDeps(
b: *std.build.Builder,
step: *std.build.LibExeObjStep,
) !void {
step.addIncludeDir("src/");
step.addCSourceFile("src/gb_math.c", &.{});
step.addIncludeDir("vendor/glad/include/");
step.addCSourceFile("vendor/glad/src/gl.c", &.{});
// Freetype
const ftlib = try ft.create(b, step.target, step.build_mode, .{});
ftlib.link(step);
// Glfw
step.addPackage(glfw.pkg);
glfw.link(b, step, .{
.metal = false,
.opengl = false, // Found at runtime
});
// Libuv
step.addPackage(libuv.pkg);
try libuv.link(b, step);
} }
fn conformanceSteps( fn conformanceSteps(
@ -139,3 +187,17 @@ fn conformanceSteps(
fn root() []const u8 { fn root() []const u8 {
return std.fs.path.dirname(@src().file) orelse unreachable; return std.fs.path.dirname(@src().file) orelse unreachable;
} }
/// ANSI escape codes for colored log output
const color_map = std.ComptimeStringMap([]const u8, .{
&.{ "black", "30m" },
&.{ "blue", "34m" },
&.{ "b", "1m" },
&.{ "d", "2m" },
&.{ "cyan", "36m" },
&.{ "green", "32m" },
&.{ "magenta", "35m" },
&.{ "red", "31m" },
&.{ "white", "37m" },
&.{ "yellow", "33m" },
});

View File

@ -10,7 +10,6 @@ const errors = @import("error.zig");
const Loop = @import("Loop.zig"); const Loop = @import("Loop.zig");
const Handle = @import("handle.zig").Handle; const Handle = @import("handle.zig").Handle;
const Stream = @import("stream.zig").Stream; const Stream = @import("stream.zig").Stream;
const Pty = @import("../Pty.zig");
handle: *c.uv_tty_t, handle: *c.uv_tty_t,
@ -28,24 +27,3 @@ pub fn deinit(self: *Tty, alloc: Allocator) void {
alloc.destroy(self.handle); alloc.destroy(self.handle);
self.* = undefined; self.* = undefined;
} }
test "Tty" {
var pty = try Pty.open(.{
.ws_row = 20,
.ws_col = 80,
.ws_xpixel = 0,
.ws_ypixel = 0,
});
defer pty.deinit();
var loop = try Loop.init(testing.allocator);
defer loop.deinit(testing.allocator);
var tty = try init(testing.allocator, loop, pty.slave);
defer tty.deinit(testing.allocator);
try testing.expect(try tty.isReadable());
try testing.expect(try tty.isWritable());
tty.close(null);
_ = try loop.run(.default);
}

169
pkg/libuv/build.zig Normal file
View File

@ -0,0 +1,169 @@
const std = @import("std");
/// Directories with our includes.
const root = thisDir() ++ "../../../vendor/libuv/";
const include_path = root ++ "include";
pub const pkg = std.build.Pkg{
.name = "libuv",
.source = .{ .path = thisDir() ++ "/main.zig" },
};
fn thisDir() []const u8 {
return std.fs.path.dirname(@src().file) orelse ".";
}
pub fn link(b: *std.build.Builder, step: *std.build.LibExeObjStep) !void {
const libuv = try buildLibuv(b, step);
step.linkLibrary(libuv);
step.addIncludePath(include_path);
}
pub fn buildLibuv(
b: *std.build.Builder,
step: *std.build.LibExeObjStep,
) !*std.build.LibExeObjStep {
const lib = b.addStaticLibrary("uv", null);
lib.setTarget(step.target);
lib.setBuildMode(step.build_mode);
const target = step.target;
// Include dirs
lib.addIncludePath(include_path);
lib.addIncludePath(root ++ "src");
// Links
if (target.isWindows()) {
lib.linkSystemLibrary("psapi");
lib.linkSystemLibrary("user32");
lib.linkSystemLibrary("advapi32");
lib.linkSystemLibrary("iphlpapi");
lib.linkSystemLibrary("userenv");
lib.linkSystemLibrary("ws2_32");
}
if (target.isLinux()) {
lib.linkSystemLibrary("pthread");
}
lib.linkLibC();
// Compilation
var flags = std.ArrayList([]const u8).init(b.allocator);
defer flags.deinit();
// try flags.appendSlice(&.{});
if (!target.isWindows()) {
try flags.appendSlice(&.{
"-D_FILE_OFFSET_BITS=64",
"-D_LARGEFILE_SOURCE",
});
}
if (target.isLinux()) {
try flags.appendSlice(&.{
"-D_GNU_SOURCE",
"-D_POSIX_C_SOURCE=200112",
});
}
if (target.isDarwin()) {
try flags.appendSlice(&.{
"-D_DARWIN_UNLIMITED_SELECT=1",
"-D_DARWIN_USE_64_BIT_INODE=1",
});
}
// C files common to all platforms
lib.addCSourceFiles(&.{
root ++ "src/fs-poll.c",
root ++ "src/idna.c",
root ++ "src/inet.c",
root ++ "src/random.c",
root ++ "src/strscpy.c",
root ++ "src/strtok.c",
root ++ "src/threadpool.c",
root ++ "src/timer.c",
root ++ "src/uv-common.c",
root ++ "src/uv-data-getter-setters.c",
root ++ "src/version.c",
}, flags.items);
if (!target.isWindows()) {
lib.addCSourceFiles(&.{
root ++ "src/unix/async.c",
root ++ "src/unix/core.c",
root ++ "src/unix/dl.c",
root ++ "src/unix/fs.c",
root ++ "src/unix/getaddrinfo.c",
root ++ "src/unix/getnameinfo.c",
root ++ "src/unix/loop-watcher.c",
root ++ "src/unix/loop.c",
root ++ "src/unix/pipe.c",
root ++ "src/unix/poll.c",
root ++ "src/unix/process.c",
root ++ "src/unix/random-devurandom.c",
root ++ "src/unix/signal.c",
root ++ "src/unix/stream.c",
root ++ "src/unix/tcp.c",
root ++ "src/unix/thread.c",
root ++ "src/unix/tty.c",
root ++ "src/unix/udp.c",
}, flags.items);
}
if (target.isLinux() or target.isDarwin()) {
lib.addCSourceFiles(&.{
root ++ "src/unix/proctitle.c",
}, flags.items);
}
if (target.isLinux()) {
lib.addCSourceFiles(&.{
root ++ "src/unix/linux-core.c",
root ++ "src/unix/linux-inotify.c",
root ++ "src/unix/linux-syscalls.c",
root ++ "src/unix/procfs-exepath.c",
root ++ "src/unix/random-getrandom.c",
root ++ "src/unix/random-sysctl-linux.c",
root ++ "src/unix/epoll.c",
}, flags.items);
}
if (target.isDarwin() or
target.isOpenBSD() or
target.isNetBSD() or
target.isFreeBSD() or
target.isDragonFlyBSD())
{
lib.addCSourceFiles(&.{
root ++ "src/unix/bsd-ifaddrs.c",
root ++ "src/unix/kqueue.c",
}, flags.items);
}
if (target.isDarwin() or target.isOpenBSD()) {
lib.addCSourceFiles(&.{
root ++ "src/unix/random-getentropy.c",
}, flags.items);
}
if (target.isDarwin()) {
lib.addCSourceFiles(&.{
root ++ "src/unix/darwin-proctitle.c",
root ++ "src/unix/darwin.c",
root ++ "src/unix/fsevents.c",
}, flags.items);
}
return lib;
}
pub fn testLibuv(
b: *std.build.Builder,
step: *std.build.LibExeObjStep,
) !*std.build.LibExeObjStep {
const lib = b.addTest(root ++ "src/main.zig");
lib.setTarget(step.target);
try link(b, step);
return lib;
}

View File

@ -7,7 +7,7 @@ const std = @import("std");
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const glfw = @import("glfw"); const glfw = @import("glfw");
const Window = @import("Window.zig"); const Window = @import("Window.zig");
const libuv = @import("libuv/main.zig"); const libuv = @import("libuv");
const tracy = @import("tracy/tracy.zig"); const tracy = @import("tracy/tracy.zig");
const Config = @import("config.zig").Config; const Config = @import("config.zig").Config;

View File

@ -12,7 +12,7 @@ const Allocator = std.mem.Allocator;
const Grid = @import("Grid.zig"); const Grid = @import("Grid.zig");
const glfw = @import("glfw"); const glfw = @import("glfw");
const gl = @import("opengl.zig"); const gl = @import("opengl.zig");
const libuv = @import("libuv/main.zig"); const libuv = @import("libuv");
const Pty = @import("Pty.zig"); const Pty = @import("Pty.zig");
const Command = @import("Command.zig"); const Command = @import("Command.zig");
const SegmentedPool = @import("segmented_pool.zig").SegmentedPool; const SegmentedPool = @import("segmented_pool.zig").SegmentedPool;

View File

@ -1,165 +0,0 @@
const std = @import("std");
/// This is the type returned by create.
pub const Library = struct {
step: *std.build.LibExeObjStep,
/// statically link this library into the given step
pub fn link(self: Library, other: *std.build.LibExeObjStep) void {
self.addIncludeDirs(other);
other.linkLibrary(self.step);
}
/// only add the include dirs to the given step. This is useful if building
/// a static library that you don't want to fully link in the code of this
/// library.
pub fn addIncludeDirs(self: Library, other: *std.build.LibExeObjStep) void {
_ = self;
other.addIncludeDir(include_dir);
}
};
/// Create this library. This is the primary API users of build.zig should
/// use to link this library to their application. On the resulting Library,
/// call the link function and given your own application step.
pub fn create(
b: *std.build.Builder,
target: std.zig.CrossTarget,
mode: std.builtin.Mode,
) !Library {
const ret = b.addStaticLibrary("uv", null);
ret.setTarget(target);
ret.setBuildMode(mode);
var flags = std.ArrayList([]const u8).init(b.allocator);
defer flags.deinit();
// try flags.appendSlice(&.{});
if (!target.isWindows()) {
try flags.appendSlice(&.{
"-D_FILE_OFFSET_BITS=64",
"-D_LARGEFILE_SOURCE",
});
}
if (target.isLinux()) {
try flags.appendSlice(&.{
"-D_GNU_SOURCE",
"-D_POSIX_C_SOURCE=200112",
});
}
if (target.isDarwin()) {
try flags.appendSlice(&.{
"-D_DARWIN_UNLIMITED_SELECT=1",
"-D_DARWIN_USE_64_BIT_INODE=1",
});
}
// C files common to all platforms
ret.addCSourceFiles(&.{
root() ++ "src/fs-poll.c",
root() ++ "src/idna.c",
root() ++ "src/inet.c",
root() ++ "src/random.c",
root() ++ "src/strscpy.c",
root() ++ "src/strtok.c",
root() ++ "src/threadpool.c",
root() ++ "src/timer.c",
root() ++ "src/uv-common.c",
root() ++ "src/uv-data-getter-setters.c",
root() ++ "src/version.c",
}, flags.items);
if (!target.isWindows()) {
ret.addCSourceFiles(&.{
root() ++ "src/unix/async.c",
root() ++ "src/unix/core.c",
root() ++ "src/unix/dl.c",
root() ++ "src/unix/fs.c",
root() ++ "src/unix/getaddrinfo.c",
root() ++ "src/unix/getnameinfo.c",
root() ++ "src/unix/loop-watcher.c",
root() ++ "src/unix/loop.c",
root() ++ "src/unix/pipe.c",
root() ++ "src/unix/poll.c",
root() ++ "src/unix/process.c",
root() ++ "src/unix/random-devurandom.c",
root() ++ "src/unix/signal.c",
root() ++ "src/unix/stream.c",
root() ++ "src/unix/tcp.c",
root() ++ "src/unix/thread.c",
root() ++ "src/unix/tty.c",
root() ++ "src/unix/udp.c",
}, flags.items);
}
if (target.isLinux() or target.isDarwin()) {
ret.addCSourceFiles(&.{
root() ++ "src/unix/proctitle.c",
}, flags.items);
}
if (target.isLinux()) {
ret.addCSourceFiles(&.{
root() ++ "src/unix/linux-core.c",
root() ++ "src/unix/linux-inotify.c",
root() ++ "src/unix/linux-syscalls.c",
root() ++ "src/unix/procfs-exepath.c",
root() ++ "src/unix/random-getrandom.c",
root() ++ "src/unix/random-sysctl-linux.c",
root() ++ "src/unix/epoll.c",
}, flags.items);
}
if (target.isDarwin() or
target.isOpenBSD() or
target.isNetBSD() or
target.isFreeBSD() or
target.isDragonFlyBSD())
{
ret.addCSourceFiles(&.{
root() ++ "src/unix/bsd-ifaddrs.c",
root() ++ "src/unix/kqueue.c",
}, flags.items);
}
if (target.isDarwin() or target.isOpenBSD()) {
ret.addCSourceFiles(&.{
root() ++ "src/unix/random-getentropy.c",
}, flags.items);
}
if (target.isDarwin()) {
ret.addCSourceFiles(&.{
root() ++ "src/unix/darwin-proctitle.c",
root() ++ "src/unix/darwin.c",
root() ++ "src/unix/fsevents.c",
}, flags.items);
}
ret.addIncludeDir(include_dir);
ret.addIncludeDir(root() ++ "src");
if (target.isWindows()) {
ret.linkSystemLibrary("psapi");
ret.linkSystemLibrary("user32");
ret.linkSystemLibrary("advapi32");
ret.linkSystemLibrary("iphlpapi");
ret.linkSystemLibrary("userenv");
ret.linkSystemLibrary("ws2_32");
}
if (target.isLinux()) {
ret.linkSystemLibrary("pthread");
}
ret.linkLibC();
return Library{ .step = ret };
}
fn root() []const u8 {
return (std.fs.path.dirname(@src().file) orelse unreachable) ++ "/../../vendor/libuv/";
}
/// Directories with our includes.
const include_dir = root() ++ "include";

View File

@ -100,8 +100,8 @@ test {
_ = @import("terminal/Terminal.zig"); _ = @import("terminal/Terminal.zig");
// Libraries // Libraries
_ = @import("libuv");
_ = @import("segmented_pool.zig"); _ = @import("segmented_pool.zig");
_ = @import("libuv/main.zig");
_ = @import("terminal/main.zig"); _ = @import("terminal/main.zig");
// TODO // TODO

View File

@ -1,7 +1,7 @@
const std = @import("std"); const std = @import("std");
const assert = std.debug.assert; const assert = std.debug.assert;
const Allocator = std.mem.Allocator; const Allocator = std.mem.Allocator;
const libuv = @import("libuv/main.zig"); const libuv = @import("libuv");
/// A coalescing timer that forces a run after a certain maximum time /// A coalescing timer that forces a run after a certain maximum time
/// since the last run. This is used for example by the renderer to try /// since the last run. This is used for example by the renderer to try