├── .gitattributes ├── .github └── workflows │ └── ci.yaml ├── .gitignore ├── LICENSE ├── README.md ├── build.zig ├── build.zig.zon └── embed.zig /.gitattributes: -------------------------------------------------------------------------------- 1 | *.zig text eol=lf 2 | *.zon text eol=lf 3 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | workflow_dispatch: 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v4 18 | 19 | - name: Setup Zig 20 | uses: mlugg/setup-zig@v1 21 | 22 | - name: Check Formatting 23 | run: zig fmt --ast-check --check . 24 | 25 | - name: Build 26 | run: zig build --summary all 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .zig-cache 2 | zig-cache 3 | zig-out 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (Expat) 2 | 3 | Copyright (c) contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![CI](https://github.com/allyourcodebase/wayland/actions/workflows/ci.yaml/badge.svg)](https://github.com/allyourcodebase/wayland/actions) 2 | 3 | # Wayland 4 | 5 | This is [Wayland](https://gitlab.freedesktop.org/wayland/wayland), packaged for [Zig](https://ziglang.org/). 6 | 7 | ## Installation 8 | 9 | First, update your `build.zig.zon`: 10 | 11 | ``` 12 | # Initialize a `zig build` project if you haven't already 13 | zig init 14 | zig fetch --save git+https://github.com/allyourcodebase/wayland.git#1.23.1-3 15 | ``` 16 | 17 | You can then import `wayland` in your `build.zig` with: 18 | 19 | ```zig 20 | const wayland = b.dependency("wayland", .{ 21 | .target = target, 22 | .optimize = optimize, 23 | }); 24 | const wayland_server = wayland.artifact("wayland-server"); 25 | const wayland_client = wayland.artifact("wayland-client"); 26 | const wayland_egl = wayland.artifact("wayland-egl"); 27 | const wayland_cursor = wayland.artifact("wayland-cursor"); 28 | 29 | // Makes sure we get `wayland-scanner` for the host platform even when cross-compiling 30 | const wayland_host = b.dependency("wayland", .{ 31 | .target = b.host, 32 | .optimize = std.builtin.OptimizeMode.Debug, 33 | }); 34 | const wayland_scanner = wayland_host.artifact("wayland-scanner"); 35 | ``` 36 | -------------------------------------------------------------------------------- /build.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | const version: std.SemanticVersion = .{ .major = 1, .minor = 23, .patch = 1 }; 4 | 5 | pub fn build(b: *std.Build) void { 6 | const upstream = b.dependency("wayland", .{}); 7 | const target = b.standardTargetOptions(.{}); 8 | const optimize = b.standardOptimizeOption(.{}); 9 | 10 | const linkage = b.option(std.builtin.LinkMode, "linkage", "Link mode") orelse .static; 11 | const strip = b.option(bool, "strip", "Omit debug information"); 12 | const pic = b.option(bool, "pie", "Produce Position Independent Code"); 13 | 14 | const dtd_validation = b.option(bool, "dtd-validation", "Validate the protocol DTD") orelse true; 15 | const icon_directory = b.option([]const u8, "icon-directory", "Location used to look for cursors (defaults to ${datadir}/icons if unset)"); 16 | 17 | const need_epoll_shim = switch (target.result.os.tag) { 18 | .freebsd, .openbsd => true, 19 | else => false, 20 | }; 21 | 22 | const link_system_expat = b.systemIntegrationOption("expat", .{}); 23 | const link_system_ffi = b.systemIntegrationOption("ffi", .{}); 24 | 25 | const cc_flags = getCCFlags(b, target); 26 | const host_cc_flags = getCCFlags(b, b.graph.host); 27 | 28 | const wayland_version_header = b.addConfigHeader(.{ 29 | .style = .{ .cmake = upstream.path("src/wayland-version.h.in") }, 30 | }, .{ 31 | .WAYLAND_VERSION_MAJOR = @as(i64, @intCast(version.major)), 32 | .WAYLAND_VERSION_MINOR = @as(i64, @intCast(version.minor)), 33 | .WAYLAND_VERSION_MICRO = @as(i64, @intCast(version.patch)), 34 | .WAYLAND_VERSION = b.fmt("{}", .{version}), 35 | }); 36 | 37 | const wayland_util = createWaylandUtil(b, target, optimize, upstream, cc_flags); 38 | const wayland_util_host = createWaylandUtil(b, b.graph.host, optimize, upstream, cc_flags); 39 | 40 | const wayland_scanner_args: CreateWaylandScannerArgs = .{ 41 | .dtd_validation = dtd_validation, 42 | .wayland = upstream, 43 | .wayland_version_header = wayland_version_header, 44 | }; 45 | 46 | const wayland_scanner = createWaylandScanner(b, target, optimize, wayland_scanner_args, cc_flags); 47 | wayland_scanner.root_module.linkLibrary(wayland_util); 48 | b.installArtifact(wayland_scanner); 49 | 50 | const wayland_scanner_host = createWaylandScanner(b, b.graph.host, optimize, wayland_scanner_args, host_cc_flags); 51 | wayland_scanner_host.root_module.linkLibrary(wayland_util_host); 52 | 53 | if (link_system_expat) { 54 | wayland_scanner.root_module.linkSystemLibrary("expat", .{}); // This is going to fail when cross-compiling 55 | wayland_scanner_host.root_module.linkSystemLibrary("expat", .{}); 56 | } else { 57 | if (b.lazyDependency("libexpat", .{ 58 | .target = target, 59 | .optimize = optimize, 60 | })) |expat| { 61 | wayland_scanner.root_module.linkLibrary(expat.artifact("expat")); 62 | } 63 | if (b.lazyDependency("libexpat", .{ 64 | .target = b.graph.host, 65 | .optimize = optimize, 66 | })) |expat_host| { 67 | wayland_scanner_host.root_module.linkLibrary(expat_host.artifact("expat")); 68 | } 69 | } 70 | 71 | const wayland_header = b.addConfigHeader(.{}, .{ 72 | .PACKAGE = "wayland", 73 | .PACKAGE_VERSION = b.fmt("{}", .{version}), 74 | .HAVE_SYS_PRCTL_H = target.result.os.tag == .linux, 75 | .HAVE_SYS_PROCCTL_H = target.result.os.isAtLeast(.freebsd, .{ .major = 10, .minor = 0, .patch = 0 }), 76 | .HAVE_SYS_UCRED_H = target.result.os.tag.isBSD(), 77 | .HAVE_ACCEPT4 = true, 78 | // libffi also has `HAVE_MKOSTEMP` but doesn't check the glibc version 79 | .HAVE_MKOSTEMP = if (target.result.isMuslLibC()) 80 | true 81 | else if (target.result.isGnuLibC()) 82 | target.result.os.version_range.linux.glibc.order(.{ .major = 2, .minor = 7, .patch = 0 }) != .lt 83 | else 84 | unreachable, 85 | .HAVE_POSIX_FALLOCATE = true, 86 | .HAVE_PRCTL = target.result.os.tag == .linux, 87 | .HAVE_MEMFD_CREATE = switch (target.result.os.tag) { 88 | .linux => if (target.result.isMuslLibC()) 89 | true 90 | else if (target.result.isGnuLibC()) 91 | target.result.os.version_range.linux.glibc.order(.{ .major = 2, .minor = 27, .patch = 0 }) != .lt 92 | else 93 | unreachable, 94 | .freebsd => target.result.os.isAtLeast(.freebsd, .{ .major = 13, .minor = 0, .patch = 0 }) orelse false, 95 | else => false, 96 | }, 97 | .HAVE_MREMAP = target.result.os.tag == .linux or target.result.os.tag == .freebsd, 98 | .HAVE_STRNDUP = true, 99 | .HAVE_BROKEN_MSG_CMSG_CLOEXEC = false, // // TODO __FreeBSD_version < 1300502 || (__FreeBSD_version >= 1400000 && __FreeBSD_version < 1400006) 100 | .HAVE_XUCRED_CR_PID = false, // TODO 101 | }); 102 | 103 | for (wayland_header.values.values()) |*entry| { 104 | if (entry.* == .boolean and !entry.boolean) entry.* = .undef; 105 | } 106 | 107 | const wayland_private = blk: { 108 | const write_files = b.addWriteFiles(); 109 | _ = write_files.addCopyFile(wayland_header.getOutput(), "config.h"); 110 | const wayland_header2 = write_files.addCopyFile(wayland_header.getOutput(), "config/config.h"); 111 | 112 | const wayland_private = b.addLibrary(.{ 113 | .linkage = .static, 114 | .name = "wayland-private", 115 | .root_module = b.createModule(.{ 116 | .target = target, 117 | .optimize = optimize, 118 | .link_libc = true, 119 | }), 120 | }); 121 | wayland_private.root_module.addIncludePath(wayland_header2.dirname()); 122 | wayland_private.root_module.addIncludePath(upstream.path("")); 123 | wayland_private.root_module.addCSourceFiles(.{ 124 | .files = &.{ 125 | "connection.c", 126 | "wayland-os.c", 127 | }, 128 | .root = upstream.path("src"), 129 | .flags = cc_flags, 130 | }); 131 | if (need_epoll_shim) wayland_private.root_module.linkSystemLibrary("epoll-shim", .{}); 132 | wayland_private.root_module.linkSystemLibrary("rt", .{}); 133 | if (link_system_ffi) { 134 | wayland_private.root_module.linkSystemLibrary("ffi", .{}); 135 | } else if (b.lazyDependency("libffi", .{ 136 | .target = target, 137 | .optimize = optimize, 138 | })) |libffi| { 139 | wayland_private.root_module.linkLibrary(libffi.artifact("ffi")); 140 | } 141 | 142 | break :blk wayland_private; 143 | }; 144 | 145 | var wayland_server_protocol_h: std.Build.LazyPath = undefined; 146 | var wayland_server_protocol_core_h: std.Build.LazyPath = undefined; 147 | var wayland_client_protocol_h: std.Build.LazyPath = undefined; 148 | var wayland_client_protocol_core_h: std.Build.LazyPath = undefined; 149 | 150 | { 151 | for ( 152 | [_][]const []const u8{ 153 | &.{"server-header"}, 154 | &.{ "server-header", "-c" }, 155 | &.{"client-header"}, 156 | &.{ "client-header", "-c" }, 157 | }, 158 | [_][]const u8{ 159 | "wayland-server-protocol.h", 160 | "wayland-server-protocol-core.h", 161 | "wayland-client-protocol.h", 162 | "wayland-client-protocol-core.h", 163 | }, 164 | [_]*std.Build.LazyPath{ 165 | &wayland_server_protocol_h, 166 | &wayland_server_protocol_core_h, 167 | &wayland_client_protocol_h, 168 | &wayland_client_protocol_core_h, 169 | }, 170 | ) |scanner_args, basename, output_file| { 171 | const run = b.addRunArtifact(wayland_scanner_host); 172 | run.addArg("-s"); 173 | run.addArgs(scanner_args); 174 | run.addFileArg(upstream.path("protocol/wayland.xml")); 175 | output_file.* = run.addOutputFileArg(basename); 176 | } 177 | } 178 | 179 | const wayland_protocol_c = blk: { 180 | const run = b.addRunArtifact(wayland_scanner_host); 181 | run.addArgs(&.{ "-s", "public-code" }); 182 | run.addFileArg(upstream.path("protocol/wayland.xml")); 183 | break :blk run.addOutputFileArg("wayland-protocol.c"); 184 | }; 185 | 186 | { 187 | const wayland_server = b.addLibrary(.{ 188 | .linkage = linkage, 189 | .name = "wayland-server", 190 | // To avoid an unnecessary SONAME bump, wayland 1.x.y produces 191 | // libwayland-server.so.0.x.y. 192 | .version = .{ .major = 0, .minor = version.minor, .patch = version.patch }, 193 | .root_module = b.createModule(.{ 194 | .target = target, 195 | .optimize = optimize, 196 | .link_libc = true, 197 | .strip = strip, 198 | .pic = pic, 199 | }), 200 | }); 201 | b.installArtifact(wayland_server); 202 | wayland_server.root_module.linkLibrary(wayland_private); 203 | wayland_server.root_module.linkLibrary(wayland_util); 204 | wayland_server.root_module.addConfigHeader(wayland_version_header); 205 | wayland_server.root_module.addConfigHeader(wayland_header); 206 | wayland_server.root_module.addIncludePath(upstream.path("src")); 207 | wayland_server.root_module.addIncludePath(wayland_server_protocol_core_h.dirname()); 208 | wayland_server.root_module.addIncludePath(wayland_server_protocol_h.dirname()); 209 | wayland_server.installHeader(wayland_server_protocol_core_h, "wayland-server-protocol-core.h"); 210 | wayland_server.installHeader(wayland_server_protocol_h, "wayland-server-protocol.h"); 211 | wayland_server.installHeader(upstream.path("src/wayland-server.h"), "wayland-server.h"); 212 | wayland_server.installHeader(upstream.path("src/wayland-server-core.h"), "wayland-server-core.h"); 213 | wayland_server.installLibraryHeaders(wayland_util); // required by wayland-server-core.h 214 | wayland_server.installConfigHeader(wayland_version_header); // required by wayland-server-core.h 215 | wayland_server.root_module.addCSourceFile(.{ 216 | .file = wayland_protocol_c, 217 | .flags = cc_flags, 218 | }); 219 | wayland_server.root_module.addCSourceFiles(.{ 220 | .files = &.{ 221 | "wayland-shm.c", 222 | "event-loop.c", 223 | }, 224 | .root = upstream.path("src"), 225 | .flags = cc_flags, 226 | }); 227 | if (need_epoll_shim) wayland_server.root_module.linkSystemLibrary("epoll-shim", .{}); 228 | wayland_server.root_module.linkSystemLibrary("rt", .{}); 229 | if (link_system_ffi) { 230 | wayland_server.root_module.linkSystemLibrary("ffi", .{}); 231 | } else if (b.lazyDependency("libffi", .{ 232 | .target = target, 233 | .optimize = optimize, 234 | })) |libffi| { 235 | wayland_server.root_module.linkLibrary(libffi.artifact("ffi")); 236 | } 237 | } 238 | 239 | const wayland_client = blk: { 240 | const wayland_client = b.addLibrary(.{ 241 | .linkage = linkage, 242 | .name = "wayland-client", 243 | // To avoid an unnecessary SONAME bump, wayland 1.x.y produces 244 | // libwayland-client.so.0.x.y. 245 | .version = .{ .major = 0, .minor = version.minor, .patch = version.patch }, 246 | .root_module = b.createModule(.{ 247 | .target = target, 248 | .optimize = optimize, 249 | .link_libc = true, 250 | .strip = strip, 251 | .pic = pic, 252 | }), 253 | }); 254 | b.installArtifact(wayland_client); 255 | wayland_client.root_module.linkLibrary(wayland_private); 256 | wayland_client.root_module.linkLibrary(wayland_util); 257 | wayland_client.root_module.addConfigHeader(wayland_version_header); 258 | wayland_client.root_module.addConfigHeader(wayland_header); 259 | wayland_client.root_module.addIncludePath(upstream.path("src")); 260 | wayland_client.root_module.addIncludePath(wayland_client_protocol_core_h.dirname()); 261 | wayland_client.root_module.addIncludePath(wayland_client_protocol_h.dirname()); 262 | wayland_client.installHeader(wayland_client_protocol_core_h, "wayland-client-protocol-core.h"); 263 | wayland_client.installHeader(wayland_client_protocol_h, "wayland-client-protocol.h"); 264 | wayland_client.installHeader(upstream.path("src/wayland-client.h"), "wayland-client.h"); 265 | wayland_client.installHeader(upstream.path("src/wayland-client-core.h"), "wayland-client-core.h"); 266 | wayland_client.installLibraryHeaders(wayland_util); // required by wayland-client-core.h 267 | wayland_client.installConfigHeader(wayland_version_header); // required by wayland-client-core.h 268 | wayland_client.root_module.addCSourceFile(.{ 269 | .file = wayland_protocol_c, 270 | .flags = cc_flags, 271 | }); 272 | wayland_client.root_module.addCSourceFile(.{ 273 | .file = upstream.path("src/wayland-client.c"), 274 | .flags = cc_flags, 275 | }); 276 | 277 | if (need_epoll_shim) wayland_client.root_module.linkSystemLibrary("epoll-shim", .{}); 278 | wayland_client.root_module.linkSystemLibrary("rt", .{}); 279 | if (link_system_ffi) { 280 | wayland_client.root_module.linkSystemLibrary("ffi", .{}); 281 | } else if (b.lazyDependency("libffi", .{ 282 | .target = target, 283 | .optimize = optimize, 284 | })) |libffi| { 285 | wayland_client.root_module.linkLibrary(libffi.artifact("ffi")); 286 | } 287 | 288 | break :blk wayland_client; 289 | }; 290 | 291 | { 292 | const wayland_egl = b.addLibrary(.{ 293 | .linkage = linkage, 294 | .name = "wayland-egl", 295 | .version = version, 296 | .root_module = b.createModule(.{ 297 | .target = target, 298 | .optimize = optimize, 299 | .link_libc = true, 300 | .strip = strip, 301 | .pic = pic, 302 | }), 303 | }); 304 | b.installArtifact(wayland_egl); 305 | wayland_egl.root_module.linkLibrary(wayland_client); 306 | wayland_egl.root_module.addConfigHeader(wayland_version_header); 307 | wayland_egl.root_module.addConfigHeader(wayland_header); 308 | wayland_egl.root_module.addIncludePath(wayland_client_protocol_core_h.dirname()); 309 | wayland_egl.root_module.addIncludePath(wayland_client_protocol_h.dirname()); 310 | wayland_egl.installHeader(upstream.path("egl/wayland-egl.h"), "wayland-egl.h"); 311 | wayland_egl.installHeader(upstream.path("egl/wayland-egl-core.h"), "wayland-egl-core.h"); 312 | wayland_egl.installHeader(upstream.path("egl/wayland-egl-backend.h"), "wayland-egl-backend.h"); 313 | wayland_egl.root_module.addCSourceFile(.{ 314 | .file = upstream.path("egl/wayland-egl.c"), 315 | .flags = cc_flags, 316 | }); 317 | } 318 | 319 | { 320 | const wayland_cursor = b.addLibrary(.{ 321 | .linkage = linkage, 322 | .name = "wayland-cursor", 323 | // To avoid an unnecessary SONAME bump, wayland 1.x.y produces 324 | // libwayland-cursor.so.0.x.y. 325 | .version = .{ .major = 0, .minor = version.minor, .patch = version.patch }, 326 | .root_module = b.createModule(.{ 327 | .target = target, 328 | .optimize = optimize, 329 | .link_libc = true, 330 | .strip = strip, 331 | .pic = pic, 332 | }), 333 | }); 334 | b.installArtifact(wayland_cursor); 335 | wayland_cursor.root_module.linkLibrary(wayland_client); 336 | wayland_cursor.root_module.addConfigHeader(wayland_version_header); 337 | wayland_cursor.root_module.addConfigHeader(wayland_header); 338 | wayland_cursor.root_module.addIncludePath(wayland_client_protocol_core_h.dirname()); 339 | wayland_cursor.root_module.addIncludePath(wayland_client_protocol_h.dirname()); 340 | wayland_cursor.installHeader(upstream.path("cursor/wayland-cursor.h"), "wayland-cursor.h"); 341 | if (icon_directory) |dir| wayland_cursor.root_module.addCMacro("ICONDIR", dir); 342 | wayland_cursor.root_module.addCSourceFiles(.{ 343 | .files = &.{ 344 | "wayland-cursor.c", 345 | "os-compatibility.c", 346 | "xcursor.c", 347 | }, 348 | .root = upstream.path("cursor"), 349 | .flags = cc_flags, 350 | }); 351 | } 352 | 353 | b.addNamedLazyPath("wayland-xml", upstream.path("protocol/wayland.xml")); 354 | b.addNamedLazyPath("wayland.dtd", upstream.path("protocol/wayland.dtd")); 355 | } 356 | 357 | fn createWaylandUtil( 358 | b: *std.Build, 359 | target: std.Build.ResolvedTarget, 360 | optimize: std.builtin.OptimizeMode, 361 | wayland: *std.Build.Dependency, 362 | cc_flags: []const []const u8, 363 | ) *std.Build.Step.Compile { 364 | const wayland_util = b.addLibrary(.{ 365 | .linkage = .static, 366 | .name = "wayland-util", 367 | .root_module = b.createModule(.{ 368 | .target = target, 369 | .optimize = optimize, 370 | .link_libc = true, 371 | }), 372 | }); 373 | wayland_util.installHeader(wayland.path("src/wayland-util.h"), "wayland-util.h"); 374 | wayland_util.root_module.addCSourceFile(.{ 375 | .file = wayland.path("src/wayland-util.c"), 376 | .flags = cc_flags, 377 | }); 378 | return wayland_util; 379 | } 380 | 381 | const CreateWaylandScannerArgs = struct { 382 | dtd_validation: bool, 383 | wayland: *std.Build.Dependency, 384 | wayland_version_header: *std.Build.Step.ConfigHeader, 385 | }; 386 | 387 | fn createWaylandScanner( 388 | b: *std.Build, 389 | target: std.Build.ResolvedTarget, 390 | optimize: std.builtin.OptimizeMode, 391 | args: CreateWaylandScannerArgs, 392 | cc_flags: []const []const u8, 393 | ) *std.Build.Step.Compile { 394 | const wayland_scanner = b.addExecutable(.{ 395 | .name = "wayland-scanner", 396 | .root_module = b.createModule(.{ 397 | .target = target, 398 | .optimize = optimize, 399 | .link_libc = true, 400 | }), 401 | }); 402 | wayland_scanner.root_module.addConfigHeader(args.wayland_version_header); 403 | wayland_scanner.root_module.addCSourceFile(.{ 404 | .file = args.wayland.path("src/scanner.c"), 405 | .flags = cc_flags, 406 | }); 407 | wayland_scanner.root_module.addIncludePath(args.wayland.path("")); 408 | wayland_scanner.root_module.addIncludePath(args.wayland.path("protocol")); 409 | 410 | if (args.dtd_validation) { 411 | const embed_exe = b.addExecutable(.{ 412 | .name = "embed", 413 | .root_module = b.createModule(.{ 414 | .root_source_file = b.path("embed.zig"), 415 | .target = b.graph.host, 416 | .optimize = optimize, 417 | }), 418 | }); 419 | const run_embed = b.addRunArtifact(embed_exe); 420 | run_embed.addFileArg(args.wayland.path("protocol/wayland.dtd")); 421 | run_embed.addArg("wayland_dtd"); 422 | 423 | const write_files = b.addWriteFiles(); 424 | const wayland_dtd = write_files.addCopyFile(run_embed.captureStdOut(), "wayland.dtd.h"); 425 | wayland_scanner.root_module.addIncludePath(wayland_dtd.dirname()); 426 | 427 | const link_system_libxml = b.systemIntegrationOption("libxml2", .{}); 428 | if (link_system_libxml) { 429 | wayland_scanner.root_module.linkSystemLibrary("libxml-2.0", .{}); 430 | } else if (b.lazyDependency("libxml2", .{ 431 | .target = target, 432 | .optimize = optimize, 433 | .minimum = true, 434 | .valid = true, 435 | })) |libxml2| { 436 | wayland_scanner.root_module.linkLibrary(libxml2.artifact("xml")); 437 | } 438 | 439 | wayland_scanner.root_module.addCMacro("HAVE_LIBXML", "1"); 440 | } 441 | 442 | return wayland_scanner; 443 | } 444 | 445 | fn getCCFlags(b: *std.Build, target: std.Build.ResolvedTarget) []const []const u8 { 446 | var cc_flags_list: std.ArrayListUnmanaged([]const u8) = .{}; 447 | cc_flags_list.appendSlice(b.allocator, &.{ 448 | "-std=c99", 449 | "-Wno-unused-parameter", 450 | "-Wstrict-prototypes", 451 | "-Wmissing-prototypes", 452 | "-fvisibility=hidden", 453 | }) catch @panic("OOM"); 454 | switch (target.result.os.tag) { 455 | .freebsd, .openbsd => {}, 456 | else => cc_flags_list.append(b.allocator, "-D_POSIX_C_SOURCE=200809L") catch @panic("OOM"), 457 | } 458 | return cc_flags_list.items; 459 | } 460 | 461 | comptime { 462 | if (version.major != 1) { 463 | // The versioning used for the shared libraries assumes that the major 464 | // version of Wayland as a whole will increase to 2 if and only if there 465 | // is an ABI break, at which point we should probably bump the SONAME of 466 | // all libraries to .so.2. For more details see 467 | // https://gitlab.freedesktop.org/wayland/wayland/-/merge_requests/177 468 | @compileError( 469 | \\We probably need to bump the SONAME of libwayland-server and -client 470 | \\We probably need to bump the SONAME of libwayland-cursor 471 | ); 472 | } 473 | } 474 | -------------------------------------------------------------------------------- /build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = .wayland, 3 | .version = "1.23.1-3", 4 | .minimum_zig_version = "0.14.0", 5 | .dependencies = .{ 6 | .wayland = .{ 7 | .url = "git+https://gitlab.freedesktop.org/wayland/wayland.git?ref=1.23.1#a9fec8dd65977c57f4039ced34327204d9b9d779", 8 | .hash = "N-V-__8AAJC3GAC2LeGXShVNoV0oWVW9T293JVzmx0kY5KVa", 9 | }, 10 | .libffi = .{ 11 | .url = "git+https://github.com/vezel-dev/libffi.git?ref=v3.4.8-2#0f6f1d1b201771e7784440b2ca1faf215c6db6d1", 12 | .hash = "libffi-3.4.8-7_tEtDcoFwCpZb5rosPGiu-AOJbA2KwTrM4fNxZJlNxg", 13 | .lazy = true, 14 | }, 15 | .libexpat = .{ 16 | .url = "git+https://github.com/allyourcodebase/libexpat.git?ref=2.7.1#917dcfdf644814a73b6a25eac6b2d434f9f1f99f", 17 | .hash = "libexpat-2.7.1-y_akI1M7AAA1huPJVegH4dosRVA-lMRgzMuX9vC7aB1s", 18 | .lazy = true, 19 | }, 20 | .libxml2 = .{ 21 | .url = "git+https://github.com/allyourcodebase/libxml2.git?ref=2.14.3#2fe1a209680cffa7f2c8b2f36228c519da26d0f8", 22 | .hash = "libxml2-2.14.3-qHdjhm8-AADj87LUvzLuq5RnsoKBZCsh1dMCP3yCI2hc", 23 | .lazy = true, 24 | }, 25 | }, 26 | .paths = .{ 27 | "build.zig", 28 | "build.zig.zon", 29 | "embed.zig", 30 | "LICENSE", 31 | "README.md", 32 | }, 33 | .fingerprint = 0xa8d655e6b011177, // Changing this has security and trust implications. 34 | } 35 | -------------------------------------------------------------------------------- /embed.zig: -------------------------------------------------------------------------------- 1 | //! This is embed.py ported to Zig: 2 | //! https://gitlab.freedesktop.org/wayland/wayland/-/blob/main/src/embed.py 3 | //! 4 | //! Simple C data embedder 5 | //! 6 | //! License: MIT 7 | //! 8 | //! Copyright (c) 2020 Simon Ser 9 | //! 10 | //! Permission is hereby granted, free of charge, to any person obtaining a copy 11 | //! of this software and associated documentation files (the "Software"), to deal 12 | //! in the Software without restriction, including without limitation the rights 13 | //! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | //! copies of the Software, and to permit persons to whom the Software is 15 | //! furnished to do so, subject to the following conditions: 16 | //! 17 | //! The above copyright notice and this permission notice shall be included in all 18 | //! copies or substantial portions of the Software. 19 | //! 20 | //! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | //! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | //! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | //! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | //! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | //! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | //! SOFTWARE. 27 | 28 | const std = @import("std"); 29 | 30 | pub fn main() !void { 31 | var general_purpose_allocator: std.heap.GeneralPurposeAllocator(.{}) = .{}; 32 | defer _ = general_purpose_allocator.deinit(); 33 | const gpa = general_purpose_allocator.allocator(); 34 | 35 | const args = try std.process.argsAlloc(gpa); 36 | defer std.process.argsFree(gpa, args); 37 | 38 | const stdout = std.io.getStdOut().writer(); 39 | const stderr = std.io.getStdErr().writer(); 40 | 41 | if (args.len != 3) { 42 | try stderr.print("usage: {s} \n", .{args[0]}); 43 | std.process.exit(1); 44 | } 45 | const filename = args[1]; 46 | const ident = args[2]; 47 | 48 | const buf = try std.fs.cwd().readFileAlloc(gpa, filename, std.math.maxInt(u32)); 49 | defer gpa.free(buf); 50 | 51 | try stdout.print("static const char {s}[] = {{\n\t", .{ident}); 52 | for (buf) |c| { 53 | try stdout.print("0x{x:0>2}, ", .{c}); 54 | } 55 | try stdout.print("\n}};\n", .{}); 56 | } 57 | --------------------------------------------------------------------------------