const std = @import("std"); const NativeTargetInfo = std.zig.system.NativeTargetInfo; pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); const libxml2_enabled = b.option(bool, "enable-libxml2", "Build libxml2") orelse true; const libxml2_iconv_enabled = b.option( bool, "enable-libxml2-iconv", "Build libxml2 with iconv", ) orelse (target.result.os.tag != .windows); const freetype_enabled = b.option(bool, "enable-freetype", "Build freetype") orelse true; const module = b.addModule("fontconfig", .{ .root_source_file = b.path("main.zig"), .target = target, .optimize = optimize, }); // For dynamic linking, we prefer dynamic linking and to search by // mode first. Mode first will search all paths for a dynamic library // before falling back to static. const dynamic_link_opts: std.Build.Module.LinkSystemLibraryOptions = .{ .preferred_link_mode = .dynamic, .search_strategy = .mode_first, }; const test_exe = b.addTest(.{ .name = "test", .root_source_file = b.path("main.zig"), .target = target, .optimize = optimize, }); const tests_run = b.addRunArtifact(test_exe); const test_step = b.step("test", "Run tests"); test_step.dependOn(&tests_run.step); if (b.systemIntegrationOption("fontconfig", .{})) { module.linkSystemLibrary("fontconfig", dynamic_link_opts); test_exe.linkSystemLibrary2("fontconfig", dynamic_link_opts); } else { const lib = try buildLib(b, module, .{ .target = target, .optimize = optimize, .libxml2_enabled = libxml2_enabled, .libxml2_iconv_enabled = libxml2_iconv_enabled, .freetype_enabled = freetype_enabled, .dynamic_link_opts = dynamic_link_opts, }); test_exe.linkLibrary(lib); } } fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Build.Step.Compile { const target = options.target; const optimize = options.optimize; const libxml2_enabled = options.libxml2_enabled; const libxml2_iconv_enabled = options.libxml2_iconv_enabled; const freetype_enabled = options.freetype_enabled; const upstream = b.dependency("fontconfig", .{}); const lib = b.addStaticLibrary(.{ .name = "fontconfig", .target = target, .optimize = optimize, }); lib.linkLibC(); if (target.result.os.tag != .windows) { lib.linkSystemLibrary("pthread"); } lib.addIncludePath(upstream.path("")); lib.addIncludePath(b.path("override/include")); module.addIncludePath(upstream.path("")); module.addIncludePath(b.path("override/include")); 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_GETPROGNAME", //"-DHAVE_GETEXECNAME", "-DHAVE_RAND", //"-DHAVE_RANDOM_R", "-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", }); switch (target.result.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 (target.result.os.tag == .windows) { 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