Extract common_ss, system_ss, and family-common objects into one qemu-system binary. Only arm, aarch64, microblaze-softmmu are listed; a new target must have arch_srcs equal to target_info_def only (target-info-def.c). Config headers stay in arch_genh.
- Union non-TARGET_* keys with y taking precedence - Reject leftover arch_srcs on participating targets - Reject TARGET_* conditions on common_ss and system_ss - Link SDL, install the binary, and apply Darwin entitlements Adding a target that still has per-target sources fails meson, for example: combined qemu-system leftover for : expected: target-info-def.c arch_srcs: target/microblaze/mmu.c target/microblaze/machine.c target-info-def.c Signed-off-by: Yonggang Luo <[email protected]> --- meson.build | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 147 insertions(+), 4 deletions(-) diff --git a/meson.build b/meson.build index d5639a2d676..7ab5c7971a8 100644 --- a/meson.build +++ b/meson.build @@ -4288,15 +4288,30 @@ if host_os == 'darwin' endif traceable = [] +single_binary_target_info_objects = [] +single_binary_config = {} +single_binary_bases = {} +single_binary_deps = [] +single_binary_crates = [] +single_binary_available = false + +single_binary_supported_targets = [ + 'aarch64-softmmu', + 'arm-softmmu', + 'microblaze-softmmu', +] + emulators = {} -target_info_def = files('target-info-def.c') +target_info_def_src = 'target-info-def.c' +target_info_def = files(target_info_def_src) target_info_def_objects = {} foreach target : target_dirs config_target = config_target_mak[target] target_name = config_target['TARGET_NAME'] target_base_arch = config_target['TARGET_BASE_ARCH'] - arch_srcs = [config_target_h[target]] + arch_srcs = [] arch_deps = [] + arch_genh = [config_target_h[target]] c_args = ['-DCOMPILING_PER_TARGET', '-DCONFIG_TARGET="@[email protected]"'.format(target), ] @@ -4322,7 +4337,7 @@ foreach target : target_dirs endif c_args += ['-DCONFIG_DEVICES="@[email protected]"'.format(target)] - arch_srcs += config_devices_h[target] + arch_genh += config_devices_h[target] link_args += enable_modules ? ['@block.syms', '@qemu.syms'] : [] else abi = config_target['TARGET_ABI_DIR'] @@ -4433,7 +4448,7 @@ foreach target : target_dirs endforeach lib = static_library('qemu-' + target, - sources: arch_srcs + genh, + sources: arch_srcs + arch_genh + genh, dependencies: lib_deps, objects: objects, include_directories: target_inc, @@ -4443,6 +4458,45 @@ foreach target : target_dirs target_info_def_objects += {target: lib.extract_objects(target_info_def)} if target.endswith('-softmmu') + if target in single_binary_supported_targets + arch_src_rels = [] + foreach src : arch_srcs + arch_src_rels += fs.relative_to(src, meson.project_source_root()) + endforeach + if arch_src_rels != [target_info_def_src] + error('combined qemu-system leftover for ' + target + ':\n' + + 'expected:\n' + target_info_def_src + '\n' + + 'arch_srcs:\n' + '\n'.join(arch_src_rels)) + endif + single_target_config = {} + foreach k, v : config_target + if not k.startswith('TARGET_') + single_target_config += {k: v} + if k not in single_binary_config or v == 'y' + single_binary_config += {k: v} + endif + endif + endforeach + target_common_no_target = common_ss.apply( + single_target_config, strict: false) + if (target_common.sources() != target_common_no_target.sources() or + target_common.dependencies() != target_common_no_target.dependencies()) + error('common_ss must not use TARGET_* conditions') + endif + target_system = system_ss.apply(config_target, strict: false) + target_system_no_target = system_ss.apply( + single_target_config, strict: false) + if (target_system.sources() != target_system_no_target.sources() or + target_system.dependencies() != target_system_no_target.dependencies()) + error('system_ss must not use TARGET_* conditions') + endif + single_binary_target_info_objects += lib.extract_objects(target_info_def) + single_binary_bases += {target_base_arch: true} + single_binary_deps += arch_deps + single_binary_deps += target_stubs + single_binary_crates += main_rs + single_binary_available = true + endif execs = [{ 'name': 'qemu-system-' + target_name, 'win_subsystem': 'console', @@ -4524,6 +4578,95 @@ foreach target : target_dirs endforeach endforeach +# Combined qemu-system: one apply + extract, same sources as +# qemu-system-$target. +# +# common_ss / system_ss use single_binary_config, the non-TARGET_* union where +# 'y' takes precedence. +# Do not use when: 'TARGET_*' on these sets; those keys are dropped and the file +# would vanish from qemu-system. +# +# Family common/system libs use config_base_arch_mak[base] (every target of that +# TARGET_BASE_ARCH, including user-mode if enabled). +# +# Each qemu-* lib contributes target-info-def.c. Participating targets must have +# arch_srcs equal to target_info_def only. +if single_binary_available + single_binary_objects = [] + target_common = common_ss.apply(single_binary_config, strict: false) + single_binary_objects += common_all.extract_objects(target_common.sources()) + single_binary_deps += target_common.dependencies() + + target_system = system_ss.apply(single_binary_config, strict: false) + single_binary_objects += libsystem.extract_objects(target_system.sources()) + single_binary_deps += target_system.dependencies() + + foreach base, _ : single_binary_bases + config_base = config_base_arch_mak[base] + if base in target_common_arch_libs + src = target_common_arch[base].apply(config_base, strict: false) + single_binary_objects += target_common_arch_libs[base].extract_objects( + src.sources()) + single_binary_deps += src.dependencies() + endif + if base in target_common_system_arch_libs + src = target_common_system_arch[base].apply(config_base, strict: false) + single_binary_objects += target_common_system_arch_libs[base].extract_objects( + src.sources()) + single_binary_deps += src.dependencies() + endif + endforeach + single_binary_objects += single_binary_target_info_objects + + single_binary_link_args = emulator_link_args + single_binary_link_args += enable_modules ? ['@block.syms', '@qemu.syms'] : [] + qemu_system_name = 'qemu-system' + if host_os == 'darwin' + qemu_system_name += '-unsigned' + endif + qemu_system = executable(qemu_system_name, + sources: [single_binary_crates, files('system/main.c')], + dependencies: single_binary_deps + [sdl], + objects: single_binary_objects, + link_depends: [block_syms, qemu_syms], + link_args: single_binary_link_args, + build_by_default: true, + install: true) + if host_os == 'darwin' + icon = 'pc-bios/qemu.rsrc' + build_input = [qemu_system, files(icon)] + install_input = [ + get_option('bindir') / qemu_system_name, + meson.current_source_dir() / icon + ] + if 'CONFIG_HVF' in single_binary_config + entitlements = 'accel/hvf/entitlements.plist' + build_input += files(entitlements) + install_input += meson.current_source_dir() / entitlements + endif + emulators += {'qemu-system': custom_target('qemu-system', + input: build_input, + output: 'qemu-system', + build_by_default: true, + command: [entitlement, '@OUTPUT@', '@INPUT@']) + } + meson.add_install_script(entitlement, '--install', + get_option('bindir') / 'qemu-system', + install_input) + else + emulators += {'qemu-system': qemu_system} + endif +else + error_str = f'''qemu-system only support targets: +@single_binary_supported_targets@ + +use ./configure --target-list= to choose at least one of them''' + 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') -- 2.52.0.windows.1
