Merge tag 'v9.0.0-rc3'
[qemu/ar7.git] / scripts / nsis.py
bloba83a6e4a059e1b91f545188de7b4eb8305ec04e2
1 #!/usr/bin/env python3
3 # Copyright (C) 2020 Red Hat, Inc.
5 # SPDX-License-Identifier: GPL-2.0-or-later
7 import argparse
8 import glob
9 import os
10 import shutil
11 import subprocess
14 def signcode(path):
15 cmd = os.environ.get("SIGNCODE")
16 if not cmd:
17 return
18 subprocess.run([cmd, path])
20 def find_deps(exe_or_dll, search_path, analyzed_deps):
21 deps = [exe_or_dll]
22 output = subprocess.check_output(["objdump", "-p", exe_or_dll], text=True)
23 output = output.split("\n")
24 for line in output:
25 if not line.startswith("\tDLL Name: "):
26 continue
28 dep = line.split("DLL Name: ")[1].strip()
29 if dep in analyzed_deps:
30 continue
32 dll = os.path.join(search_path, dep)
33 if not os.path.exists(dll):
34 # assume it's a Windows provided dll, skip it
35 continue
37 analyzed_deps.add(dep)
38 # locate the dll dependencies recursively
39 rdeps = find_deps(dll, search_path, analyzed_deps)
40 deps.extend(rdeps)
42 return deps
44 def main():
45 parser = argparse.ArgumentParser(description="QEMU NSIS build helper.")
46 parser.add_argument("outfile")
47 parser.add_argument("prefix")
48 parser.add_argument("srcdir")
49 parser.add_argument("dlldir")
50 parser.add_argument("cpu")
51 parser.add_argument("nsisargs", nargs="*")
52 args = parser.parse_args()
54 # canonicalize the Windows native prefix path
55 prefix = os.path.splitdrive(args.prefix)[1]
56 destdir = os.getcwd()
57 try:
58 subprocess.run(["make", "install", "DESTDIR=" + destdir])
59 with open(
60 os.path.join(destdir + prefix, "system-emulations.nsh"), "w"
61 ) as nsh, open(
62 os.path.join(destdir + prefix, "system-mui-text.nsh"), "w"
63 ) as muinsh:
64 for exe in sorted(glob.glob(
65 os.path.join(destdir + prefix, "qemu-system-*.exe")
66 )):
67 exe = os.path.basename(exe)
68 arch = exe[12:-4]
69 nsh.write(
70 """
71 Section "{0}" Section_{0}
72 SetOutPath "$INSTDIR"
73 File "${{BINDIR}}\\{1}"
74 SectionEnd
75 """.format(
76 arch, exe
79 if arch.endswith('w'):
80 desc = arch[:-1] + " emulation (GUI)."
81 else:
82 desc = arch + " emulation."
84 muinsh.write(
85 """
86 !insertmacro MUI_DESCRIPTION_TEXT ${{Section_{0}}} "{1}"
87 """.format(arch, desc))
89 search_path = args.dlldir
90 print("Searching '%s' for the dependent dlls ..." % search_path)
91 dlldir = destdir + prefix
93 for exe in glob.glob(os.path.join(destdir + prefix, "*.exe")):
94 signcode(exe)
96 # find all dll dependencies
97 deps = set(find_deps(exe, search_path, set()))
98 deps.remove(exe)
100 # copy all dlls to the DLLDIR
101 for dep in deps:
102 dllfile = os.path.join(dlldir, os.path.basename(dep))
103 if (os.path.exists(dllfile)):
104 continue
105 print("Copying '%s' to '%s'" % (dep, dllfile))
106 shutil.copy(dep, dllfile)
108 iconsdir = "/mingw32/share/icons"
109 if args.cpu == "x86_64":
110 iconsdir = "/mingw64/share/icons"
111 if os.path.exists("/usr/" + args.cpu + "-w64-mingw32/sys-root/mingw/share/icons"):
112 iconsdir = "/usr/" + args.cpu + "-w64-mingw32/sys-root/mingw/share/icons"
114 makensis = [
115 "makensis",
116 "-V2",
117 "-NOCD",
118 "-DSRCDIR=" + args.srcdir,
119 "-DBINDIR=" + destdir + prefix,
120 "-DDLLDIR=" + dlldir,
121 "-DICONSDIR=" + iconsdir,
122 "-DOUTFILE=" + args.outfile,
125 signcode_cmd = os.environ.get("SIGNCODE")
126 if signcode_cmd:
127 makensis += ["-DSIGNCODE=" + signcode_cmd]
129 if args.cpu == "x86_64":
130 makensis += ["-DW64"]
132 makensis += args.nsisargs
133 subprocess.run(makensis)
134 finally:
135 print("Done.")
137 if __name__ == "__main__":
138 main()