"""Build the Solmate v1 SBF program with Anza platform-tools v1.58.""" import argparse import hashlib import subprocess import sys import urllib.request from pathlib import Path ROOT = Path(__file__).resolve().parent C_SDK = "d9f20e951a06b61e4505da0955228020b96a8915" # solana-labs/solana v1.18.26 REQUIRED = ["c/sbf.ld", *("c/inc/sol/" + name + ".h" for name in ("entrypoint", "constants", "types", "pubkey", "deserialize", "cpi"))] def main(): parser = argparse.ArgumentParser(__doc__) parser.add_argument("--llvm", type=Path, required=True, help="Anza platform-tools llvm/bin directory") parser.add_argument("--sdk", type=Path, default=ROOT / ".build/sbf", help="Solana SDK directory containing c/inc/sol and c/sbf.ld") args = parser.parse_args() for rel in REQUIRED: dest = args.sdk / rel if not dest.exists(): dest.parent.mkdir(parents=True, exist_ok=True) url = f"https://raw.githubusercontent.com/solana-labs/solana/{C_SDK}/sdk/sbf/{rel}" with urllib.request.urlopen(url, timeout=30) as response: dest.write_bytes(response.read()) cache = ROOT / ".build" includes = cache / "headers" includes.mkdir(parents=True, exist_ok=True) (includes / "stdbool.h").write_text("/* C23 provides bool, true and false. */\n", encoding="ascii") out = ROOT / "build/solmate_registry.so" out.parent.mkdir(exist_ok=True) obj = cache / "registry.o" ext = ".exe" if sys.platform == "win32" else "" subprocess.run([args.llvm / ("clang" + ext), "--target=sbf", "-mcpu=generic", "-std=c23", "-O2", "-fPIC", "-fno-builtin", "-fno-stack-protector", "-Werror", "-I", args.sdk / "c/inc", "-I", includes, "-c", ROOT / "registry.c", "-o", obj], check=True) subprocess.run([args.llvm / ("ld.lld" + ext), "-z", "notext", "-shared", "--Bdynamic", "-T", args.sdk / "c/sbf.ld", "--entry", "entrypoint", "--strip-all", "-o", out, obj], check=True) print(out.name, len(out.read_bytes()), "bytes / SHA-256", hashlib.sha256(out.read_bytes()).hexdigest()) if __name__ == "__main__": main()