Skip to content

Commit 4385a4d

Browse files
committed
Update SDL CFFI parser.
This is a backport of the SDL parser updates from the ESDL subproject. This may change what symbols are exported, but it will export more than before. It should also be more stable.
1 parent 858617b commit 4385a4d

File tree

7 files changed

+309
-288
lines changed

7 files changed

+309
-288
lines changed

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@
216216
"PAGEUP",
217217
"pathfinding",
218218
"pathlib",
219+
"pcpp",
219220
"PILCROW",
220221
"pilmode",
221222
"PRINTF",

build_libtcod.py

Lines changed: 11 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,24 @@
55
import os
66
import platform
77
import re
8-
import shutil
9-
import subprocess
108
import sys
11-
import zipfile
129
from pathlib import Path
1310
from typing import Any, Dict, Iterable, Iterator, List, Set, Tuple, Union
14-
from urllib.request import urlretrieve
1511

1612
from cffi import FFI # type: ignore
1713

1814
sys.path.append(str(Path(__file__).parent)) # Allow importing local modules.
1915

20-
import parse_sdl2 # noqa: E402
16+
import build_sdl # noqa: E402
2117

2218
# The SDL2 version to parse and export symbols from.
2319
SDL2_PARSE_VERSION = os.environ.get("SDL_VERSION", "2.0.5")
2420

2521
# The SDL2 version to include in binary distributions.
2622
SDL2_BUNDLE_VERSION = os.environ.get("SDL_VERSION", "2.0.14")
2723

24+
Py_LIMITED_API = 0x03060000
25+
2826
HEADER_PARSE_PATHS = ("tcod/", "libtcod/src/libtcod/")
2927
HEADER_PARSE_EXCLUDES = ("gl2_ext_.h", "renderer_gl_internal.h", "event.h")
3028

@@ -137,60 +135,24 @@ def walk_sources(directory: str) -> Iterator[str]:
137135
yield str(Path(path, source))
138136

139137

140-
def get_sdl2_file(version: str) -> Path:
141-
if sys.platform == "win32":
142-
sdl2_file = f"SDL2-devel-{version}-VC.zip"
143-
else:
144-
assert sys.platform == "darwin"
145-
sdl2_file = f"SDL2-{version}.dmg"
146-
sdl2_local_file = Path("dependencies", sdl2_file)
147-
sdl2_remote_file = f"https://www.libsdl.org/release/{sdl2_file}"
148-
if not sdl2_local_file.exists():
149-
print(f"Downloading {sdl2_remote_file}")
150-
os.makedirs("dependencies/", exist_ok=True)
151-
urlretrieve(sdl2_remote_file, sdl2_local_file)
152-
return sdl2_local_file
153-
154-
155-
def unpack_sdl2(version: str) -> Path:
156-
sdl2_path = Path(f"dependencies/SDL2-{version}")
157-
if sys.platform == "darwin":
158-
sdl2_dir = sdl2_path
159-
sdl2_path /= "SDL2.framework"
160-
if sdl2_path.exists():
161-
return sdl2_path
162-
sdl2_arc = get_sdl2_file(version)
163-
print(f"Extracting {sdl2_arc}")
164-
if sdl2_arc.suffix == ".zip":
165-
with zipfile.ZipFile(sdl2_arc) as zf:
166-
zf.extractall("dependencies/")
167-
elif sys.platform == "darwin":
168-
assert sdl2_arc.suffix == ".dmg"
169-
subprocess.check_call(["hdiutil", "mount", sdl2_arc])
170-
subprocess.check_call(["mkdir", "-p", sdl2_dir])
171-
subprocess.check_call(["cp", "-r", "/Volumes/SDL2/SDL2.framework", sdl2_dir])
172-
subprocess.check_call(["hdiutil", "unmount", "/Volumes/SDL2"])
173-
return sdl2_path
174-
175-
176138
includes = parse_includes()
177139

