[gimp] build: improve a bit the dll_link build script.



commit 3f3c5b242eec97de88d9475d59fe9faae508a2a9
Author: Jehan <jehan girinstud io>
Date:   Tue Oct 20 17:58:56 2020 +0200

    build: improve a bit the dll_link build script.
    
    Add a --debug mode which will help for testing and improve various
    pieces of code.

 build/windows/crossbuild-gitlab-ci/dll_link.py | 120 ++++++++++++++-----------
 1 file changed, 66 insertions(+), 54 deletions(-)
---
diff --git a/build/windows/crossbuild-gitlab-ci/dll_link.py b/build/windows/crossbuild-gitlab-ci/dll_link.py
index 5a98ca4da7..942bad82ea 100755
--- a/build/windows/crossbuild-gitlab-ci/dll_link.py
+++ b/build/windows/crossbuild-gitlab-ci/dll_link.py
@@ -13,58 +13,61 @@
 # copied into /path/install/bin folder. To copy the DLL, the root path to
 # Windows environnement should be passed, here /winenv/.
 
-import sys
+import argparse
 import os
 import subprocess
 import re
-import string
 import shutil
-from pathlib import Path
+import sys
 
 ################################################################################
 # Global variables
 
 # Sets for executable and system DLL
-dll_siril_set = set()
-dll_sys_set = set()
-
-# Install prefix
-prefix = ''
-
-# Windows environement root
-basedir = ''
+dlls = set()
+sys_dlls = set()
 
 # Common paths
-binary_dir = '/bin/'
-lib_dir = '/lib/'
-etc_dir = '/etc/'
-share_dir = '/share/'
+bindir = 'bin'
 
 ################################################################################
 # Functions
 
 # Main function
-def main():
-  global basedir
-  global prefix
-
-  if len(sys.argv) < 4:
-    exit(1)
-
-  filename = sys.argv[1]
-  basedir = sys.argv[2]
-  prefix = sys.argv[3]
-
-  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):
+def main(binary, srcdir, destdir, debug):
+  find_dependencies(binary, srcdir)
+  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)
+
+def find_dependencies(obj, srcdir):
+  '''
+  List DLLs of an object file in a recursive way.
+  '''
+  if os.path.exists(obj):
+    # If DLL exists, extract dependencies.
     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')
     if 'PE32+' in file_type:
       objdump = 'x86_64-w64-mingw32-objdump'
@@ -72,31 +75,40 @@ def recursive(filename):
       objdump = 'i686-w64-mingw32-objdump'
 
     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)
 
-    result = subprocess.run([objdump, '-p', filename], stdout=subprocess.PIPE)
+    result = subprocess.run([objdump, '-p', obj], stdout=subprocess.PIPE)
     out = result.stdout.decode('utf-8')
     # Parse lines with DLL Name instead of lib*.dll directly
-    items = re.findall(r"DLL Name: \S+.dll", out, re.MULTILINE)
-    for x in items:
-      x = x.split(' ')[2]
-      l = len(dll_siril_set)
-      dll_siril_set.add(x)
-      if len(dll_siril_set) > l:
-        new_dll = basedir + binary_dir + x
-        recursive(new_dll)
-  # Otherwise, it is a system DLL
+    for match in re.finditer(r"DLL Name: *(\S+.dll)", out, re.MULTILINE):
+      dll = match.group(1)
+      if dll not in dlls:
+        dlls.add(dll)
+        next_dll = os.path.join(srcdir, bindir, dll)
+        find_dependencies(next_dll, srcdir)
   else:
-    dll_sys_set.add(os.path.basename(filename))
-
-# Copy a DLL set into the /prefix/bin directory
-def copy_dll(dll_list):
-  for file in dll_list:
-    full_file_name = os.path.join(basedir + binary_dir, file)
+    # Otherwise, it is a system DLL
+    sys_dlls.add(os.path.basename(obj))
+
+# Copy a DLL set into the /destdir/bin directory
+def copy_dlls(dll_list, srcdir, destdir):
+  destbin = os.path.join(destdir, bindir)
+  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):
-      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__":
-  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)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]