screensaver/build.zig

192 lines
5.9 KiB
Zig

// Majora's Screensaver (expects zig v0.15.x)
// @author: Abner Coimbre <abner@terminal.click>
// @description: Sample C app for Windows, Mac & Linux. Adapted from floooh's sokol examples.
// The goal is to demonstrate how to write a cross-platform native app/game in vanilla C, using only Zig to compile.
// Single-Header Libraries:
// - Sokol (https://github.com/floooh/sokol): Windowing, input, and/or graphics
// - STB (https://github.com/nothings/stb): Loading images/assets
// Instructions
// ---
// 1. Ensure Zig is on your PATH: download from https://ziglang.org/download
// 2. Navigate to this project's folder
// 3. Run the `zig build` command
// 4. For a macOS App Bundle try `zig build bundle` instead
// ---
// You may now run the executable under zig-out/
// The command `zig build` executes build() below. Learn more at https://zig.guide/
const std = @import("std");
pub fn build(b: *std.Build) void {
// Initial exe
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "screensaver",
.root_module = b.createModule(.{
.optimize = optimize,
.target = target,
}),
});
// Compiler flags: update as needed
const win_flags = &[_][]const u8{
"-DSOKOL_D3D11",
"-O0",
"-ggdb3",
"-std=c99",
"-Werror", // Without this we can't emit warnings. This is a Zig bug: https://github.com/ziglang/zig/issues/15912
};
const macos_flags = &[_][]const u8{
"-ObjC",
"-DSOKOL_METAL",
"-O0",
"-ggdb3",
"-std=c99",
"-Werror",
};
const linux_flags = &[_][]const u8{
"-DSOKOL_GLCORE33",
"-O0",
"-ggdb3",
"-std=c99",
"-Werror",
};
// Add include folder(s)
exe.addIncludePath(b.path("inc"));
exe.addIncludePath(b.path("data/shaders"));
// Which OS are we in?
const tag = target.result.os.tag;
// Select appropriate compiler flags
const target_flags = switch (tag) {
.windows => win_flags,
.macos => macos_flags,
.linux => linux_flags,
else => {
std.debug.print("Error: Unsupported OS! Contact abner@terminal.click\n", .{});
std.process.exit(1);
},
};
// Add our source code
exe.addCSourceFile(.{ .file = b.path("main.c"), .flags = target_flags });
// Link against C's standard library
exe.linkLibC();
// Link against appropriate system libraries
switch (tag) {
.windows => {
exe.linkSystemLibrary("kernel32");
exe.linkSystemLibrary("gdi32");
exe.linkSystemLibrary("d3d11");
},
.macos => {
exe.linkFramework("MetalKit");
exe.linkFramework("Metal");
exe.linkFramework("Cocoa");
exe.linkFramework("QuartzCore");
},
.linux => {
exe.linkSystemLibrary("GL");
exe.linkSystemLibrary("X11");
exe.linkSystemLibrary("Xi");
exe.linkSystemLibrary("Xcursor");
},
else => unreachable,
}
b.installArtifact(exe);
//
// macOS App Bundle - prepares one if user called `zig build bundle`
//
// ---
if (tag == .macos) {
const app_name = "Screensaver";
const bundle_path = b.fmt("zig-out/{s}.app/Contents", .{app_name});
const mkdir = b.addSystemCommand(&.{
"mkdir", "-p",
b.fmt("{s}/MacOS", .{bundle_path}),
});
const mkdir_res = b.addSystemCommand(&.{
"mkdir", "-p",
b.fmt("{s}/Resources", .{bundle_path}),
});
const copy_exe = b.addSystemCommand(&.{
"cp",
b.getInstallPath(.bin, "screensaver"),
b.fmt("{s}/MacOS/screensaver", .{bundle_path}),
});
copy_exe.step.dependOn(&mkdir.step);
copy_exe.step.dependOn(b.getInstallStep());
const plist_content =
\\<?xml version="1.0" encoding="UTF-8"?>
\\<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
\\<plist version="1.0">
\\<dict>
\\ <key>CFBundleExecutable</key>
\\ <string>screensaver</string>
\\ <key>CFBundleIdentifier</key>
\\ <string>click.terminal.screensaver</string>
\\ <key>CFBundleName</key>
\\ <string>Screensaver</string>
\\ <key>CFBundlePackageType</key>
\\ <string>APPL</string>
\\ <key>CFBundleVersion</key>
\\ <string>1.0</string>
\\</dict>
\\</plist>
;
const write_files = b.addWriteFiles();
const plist_file = write_files.add("Info.plist", plist_content);
const copy_plist = b.addInstallFile(plist_file, b.fmt("{s}.app/Contents/Info.plist", .{app_name}));
const copy_data = b.addSystemCommand(&.{
"cp", "-R",
"data",
b.fmt("{s}/Resources/", .{bundle_path}),
});
copy_data.step.dependOn(&mkdir_res.step);
const bundle_step = b.step("bundle", "Create macOS app bundle");
bundle_step.dependOn(&copy_exe.step);
bundle_step.dependOn(&copy_plist.step);
bundle_step.dependOn(&mkdir_res.step);
bundle_step.dependOn(&copy_data.step);
bundle_step.dependOn(&copy_plist.step);
}
// ---
//
// We're done! Complete Zig's build graph
//
//---
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
//---
}