| 1 | #!/usr/bin/env python3 |
| 2 | """Builds snowbound-relay, the Live Share relay, and snowbound-site, which serves the web build and |
| 3 | the codes' pages (crates/relay), as static executables for each Linux architecture a server |
| 4 | runs, with the files that deploy them, into target/relay/ by default. |
| 5 | It ships on its own, outside the app's builds and latest.json; see crates/relay/README.md.""" |
| 6 | import argparse |
| 7 | import hashlib |
| 8 | import os |
| 9 | from pathlib import Path |
| 10 | import shutil |
| 11 | import subprocess |
| 12 | |
| 13 | ROOT = Path(__file__).resolve().parents[1] |
| 14 | ARCHITECTURES = ['x86_64', 'aarch64'] |
| 15 | |
| 16 | |
| 17 | def build(arch, output): |
| 18 | """Linked against Rust's own musl by its own lld, so the file needs nothing of the Linux it |
| 19 | runs on.""" |
| 20 | triple = f'{arch}-unknown-linux-musl' |
| 21 | subprocess.run(['rustup', 'target', 'add', triple], check=True, capture_output=True) |
| 22 | environment = {**os.environ, f'CARGO_TARGET_{triple.upper().replace("-", "_")}_LINKER': 'rust-lld', |
| 23 | 'CARGO_PROFILE_RELEASE_STRIP': 'symbols'} |
| 24 | subprocess.run(['cargo', 'build', '--locked', '--release', '-p', 'relay', '--target', triple], |
| 25 | cwd=ROOT, env=environment, check=True) |
| 26 | target = Path(os.environ.get('CARGO_TARGET_DIR') or ROOT / 'target') |
| 27 | files = [] |
| 28 | for name in ['snowbound-relay', 'snowbound-site']: |
| 29 | file = output / f'{name}-linux-{arch}' |
| 30 | shutil.copy(target / triple / f'release/{name}', file) |
| 31 | files.append(file) |
| 32 | return files |
| 33 | |
| 34 | |
| 35 | def main(): |
| 36 | parser = argparse.ArgumentParser(description=__doc__) |
| 37 | parser.add_argument('--output', type=Path, default=ROOT / 'target/relay') |
| 38 | parser.add_argument('--architectures', nargs='+', choices=ARCHITECTURES, default=ARCHITECTURES) |
| 39 | args = parser.parse_args() |
| 40 | args.output.mkdir(parents=True, exist_ok=True) |
| 41 | files = [file for arch in args.architectures for file in build(arch, args.output)] |
| 42 | for deployed in (ROOT / 'crates/relay/deploy').iterdir(): |
| 43 | shutil.copy(deployed, args.output) |
| 44 | shutil.copy(ROOT / 'crates/relay/README.md', args.output) |
| 45 | sums = ''.join(f'{hashlib.sha256(file.read_bytes()).hexdigest()} {file.name}\n' for file in files) |
| 46 | (args.output / 'SHA256SUMS').write_text(sums) |
| 47 | print(f'{args.output}:\n{sums}', end='') |
| 48 | |
| 49 | |
| 50 | if __name__ == '__main__': |
| 51 | main() |