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/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(-)
>
> diff --git a/meson.build b/meson.build
> index 449d50f2983..b4f435f6a22 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -4250,6 +4250,10 @@ endif
>
> traceable = []
> emulators = {}
> +target_softmmu = {}
> +combo_softmmu = ['aarch64-softmmu', 'arm-softmmu', 'riscv32-softmmu', 'riscv64-softmmu']
> +have_qemu_system_combo = ('aarch64-softmmu' in target_dirs
> + and 'riscv64-softmmu' in target_dirs)
> foreach target : target_dirs
> config_target = config_target_mak[target]
> target_name = config_target['TARGET_NAME']
> @@ -4399,20 +4403,37 @@ foreach target : target_dirs
> c_args: c_args,
> build_by_default: false)
>
> + if target in combo_softmmu
> + target_softmmu += {target: {
> + 'lib': lib,
> + 'arch_srcs': arch_srcs,
> + 'arch_deps': arch_deps,
> + 'c_args': c_args,
> + 'link_args': link_args,
> + 'target_stubs': target_stubs,
> + 'main_rs': main_rs,
> + 'config_target': config_target,
> + 'target_base_arch': target_base_arch,
> + }}
> + endif
> +
> if target.endswith('-softmmu')
> - execs = [{
> - 'name': 'qemu-system-' + target_name,
> - 'win_subsystem': 'console',
> - 'sources': [main_rs, files('system/main.c')],
> - 'dependencies': [sdl, target_stubs],
> - }]
> - if host_os == 'windows' and (sdl.found() or gtk.found())
> + execs = []
> + if not (have_qemu_system_combo and target in combo_softmmu)
> execs += [{
> - 'name': 'qemu-system-' + target_name + 'w',
> - 'win_subsystem': 'windows',
> + 'name': 'qemu-system-' + target_name,
> + 'win_subsystem': 'console',
> 'sources': [main_rs, files('system/main.c')],
> 'dependencies': [sdl, target_stubs],
> }]
> + if host_os == 'windows' and (sdl.found() or gtk.found())
> + execs += [{
> + 'name': 'qemu-system-' + target_name + 'w',
> + 'win_subsystem': 'windows',
> + 'sources': [main_rs, files('system/main.c')],
> + 'dependencies': [sdl, target_stubs],
> + }]
> + endif
> endif
> if get_option('fuzzing')
> specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
> @@ -4481,6 +4502,123 @@ foreach target : target_dirs
> endforeach
> endforeach
>
> +# Combined ARM + RISC-V system emulator (32 and 64).
> +# Common/system objects come from aarch64. RISC-V arch objects come
> +# from the existing riscv64 lib. 32-bit TargetInfo and 32-only boards
> +# come from the arm/riscv32 libs. Per-target qemu-system-* names are
> +# symlinks to qemu-system (argv[0] selects TargetInfo).
> +if have_qemu_system_combo
> + a64 = target_softmmu['aarch64-softmmu']
> + rv = target_softmmu['riscv64-softmmu']
> + extra_objs = []
> + target_info_def = files('target-info-def.c')
> + foreach spec : [[common_ss, common_all], [system_ss, libsystem]]
> + rv_src = spec[0].apply(rv['config_target'], strict: false)
> + a64_src = spec[0].apply(a64['config_target'], strict: false)
> + extra = []
> + foreach f : rv_src.sources()
> + if f not in a64_src.sources() and not f.full_path().endswith('_stubs.c')
> + extra += f
> + endif
> + endforeach
> + if extra.length() > 0
> + extra_objs += spec[1].extract_objects(extra)
> + endif
> + endforeach
> + rv_base = rv['target_base_arch']
> + if rv_base in target_common_arch_libs
> + src = target_common_arch[rv_base].apply(rv['config_target'], strict: false)
> + extra_objs += target_common_arch_libs[rv_base].extract_objects(src.sources())
> + endif
> + if rv_base in target_common_system_arch_libs
> + src = target_common_system_arch[rv_base].apply(rv['config_target'], strict: false)
> + extra_objs += target_common_system_arch_libs[rv_base].extract_objects(src.sources())
> + endif
> + foreach pair : [['arm-softmmu', 'aarch64-softmmu'], ['riscv32-softmmu', 'riscv64-softmmu']]
> + t32 = pair[0]
> + t64 = pair[1]
> + if t32 in target_softmmu
> + extra_objs += target_softmmu[t32]['lib'].extract_objects(target_info_def)
> + base32 = target_softmmu[t32]['target_base_arch']
> + if base32 in hw_arch
> + hw32 = hw_arch[base32].apply(target_softmmu[t32]['config_target'], strict: false)
> + hw64 = hw_arch[base32].apply(target_softmmu[t64]['config_target'], strict: false)
> + extra_hw = []
> + foreach f : hw32.sources()
> + if f not in hw64.sources()
> + extra_hw += f
> + endif
> + endforeach
> + if extra_hw.length() > 0
> + extra_objs += target_softmmu[t32]['lib'].extract_objects(extra_hw)
> + endif
> + endif
> + endif
> + endforeach
> + combo_objects = extra_objs
> + combo_objects += a64['lib'].extract_all_objects(recursive: true)
> + combo_objects += rv['lib'].extract_objects(rv['arch_srcs'])
> + combo_deps = a64['arch_deps'] + rv['arch_deps'] + [sdl, a64['target_stubs'], rv['target_stubs']]
> + if 'arm-softmmu' in target_softmmu
> + combo_deps += target_softmmu['arm-softmmu']['arch_deps']
> + endif
> + if 'riscv32-softmmu' in target_softmmu
> + combo_deps += target_softmmu['riscv32-softmmu']['arch_deps']
> + endif
> + combo_execs = [{
> + 'name': 'qemu-system',
> + 'win_subsystem': 'console',
> + }]
> + if host_os == 'windows' and (sdl.found() or gtk.found())
> + combo_execs += [{
> + 'name': 'qemu-systemw',
> + 'win_subsystem': 'windows',
> + }]
> + endif
> + combo_exe_suffix = host_os == 'windows' ? '.exe' : ''
> + combo_alias_py = 'import os, sys; src, dst = sys.argv[1:3]; os.path.exists(dst) and os.remove(dst); os.symlink(os.path.basename(src), dst)'
> + foreach exe : combo_execs
> + emulator = executable(exe['name'], [a64['main_rs'], files('system/main.c')],
> + install: true,
> + c_args: a64['c_args'],
> + dependencies: combo_deps,
> + objects: combo_objects,
> + link_depends: [block_syms, qemu_syms],
> + link_args: a64['link_args'],
> + win_subsystem: exe['win_subsystem'])
> + emulators += {exe['name']: emulator}
> + traceable += [{
> + 'exe': exe['name'],
> + 'probe-prefix': 'qemu.system.multi',
> + }]
> + foreach t : combo_softmmu
> + if t not in target_softmmu
> + continue
> + endif
> + tname = target_softmmu[t]['config_target']['TARGET_NAME']
> + if exe['name'] == 'qemu-systemw'
> + alias = 'qemu-system-' + tname + 'w'
> + else
> + alias = 'qemu-system-' + tname
> + endif
> + alias_tgt = custom_target(alias,
> + input: emulator,
> + output: alias + combo_exe_suffix,
> + command: [python, '-c', combo_alias_py, '@INPUT@', '@OUTPUT@'],
> + build_by_default: true,
> + install: false)
> + emulators += {alias: alias_tgt}
> + install_symlink(alias + combo_exe_suffix,
> + pointing_to: exe['name'] + combo_exe_suffix,
> + install_dir: get_option('bindir'))
> + traceable += [{
> + 'exe': alias,
> + 'probe-prefix': 'qemu.system.' + tname,
> + }]
> + endforeach
> + endforeach
> +endif
> +
> # Other build targets
>
> if get_option('plugins')
Please find attached a much simpler implementation, which only requires
a single line update as we add new targets in single-binary.
Regards,
Pierrick
6261b0c255e1a8f0df2b41928b8dfb365d0fa488.patch.txt
(text/plain, 2.9 KB)
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', +] +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@ + +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')