Skip to content

Commit f2c7209

Browse files
committed
Modernize SDL build script.
1 parent dc2f84f commit f2c7209

1 file changed

Lines changed: 33 additions & 24 deletions

File tree

build_sdl.py

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/usr/bin/env python3
2+
"""Build script to parse SDL headers and generate CFFI bindings."""
23
from __future__ import annotations
34

45
import io
@@ -10,12 +11,14 @@
1011
import sys
1112
import zipfile
1213
from pathlib import Path
13-
from typing import Any, Dict, List, Set
14+
from typing import Any
1415

1516
import pcpp # type: ignore
1617
import requests
1718

18-
BITSIZE, LINKAGE = platform.architecture()
19+
# ruff: noqa: S603, S607 # This script calls a lot of programs.
20+
21+
BIT_SIZE, LINKAGE = platform.architecture()
1922

2023
# Reject versions of SDL older than this, update the requirements in the readme if you change this.
2124
SDL_MIN_VERSION = (2, 0, 10)
@@ -80,19 +83,21 @@ def check_sdl_version() -> None:
8083
needed_version = f"{SDL_MIN_VERSION[0]}.{SDL_MIN_VERSION[1]}.{SDL_MIN_VERSION[2]}"
8184
try:
8285
sdl_version_str = subprocess.check_output(["sdl2-config", "--version"], universal_newlines=True).strip()
83-
except FileNotFoundError:
84-
raise RuntimeError(
85-
"libsdl2-dev or equivalent must be installed on your system"
86-
f" and must be at least version {needed_version}."
87-
"\nsdl2-config must be on PATH."
86+
except FileNotFoundError as exc:
87+
msg = (
88+
"libsdl2-dev or equivalent must be installed on your system and must be at least version"
89+
f" {needed_version}.\nsdl2-config must be on PATH."
8890
)
91+
raise RuntimeError(msg) from exc
8992
print(f"Found SDL {sdl_version_str}.")
9093
sdl_version = tuple(int(s) for s in sdl_version_str.split("."))
9194
if sdl_version < SDL_MIN_VERSION:
92-
raise RuntimeError("SDL version must be at least %s, (found %s)" % (needed_version, sdl_version_str))
95+
msg = f"SDL version must be at least {needed_version}, (found {sdl_version_str})"
96+
raise RuntimeError(msg)
9397

9498

9599
def get_sdl2_file(version: str) -> Path:
100+
"""Return a path to an SDL2 archive for the current platform. The archive is downloaded if missing."""
96101
if sys.platform == "win32":
97102
sdl2_file = f"SDL2-devel-{version}-VC.zip"
98103
else:
@@ -102,14 +107,15 @@ def get_sdl2_file(version: str) -> Path:
102107
sdl2_remote_file = f"https://www.libsdl.org/release/{sdl2_file}"
103108
if not sdl2_local_file.exists():
104109
print(f"Downloading {sdl2_remote_file}")
105-
os.makedirs("dependencies/", exist_ok=True)
106-
with requests.get(sdl2_remote_file) as response:
110+
Path("dependencies/").mkdir(parents=True, exist_ok=True)
111+
with requests.get(sdl2_remote_file) as response: # noqa: S113
107112
response.raise_for_status()
108113
sdl2_local_file.write_bytes(response.content)
109114
return sdl2_local_file
110115

111116

112117
def unpack_sdl2(version: str) -> Path:
118+
"""Return the path to an extracted SDL distribution. Creates it if missing."""
113119
sdl2_path = Path(f"dependencies/SDL2-{version}")
114120
if sys.platform == "darwin":
115121
sdl2_dir = sdl2_path
@@ -134,10 +140,11 @@ class SDLParser(pcpp.Preprocessor): # type: ignore
134140
"""A modified preprocessor to output code in a format for CFFI."""
135141

136142
def __init__(self) -> None:
143+
"""Initialise the object with empty values."""
137144
super().__init__()
138145
self.line_directive = None # Don't output line directives.
139-
self.known_string_defines: Dict[str, str] = {}
140-
self.known_defines: Set[str] = set()
146+
self.known_string_defines: dict[str, str] = {}
147+
self.known_defines: set[str] = set()
141148

142149
def get_output(self) -> str:
143150
"""Return this objects current tokens as a string."""
@@ -151,7 +158,7 @@ def on_include_not_found(self, is_malformed: bool, is_system_include: bool, curd
151158
"""Remove bad includes such as stddef.h and stdarg.h."""
152159
raise pcpp.OutputDirective(pcpp.Action.IgnoreAndRemove)
153160

154-
def _should_track_define(self, tokens: List[Any]) -> bool:
161+
def _should_track_define(self, tokens: list[Any]) -> bool:
155162
if len(tokens) < 3:
156163
return False
157164
if tokens[0].value in IGNORE_DEFINES:
@@ -175,8 +182,9 @@ def _should_track_define(self, tokens: List[Any]) -> bool:
175182
)
176183

177184
def on_directive_handle(
178-
self, directive: Any, tokens: List[Any], if_passthru: bool, preceding_tokens: List[Any]
179-
) -> Any:
185+
self, directive: Any, tokens: list[Any], if_passthru: bool, preceding_tokens: list[Any] # noqa: ANN401
186+
) -> Any: # noqa: ANN401
187+
"""Catch and store definitions."""
180188
if directive.value == "define" and self._should_track_define(tokens):
181189
if tokens[2].type == "CPP_STRING":
182190
self.known_string_defines[tokens[0].value] = tokens[2].value
@@ -204,7 +212,7 @@ def on_directive_handle(
204212
assert matches
205213

206214
for match in matches:
207-
if os.path.isfile(Path(match, "SDL_stdinc.h")):
215+
if Path(match, "SDL_stdinc.h").is_file():
208216
SDL2_INCLUDE = match
209217
assert SDL2_INCLUDE
210218

@@ -224,6 +232,7 @@ def on_directive_handle(
224232

225233

226234
def get_cdef() -> str:
235+
"""Return the parsed code of SDL for CFFI."""
227236
parser = SDLParser()
228237
parser.add_path(SDL2_INCLUDE)
229238
parser.parse(
@@ -261,12 +270,12 @@ def get_cdef() -> str:
261270
return sdl2_cdef + EXTRA_CDEF
262271

263272

264-
include_dirs: List[str] = []
265-
extra_compile_args: List[str] = []
266-
extra_link_args: List[str] = []
273+
include_dirs: list[str] = []
274+
extra_compile_args: list[str] = []
275+
extra_link_args: list[str] = []
267276

268-
libraries: List[str] = []
269-
library_dirs: List[str] = []
277+
libraries: list[str] = []
278+
library_dirs: list[str] = []
270279

271280

272281
if sys.platform == "darwin":
@@ -278,16 +287,16 @@ def get_cdef() -> str:
278287
if sys.platform == "win32":
279288
include_dirs.append(str(SDL2_INCLUDE))
280289
ARCH_MAPPING = {"32bit": "x86", "64bit": "x64"}
281-
SDL2_LIB_DIR = Path(SDL2_BUNDLE_PATH, "lib/", ARCH_MAPPING[BITSIZE])
290+
SDL2_LIB_DIR = Path(SDL2_BUNDLE_PATH, "lib/", ARCH_MAPPING[BIT_SIZE])
282291
library_dirs.append(str(SDL2_LIB_DIR))
283-
SDL2_LIB_DEST = Path("tcod", ARCH_MAPPING[BITSIZE])
292+
SDL2_LIB_DEST = Path("tcod", ARCH_MAPPING[BIT_SIZE])
284293
SDL2_LIB_DEST.mkdir(exist_ok=True)
285294
shutil.copy(SDL2_LIB_DIR / "SDL2.dll", SDL2_LIB_DEST)
286295

287296
# Link to the SDL2 framework on MacOS.
288297
# Delocate will bundle the binaries in a later step.
289298
if sys.platform == "darwin":
290-
HEADER_DIR = os.path.join(SDL2_PARSE_PATH, "Headers")
299+
HEADER_DIR = Path(SDL2_PARSE_PATH, "Headers")
291300
include_dirs.append(HEADER_DIR)
292301
extra_link_args += [f"-F{SDL2_BUNDLE_PATH}/.."]
293302
extra_link_args += ["-rpath", f"{SDL2_BUNDLE_PATH}/.."]

0 commit comments

Comments
 (0)