summary refs log tree commit diff stats
path: root/scripts/nsis.py
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2022-10-31 13:01:12 -0400
committerStefan Hajnoczi <stefanha@redhat.com>2022-10-31 13:01:12 -0400
commit0d0e18cf7d220e25d4c1d06bdaa809409bcfa0c0 (patch)
tree4252e63f4350af40a032b91d769e28764d2a3989 /scripts/nsis.py
parent95539e546759e9cdd87ae6c8f9b314d881789435 (diff)
parent588fec8a4c3fe9e0d1cb3f7ea6fdd46221e42814 (diff)
downloadfocaccia-qemu-0d0e18cf7d220e25d4c1d06bdaa809409bcfa0c0.tar.gz
focaccia-qemu-0d0e18cf7d220e25d4c1d06bdaa809409bcfa0c0.zip
Merge tag 'pull-qemu-20221031' of https://gitlab.com/stweil/qemu into staging
Patches for Windows

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEESSNv6nXJXWmOwreK4Iwh1Wd0UK0FAmNfkC0ACgkQ4Iwh1Wd0
# UK2tEw//QQapqOnJQmjiGVWJ3xUEVoDUmZbhXlPaLKOzSkAnrnIdIO2p4jsXrITi
# LfL8PF7wCg1+oldPsKmhh+ZD6XiUyNBpTt61atXRJS/TybKAGjI33XC+/Hliwity
# 4A0+WxJ960ExLwZzaE/ANTYM86Jo5SqhzACosGh8txRbL1rkmqlrCU1DwnhU6vq1
# 5ph1HFgpqkii43Eiq+v1nmkbh5MWVuMap6MOoQzgwVTkaUU0cTmR8/KqhSHrIryj
# xFPH2wY8pA3vFgMv5OSOjq5Lg197kiWUyhJa6eBBsi4MKnQgRzAxE6yHhpyYZ5EA
# dMW9iLhPVFRDAoQOiSRLj/NA1nl2gwDdjs5WhKqF6AtxMck5IDqltLKFvLlXIxiK
# BYi3ghVeA5LUarcxuAOHse8rCXxBaIJI3aSolO5fDe0mcpNIb7CgCleBKlnBWEsP
# GtRhr1AkoKHcetO5iEfg1QG71/XWdWWy3hfW39GJeBl9C7/AxzoLC7yStI7Iv3b4
# tv/Tylt+Js1KadA9z/tof4wm4NkGf2Q9aFoSbm4pSZH+7b4ZI5LVLlDKYCnjT37v
# LekyJgkU3wRjKdLkM1n6qhsa5Ey2D7STw9ANWQwqOImoj5Dkix2FIqfaydctgrxq
# zmdQpJhOzIO8b9vVSRLn2xYtae5LNlxiAx85r5l11jwfqDOWTts=
# =ZJqu
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 31 Oct 2022 05:06:53 EDT
# gpg:                using RSA key 49236FEA75C95D698EC2B78AE08C21D5677450AD
# gpg: Good signature from "Stefan Weil <sw@weilnetz.de>" [unknown]
# gpg:                 aka "Stefan Weil (Universitätsbibliothek Mannheim) <stefan.weil@uni-mannheim.de>" [unknown]
# gpg:                 aka "Stefan Weil <stefan.weil@bib.uni-mannheim.de>" [unknown]
# gpg:                 aka "Stefan Weil <stefan.weil@weilnetz.de>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 4923 6FEA 75C9 5D69 8EC2  B78A E08C 21D5 6774 50AD

* tag 'pull-qemu-20221031' of https://gitlab.com/stweil/qemu:
  block/nfs: Fix 32-bit Windows build
  scripts/nsis.py: Automatically package required DLLs of QEMU executables
  scripts/nsis.py: Fix destination directory name when invoked on Windows
  scripts/nsis.py: Drop the unnecessary path separator

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'scripts/nsis.py')
-rw-r--r--scripts/nsis.py60
1 files changed, 50 insertions, 10 deletions
diff --git a/scripts/nsis.py b/scripts/nsis.py
index 462d6cac3b..03ed7608a2 100644
--- a/scripts/nsis.py
+++ b/scripts/nsis.py
@@ -18,26 +18,52 @@ def signcode(path):
         return
     subprocess.run([cmd, path])
 
