[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 3/7] scripts/nsis.py: Automatically package required DLLs of
From: |
Bin Meng |
Subject: |
Re: [PATCH 3/7] scripts/nsis.py: Automatically package required DLLs of QEMU executables |
Date: |
Sat, 10 Sep 2022 08:37:36 +0800 |
On Sat, Sep 10, 2022 at 12:49 AM Mark Cave-Ayland
<mark.cave-ayland@ilande.co.uk> wrote:
>
> On 08/09/2022 14:28, Bin Meng wrote:
>
> > From: Bin Meng <bin.meng@windriver.com>
> >
> > 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>
> > ---
> >
> > meson.build | 1 +
> > scripts/nsis.py | 46 ++++++++++++++++++++++++++++++++++++++++++----
> > 2 files changed, 43 insertions(+), 4 deletions(-)
> >
> > diff --git a/meson.build b/meson.build
> > index c2adb7caf4..4c03850f9f 100644
> > --- a/meson.build
> > +++ b/meson.build
> > @@ -3657,6 +3657,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)
>
> FWIW I wrote a similar script a while back to help package a custom Windows
> build for
> a client, however I used ldd instead of objdump since it provided the full
> paths for
> DLLs installed in the msys2/mingw-w64 environment via pacman which were
> outside the
> QEMU build tree.
>
Yep, ldd also works, but only on Windows native build. objdump can
work on both Windows native and Linux cross builds.
> Once the complete list of DLLs was obtained, it was simple matter of
> filtering out
> those DLLs that started with the %WINDIR% prefix before copying them to the
> final
> distribution directory.
>
Regards,
Bin