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>
This commit is contained in:
parent
93dbca2ce9
commit
a3c1e6458d
@ -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(),
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user