134 lines
4.1 KiB
Python
134 lines
4.1 KiB
Python
#!/usr/bin/env python3
|
|
"""Tái tạo native_host/fluidsynth_runtime/ — tập DLL runtime cho SFHost (T14).
|
|
|
|
FluidSynth native bridge (SFHost.cpp) load libfluidsynth-3.dll + dependency
|
|
closure từ thư mục này (gitignore — KHÔNG commit DLL ~13MB vào git).
|
|
|
|
Cách dùng:
|
|
python scripts/dl_fluidsynth_runtime.py [--out native_host/fluidsynth_runtime]
|
|
|
|
Tải package MSYS2 mingw64 (repo.msys2.org), giải nén, copy closure DLL.
|
|
Cần network; không cần MSYS2/vcpkg cài sẵn.
|
|
"""
|
|
import argparse
|
|
import os
|
|
import re
|
|
import shutil
|
|
import tarfile
|
|
import tempfile
|
|
import urllib.request
|
|
import zstandard
|
|
|
|
BASE = "https://repo.msys2.org/mingw/mingw64/"
|
|
DEFAULT_OUT = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
|
|
"fluidsynth_runtime")
|
|
|
|
# Package chứa closure DLL của libfluidsynth-3.dll (FluidSynth 2.5.6, MSYS2 mingw64).
|
|
PACKAGES = [
|
|
"mingw-w64-x86_64-fluidsynth",
|
|
"mingw-w64-x86_64-glib2",
|
|
"mingw-w64-x86_64-libsndfile",
|
|
"mingw-w64-x86_64-gcc-libs",
|
|
"mingw-w64-x86_64-libiconv",
|
|
"mingw-w64-x86_64-gettext-runtime",
|
|
"mingw-w64-x86_64-pcre2",
|
|
"mingw-w64-x86_64-zlib-ng-compat",
|
|
"mingw-w64-x86_64-libffi",
|
|
"mingw-w64-x86_64-libogg",
|
|
"mingw-w64-x86_64-libvorbis",
|
|
"mingw-w64-x86_64-flac",
|
|
"mingw-w64-x86_64-mpg123",
|
|
"mingw-w64-x86_64-opus",
|
|
"mingw-w64-x86_64-xz",
|
|
"mingw-w64-x86_64-lame",
|
|
"mingw-w64-x86_64-wavpack",
|
|
"mingw-w64-x86_64-libwinpthread",
|
|
"mingw-w64-x86_64-portaudio",
|
|
"mingw-w64-x86_64-readline",
|
|
"mingw-w64-x86_64-termcap",
|
|
"mingw-w64-x86_64-sdl3",
|
|
]
|
|
|
|
# Closure DLL (xác minh bằng dumpbin /dependents BFS, 22 file).
|
|
# ponytail: closure snapshot theo FluidSynth 2.5.6 mingw64 — nếu upgrade
|
|
# libfluidsynth, chạy lại BFS dumpbin để cập nhật list này.
|
|
NEEDED = [
|
|
"libfluidsynth-3.dll",
|
|
"libglib-2.0-0.dll",
|
|
"libgmodule-2.0-0.dll",
|
|
"libgomp-1.dll",
|
|
"libgcc_s_seh-1.dll",
|
|
"libstdc++-6.dll",
|
|
"libsndfile-1.dll",
|
|
"libFLAC.dll",
|
|
"libogg-0.dll",
|
|
"libvorbis-0.dll",
|
|
"libvorbisenc-2.dll",
|
|
"libopus-0.dll",
|
|
"libmpg123-0.dll",
|
|
"libmp3lame-0.dll",
|
|
"libiconv-2.dll",
|
|
"libintl-8.dll",
|
|
"libpcre2-8-0.dll",
|
|
"libwinpthread-1.dll",
|
|
"libportaudio.dll",
|
|
"libreadline8.dll",
|
|
"libtermcap-0.dll",
|
|
"SDL3.dll",
|
|
]
|
|
|
|
|
|
def latest(files, prefix):
|
|
cands = [f for f in files
|
|
if f.startswith(prefix + "-") and f.endswith(".pkg.tar.zst") and ".sig" not in f]
|
|
return sorted(cands)[-1]
|
|
|
|
|
|
def main():
|
|
ap = argparse.ArgumentParser()
|
|
ap.add_argument("--out", default=DEFAULT_OUT)
|
|
ap.add_argument("--cache", default=None, help="thư mục chứa .pkg.tar.zst đã tải")
|
|
args = ap.parse_args()
|
|
|
|
cache = args.cache or tempfile.mkdtemp(prefix="msys2_pkgs_")
|
|
stage = tempfile.mkdtemp(prefix="msys2_stage_")
|
|
|
|
print("== liệt kê mirror")
|
|
html = urllib.request.urlopen(BASE, timeout=60).read().decode("utf-8", "ignore")
|
|
files = re.findall(r'href="([^"]+\.pkg\.tar\.zst)"', html)
|
|
|
|
dctx = zstandard.ZstdDecompressor()
|
|
for pkg in PACKAGES:
|
|
fname = latest(files, pkg)
|
|
path = os.path.join(cache, fname)
|
|
if not os.path.exists(path):
|
|
print("== tải", fname)
|
|
urllib.request.urlretrieve(BASE + fname, path)
|
|
else:
|
|
print("== có sẵn", fname)
|
|
with open(path, "rb") as f:
|
|
with dctx.stream_reader(f) as r:
|
|
with tarfile.open(fileobj=r, mode="r|") as tf:
|
|
for m in tf:
|
|
if m.isfile():
|
|
tf.extract(m, stage, filter="data")
|
|
|
|
bin_dir = os.path.join(stage, "mingw64", "bin")
|
|
os.makedirs(args.out, exist_ok=True)
|
|
missing = []
|
|
for dll in NEEDED:
|
|
src = os.path.join(bin_dir, dll)
|
|
if not os.path.exists(src):
|
|
missing.append(dll)
|
|
continue
|
|
shutil.copy2(src, os.path.join(args.out, dll))
|
|
print("== copy", dll)
|
|
|
|
if missing:
|
|
raise SystemExit("THIẾU DLL trong stage: " + ", ".join(missing))
|
|
print("OK —", len(NEEDED), "DLL ->", args.out)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|