|
| 1 | +const std = @import("std"); |
| 2 | + |
| 3 | +const manifest = @import("build.zig.zon"); |
| 4 | + |
| 5 | +pub fn build(b: *std.Build) !void { |
| 6 | + const target = b.standardTargetOptions(.{}); |
| 7 | + const optimize = b.standardOptimizeOption(.{}); |
| 8 | + |
| 9 | + const upstream = b.dependency("upstream", .{}); |
| 10 | + const version: std.SemanticVersion = try .parse(manifest.version); |
| 11 | + const src = upstream.path(""); |
| 12 | + |
| 13 | + const os = target.result.os.tag; |
| 14 | + const is_posix = os != .windows; |
| 15 | + const is_linux = os == .linux; |
| 16 | + |
| 17 | + const options = .{ |
| 18 | + .linkage = b.option(std.builtin.LinkMode, "linkage", "Library linkage type") orelse .static, |
| 19 | + .@"enable-x11" = b.option(bool, "enable-x11", "Build libxkbcommon-x11") orelse false, |
| 20 | + .xkb_config_root = b.option([]const u8, "xkb-config-root", "Root XKB config directory") orelse "/usr/share/X11/xkb", |
| 21 | + .xkb_extra_path = b.option([]const u8, "xkb-config-extra-path", "Extra XKB config path") orelse b.pathJoin(&.{ b.install_prefix, "etc/xkb" }), |
| 22 | + .xlocaledir = b.option([]const u8, "x-locale-root", "X11 locale directory") orelse b.pathJoin(&.{ b.install_prefix, "share/X11/locale" }), |
| 23 | + .default_rules = b.option([]const u8, "default-rules", "Default XKB rules") orelse "evdev", |
| 24 | + .default_model = b.option([]const u8, "default-model", "Default XKB model") orelse "pc105", |
| 25 | + .default_layout = b.option([]const u8, "default-layout", "Default XKB layout") orelse "us", |
| 26 | + }; |
| 27 | + |
| 28 | + const config_h = b.addConfigHeader(.{ .style = .blank, .include_path = "config.h" }, .{ |
| 29 | + .EXIT_INVALID_USAGE = @as(i64, 2), |
| 30 | + .LIBXKBCOMMON_VERSION = manifest.version, |
| 31 | + .LIBXKBCOMMON_TOOL_PATH = b.pathJoin(&.{ b.install_prefix, "libexec/xkbcommon" }), |
| 32 | + .DFLT_XKB_LEGACY_ROOT = options.xkb_config_root, |
| 33 | + .DFLT_XKB_CONFIG_ROOT = options.xkb_config_root, |
| 34 | + .DFLT_XKB_CONFIG_EXTRA_PATH = options.xkb_extra_path, |
| 35 | + .XLOCALEDIR = options.xlocaledir, |
| 36 | + .DEFAULT_XKB_RULES = options.default_rules, |
| 37 | + .DEFAULT_XKB_MODEL = options.default_model, |
| 38 | + .DEFAULT_XKB_LAYOUT = options.default_layout, |
| 39 | + .HAVE_UNISTD_H = opt(is_posix), |
| 40 | + .HAVE_DIRENT_H = opt(is_posix), |
| 41 | + .HAVE_XKB_EXTENSIONS_DIRECTORIES = opt(is_posix), |
| 42 | + .HAVE___BUILTIN_EXPECT = opt(is_posix), |
| 43 | + .HAVE_STRNDUP = opt(is_posix), |
| 44 | + .HAVE_EACCESS = opt(is_linux), |
| 45 | + .HAVE_EUIDACCESS = opt(is_linux), |
| 46 | + .HAVE_ASPRINTF = opt(is_posix), |
| 47 | + .HAVE_SECURE_GETENV = opt(is_linux), |
| 48 | + .HAVE_NEWLOCALE = opt(is_linux), |
| 49 | + }); |
| 50 | + |
| 51 | + // Bison parser generation |
| 52 | + const parser_wf = b.addWriteFiles(); |
| 53 | + const bison = b.addSystemCommand(&.{"bison"}); |
| 54 | + const parser_header = bison.addPrefixedOutputFileArg("--defines=", "parser.h"); |
| 55 | + bison.addArg("-o"); |
| 56 | + const parser_source = bison.addOutputFileArg("parser.c"); |
| 57 | + bison.addArgs(&.{ "-p", "_xkbcommon_" }); |
| 58 | + bison.addFileArg(upstream.path("src/xkbcomp/parser.y")); |
| 59 | + _ = parser_wf.addCopyFile(parser_source, "parser.c"); |
| 60 | + _ = parser_wf.addCopyFile(parser_header, "parser.h"); |
| 61 | + |
| 62 | + const flags: []const []const u8 = &.{ |
| 63 | + "-D_GNU_SOURCE", "-DDEFAULT_XKB_VARIANT=NULL", |
| 64 | + "-DDEFAULT_XKB_OPTIONS=NULL", "-fno-strict-aliasing", |
| 65 | + "-fvisibility=hidden", "-std=c11", |
| 66 | + "-Wno-unused-parameter", "-Wno-missing-field-initializers", |
| 67 | + }; |
| 68 | + |
| 69 | + const mod = b.createModule(.{ .target = target, .optimize = optimize, .link_libc = true }); |
| 70 | + mod.addConfigHeader(config_h); |
| 71 | + mod.addIncludePath(src); |
| 72 | + mod.addIncludePath(upstream.path("src")); |
| 73 | + mod.addIncludePath(upstream.path("include")); |
| 74 | + mod.addIncludePath(parser_wf.getDirectory()); |
| 75 | + mod.addCSourceFiles(.{ .root = src, .files = libxkbcommon_sources, .flags = flags }); |
| 76 | + mod.addCSourceFiles(.{ .root = parser_wf.getDirectory(), .files = &.{"parser.c"}, .flags = flags }); |
| 77 | + |
| 78 | + const xkbcommon = b.addLibrary(.{ |
| 79 | + .name = "xkbcommon", |
| 80 | + .root_module = mod, |
| 81 | + .linkage = options.linkage, |
| 82 | + .version = .{ .major = 0, .minor = version.minor, .patch = version.patch }, |
| 83 | + }); |
| 84 | + if (options.linkage == .dynamic) xkbcommon.version_script = upstream.path("xkbcommon.map"); |
| 85 | + inline for (installed_headers) |h| |
| 86 | + xkbcommon.installHeader(upstream.path("include/xkbcommon/" ++ h), "xkbcommon/" ++ h); |
| 87 | + b.installArtifact(xkbcommon); |
| 88 | + |
| 89 | + if (options.@"enable-x11") { |
| 90 | + const x11_mod = b.createModule(.{ .target = target, .optimize = optimize, .link_libc = true }); |
| 91 | + x11_mod.addConfigHeader(config_h); |
| 92 | + x11_mod.addIncludePath(src); |
| 93 | + x11_mod.addIncludePath(upstream.path("src")); |
| 94 | + x11_mod.addIncludePath(upstream.path("include")); |
| 95 | + x11_mod.linkLibrary(xkbcommon); |
| 96 | + x11_mod.linkSystemLibrary("xcb", .{}); |
| 97 | + x11_mod.linkSystemLibrary("xcb-xkb", .{}); |
| 98 | + x11_mod.addCSourceFiles(.{ .root = src, .files = libxkbcommon_x11_sources, .flags = flags }); |
| 99 | + |
| 100 | + const xkbcommon_x11 = b.addLibrary(.{ |
| 101 | + .name = "xkbcommon-x11", |
| 102 | + .root_module = x11_mod, |
| 103 | + .linkage = options.linkage, |
| 104 | + .version = .{ .major = 0, .minor = version.minor, .patch = version.patch }, |
| 105 | + }); |
| 106 | + if (options.linkage == .dynamic) xkbcommon_x11.version_script = upstream.path("xkbcommon-x11.map"); |
| 107 | + xkbcommon_x11.installHeader(upstream.path("include/xkbcommon/xkbcommon-x11.h"), "xkbcommon/xkbcommon-x11.h"); |
| 108 | + b.installArtifact(xkbcommon_x11); |
| 109 | + } |
| 110 | +} |
| 111 | + |
| 112 | +inline fn opt(v: bool) ?bool { |
| 113 | + return if (v) true else null; |
| 114 | +} |
| 115 | + |
| 116 | +const libxkbcommon_sources: []const []const u8 = &.{ |
| 117 | + "src/compose/parser.c", "src/compose/paths.c", "src/compose/state.c", |
| 118 | + "src/compose/table.c", "src/xkbcomp/action.c", "src/xkbcomp/ast-build.c", |
| 119 | + "src/xkbcomp/compat.c", "src/xkbcomp/expr.c", "src/xkbcomp/include.c", |
| 120 | + "src/xkbcomp/keycodes.c", "src/xkbcomp/keymap.c", "src/xkbcomp/keymap-dump.c", |
| 121 | + "src/xkbcomp/keywords.c", "src/xkbcomp/rules.c", "src/xkbcomp/scanner.c", |
| 122 | + "src/xkbcomp/symbols.c", "src/xkbcomp/types.c", "src/xkbcomp/vmod.c", |
| 123 | + "src/xkbcomp/xkbcomp.c", "src/atom.c", "src/context.c", |
| 124 | + "src/context-priv.c", "src/keysym.c", "src/keysym-case-mappings.c", |
| 125 | + "src/keysym-utf.c", "src/keymap.c", "src/keymap-compare.c", |
| 126 | + "src/keymap-priv.c", "src/rmlvo.c", "src/scanner-utils.c", |
| 127 | + "src/state.c", "src/text.c", "src/utf8.c", |
| 128 | + "src/utf8-decoding.c", "src/utils.c", "src/utils-paths.c", |
| 129 | +}; |
| 130 | + |
| 131 | +const libxkbcommon_x11_sources: []const []const u8 = &.{ |
| 132 | + "src/x11/keymap.c", "src/x11/state.c", "src/x11/util.c", |
| 133 | + "src/context.c", "src/context-priv.c", "src/keymap-priv.c", |
| 134 | + "src/atom.c", "src/utils.c", |
| 135 | +}; |
| 136 | + |
| 137 | +const installed_headers: []const []const u8 = &.{ |
| 138 | + "xkbcommon.h", "xkbcommon-compat.h", |
| 139 | + "xkbcommon-compose.h", "xkbcommon-keysyms.h", |
| 140 | + "xkbcommon-names.h", |
| 141 | +}; |
0 commit comments