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

Pierrick Bouvier <[email protected]>
Newsgroups org.nongnu.qemu-riscv,org.nongnu.qemu-arm,org.nongnu.qemu-devel
Message-ID <[email protected]>
On 8/26/2026 6:00 AM, Daniel P. Berrangé wrote:
> 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.
>

Maybe it's now more obvious why our original goal, presented at KVM
Forum 2025, was to have only arm/aarch64/microblaze, and not riscv.
It just requires more work to have it, and iteration is key. But we need
a minimum viable product to start somewhere.

It is still our goal to this date.

> 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
>

There is nothing new here, and we discovered all that more than a year
ago. That's why we started using stub_ss more, as it provides the weak
symbol semantic we need. It's not the end of the story though, as we'll
have to adapt some functions to this new "multi target" world.
But to be able to test and debug that, we need to have a single-binary
first.

> 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.
>

It is a wrong analysis, and there is no need to have yet another
Kconfig. The only cases to handle to solve symbols duplication are:
- true conflict -> unify implementation or dispatch per target
- false conflict -> implementation vs stubs, solved with "weak symbols"
+ additional target/config checks on implementation.

The linker has the final word, and we just need to follow what it says.

>> +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.
>

No strong opinion here, I would be happy to implement a different
behavior for this. I personally prefer predictable/boring software
without any implicit behavior, and guide user to what it wants, instead
of guessing for him/her.

I didn't post this patch for review, just to show there is no need to
have a complex mechanic, and simply mixing object files together works,
once target was cleaned to work with single-binary.

This has been presented at KVM Forum 2025, and we didn't find any
situation that required to change our strategy so far.

> 
>> +
>> +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
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.