stevee

My wayland statusbar
git clone git://gtms.dev/stevee
Log | Files | Refs | README | LICENSE

build.zig (5647B)


      1 const std = @import("std");
      2 const Build = std.Build;
      3 const fs = std.fs;
      4 const mem = std.mem;
      5 
      6 pub fn build(b: *Build) void {
      7     const enable_tests = b.option(bool, "enable-tests", "allow running tests") orelse false;
      8 
      9     if (!enable_tests) return;
     10 
     11     const target = b.standardTargetOptions(.{});
     12     const optimize = b.standardOptimizeOption(.{});
     13 
     14     const scanner = Scanner.create(b, .{});
     15 
     16     const wayland = b.createModule(.{ .root_source_file = scanner.result });
     17 
     18     scanner.generate("wl_compositor", 1);
     19     scanner.generate("wl_shm", 1);
     20     scanner.generate("wl_seat", 2);
     21     scanner.generate("wl_output", 1);
     22 
     23     inline for ([_][]const u8{ "globals", "list", "listener", "seats" }) |example| {
     24         const exe = b.addExecutable(.{
     25             .name = example,
     26             .root_source_file = b.path("example/" ++ example ++ ".zig"),
     27             .target = target,
     28             .optimize = optimize,
     29         });
     30 
     31         exe.root_module.addImport("wayland", wayland);
     32         exe.linkLibC();
     33         exe.linkSystemLibrary("wayland-client");
     34 
     35         b.installArtifact(exe);
     36     }
     37 
     38     const test_step = b.step("test", "Run the tests");
     39     {
     40         const ref_all = b.addTest(.{
     41             .root_source_file = b.path("test/ref_all.zig"),
     42             .target = target,
     43             .optimize = optimize,
     44         });
     45 
     46         ref_all.root_module.addImport("wayland", wayland);
     47         ref_all.linkLibC();
     48         ref_all.linkSystemLibrary("wayland-client");
     49         ref_all.linkSystemLibrary("wayland-server");
     50         ref_all.linkSystemLibrary("wayland-egl");
     51         ref_all.linkSystemLibrary("wayland-cursor");
     52 
     53         const run_ref_all = b.addRunArtifact(ref_all);
     54         test_step.dependOn(&run_ref_all.step);
     55     }
     56     {
     57         const snapshot = b.addTest(.{
     58             .root_source_file = b.path("test/snapshot.zig"),
     59             .target = target,
     60             .optimize = optimize,
     61         });
     62 
     63         const options = b.addOptions();
     64         options.addOptionPath("snapshot_actual", scanner.result);
     65 
     66         snapshot.root_module.addOptions("build_options", options);
     67 
     68         const run_snapshot = b.addRunArtifact(snapshot);
     69         test_step.dependOn(&run_snapshot.step);
     70     }
     71 }
     72 
     73 const zig_wayland_build_zig = @This();
     74 
     75 pub const Scanner = struct {
     76     run: *Build.Step.Run,
     77     result: Build.LazyPath,
     78 
     79     wayland_protocols: Build.LazyPath,
     80 
     81     pub const Options = struct {
     82         /// Path to the wayland.xml file.
     83         /// If null, the output of `pkg-config --variable=pkgdatadir wayland-scanner` will be used.
     84         wayland_xml: ?Build.LazyPath = null,
     85         /// Path to the wayland-protocols installation.
     86         /// If null, the output of `pkg-config --variable=pkgdatadir wayland-protocols` will be used.
     87         wayland_protocols: ?Build.LazyPath = null,
     88     };
     89 
     90     pub fn create(b: *Build, options: Options) *Scanner {
     91         const wayland_xml: Build.LazyPath = options.wayland_xml orelse blk: {
     92             const pc_output = b.run(&.{ "pkg-config", "--variable=pkgdatadir", "wayland-scanner" });
     93             break :blk .{
     94                 .cwd_relative = b.pathJoin(&.{ mem.trim(u8, pc_output, &std.ascii.whitespace), "wayland.xml" }),
     95             };
     96         };
     97         const wayland_protocols: Build.LazyPath = options.wayland_protocols orelse blk: {
     98             const pc_output = b.run(&.{ "pkg-config", "--variable=pkgdatadir", "wayland-protocols" });
     99             break :blk .{
    100                 .cwd_relative = mem.trim(u8, pc_output, &std.ascii.whitespace),
    101             };
    102         };
    103 
    104         const exe = b.addExecutable(.{
    105             .name = "zig-wayland-scanner",
    106             .root_source_file = if (b.available_deps.len > 0)
    107                 b.dependencyFromBuildZig(zig_wayland_build_zig, .{}).path("src/scanner.zig")
    108             else
    109                 b.path("src/scanner.zig"),
    110             .target = b.graph.host,
    111         });
    112 
    113         const run = b.addRunArtifact(exe);
    114 
    115         run.addArg("-o");
    116         const result = run.addOutputFileArg("wayland.zig");
    117 
    118         run.addArg("-i");
    119         run.addFileArg(wayland_xml);
    120 
    121         const scanner = b.allocator.create(Scanner) catch @panic("OOM");
    122         scanner.* = .{
    123             .run = run,
    124             .result = result,
    125             .wayland_protocols = wayland_protocols,
    126         };
    127 
    128         return scanner;
    129     }
    130 
    131     /// Scan protocol xml provided by the wayland-protocols package at the given path
    132     /// relative to the wayland-protocols installation. (e.g. "stable/xdg-shell/xdg-shell.xml")
    133     pub fn addSystemProtocol(scanner: *Scanner, sub_path: []const u8) void {
    134         const b = scanner.run.step.owner;
    135 
    136         scanner.run.addArg("-i");
    137         scanner.run.addFileArg(scanner.wayland_protocols.path(b, sub_path));
    138     }
    139 
    140     /// Scan the protocol xml at the given path.
    141     pub fn addCustomProtocol(scanner: *Scanner, path: Build.LazyPath) void {
    142         scanner.run.addArg("-i");
    143         scanner.run.addFileArg(path);
    144     }
    145 
    146     /// Generate code for the given global interface at the given version,
    147     /// as well as all interfaces that can be created using it at that version.
    148     /// If the version found in the protocol xml is less than the requested version,
    149     /// an error will be printed and code generation will fail.
    150     /// Code is always generated for wl_display, wl_registry, wl_callback, and wl_buffer.
    151     pub fn generate(scanner: *Scanner, global_interface: []const u8, version: u32) void {
    152         var buffer: [32]u8 = undefined;
    153         const version_str = std.fmt.bufPrint(&buffer, "{}", .{version}) catch unreachable;
    154 
    155         scanner.run.addArgs(&.{ "-g", global_interface, version_str });
    156     }
    157 };