fix(ci, windows): track bundle_deps.py and improve mingw dynamic library resolution
This commit is contained in:
parent
0ecd522da0
commit
c6787bd7ee
2 changed files with 119 additions and 1 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -3,4 +3,5 @@
|
||||||
scratch/
|
scratch/
|
||||||
*.orig
|
*.orig
|
||||||
*.obOCNTS
|
*.obOCNTS
|
||||||
*.py
|
/*.py
|
||||||
|
!packaging/**/*.py
|
||||||
|
|
|
||||||
117
packaging/windows/bundle_deps.py
Normal file
117
packaging/windows/bundle_deps.py
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import glob
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
def main():
|
||||||
|
bundle_dir = sys.argv[1] if len(sys.argv) > 1 else "dist/bundle"
|
||||||
|
if not os.path.exists(bundle_dir):
|
||||||
|
print(f"Error: Bundle directory '{bundle_dir}' not found.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print(f"Resolving dynamic Windows dependencies for {bundle_dir}...")
|
||||||
|
|
||||||
|
# 1. Locate MinGW bin directory containing FFmpeg DLLs
|
||||||
|
candidate_dirs = [
|
||||||
|
os.path.dirname(os.path.abspath(sys.executable)),
|
||||||
|
"/mingw64/bin",
|
||||||
|
"C:/msys64/mingw64/bin",
|
||||||
|
"D:/msys64/mingw64/bin",
|
||||||
|
]
|
||||||
|
mingw_bin = None
|
||||||
|
for cand in candidate_dirs:
|
||||||
|
if os.path.isdir(cand) and glob.glob(os.path.join(cand, "avcodec-*.dll")):
|
||||||
|
mingw_bin = cand
|
||||||
|
break
|
||||||
|
|
||||||
|
if not mingw_bin:
|
||||||
|
for cand in candidate_dirs:
|
||||||
|
if os.path.isdir(cand):
|
||||||
|
mingw_bin = cand
|
||||||
|
break
|
||||||
|
|
||||||
|
if not mingw_bin:
|
||||||
|
mingw_bin = "/mingw64/bin"
|
||||||
|
|
||||||
|
print(f"Using MinGW bin directory: {mingw_bin}")
|
||||||
|
|
||||||
|
patterns = [
|
||||||
|
"avcodec-*.dll",
|
||||||
|
"avformat-*.dll",
|
||||||
|
"avutil-*.dll",
|
||||||
|
"swresample-*.dll",
|
||||||
|
"swscale-*.dll",
|
||||||
|
"avfilter-*.dll",
|
||||||
|
"avdevice-*.dll",
|
||||||
|
"libwinpthread-*.dll",
|
||||||
|
"libgcc_s_seh-*.dll",
|
||||||
|
"libstdc++-*.dll",
|
||||||
|
"zlib*.dll",
|
||||||
|
]
|
||||||
|
|
||||||
|
for pat in patterns:
|
||||||
|
for match in glob.glob(os.path.join(mingw_bin, pat)):
|
||||||
|
dest = os.path.join(bundle_dir, os.path.basename(match))
|
||||||
|
if not os.path.exists(dest):
|
||||||
|
shutil.copy2(match, dest)
|
||||||
|
print(f"Explicitly copied: {os.path.basename(match)}")
|
||||||
|
|
||||||
|
# 2. Recursive dependency discovery via ldd
|
||||||
|
def get_ldd_deps(filepath):
|
||||||
|
deps = []
|
||||||
|
try:
|
||||||
|
out = subprocess.check_output(["ldd", filepath], text=True, stderr=subprocess.DEVNULL)
|
||||||
|
for line in out.splitlines():
|
||||||
|
line = line.strip()
|
||||||
|
if "mingw64/bin" in line.lower():
|
||||||
|
tokens = line.split()
|
||||||
|
for token in tokens:
|
||||||
|
if "mingw64/bin" in token.lower() and token.lower().endswith(".dll"):
|
||||||
|
if os.path.exists(token):
|
||||||
|
deps.append(token)
|
||||||
|
elif mingw_bin and os.path.exists(os.path.join(mingw_bin, os.path.basename(token))):
|
||||||
|
deps.append(os.path.join(mingw_bin, os.path.basename(token)))
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return deps
|
||||||
|
|
||||||
|
visited = set()
|
||||||
|
added_count = 0
|
||||||
|
|
||||||
|
while True:
|
||||||
|
candidates = [
|
||||||
|
os.path.join(bundle_dir, f)
|
||||||
|
for f in os.listdir(bundle_dir)
|
||||||
|
if (f.lower().endswith(".exe") or f.lower().endswith(".dll")) and f not in visited
|
||||||
|
]
|
||||||
|
if not candidates:
|
||||||
|
break
|
||||||
|
|
||||||
|
new_found = False
|
||||||
|
for c in candidates:
|
||||||
|
visited.add(os.path.basename(c))
|
||||||
|
for dep in get_ldd_deps(c):
|
||||||
|
dll_name = os.path.basename(dep)
|
||||||
|
dest = os.path.join(bundle_dir, dll_name)
|
||||||
|
if not os.path.exists(dest):
|
||||||
|
shutil.copy2(dep, dest)
|
||||||
|
added_count += 1
|
||||||
|
new_found = True
|
||||||
|
print(f"Discovered dependency: {dll_name} (from {os.path.basename(c)})")
|
||||||
|
|
||||||
|
if not new_found:
|
||||||
|
break
|
||||||
|
|
||||||
|
# 3. Validation
|
||||||
|
all_files = os.listdir(bundle_dir)
|
||||||
|
has_avcodec = any("avcodec" in f.lower() for f in all_files)
|
||||||
|
if not has_avcodec:
|
||||||
|
print("ERROR: avcodec-*.dll was NOT found in bundle directory!")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print(f"Successfully assembled bundle in '{bundle_dir}' with {len(all_files)} total files.")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Loading…
Add table
Reference in a new issue