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/
|
||||
*.orig
|
||||
*.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