Re: [PATCH 12/12] meson: link ARM and RISC-V into qemu-system

Daniel P. Berrangé <[email protected]>
Newsgroups org.nongnu.qemu-riscv,org.nongnu.qemu-arm,org.nongnu.qemu-devel
Message-ID <[email protected]>
On Mon, Aug 24, 2026 at 09:20:38AM -0700, Pierrick Bouvier wrote:
> On 8/23/2026 8:07 AM, Yonggang Luo wrote:
> > - Build qemu-system (and qemu-systemw on Windows) from aarch64
> >   common/system objects plus RISC-V arch objects taken from the
> >   existing riscv64 lib.
> > - Pull 32-bit TargetInfo and 32-only boards from the arm/riscv32
> >   libs so hw/arm and target/riscv are not compiled twice.
> > - Skip linking qemu-system-{arm,aarch64,riscv32,riscv64} and the
> >   Windows *w variants; symlink those names to qemu-system so
> >   argv[0] still selects TargetInfo.
> > 
> > Signed-off-by: Yonggang Luo <[email protected]>
> > ---
> >  meson.build | 156 +++++++++++++++++++++++++++++++++++++++++++++++++---
> >  1 file changed, 147 insertions(+), 9 deletions(-)

I think this approach of taking common/system from aarch64
and adding in riscv specific objects only works by luck.

That's not obvious from your patch, but Pierrick's counterproposal
below will expose it with a little  tweak....


> From 6261b0c255e1a8f0df2b41928b8dfb365d0fa488 Mon Sep 17 00:00:00 2001
> From: Pierrick Bouvier <[email protected]>
> Date: Tue, 14 Apr 2026 10:56:15 -0700
> Subject: [PATCH] meson: build single binary
> 
> This is not built by default.
> Build with: ninja -C build qemu-system
> 
> All available *-softmmu targets are aggregated, ./configure
> --target-list can be used to restrict which targets are included.
> 
> In case user has targets that are not supported, we emit an error
> message when build qemu-system target. This way, it's not necessary to
> have a custom configure flag, and qemu-system can live next to existing
> binaries without complexifying the workflow more than it is already.
> 
> Signed-off-by: Pierrick Bouvier <[email protected]>
> ---
>  meson.build | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 48 insertions(+)
> 
> diff --git a/meson.build b/meson.build
> index 553df3e7f053..4a31a520d9eb 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -4264,6 +4264,9 @@ if host_os == 'darwin'
>  endif
>  
>  traceable = []
> +single_binary_libs = []
> +single_binary_deps = []
> +single_binary_crates = []
>  emulators = {}
>  foreach target : target_dirs
>    config_target = config_target_mak[target]
> @@ -4419,6 +4422,10 @@ foreach target : target_dirs
>                   build_by_default: false)
>  
>    if target.endswith('-softmmu')
> +    single_binary_libs += lib
> +    single_binary_deps += arch_deps
> +    single_binary_deps += target_stubs
> +    single_binary_crates += main_rs
>      execs = [{
>        'name': 'qemu-system-' + target_name,
>        'win_subsystem': 'console',
> @@ -4500,6 +4507,47 @@ foreach target : target_dirs
>    endforeach
>  endforeach
>  
> +single_binary_objects = []
> +foreach lib: single_binary_libs
> +  single_binary_objects += lib.extract_all_objects(recursive: true)
> +endforeach
> +
> +single_binary_link_args = emulator_link_args
> +single_binary_link_args += enable_modules ? ['@block.syms', '@qemu.syms'] : []
> +
> +supported_targets = [
> +  'aarch64-softmmu',
> +  'arm-softmmu',
> +]

Adding in riscv64-softmmu to this list and building with
configure --target-list=aarch64-softmmu,riscv64-softmmu
will fail with this meson approach.

Specifically we'll hit duplicate symbols to to taking
different KConfig branches, resulting in building in
both the real impl and the stubs:

  /usr/bin/ld.bfd: libsystem.a.p/hw_pci-bridge_pci_expander_bridge_stubs.c.o: in function `pxb_cxl_hook_up_registers':
/home/berrange/src/virt/qemu/build-alt/../hw/pci-bridge/pci_expander_bridge_stubs.c:14: multiple definition of `pxb_cxl_hook_up_registers'; libsystem.a.p/hw_pci-bridge_pci_expander_bridge.c.o:/home/berrange/src/virt/qemu/build-alt/../hw/pci-bridge/pci_expander_bridge.c:214: first defined here

The problem is that aarch64 enables CONFIG_PXB and
riscv64 does not.

Yonggang's patch only worked by luck since it preferred
to the common system objects from aarch64 and thus kept
the real PXB impl. If Yonggang had instead used common
system objects from riscv64, the qemu-system would have
lost the PXB impl and got a stub.

This is unfixable if both targets have some Kconfigs
that the other target does not.

So to be able to build qemu-system, we can't simply
pull in the union of objects from each architecture
qemu-system-$TARGET binary. 

Instead we need to setup a new Kconfig specifically
for qemu-system, which is the combination of all
Kconfigs from each target. Then derive a new list
of objects from that.  This shouldn't involve building
any more .o files, just means we build an accurate
list of what .o files we need.

> +unsupported_targets = []
> +foreach target : target_dirs
> +  if target.endswith('-softmmu') and target not in supported_targets
> +    unsupported_targets += target
> +  endif
> +endforeach
> +
> +if unsupported_targets.length() == 0
> +  executable('qemu-system',
> +             sources: [single_binary_crates, files('system/main.c')],
> +             dependencies: single_binary_deps,
> +             objects: single_binary_objects,
> +             link_depends: [block_syms, qemu_syms],
> +             link_args: single_binary_link_args,
> +             build_by_default: false)
> +else
> +  error_str = f'''qemu-system only support targets:
> +@supported_targets@

With the Kconfig union problem solved, IMHO we should unconditionally
always build the 'qemu-system' binary. If there are targets that
do not yet support the single bniary concept that's fine, just ignore
them. qemu-system-$TARGET will still be built for everything, and
qemu-system only needs to include what's currently possible.


> +
> +unsupported targets:
> +@unsupported_targets@
> +
> +use ./configure --target-list= to choose list of targets'''
> +  t = custom_target(command: ['sh', '-c', 'echo "' + error_str + '" && exit 1'],
> +                    output: 'none',
> +                    build_by_default: false)
> +  alias_target('qemu-system', t)
> +endif
> +
>  # Other build targets
>  
>  if get_option('plugins')


With regards,
Daniel
-- 
|: https://berrange.com       ~~        https://hachyderm.io/@berrange :|
|: https://libvirt.org          ~~          https://entangle-photo.org :|
|: https://pixelfed.art/berrange   ~~    https://fstop138.berrange.com :|
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.