Add Python script which finds Windows dependencies

Signed-off-by: Stefan Weil <sw@weilnetz.de>
This commit is contained in:
Stefan Weil 2024-10-31 22:32:42 +01:00
parent d0d43dfbce
commit 827a4e7c7f
2 changed files with 68 additions and 1 deletions

View File

@ -107,8 +107,11 @@ export PKG_CONFIG_PATH
make all training
MINGW_INSTALL=${PWD}${MINGW}
make install-jars install training-install html prefix="$MINGW_INSTALL"
test -d venv || python3 -m venv venv
source venv/bin/activate
pip install pefile
mkdir -p dll
ln -sv $($ROOTDIR/nsis/find_deps.py $MINGW_INSTALL/bin/*.exe $MINGW_INSTALL/bin/*.dll | sort | uniq) dll/
ln -sv $("$ROOTDIR/nsis/find_deps.py" "$MINGW_INSTALL"/bin/*.exe "$MINGW_INSTALL"/bin/*.dll) dll/
make winsetup prefix="$MINGW_INSTALL"
# Copy result for upload.

64
nsis/find_deps.py Executable file
View File

@ -0,0 +1,64 @@
#!/usr/bin/env python3
#
# Copyright (C) 2024 Stefan Weil
#
# SPDX-License-Identifier: MIT
#
# Find the DLL files which are required for a given set of
# Windows executables and libraries.
import argparse
import os
import pefile
VERBOSE = False
def find_dependencies(binary, search_path, analyzed_deps):
pe = pefile.PE(binary)
pe.parse_data_directories()
if VERBOSE:
print(f'{binary}:')
# print(pe.dump_info())
for entry in pe.DIRECTORY_ENTRY_IMPORT:
name = entry.dll.decode('utf-8')
if name in analyzed_deps:
if VERBOSE:
print(f'skip {name} (already analyzed)')
continue
analyzed_deps.add(name)
fullpath = os.path.join(search_path, name)
if not os.path.exists(fullpath):
# Not found, maybe system DLL. Skip it.
if VERBOSE:
print(f'skip {name} (not found, maybe system DLL)')
continue
print(fullpath)
analyzed_deps = find_dependencies(fullpath, search_path, analyzed_deps)
return analyzed_deps
def main():
"""
Command-line interface for universal dependency scanner.
"""
parser = argparse.ArgumentParser(description='Find and copy DLL dependencies')
parser.add_argument('files', nargs='+', help='Paths to executable or library files')
parser.add_argument('--dlldir', dest='dlldir', default='/mingw64/bin/',
help='path to dll files')
args = parser.parse_args()
# try:
# Find dependencies
analyzed_deps = set()
for binary in args.files:
if True:
analyzed_deps = find_dependencies(binary, args.dlldir, analyzed_deps)
# except:
# print(f'error: failed to find dependencies for {binary}')
if __name__ == '__main__':
main()