]>
Commit | Line | Data |
---|---|---|
8adfeba9 MAL |
1 | #!/usr/bin/env python3 |
2 | # | |
3 | # Copyright (C) 2020 Red Hat, Inc. | |
4 | # | |
5 | # SPDX-License-Identifier: GPL-2.0-or-later | |
6 | ||
7 | import argparse | |
8 | import glob | |
9 | import os | |
10 | import shutil | |
11 | import subprocess | |
12 | import tempfile | |
13 | ||
14 | ||
15 | def signcode(path): | |
16 | cmd = os.environ.get("SIGNCODE") | |
17 | if not cmd: | |
18 | return | |
19 | subprocess.run([cmd, path]) | |
20 | ||
a3c1e645 BM |
21 | def find_deps(exe_or_dll, search_path, analyzed_deps): |
22 | deps = [exe_or_dll] | |
23 | output = subprocess.check_output(["objdump", "-p", exe_or_dll], text=True) | |
24 | output = output.split("\n") | |
25 | for line in output: | |
26 | if not line.startswith("\tDLL Name: "): | |
27 | continue | |
28 | ||
29 | dep = line.split("DLL Name: ")[1].strip() | |
30 | if dep in analyzed_deps: | |
31 | continue | |
32 | ||
33 | dll = os.path.join(search_path, dep) | |
34 | if not os.path.exists(dll): | |
35 | # assume it's a Windows provided dll, skip it | |
36 | continue | |
37 | ||
38 | analyzed_deps.add(dep) | |
39 | # locate the dll dependencies recursively | |
40 | rdeps = find_deps(dll, search_path, analyzed_deps) | |
41 | deps.extend(rdeps) | |
42 | ||
43 | return deps | |
8adfeba9 MAL |
44 | |
45 | def main(): | |
46 | parser = argparse.ArgumentParser(description="QEMU NSIS build helper.") | |
47 | parser.add_argument("outfile") | |
48 | parser.add_argument("prefix") | |
49 | parser.add_argument("srcdir") | |
a3c1e645 | 50 | parser.add_argument("dlldir") |
8adfeba9 MAL |
51 | parser.add_argument("cpu") |
52 | parser.add_argument("nsisargs", nargs="*") | |
53 | args = parser.parse_args() | |
54 | ||
93dbca2c BM |
55 | # canonicalize the Windows native prefix path |
56 | prefix = os.path.splitdrive(args.prefix)[1] | |
8adfeba9 MAL |
57 | destdir = tempfile.mkdtemp() |
58 | try: | |
7f8c0440 | 59 | subprocess.run(["make", "install", "DESTDIR=" + destdir]) |
8adfeba9 | 60 | with open( |
93dbca2c | 61 | os.path.join(destdir + prefix, "system-emulations.nsh"), "w" |
c0879637 | 62 | ) as nsh, open( |
93dbca2c | 63 | os.path.join(destdir + prefix, "system-mui-text.nsh"), "w" |
c0879637 | 64 | ) as muinsh: |
e422d92a | 65 | for exe in sorted(glob.glob( |
93dbca2c | 66 | os.path.join(destdir + prefix, "qemu-system-*.exe") |
e422d92a | 67 | )): |
8adfeba9 MAL |
68 | exe = os.path.basename(exe) |
69 | arch = exe[12:-4] | |
70 | nsh.write( | |
71 | """ | |
72 | Section "{0}" Section_{0} | |
73 | SetOutPath "$INSTDIR" | |
74 | File "${{BINDIR}}\\{1}" | |
75 | SectionEnd | |
76 | """.format( | |
77 | arch, exe | |
78 | ) | |
79 | ) | |
c0879637 PM |
80 | if arch.endswith('w'): |
81 | desc = arch[:-1] + " emulation (GUI)." | |
82 | else: | |
83 | desc = arch + " emulation." | |
84 | ||
85 | muinsh.write( | |
86 | """ | |
87 | !insertmacro MUI_DESCRIPTION_TEXT ${{Section_{0}}} "{1}" | |
88 | """.format(arch, desc)) | |
8adfeba9 | 89 | |
a3c1e645 BM |
90 | search_path = args.dlldir |
91 | print("Searching '%s' for the dependent dlls ..." % search_path) | |
92 | dlldir = os.path.join(destdir + prefix, "dll") | |
93 | os.mkdir(dlldir) | |
94 | ||
93dbca2c | 95 | for exe in glob.glob(os.path.join(destdir + prefix, "*.exe")): |
8adfeba9 MAL |
96 | signcode(exe) |
97 | ||
a3c1e645 BM |
98 | # find all dll dependencies |
99 | deps = set(find_deps(exe, search_path, set())) | |
100 | deps.remove(exe) | |
101 | ||
102 | # copy all dlls to the DLLDIR | |
103 | for dep in deps: | |
104 | dllfile = os.path.join(dlldir, os.path.basename(dep)) | |
105 | if (os.path.exists(dllfile)): | |
106 | continue | |
107 | print("Copying '%s' to '%s'" % (dep, dllfile)) | |
108 | shutil.copy(dep, dllfile) | |
109 | ||
8adfeba9 MAL |
110 | makensis = [ |
111 | "makensis", | |
112 | "-V2", | |
113 | "-NOCD", | |
114 | "-DSRCDIR=" + args.srcdir, | |
93dbca2c | 115 | "-DBINDIR=" + destdir + prefix, |
8adfeba9 | 116 | ] |
8adfeba9 | 117 | if args.cpu == "x86_64": |
8adfeba9 | 118 | makensis += ["-DW64"] |
a3c1e645 | 119 | makensis += ["-DDLLDIR=" + dlldir] |
8adfeba9 MAL |
120 | |
121 | makensis += ["-DOUTFILE=" + args.outfile] + args.nsisargs | |
122 | subprocess.run(makensis) | |
123 | signcode(args.outfile) | |
124 | finally: | |
125 | shutil.rmtree(destdir) | |
126 | ||
127 | ||
128 | if __name__ == "__main__": | |
129 | main() |