build: improve a bit the dll_link build script.

Add a --debug mode which will help for testing and improve various
pieces of code.
This commit is contained in:
Jehan 2020-10-20 17:58:56 +02:00
parent 29565fcfd8
commit 3f3c5b242e
1 changed files with 64 additions and 52 deletions

View File

@ -13,58 +13,61 @@
# copied into /path/install/bin folder. To copy the DLL, the root path to # copied into /path/install/bin folder. To copy the DLL, the root path to
# Windows environnement should be passed, here /winenv/. # Windows environnement should be passed, here /winenv/.
import sys import argparse
import os import os
import subprocess import subprocess
import re import re
import string
import shutil import shutil
from pathlib import Path import sys
################################################################################ ################################################################################
# Global variables # Global variables
# Sets for executable and system DLL # Sets for executable and system DLL
dll_siril_set = set() dlls = set()
dll_sys_set = set() sys_dlls = set()
# Install prefix
prefix = ''
# Windows environement root
basedir = ''
# Common paths # Common paths
binary_dir = '/bin/' bindir = 'bin'
lib_dir = '/lib/'
etc_dir = '/etc/'
share_dir = '/share/'
################################################################################ ################################################################################
# Functions # Functions
# Main function # Main function
def main(): def main(binary, srcdir, destdir, debug):
global basedir find_dependencies(binary, srcdir)
global prefix if args.debug:
print("Running in debug mode (no DLL moved)")
if len(dlls) > 0:
sys.stdout.write("Needed DLLs:\n\t- ")
sys.stdout.write("\n\t- ".join(list(dlls)))
print()
if len(sys_dlls) > 0:
sys.stdout.write('System DLLs:\n\t- ')
sys.stdout.write("\n\t- ".join(sys_dlls))
print()
removed_dlls = sys_dlls & dlls
if len(removed_dlls) > 0:
sys.stdout.write('Non installed DLLs:\n\t- ')
sys.stdout.write("\n\t- ".join(removed_dlls))
print()
installed_dlls = dlls - sys_dlls
if len(installed_dlls) > 0:
sys.stdout.write('Installed DLLs:\n\t- ')
sys.stdout.write("\n\t- ".join(installed_dlls))
print()
else:
copy_dlls(dlls - sys_dlls, srcdir, destdir)
if len(sys.argv) < 4: def find_dependencies(obj, srcdir):
exit(1) '''
List DLLs of an object file in a recursive way.
filename = sys.argv[1] '''
basedir = sys.argv[2] if os.path.exists(obj):
prefix = sys.argv[3] # If DLL exists, extract dependencies.
recursive(filename)
copy_dll(dll_siril_set-dll_sys_set)
# List DLL of an executable file in a recursive way
def recursive(filename):
# Check if DLL exist in /bin folder, if true extract depencies too.
if os.path.exists(filename):
objdump = None objdump = None
result = subprocess.run(['file', filename], stdout=subprocess.PIPE) result = subprocess.run(['file', obj], stdout=subprocess.PIPE)
file_type = result.stdout.decode('utf-8') file_type = result.stdout.decode('utf-8')
if 'PE32+' in file_type: if 'PE32+' in file_type:
objdump = 'x86_64-w64-mingw32-objdump' objdump = 'x86_64-w64-mingw32-objdump'
@ -72,31 +75,40 @@ def recursive(filename):
objdump = 'i686-w64-mingw32-objdump' objdump = 'i686-w64-mingw32-objdump'
if objdump is None: if objdump is None:
sys.stderr.write('File type of {} unknown: {}\n'.format(filename, file_type)) sys.stderr.write('File type of {} unknown: {}\n'.format(obj, file_type))
sys.exit(os.EX_UNAVAILABLE) sys.exit(os.EX_UNAVAILABLE)
result = subprocess.run([objdump, '-p', filename], stdout=subprocess.PIPE) result = subprocess.run([objdump, '-p', obj], stdout=subprocess.PIPE)
out = result.stdout.decode('utf-8') out = result.stdout.decode('utf-8')
# Parse lines with DLL Name instead of lib*.dll directly # Parse lines with DLL Name instead of lib*.dll directly
items = re.findall(r"DLL Name: \S+.dll", out, re.MULTILINE) for match in re.finditer(r"DLL Name: *(\S+.dll)", out, re.MULTILINE):
for x in items: dll = match.group(1)
x = x.split(' ')[2] if dll not in dlls:
l = len(dll_siril_set) dlls.add(dll)
dll_siril_set.add(x) next_dll = os.path.join(srcdir, bindir, dll)
if len(dll_siril_set) > l: find_dependencies(next_dll, srcdir)
new_dll = basedir + binary_dir + x
recursive(new_dll)
# Otherwise, it is a system DLL
else: else:
dll_sys_set.add(os.path.basename(filename)) # Otherwise, it is a system DLL
sys_dlls.add(os.path.basename(obj))
# Copy a DLL set into the /prefix/bin directory # Copy a DLL set into the /destdir/bin directory
def copy_dll(dll_list): def copy_dlls(dll_list, srcdir, destdir):
for file in dll_list: destbin = os.path.join(destdir, bindir)
full_file_name = os.path.join(basedir + binary_dir, file) os.makedirs(destbin, exist_ok=True)
for dll in dll_list:
full_file_name = os.path.join(srcdir, bindir, dll)
if os.path.isfile(full_file_name): if os.path.isfile(full_file_name):
shutil.copy(full_file_name, prefix+binary_dir) shutil.copy(full_file_name, destbin)
else:
sys.stderr.write("Missing DLL: {}\n".format(full_file_name))
sys.exit(os.EX_DATAERR)
if __name__ == "__main__": if __name__ == "__main__":
main() parser = argparse.ArgumentParser()
parser.add_argument('--debug', dest='debug', action = 'store_true', default = False)
parser.add_argument('bin')
parser.add_argument('src')
parser.add_argument('dest')
args = parser.parse_args(sys.argv[1:])
main(args.bin, args.src, args.dest, args.debug)