mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00

Fixes the next issue on windows. The fontconfig library is calling the function xmlCreatePushParserCtxt from libxml2, however, the function declaration was being omitted because fontconfig was not defining the LIBXML_PUSH_ENABLED preprocessor symbol. However, instead of a compile error, C's support for implicit function declrations allows it to happily call the function anyway, with the wrong ABI. The main issue was the return type being implicitly declared as "int" instead of a pointer. On my system this was causing the return pointer to be truncated to 32 bits and then sign-extended which caused a segfault once it was dereferenced. I've gone ahead and added the -Werror=implicit-function-declaration to fontconfig to avoid these issues in the future. However, this flag didn't compile on linux so I've left it as Windows only for now. I also needed to add the LIBXML_STATIC define because not defining it causes some functions on windows to be declared with `__declspec(dllimport)` which results in linker errors since we are actually statically linking libxml2.
241 lines
6.7 KiB
Zig
241 lines
6.7 KiB
Zig
const std = @import("std");
|
|
const builtin = @import("builtin");
|
|
const NativeTargetInfo = std.zig.system.NativeTargetInfo;
|
|
|
|
/// Directories with our includes.
|
|
const root = thisDir() ++ "../../../vendor/fontconfig-2.14.0/";
|
|
const include_path = root;
|
|
const include_path_self = thisDir();
|
|
|
|
pub const include_paths = .{ include_path, include_path_self };
|
|
|
|
pub fn module(b: *std.Build) *std.build.Module {
|
|
return b.createModule(.{
|
|
.source_file = .{ .path = (comptime thisDir()) ++ "/main.zig" },
|
|
});
|
|
}
|
|
|
|
fn thisDir() []const u8 {
|
|
return std.fs.path.dirname(@src().file) orelse ".";
|
|
}
|
|
|
|
pub const Options = struct {
|
|
freetype: Freetype = .{},
|
|
expat: Expat = .{},
|
|
libxml2: bool = false,
|
|
|
|
pub const Freetype = struct {
|
|
enabled: bool = false,
|
|
step: ?*std.build.LibExeObjStep = null,
|
|
include: ?[]const []const u8 = null,
|
|
};
|
|
|
|
pub const Expat = struct {
|
|
enabled: bool = false,
|
|
step: ?*std.build.LibExeObjStep = null,
|
|
include: ?[]const []const u8 = null,
|
|
};
|
|
};
|
|
|
|
pub fn link(
|
|
b: *std.Build,
|
|
step: *std.build.LibExeObjStep,
|
|
opt: Options,
|
|
) !*std.build.LibExeObjStep {
|
|
const lib = try buildFontconfig(b, step, opt);
|
|
step.linkLibrary(lib);
|
|
step.addIncludePath(.{ .path = include_path });
|
|
step.addIncludePath(.{ .path = include_path_self });
|
|
return lib;
|
|
}
|
|
|
|
pub fn buildFontconfig(
|
|
b: *std.Build,
|
|
step: *std.build.LibExeObjStep,
|
|
opt: Options,
|
|
) !*std.build.LibExeObjStep {
|
|
const target = step.target;
|
|
const lib = b.addStaticLibrary(.{
|
|
.name = "fontconfig",
|
|
.target = step.target,
|
|
.optimize = step.optimize,
|
|
});
|
|
|
|
// Include
|
|
lib.addIncludePath(.{ .path = include_path });
|
|
lib.addIncludePath(.{ .path = include_path_self });
|
|
|
|
// Link
|
|
lib.linkLibC();
|
|
if (opt.expat.enabled) {
|
|
if (opt.expat.step) |expat|
|
|
lib.linkLibrary(expat)
|
|
else
|
|
lib.linkSystemLibrary("expat");
|
|
|
|
if (opt.expat.include) |dirs|
|
|
for (dirs) |dir| lib.addIncludePath(.{ .path = dir });
|
|
}
|
|
if (opt.freetype.enabled) {
|
|
if (opt.freetype.step) |freetype|
|
|
lib.linkLibrary(freetype)
|
|
else
|
|
lib.linkSystemLibrary("freetype2");
|
|
|
|
if (opt.freetype.include) |dirs|
|
|
for (dirs) |dir| lib.addIncludePath(.{ .path = dir });
|
|
}
|
|
if (!target.isWindows()) {
|
|
lib.linkSystemLibrary("pthread");
|
|
}
|
|
|
|
// Compile
|
|
var flags = std.ArrayList([]const u8).init(b.allocator);
|
|
defer flags.deinit();
|
|
|
|
try flags.appendSlice(&.{
|
|
"-DHAVE_DIRENT_H",
|
|
"-DHAVE_FCNTL_H",
|
|
"-DHAVE_STDLIB_H",
|
|
"-DHAVE_STRING_H",
|
|
"-DHAVE_UNISTD_H",
|
|
"-DHAVE_SYS_PARAM_H",
|
|
|
|
"-DHAVE_MKSTEMP",
|
|
"-DHAVE__MKTEMP_S",
|
|
"-DHAVE_MKDTEMP",
|
|
"-DHAVE_GETOPT",
|
|
"-DHAVE_GETOPT_LONG",
|
|
//"-DHAVE_GETPROGNAME",
|
|
//"-DHAVE_GETEXECNAME",
|
|
"-DHAVE_RAND",
|
|
//"-DHAVE_RANDOM_R",
|
|
"-DHAVE_FSTATVFS",
|
|
"-DHAVE_FSTATFS",
|
|
"-DHAVE_VPRINTF",
|
|
|
|
"-DHAVE_FT_GET_BDF_PROPERTY",
|
|
"-DHAVE_FT_GET_PS_FONT_INFO",
|
|
"-DHAVE_FT_HAS_PS_GLYPH_NAMES",
|
|
"-DHAVE_FT_GET_X11_FONT_FORMAT",
|
|
"-DHAVE_FT_DONE_MM_VAR",
|
|
|
|
"-DHAVE_POSIX_FADVISE",
|
|
|
|
//"-DHAVE_STRUCT_STATVFS_F_BASETYPE",
|
|
// "-DHAVE_STRUCT_STATVFS_F_FSTYPENAME",
|
|
// "-DHAVE_STRUCT_STATFS_F_FLAGS",
|
|
// "-DHAVE_STRUCT_STATFS_F_FSTYPENAME",
|
|
// "-DHAVE_STRUCT_DIRENT_D_TYPE",
|
|
|
|
"-DFLEXIBLE_ARRAY_MEMBER",
|
|
|
|
"-DHAVE_STDATOMIC_PRIMITIVES",
|
|
|
|
"-DFC_GPERF_SIZE_T=size_t",
|
|
|
|
// Default errors that fontconfig can't handle
|
|
"-Wno-implicit-function-declaration",
|
|
"-Wno-int-conversion",
|
|
|
|
// https://gitlab.freedesktop.org/fontconfig/fontconfig/-/merge_requests/231
|
|
"-fno-sanitize=undefined",
|
|
"-fno-sanitize-trap=undefined",
|
|
});
|
|
const target_info = try NativeTargetInfo.detect(target);
|
|
switch (target_info.target.ptrBitWidth()) {
|
|
32 => try flags.appendSlice(&.{
|
|
"-DSIZEOF_VOID_P=4",
|
|
"-DALIGNOF_VOID_P=4",
|
|
}),
|
|
|
|
64 => try flags.appendSlice(&.{
|
|
"-DSIZEOF_VOID_P=8",
|
|
"-DALIGNOF_VOID_P=8",
|
|
}),
|
|
|
|
else => @panic("unsupported arch"),
|
|
}
|
|
|
|
if (opt.libxml2) {
|
|
try flags.appendSlice(&.{
|
|
"-DENABLE_LIBXML2",
|
|
"-DLIBXML_STATIC",
|
|
"-DLIBXML_PUSH_ENABLED",
|
|
});
|
|
if (target.isWindows()) {
|
|
// NOTE: this should be defined on all targets
|
|
try flags.appendSlice(&.{
|
|
"-Werror=implicit-function-declaration",
|
|
});
|
|
}
|
|
}
|
|
|
|
if (target.isWindows()) {
|
|
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",
|
|
|
|
"-DFC_CACHEDIR=\"/var/cache/fontconfig\"",
|
|
"-DFC_TEMPLATEDIR=\"/usr/share/fontconfig/conf.avail\"",
|
|
"-DFONTCONFIG_PATH=\"/etc/fonts\"",
|
|
"-DCONFIGDIR=\"/usr/local/fontconfig/conf.d\"",
|
|
"-DFC_DEFAULT_FONTS=\"<dir>/usr/share/fonts</dir><dir>/usr/local/share/fonts</dir>\"",
|
|
});
|
|
}
|
|
|
|
// C files
|
|
lib.addCSourceFiles(srcs, flags.items);
|
|
|
|
return lib;
|
|
}
|
|
|
|
const srcs = &.{
|
|
root ++ "src/fcatomic.c",
|
|
root ++ "src/fccache.c",
|
|
root ++ "src/fccfg.c",
|
|
root ++ "src/fccharset.c",
|
|
root ++ "src/fccompat.c",
|
|
root ++ "src/fcdbg.c",
|
|
root ++ "src/fcdefault.c",
|
|
root ++ "src/fcdir.c",
|
|
root ++ "src/fcformat.c",
|
|
root ++ "src/fcfreetype.c",
|
|
root ++ "src/fcfs.c",
|
|
root ++ "src/fcptrlist.c",
|
|
root ++ "src/fchash.c",
|
|
root ++ "src/fcinit.c",
|
|
root ++ "src/fclang.c",
|
|
root ++ "src/fclist.c",
|
|
root ++ "src/fcmatch.c",
|
|
root ++ "src/fcmatrix.c",
|
|
root ++ "src/fcname.c",
|
|
root ++ "src/fcobjs.c",
|
|
root ++ "src/fcpat.c",
|
|
root ++ "src/fcrange.c",
|
|
root ++ "src/fcserialize.c",
|
|
root ++ "src/fcstat.c",
|
|
root ++ "src/fcstr.c",
|
|
root ++ "src/fcweight.c",
|
|
root ++ "src/fcxml.c",
|
|
root ++ "src/ftglue.c",
|
|
};
|