aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBin Meng <bin.meng@windriver.com>2022-09-08 21:28:13 +0800
committerStefan Weil <sw@weilnetz.de>2022-10-31 10:06:11 +0100
commita3c1e6458dbbe3647ccadfb39cbb585fdc4373a5 (patch)
treedb7d4f704001b83ffea578249c41fb32656290c9
parent93dbca2ce9f112ee8bfd641fa2ea6ff0771c6c39 (diff)
scripts/nsis.py: Automatically package required DLLs of QEMU executables
At present packaging the required DLLs of QEMU executables is a manual process, and error prone. Actually build/config-host.mak contains a GLIB_BINDIR variable which is the directory where glib and other DLLs reside. This works for both Windows native build and cross-build on Linux. We can use it as the search directory for DLLs and automate the whole DLL packaging process. Signed-off-by: Bin Meng <bin.meng@windriver.com> Message-Id: <20220908132817.1831008-4-bmeng.cn@gmail.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Tested-by: Stefan Weil <sw@weilnetz.de> Signed-off-by: Stefan Weil <sw@weilnetz.de>
-rw-r--r--meson.build1
-rw-r--r--scripts/nsis.py46
2 files changed, 43 insertions, 4 deletions
diff --git a/meson.build b/meson.build
index 37737913df..d0a186e7f5 100644
--- a/meson.build
+++ b/meson.build
@@ -3616,6 +3616,7 @@ if host_machine.system() == 'windows'
'@OUTPUT@',
get_option('prefix'),
meson.current_source_dir(),
+ config_host['GLIB_BINDIR'],
host_machine.cpu(),
'--',
'-DDISPLAYVERSION=' + meson.project_version(),
diff --git a/scripts/nsis.py b/scripts/nsis.py
index baa6ef9594..03ed7608a2 100644
--- a/scripts/nsis.py
+++ b/scripts/nsis.py
@@ -18,12 +18,36 @@ 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()
@@ -63,9 +87,26 @@ def main():
!insertmacro MUI_DESCRIPTION_TEXT ${{Section_{0}}} "{1}"
""".format(arch, desc))
+ 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",
@@ -73,12 +114,9 @@ def main():
"-DSRCDIR=" + args.srcdir,
"-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)