178140
module_name = "tcod._libtcod"
179-
include_dirs = [
141+
include_dirs: List[str] = [
180142
".",
181143
"libtcod/src/vendor/",
182144
"libtcod/src/vendor/utf8proc",
183145
"libtcod/src/vendor/zlib/",
146+
*build_sdl.include_dirs,
184147
]
185148

186-
extra_parse_args = []
187-
extra_compile_args = []
188-
extra_link_args = []
149+
extra_compile_args: List[str] = [*build_sdl.extra_compile_args]
150+
extra_link_args: List[str] = [*build_sdl.extra_link_args]
189151
sources: List[str] = []
190152

191-
libraries = []
192-
library_dirs: List[str] = []
193-
define_macros: List[Tuple[str, Any]] = [("Py_LIMITED_API", 0x03060000)]
153+
libraries: List[str] = [*build_sdl.libraries]
154+
library_dirs: List[str] = [*build_sdl.library_dirs]
155+
define_macros: List[Tuple[str, Any]] = [("Py_LIMITED_API", Py_LIMITED_API)]
194156

195157
sources += walk_sources("tcod/")
196158
sources += walk_sources("libtcod/src/libtcod/")
@@ -205,74 +167,14 @@ def unpack_sdl2(version: str) -> Path:
205167
define_macros.append(("TCODLIB_API", ""))
206168
define_macros.append(("_CRT_SECURE_NO_WARNINGS", None))
207169

208-
if sys.platform == "darwin":
209-
extra_link_args += ["-framework", "SDL2"]
210-
else:
211-
libraries += ["SDL2"]
212-
213-
# included SDL headers are for whatever OS's don't easily come with them
214-
215170
if sys.platform in ["win32", "darwin"]:
216-
SDL2_PARSE_PATH = unpack_sdl2(SDL2_PARSE_VERSION)
217-
SDL2_BUNDLE_PATH = unpack_sdl2(SDL2_BUNDLE_VERSION)
218171
include_dirs.append("libtcod/src/zlib/")
219172

220-
if sys.platform == "win32":
221-
SDL2_INCLUDE = Path(SDL2_PARSE_PATH, "include")
222-
elif sys.platform == "darwin":
223-
SDL2_INCLUDE = Path(SDL2_PARSE_PATH, "Versions/A/Headers")
224-
else:
225-
matches = re.findall(
226-
r"-I(\S+)",
227-
subprocess.check_output(["sdl2-config", "--cflags"], universal_newlines=True),
228-
)
229-
assert matches
230-
231-
SDL2_INCLUDE = None
232-
for match in matches:
233-
if Path(match, "SDL_stdinc.h").is_file():
234-
SDL2_INCLUDE = match
235-
assert SDL2_INCLUDE
236-
237-
if sys.platform == "win32":
238-
include_dirs.append(str(SDL2_INCLUDE))
239-
ARCH_MAPPING = {"32bit": "x86", "64bit": "x64"}
240-
SDL2_LIB_DIR = Path(SDL2_BUNDLE_PATH, "lib/", ARCH_MAPPING[BITSIZE])
241-
library_dirs.append(str(SDL2_LIB_DIR))
242-
SDL2_LIB_DEST = Path("tcod", ARCH_MAPPING[BITSIZE])
243-
if not SDL2_LIB_DEST.exists():
244-
os.mkdir(SDL2_LIB_DEST)
245-
shutil.copy(Path(SDL2_LIB_DIR, "SDL2.dll"), SDL2_LIB_DEST)
246-
247-
248-
def fix_header(path: Path) -> None:
249-
"""Removes leading whitespace from a MacOS header file.
250-
251-
This whitespace is causing issues with directives on some platforms.
252-
"""
253-
current = path.read_text(encoding="utf-8")
254-
fixed = "\n".join(line.strip() for line in current.split("\n"))
255-
if current == fixed:
256-
return
257-
path.write_text(fixed, encoding="utf-8")
258-
259173

260174
if sys.platform == "darwin":
261-
HEADER_DIR = Path(SDL2_PARSE_PATH, "Headers")
262-
fix_header(Path(HEADER_DIR, "SDL_assert.h"))
263-
fix_header(Path(HEADER_DIR, "SDL_config_macosx.h"))
264-
include_dirs.append(HEADER_DIR)
265-
extra_link_args += [f"-F{SDL2_BUNDLE_PATH}/.."]
266-
extra_link_args += ["-rpath", f"{SDL2_BUNDLE_PATH}/.."]
267-
extra_link_args += ["-rpath", "/usr/local/opt/llvm/lib/"]
268-
269175
# Fix "implicit declaration of function 'close'" in zlib.
270176
define_macros.append(("HAVE_UNISTD_H", 1))
271177

272-
if sys.platform not in ["win32", "darwin"]:
273-
extra_parse_args += subprocess.check_output(["sdl2-config", "--cflags"], universal_newlines=True).strip().split()
274-
extra_compile_args += extra_parse_args
275-
extra_link_args += subprocess.check_output(["sdl2-config", "--libs"], universal_newlines=True).strip().split()
276178

277179
tdl_build = os.environ.get("TDL_BUILD", "RELEASE").upper()
278180

@@ -299,7 +201,7 @@ def fix_header(path: Path) -> None:
299201
extra_link_args.extend(GCC_CFLAGS[tdl_build])
300202

301203
ffi = FFI()
302-
parse_sdl2.add_to_ffi(ffi, SDL2_INCLUDE)
204+
ffi.cdef(build_sdl.get_cdef())
303205
for include in includes:
304206
try:
305207
ffi.cdef(include.header)

0 commit comments

Comments
 (0)