mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-07-26 11:53:53 -06:00

In msys2 distribution objdump from gcc is using single tab character prefix, but objdump from clang is using 4 white space characters instead. The script will not identify any dll dependencies for a QEMU build generated with clang. This in turn will fail the build, because there will be no files inside dlldir and no setup file will be created. Instead of checking for whitespace in prefix use lstrip to accommodate for differences in outputs. Signed-off-by: Arthur Sengileyev <arthur.sengileyev@gmail.com> Reviewed-by: Stefan Weil <sw@weilnetz.de> Reviewed-by: Michael Tokarev <mjt@tls.msk.ru> Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
129 lines
3.8 KiB
Python
129 lines
3.8 KiB
Python
#!/usr/bin/env python3
|
|
#
|
|
# Copyright (C) 2020 Red Hat, Inc.
|
|
#
|
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
import argparse
|
|
import glob
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
import tempfile
|
|
|
|
|
|
def signcode(path):
|
|
cmd = os.environ.get("SIGNCODE")
|
|
if not cmd:
|
|
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.lstrip().startswith("DLL 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
|
|
analyzed_deps, rdeps = find_deps(dll, search_path, analyzed_deps)
|
|
deps.extend(rdeps)
|
|
|
|
return analyzed_deps, 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])
|
|
with open(
|
|
os.path.join(destdir + prefix, "system-emulations.nsh"), "w"
|
|
) as nsh, open(
|
|
os.path.join(destdir + prefix, "system-mui-text.nsh"), "w"
|
|
) as muinsh:
|
|
for exe in sorted(glob.glob(
|
|
os.path.join(destdir + prefix, "qemu-system-*.exe")
|
|
)):
|
|
exe = os.path.basename(exe)
|
|
arch = exe[12:-4]
|
|
nsh.write(
|
|
"""
|
|
Section "{0}" Section_{0}
|
|
SetOutPath "$INSTDIR"
|
|
File "${{BINDIR}}\\{1}"
|
|
SectionEnd
|
|
""".format(
|
|
arch, exe
|
|
)
|
|
)
|
|
if arch.endswith('w'):
|
|
desc = arch[:-1] + " emulation (GUI)."
|
|
else:
|
|
desc = arch + " emulation."
|
|
|
|
muinsh.write(
|
|
"""
|
|
!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)
|
|
|
|
analyzed_deps = set()
|
|
for exe in glob.glob(os.path.join(destdir + prefix, "*.exe")):
|
|
signcode(exe)
|
|
|
|
# find all dll dependencies
|
|
analyzed_deps, deps = find_deps(exe, search_path, analyzed_deps)
|
|
deps = set(deps)
|
|
deps.remove(exe)
|
|
|
|
# copy all dlls to the DLLDIR
|
|
for dep in deps:
|
|
dllfile = os.path.join(dlldir, os.path.basename(dep))
|
|
print("Copying '%s' to '%s'" % (dep, dllfile))
|
|
shutil.copy(dep, dllfile)
|
|
|
|
makensis = [
|
|
"makensis",
|
|
"-V2",
|
|
"-NOCD",
|
|
"-DSRCDIR=" + args.srcdir,
|
|
"-DBINDIR=" + destdir + prefix,
|
|
]
|
|
if args.cpu == "x86_64":
|
|
makensis += ["-DW64"]
|
|
makensis += ["-DDLLDIR=" + dlldir]
|
|
|
|
makensis += ["-DOUTFILE=" + args.outfile] + args.nsisargs
|
|
subprocess.run(makensis)
|
|
signcode(args.outfile)
|
|
finally:
|
|
shutil.rmtree(destdir)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|