+def find_deps(exe_or_dll, search_path, analyzed_deps):
+    deps = [exe_or_dll]
+    output = subprocess.check_output(["objdump", "-p", exe_or_dll], text=True)
+    output = output.split("\n")
+    for line in output:
+        if not line.startswith("\tDLL Name: "):
+            continue
+
+        dep = line.split("DLL Name: ")[1].strip()
+        if dep in analyzed_deps:
+            continue
+
+        dll = os.path.join(search_path, dep)
+        if not os.path.exists(dll):
+            # assume it's a Windows provided dll, skip it
+            continue
+
+        analyzed_deps.add(dep)
+        # locate the dll dependencies recursively
+        rdeps = find_deps(dll, search_path, analyzed_deps)
+        deps.extend(rdeps)
+
+    return deps
 
 def main():
     parser = argparse.ArgumentParser(description="QEMU NSIS build helper.")
     parser.add_argument("outfile")
     parser.add_argument("prefix")
     parser.add_argument("srcdir")
+    parser.add_argument("dlldir")
     parser.add_argument("cpu")
     parser.add_argument("nsisargs", nargs="*")
     args = parser.parse_args()
 
+    # canonicalize the Windows native prefix path
+    prefix = os.path.splitdrive(args.prefix)[1]
     destdir = tempfile.mkdtemp()
     try:
-        subprocess.run(["make", "install", "DESTDIR=" + destdir + os.path.sep])
+        subprocess.run(["make", "install", "DESTDIR=" + destdir])
         with open(
-            os.path.join(destdir + args.prefix, "system-emulations.nsh"), "w"
+            os.path.join(destdir + prefix, "system-emulations.nsh"), "w"
         ) as nsh, open(
-            os.path.join(destdir + args.prefix, "system-mui-text.nsh"), "w"
+            os.path.join(destdir + prefix, "system-mui-text.nsh"), "w"
         ) as muinsh:
             for exe in sorted(glob.glob(
-                os.path.join(destdir + args.prefix, "qemu-system-*.exe")
+                os.path.join(destdir + prefix, "qemu-system-*.exe")
             )):
                 exe = os.path.basename(exe)
                 arch = exe[12:-4]
@@ -61,22 +87,36 @@ def main():
                 !insertmacro MUI_DESCRIPTION_TEXT ${{Section_{0}}} "{1}"
                 """.format(arch, desc))
 
-        for exe in glob.glob(os.path.join(destdir + args.prefix, "*.exe")):
+        search_path = args.dlldir
+        print("Searching '%s' for the dependent dlls ..." % search_path)
+        dlldir = os.path.join(destdir + prefix, "dll")
+        os.mkdir(dlldir)
+
+        for exe in glob.glob(os.path.join(destdir + prefix, "*.exe")):
             signcode(exe)
 
+            # find all dll dependencies
+            deps = set(find_deps(exe, search_path, set()))
+            deps.remove(exe)
+
+            # copy all dlls to the DLLDIR
+            for dep in deps:
+                dllfile = os.path.join(dlldir, os.path.basename(dep))
+                if (os.path.exists(dllfile)):
+                    continue
+                print("Copying '%s' to '%s'" % (dep, dllfile))
+                shutil.copy(dep, dllfile)
+
         makensis = [
             "makensis",
             "-V2",
             "-NOCD",
             "-DSRCDIR=" + args.srcdir,
-            "-DBINDIR=" + destdir + args.prefix,
+            "-DBINDIR=" + destdir + prefix,
         ]
-        dlldir = "w32"
         if args.cpu == "x86_64":
-            dlldir = "w64"
             makensis += ["-DW64"]
-        if os.path.exists(os.path.join(args.srcdir, "dll")):
-            makensis += ["-DDLLDIR={0}/dll/{1}".format(args.srcdir, dlldir)]
+        makensis += ["-DDLLDIR=" + dlldir]
 
         makensis += ["-DOUTFILE=" + args.outfile] + args.nsisargs
         subprocess.run(makensis)