Hi

(adding Stefan Weil in CC, who currently provides Windows installer)

On Thu, Sep 8, 2022 at 5:34 PM Bin Meng <bmeng...@gmail.com> wrote:

> From: Bin Meng <bin.m...@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.m...@windriver.com>
>

That seems reasonable to me, although packaging dependencies is not just
about linked DLLs.. There are dynamic stuff, executables, data, legal docs
etc etc. I have no clear picture how is everything really packaged in the
installer tbh (I would recommend msys2 qemu installation at this point)

anyhow, for the patch, as far as I am concerned:
Reviewed-by: Marc-André Lureau <marcandre.lur...@redhat.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)
> --
> 2.34.1
>
>
>

-- 
Marc-André Lureau

Reply via email to