1#!/usr/bin/env python3
2import argparse
3import json
4from pathlib import Path
5import re
6import subprocess
7
8
9parser = argparse.ArgumentParser()
10parser.add_argument("--arch", choices=["x86", "x86_64", "aarch64"], default="x86_64")
11parser.add_argument("--output", type=Path, default=Path(__file__).parent / "build")
12args = parser.parse_args()
13source = Path(__file__).resolve().parent
14args.output.mkdir(parents=True, exist_ok=True)
15schema = json.loads((source / "protocol.json").read_text())
16header = ["#ifndef SG_PROTOCOL_H", "#define SG_PROTOCOL_H"]
17header += [f"#define SG_MAX_{key.upper()} {value}u" for key, value in schema["limits"].items()]
18header += [f"#define SG_XOR_{key.upper()} {value}u" for key, value in schema["xor_bits"].items()]
19for name, packet in schema["packets"].items():
20 header += [f"#define SG_{name.upper()} {packet['id']}u", f"#define SG_{name.upper()}_WORDS {len(packet['fields'])}u"]
21 header += [f"#define SG_{name.upper()}_{field.upper()} {index}u" for index, field in enumerate(packet["fields"])]
22header += [f'#define SG_MAGIC "{schema["magic"]}"', f'#define SG_CHANNEL L"{schema["channel"]}"', "#endif"]
23(args.output / "protocol.h").write_text("\n".join(header) + "\n")
24subsystem = "10.0" if args.arch == "aarch64" else "6.1"
25environment = subprocess.check_output(["zig", "env"], text=True)
26match = re.search(r'\.lib_dir\s*=\s*"([^"]+)"', environment)
27library = Path(match[1] if match else json.loads(environment)["lib_dir"])
28subprocess.run([
29 "zig", "cc", "-target", args.arch + ("-windows.win10-gnu" if args.arch == "aarch64" else "-windows.win7-gnu"), "-std=c99", "-Os", "-Wall", "-Wextra", "-Werror",
30 "-ffreestanding", "-fno-stack-protector", "-nostdlib", "-D_WIN32_WINNT=0x0601", "-DWINVER=0x0601",
31 "-isystem", str(library / "libc/include/any-windows-any"),
32 "-I", str(args.output), str(source / "cursor.c"), str(source / "windows.c"),
33 "-lkernel32", "-luser32", "-lgdi32", "-Wl,--entry,mainCRTStartup", "-Wl,--subsystem,windows",
34 "-Wl,--major-subsystem-version," + subsystem.split(".")[0], "-Wl,--minor-subsystem-version," + subsystem.split(".")[1],
35 "-o", str(args.output / ("snowglobe-guest-" + args.arch + ".exe")),
36], check=True)