| 1 | #!/usr/bin/env python3 |
| 2 | import argparse |
| 3 | import json |
| 4 | from pathlib import Path |
| 5 | import re |
| 6 | import subprocess |
| 7 | |
| 8 | |
| 9 | parser = argparse.ArgumentParser() |
| 10 | parser.add_argument("--arch", choices=["x86", "x86_64", "aarch64"], default="x86_64") |
| 11 | parser.add_argument("--output", type=Path, default=Path(__file__).parent / "build") |
| 12 | args = parser.parse_args() |
| 13 | source = Path(__file__).resolve().parent |
| 14 | args.output.mkdir(parents=True, exist_ok=True) |
| 15 | schema = json.loads((source / "protocol.json").read_text()) |
| 16 | header = ["#ifndef SG_PROTOCOL_H", "#define SG_PROTOCOL_H"] |
| 17 | header += [f"#define SG_MAX_{key.upper()} {value}u" for key, value in schema["limits"].items()] |
| 18 | header += [f"#define SG_XOR_{key.upper()} {value}u" for key, value in schema["xor_bits"].items()] |
| 19 | for 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"])] |
| 22 | header += [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") |
| 24 | subsystem = "10.0" if args.arch == "aarch64" else "6.1" |
| 25 | environment = subprocess.check_output(["zig", "env"], text=True) |
| 26 | match = re.search(r'\.lib_dir\s*=\s*"([^"]+)"', environment) |
| 27 | library = Path(match[1] if match else json.loads(environment)["lib_dir"]) |
| 28 | subprocess.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) |