192 lines
5.9 KiB
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_GLCORE",
|
|
"-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(©_exe.step);
|
|
bundle_step.dependOn(©_plist.step);
|
|
bundle_step.dependOn(&mkdir_res.step);
|
|
bundle_step.dependOn(©_data.step);
|
|
bundle_step.dependOn(©_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);
|
|
//---
|
|
}
|