1 project('qemu', ['c'], meson_version: '>=0.55.0',
2 default_options: ['warning_level=1', 'c_std=gnu99', 'cpp_std=gnu++11', 'b_lundef=false'],
3 version: run_command('head', meson.source_root() / 'VERSION').stdout().strip())
5 not_found = dependency('', required: false)
6 keyval = import('unstable-keyval')
7 ss = import('sourceset')
9 sh = find_program('sh')
10 cc = meson.get_compiler('c')
11 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
12 config_all_disas = keyval.load(meson.current_build_dir() / 'config-all-disas.mak')
13 enable_modules = 'CONFIG_MODULES' in config_host
15 add_project_arguments(config_host['QEMU_CFLAGS'].split(),
16 native: false, language: ['c', 'objc'])
17 add_project_arguments(config_host['QEMU_CXXFLAGS'].split(),
18 native: false, language: 'cpp')
19 add_project_link_arguments(config_host['QEMU_LDFLAGS'].split(),
20 native: false, language: ['c', 'cpp', 'objc'])
21 add_project_arguments(config_host['QEMU_INCLUDES'].split(),
22 language: ['c', 'cpp', 'objc'])
24 python = import('python').find_installation()
26 link_language = meson.get_external_property('link_language', 'cpp')
27 if link_language == 'cpp'
28 add_languages('cpp', required: true, native: false)
30 if host_machine.system() == 'darwin'
31 add_languages('objc', required: false, native: false)
34 if 'SPARSE_CFLAGS' in config_host
36 command: [find_program('scripts/check_sparse.py'),
37 config_host['SPARSE_CFLAGS'].split(),
38 'compile_commands.json'])
41 configure_file(input: files('scripts/ninjatool.py'),
43 configuration: config_host)
45 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
46 supported_cpus = ['ppc', 'ppc64', 's390x', 'sparc64', 'riscv32', 'riscv64', 'x86', 'x86_64',
47 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
49 cpu = host_machine.cpu_family()
50 targetos = host_machine.system()
52 m = cc.find_library('m', required: false)
53 util = cc.find_library('util', required: false)
61 if targetos == 'windows'
62 socket = cc.find_library('ws2_32')
63 winmm = cc.find_library('winmm')
65 win = import('windows')
66 version_res = win.compile_resources('version.rc',
67 depend_files: files('pc-bios/qemu-nsis.ico'),
68 include_directories: include_directories('.'))
69 elif targetos == 'darwin'
70 coref = dependency('appleframeworks', modules: 'CoreFoundation')
71 iokit = dependency('appleframeworks', modules: 'IOKit')
72 cocoa = dependency('appleframeworks', modules: 'Cocoa')
73 hvf = dependency('appleframeworks', modules: 'Hypervisor')
74 elif targetos == 'sunos'
75 socket = [cc.find_library('socket'),
76 cc.find_library('nsl'),
77 cc.find_library('resolv')]
78 elif targetos == 'haiku'
79 socket = [cc.find_library('posix_error_mapper'),
80 cc.find_library('network'),
81 cc.find_library('bsd')]
83 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
84 link_args: config_host['GLIB_LIBS'].split())
86 if 'CONFIG_GIO' in config_host
87 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
88 link_args: config_host['GIO_LIBS'].split())
91 if 'CONFIG_TRACE_UST' in config_host
92 lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
95 if 'CONFIG_TRACE_UST' in config_host
96 urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
99 if 'CONFIG_NETTLE' in config_host
100 nettle = declare_dependency(compile_args: config_host['NETTLE_CFLAGS'].split(),
101 link_args: config_host['NETTLE_LIBS'].split())
104 if 'CONFIG_GNUTLS' in config_host
105 gnutls = declare_dependency(compile_args: config_host['GNUTLS_CFLAGS'].split(),
106 link_args: config_host['GNUTLS_LIBS'].split())
108 pixman = declare_dependency(compile_args: config_host['PIXMAN_CFLAGS'].split(),
109 link_args: config_host['PIXMAN_LIBS'].split())
111 if 'CONFIG_AUTH_PAM' in config_host
112 pam = cc.find_library('pam')
114 libaio = cc.find_library('aio', required: false)
116 if 'CONFIG_ZLIB' in config_host
117 zlib = declare_dependency(compile_args: config_host['ZLIB_CFLAGS'].split(),
118 link_args: config_host['ZLIB_LIBS'].split())
120 linux_io_uring = not_found
121 if 'CONFIG_LINUX_IO_URING' in config_host
122 linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
123 link_args: config_host['LINUX_IO_URING_LIBS'].split())
126 if 'CONFIG_LIBXML2' in config_host
127 libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
128 link_args: config_host['LIBXML2_LIBS'].split())
131 if 'CONFIG_LIBNFS' in config_host
132 libnfs = declare_dependency(link_args: config_host['LIBNFS_LIBS'].split())
135 if 'CONFIG_ATTR' in config_host
136 libattr = declare_dependency(link_args: config_host['LIBATTR_LIBS'].split())
139 if 'CONFIG_SECCOMP' in config_host
140 seccomp = declare_dependency(compile_args: config_host['SECCOMP_CFLAGS'].split(),
141 link_args: config_host['SECCOMP_LIBS'].split())
143 libcap_ng = not_found
144 if 'CONFIG_LIBCAP_NG' in config_host
145 libcap_ng = declare_dependency(link_args: config_host['LIBCAP_NG_LIBS'].split())
147 xkbcommon = not_found
148 if 'CONFIG_XKBCOMMON' in config_host
149 xkbcommon = declare_dependency(compile_args: config_host['XKBCOMMON_CFLAGS'].split(),
150 link_args: config_host['XKBCOMMON_LIBS'].split())
153 if config_host.has_key('CONFIG_SLIRP')
154 slirp = declare_dependency(compile_args: config_host['SLIRP_CFLAGS'].split(),
155 link_args: config_host['SLIRP_LIBS'].split())
158 if config_host.has_key('CONFIG_VDE')
159 vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
162 if 'CONFIG_LIBPULSE' in config_host
163 pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
164 link_args: config_host['PULSE_LIBS'].split())
167 if 'CONFIG_ALSA' in config_host
168 alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
169 link_args: config_host['ALSA_LIBS'].split())
172 if 'CONFIG_LIBJACK' in config_host
173 jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
176 if 'CONFIG_SPICE' in config_host
177 spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
178 link_args: config_host['SPICE_LIBS'].split())
180 rt = cc.find_library('rt', required: false)
181 libmpathpersist = not_found
182 if config_host.has_key('CONFIG_MPATH')
183 libmpathpersist = cc.find_library('mpathpersist')
186 if 'CONFIG_LIBISCSI' in config_host
187 libiscsi = declare_dependency(compile_args: config_host['LIBISCSI_CFLAGS'].split(),
188 link_args: config_host['LIBISCSI_LIBS'].split())
191 if 'CONFIG_ZSTD' in config_host
192 zstd = declare_dependency(compile_args: config_host['ZSTD_CFLAGS'].split(),
193 link_args: config_host['ZSTD_LIBS'].split())
196 if 'CONFIG_GBM' in config_host
197 gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
198 link_args: config_host['GBM_LIBS'].split())
201 if 'CONFIG_VIRGL' in config_host
202 virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
203 link_args: config_host['VIRGL_LIBS'].split())
206 if 'CONFIG_CURL' in config_host
207 curl = declare_dependency(compile_args: config_host['CURL_CFLAGS'].split(),
208 link_args: config_host['CURL_LIBS'].split())
211 if 'CONFIG_LIBUDEV' in config_host
212 libudev = declare_dependency(link_args: config_host['LIBUDEV_LIBS'].split())
215 if 'CONFIG_BRLAPI' in config_host
216 brlapi = declare_dependency(link_args: config_host['BRLAPI_LIBS'].split())
220 if 'CONFIG_SDL' in config_host
221 sdl = declare_dependency(compile_args: config_host['SDL_CFLAGS'].split(),
222 link_args: config_host['SDL_LIBS'].split())
223 sdlwindows = config_host['SDL_LIBS'].contains('-mwindows')
226 if 'CONFIG_RBD' in config_host
227 rbd = declare_dependency(link_args: config_host['RBD_LIBS'].split())
229 glusterfs = not_found
230 if 'CONFIG_GLUSTERFS' in config_host
231 glusterfs = declare_dependency(compile_args: config_host['GLUSTERFS_CFLAGS'].split(),
232 link_args: config_host['GLUSTERFS_LIBS'].split())
235 if 'CONFIG_LIBSSH' in config_host
236 libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
237 link_args: config_host['LIBSSH_LIBS'].split())
240 if 'CONFIG_BZIP2' in config_host
241 libbzip2 = declare_dependency(link_args: config_host['BZIP2_LIBS'].split())
244 if 'CONFIG_LZFSE' in config_host
245 liblzfse = declare_dependency(link_args: config_host['LZFSE_LIBS'].split())
248 if 'CONFIG_AUDIO_OSS' in config_host
249 oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
252 if 'CONFIG_AUDIO_DSOUND' in config_host
253 dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
255 coreaudio = not_found
256 if 'CONFIG_AUDIO_COREAUDIO' in config_host
257 coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
260 if 'CONFIG_OPENGL' in config_host
261 opengl = declare_dependency(link_args: config_host['OPENGL_LIBS'].split())
265 if 'CONFIG_GTK' in config_host
266 gtk = declare_dependency(compile_args: config_host['GTK_CFLAGS'].split(),
267 link_args: config_host['GTK_LIBS'].split())
270 if 'CONFIG_VTE' in config_host
271 vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
272 link_args: config_host['VTE_LIBS'].split())
275 if 'CONFIG_X11' in config_host
276 x11 = declare_dependency(compile_args: config_host['X11_CFLAGS'].split(),
277 link_args: config_host['X11_LIBS'].split())
280 if 'CONFIG_CURSES' in config_host
281 curses = declare_dependency(compile_args: config_host['CURSES_CFLAGS'].split(),
282 link_args: config_host['CURSES_LIBS'].split())
285 if 'CONFIG_ICONV' in config_host
286 iconv = declare_dependency(compile_args: config_host['ICONV_CFLAGS'].split(),
287 link_args: config_host['ICONV_LIBS'].split())
290 if 'CONFIG_GIO' in config_host
291 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
292 link_args: config_host['GIO_LIBS'].split())
295 if 'CONFIG_VNC_PNG' in config_host
296 png = declare_dependency(compile_args: config_host['PNG_CFLAGS'].split(),
297 link_args: config_host['PNG_LIBS'].split())
300 if 'CONFIG_VNC_JPEG' in config_host
301 jpeg = declare_dependency(compile_args: config_host['JPEG_CFLAGS'].split(),
302 link_args: config_host['JPEG_LIBS'].split())
305 if 'CONFIG_VNC_SASL' in config_host
306 sasl = declare_dependency(compile_args: config_host['SASL_CFLAGS'].split(),
307 link_args: config_host['SASL_LIBS'].split())
310 if 'CONFIG_FDT' in config_host
311 fdt = declare_dependency(compile_args: config_host['FDT_CFLAGS'].split(),
312 link_args: config_host['FDT_LIBS'].split())
315 if 'CONFIG_SNAPPY' in config_host
316 snappy = declare_dependency(link_args: config_host['SNAPPY_LIBS'].split())
319 if 'CONFIG_LZO' in config_host
320 lzo = declare_dependency(link_args: config_host['LZO_LIBS'].split())
323 if 'CONFIG_RDMA' in config_host
324 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
327 if 'CONFIG_NUMA' in config_host
328 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
331 if 'CONFIG_XEN_BACKEND' in config_host
332 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
333 link_args: config_host['XEN_LIBS'].split())
336 if 'CONFIG_SMARTCARD' in config_host
337 cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
338 link_args: config_host['SMARTCARD_LIBS'].split())
341 if 'CONFIG_USB_REDIR' in config_host
342 usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
343 link_args: config_host['USB_REDIR_LIBS'].split())
346 if 'CONFIG_USB_LIBUSB' in config_host
347 libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
348 link_args: config_host['LIBUSB_LIBS'].split())
351 if 'CONFIG_CAPSTONE' in config_host
352 capstone = declare_dependency(compile_args: config_host['CAPSTONE_CFLAGS'].split(),
353 link_args: config_host['CAPSTONE_LIBS'].split())
356 if 'CONFIG_LIBPMEM' in config_host
357 libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
358 link_args: config_host['LIBPMEM_LIBS'].split())
361 create_config = find_program('scripts/create_config')
362 minikconf = find_program('scripts/minikconf.py')
363 target_dirs = config_host['TARGET_DIRS'].split()
366 config_devices_mak_list = []
367 config_devices_h = {}
368 config_target_mak = {}
369 kconfig_external_symbols = [
378 'CONFIG_VHOST_KERNEL',
383 foreach target : target_dirs
384 have_user = have_user or target.endswith('-user')
385 config_target = keyval.load(meson.current_build_dir() / target / 'config-target.mak') + config_host
387 if target.endswith('-softmmu')
391 foreach sym : kconfig_external_symbols
392 if sym in config_target
393 base_kconfig += '@0@=y'.format(sym)
397 config_devices_mak = target + '-config-devices.mak'
398 config_devices_mak = configure_file(
399 input: ['default-configs' / target + '.mak', 'Kconfig'],
400 output: config_devices_mak,
401 depfile: config_devices_mak + '.d',
403 command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'],
404 config_devices_mak, '@DEPFILE@', '@INPUT@',
406 config_devices_h += {target: custom_target(
407 target + '-config-devices.h',
408 input: config_devices_mak,
409 output: target + '-config-devices.h',
411 command: [create_config, '@INPUT@'])}
412 config_devices_mak_list += config_devices_mak
413 config_target += keyval.load(config_devices_mak)
415 config_target_mak += {target: config_target}
417 have_tools = 'CONFIG_TOOLS' in config_host
418 have_block = have_system or have_tools
420 grepy = find_program('scripts/grepy.sh')
421 # This configuration is used to build files that are shared by
422 # multiple binaries, and then extracted out of the "common"
423 # static_library target.
425 # We do not use all_sources()/all_dependencies(), because it would
426 # build literally all source files, including devices only used by
427 # targets that are not built for this compilation. The CONFIG_ALL
428 # pseudo symbol replaces it.
431 config_all_devices_mak = configure_file(
432 output: 'config-all-devices.mak',
433 input: config_devices_mak_list,
435 command: [grepy, '@INPUT@'],
437 config_all_devices = keyval.load(config_all_devices_mak)
439 config_all_devices = {}
441 config_all = config_all_devices
442 config_all += config_host
443 config_all += config_all_disas
445 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
446 'CONFIG_SOFTMMU': have_system,
447 'CONFIG_USER_ONLY': have_user,
454 hxtool = find_program('scripts/hxtool')
455 shaderinclude = find_program('scripts/shaderinclude.pl')
456 qapi_gen = find_program('scripts/qapi-gen.py')
457 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
458 meson.source_root() / 'scripts/qapi/commands.py',
459 meson.source_root() / 'scripts/qapi/common.py',
460 meson.source_root() / 'scripts/qapi/doc.py',
461 meson.source_root() / 'scripts/qapi/error.py',
462 meson.source_root() / 'scripts/qapi/events.py',
463 meson.source_root() / 'scripts/qapi/expr.py',
464 meson.source_root() / 'scripts/qapi/gen.py',
465 meson.source_root() / 'scripts/qapi/introspect.py',
466 meson.source_root() / 'scripts/qapi/parser.py',
467 meson.source_root() / 'scripts/qapi/schema.py',
468 meson.source_root() / 'scripts/qapi/source.py',
469 meson.source_root() / 'scripts/qapi/types.py',
470 meson.source_root() / 'scripts/qapi/visit.py',
471 meson.source_root() / 'scripts/qapi/common.py',
472 meson.source_root() / 'scripts/qapi/doc.py',
473 meson.source_root() / 'scripts/qapi-gen.py'
477 python, files('scripts/tracetool.py'),
478 '--backend=' + config_host['TRACE_BACKENDS']
481 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
482 meson.current_source_dir(),
483 config_host['PKGVERSION'], config_host['VERSION']]
484 qemu_version = custom_target('qemu-version.h',
485 output: 'qemu-version.h',
486 command: qemu_version_cmd,
488 build_by_default: true,
489 build_always_stale: true)
492 config_host_h = custom_target('config-host.h',
493 input: meson.current_build_dir() / 'config-host.mak',
494 output: 'config-host.h',
496 command: [create_config, '@INPUT@'])
497 genh += config_host_h
501 ['qemu-options.hx', 'qemu-options.def'],
502 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
506 ['hmp-commands.hx', 'hmp-commands.h'],
507 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
510 foreach d : hx_headers
511 hxdep += custom_target(d[1],
515 build_by_default: true, # to be removed when added to a target
516 command: [hxtool, '-h', '@INPUT0@'])
520 # Collect sourcesets.
522 util_ss = ss.source_set()
523 stub_ss = ss.source_set()
524 trace_ss = ss.source_set()
525 block_ss = ss.source_set()
526 blockdev_ss = ss.source_set()
527 qmp_ss = ss.source_set()
528 common_ss = ss.source_set()
529 softmmu_ss = ss.source_set()
530 user_ss = ss.source_set()
531 bsd_user_ss = ss.source_set()
532 linux_user_ss = ss.source_set()
533 specific_ss = ss.source_set()
534 specific_fuzz_ss = ss.source_set()
539 target_softmmu_arch = {}
545 # TODO: add each directory to the subdirs from its own meson.build, once
547 trace_events_subdirs = [
554 trace_events_subdirs += [ 'linux-user' ]
557 trace_events_subdirs += [
566 trace_events_subdirs += [
577 'hw/block/dataplane',
622 trace_events_subdirs += [
649 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
650 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
653 # Build targets from sourcesets
655 stub_ss = stub_ss.apply(config_all, strict: false)
657 util_ss.add_all(trace_ss)
658 util_ss = util_ss.apply(config_all, strict: false)
659 libqemuutil = static_library('qemuutil',
660 sources: util_ss.sources() + stub_ss.sources() + genh,
661 dependencies: [util_ss.dependencies(), m, glib, socket])
662 qemuutil = declare_dependency(link_with: libqemuutil,
663 sources: genh + version_res)
665 decodetree = generator(find_program('scripts/decodetree.py'),
666 output: 'decode-@BASENAME@.c.inc',
667 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
673 subdir('libdecnumber')
683 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
689 blockdev_ss.add(files(
696 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
697 # os-win32.c does not
698 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
699 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
701 softmmu_ss.add_all(blockdev_ss)
702 softmmu_ss.add(files(
708 softmmu_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c'))
709 softmmu_ss.add(when: 'CONFIG_SECCOMP', if_true: [files('qemu-seccomp.c'), seccomp])
710 softmmu_ss.add(when: ['CONFIG_FDT', fdt], if_true: [files('device_tree.c')])
712 common_ss.add(files('cpus-common.c'))
716 specific_ss.add(files('disas.c', 'exec.c', 'gdbstub.c'), capstone, libpmem)
717 specific_ss.add(files('exec-vary.c'))
718 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
727 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
741 bsd_user_ss.add(files('gdbstub.c'))
742 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
744 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
745 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
747 # needed for fuzzing binaries
748 subdir('tests/qtest/libqos')
749 subdir('tests/qtest/fuzz')
753 foreach d, list : modules
754 foreach m, module_ss : list
755 if enable_modules and targetos != 'windows'
756 module_ss = module_ss.apply(config_host, strict: false)
757 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
758 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
766 block_ss.add_all(module_ss)
768 softmmu_ss.add_all(module_ss)
774 nm = find_program('nm')
775 undefsym = find_program('scripts/undefsym.sh')
776 block_syms = custom_target('block.syms', output: 'block.syms',
777 input: [libqemuutil, block_mods],
779 command: [undefsym, nm, '@INPUT@'])
780 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
781 input: [libqemuutil, softmmu_mods],
783 command: [undefsym, nm, '@INPUT@'])
785 block_ss = block_ss.apply(config_host, strict: false)
786 libblock = static_library('block', block_ss.sources() + genh,
787 dependencies: block_ss.dependencies(),
788 link_depends: block_syms,
790 build_by_default: false)
792 block = declare_dependency(link_whole: [libblock],
793 link_args: '@block.syms',
794 dependencies: [crypto, io])
796 qmp_ss = qmp_ss.apply(config_host, strict: false)
797 libqmp = static_library('qmp', qmp_ss.sources() + genh,
798 dependencies: qmp_ss.dependencies(),
800 build_by_default: false)
802 qmp = declare_dependency(link_whole: [libqmp])
804 foreach m : block_mods + softmmu_mods
805 shared_module(m.name(),
809 install_dir: config_host['qemu_moddir'])
812 softmmu_ss.add(authz, block, chardev, crypto, io, qmp)
813 common_ss.add(qom, qemuutil)
815 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
816 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
818 common_all = common_ss.apply(config_all, strict: false)
819 common_all = static_library('common',
820 build_by_default: false,
821 sources: common_all.sources() + genh,
822 dependencies: common_all.dependencies(),
825 feature_to_c = find_program('scripts/feature_to_c.sh')
828 foreach target : target_dirs
829 config_target = config_target_mak[target]
830 target_name = config_target['TARGET_NAME']
831 arch = config_target['TARGET_BASE_ARCH']
834 c_args = ['-DNEED_CPU_H',
835 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
836 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
839 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
840 if targetos == 'linux'
841 target_inc += include_directories('linux-headers', is_system: true)
843 if target.endswith('-softmmu')
844 qemu_target_name = 'qemu-system-' + target_name
846 t = target_softmmu_arch[arch].apply(config_target, strict: false)
847 arch_srcs += t.sources()
848 arch_deps += t.dependencies()
850 hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
851 hw = hw_arch[hw_dir].apply(config_target, strict: false)
852 arch_srcs += hw.sources()
853 arch_deps += hw.dependencies()
855 arch_srcs += config_devices_h[target]
856 link_args += ['@block.syms', '@qemu.syms']
858 abi = config_target['TARGET_ABI_DIR']
860 qemu_target_name = 'qemu-' + target_name
861 if 'CONFIG_LINUX_USER' in config_target
862 base_dir = 'linux-user'
863 target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
865 base_dir = 'bsd-user'
867 target_inc += include_directories(
871 if 'CONFIG_LINUX_USER' in config_target
873 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
874 if config_target.has_key('TARGET_SYSTBL_ABI')
876 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
877 extra_args : config_target['TARGET_SYSTBL_ABI'])
882 if 'TARGET_XML_FILES' in config_target
883 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
884 output: target + '-gdbstub-xml.c',
885 input: files(config_target['TARGET_XML_FILES'].split()),
886 command: [feature_to_c, '@INPUT@'],
888 arch_srcs += gdbstub_xml
891 t = target_arch[arch].apply(config_target, strict: false)
892 arch_srcs += t.sources()
893 arch_deps += t.dependencies()
895 target_common = common_ss.apply(config_target, strict: false)
896 objects = common_all.extract_objects(target_common.sources())
897 deps = target_common.dependencies()
899 # TODO: Change to generator once obj-y goes away
900 config_target_h = custom_target(target + '-config-target.h',
901 input: meson.current_build_dir() / target / 'config-target.mak',
902 output: target + '-config-target.h',
904 command: [create_config, '@INPUT@'])
906 target_specific = specific_ss.apply(config_target, strict: false)
907 arch_srcs += target_specific.sources()
908 arch_deps += target_specific.dependencies()
910 lib = static_library('qemu-' + target,
911 sources: arch_srcs + [config_target_h] + genh,
913 include_directories: target_inc,
915 build_by_default: false,
918 if target.endswith('-softmmu')
920 'name': 'qemu-system-' + target_name,
922 'sources': files('softmmu/main.c'),
927 'name': 'qemu-system-' + target_name + 'w',
929 'sources': files('softmmu/main.c'),
933 if config_host.has_key('CONFIG_FUZZ')
934 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
936 'name': 'qemu-fuzz-' + target_name,
938 'sources': specific_fuzz.sources(),
939 'dependencies': specific_fuzz.dependencies(),
940 'link_depends': [files('tests/qtest/fuzz/fork_fuzz.ld')],
945 'name': 'qemu-' + target_name,
952 emulators += executable(exe['name'], exe['sources'],
955 dependencies: arch_deps + deps + exe['dependencies'],
956 objects: lib.extract_all_objects(recursive: true),
957 link_language: link_language,
958 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
959 link_args: link_args,
964 # Other build targets
966 if 'CONFIG_PLUGIN' in config_host
967 install_headers('include/qemu/qemu-plugin.h')
970 if 'CONFIG_GUEST_AGENT' in config_host
975 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
976 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
977 qemu_io = executable('qemu-io', files('qemu-io.c'),
978 dependencies: [block, qemuutil], install: true)
979 if targetos == 'linux' or targetos == 'sunos' or targetos.endswith('bsd')
980 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
981 dependencies: [block, qemuutil], install: true)
984 subdir('storage-daemon')
985 subdir('contrib/rdmacm-mux')
986 subdir('contrib/elf2dmp')
988 if 'CONFIG_XKBCOMMON' in config_host
989 executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c'),
990 dependencies: [qemuutil, xkbcommon], install: true)
993 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
994 dependencies: qemuutil,
997 if 'CONFIG_VHOST_USER' in config_host
998 subdir('contrib/libvhost-user')
999 subdir('contrib/vhost-user-blk')
1000 if 'CONFIG_LINUX' in config_host
1001 subdir('contrib/vhost-user-gpu')
1003 subdir('contrib/vhost-user-input')
1004 subdir('contrib/vhost-user-scsi')
1007 if targetos == 'linux'
1008 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
1009 dependencies: [qemuutil, libcap_ng],
1011 install_dir: get_option('libexecdir'))
1013 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
1014 dependencies: [authz, crypto, io, qom, qemuutil,
1015 libcap_ng, libudev, libmpathpersist],
1019 if 'CONFIG_IVSHMEM' in config_host
1020 subdir('contrib/ivshmem-client')
1021 subdir('contrib/ivshmem-server')
1030 summary_info += {'Install prefix': config_host['prefix']}
1031 summary_info += {'BIOS directory': config_host['qemu_datadir']}
1032 summary_info += {'firmware path': config_host['qemu_firmwarepath']}
1033 summary_info += {'binary directory': config_host['bindir']}
1034 summary_info += {'library directory': config_host['libdir']}
1035 summary_info += {'module directory': config_host['qemu_moddir']}
1036 summary_info += {'libexec directory': config_host['libexecdir']}
1037 summary_info += {'include directory': config_host['includedir']}
1038 summary_info += {'config directory': config_host['sysconfdir']}
1039 if targetos != 'windows'
1040 summary_info += {'local state directory': config_host['qemu_localstatedir']}
1041 summary_info += {'Manual directory': config_host['mandir']}
1043 summary_info += {'local state directory': 'queried at runtime'}
1045 summary_info += {'Build directory': meson.current_build_dir()}
1046 summary_info += {'Source path': meson.current_source_dir()}
1047 summary_info += {'GIT binary': config_host['GIT']}
1048 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
1049 summary_info += {'C compiler': meson.get_compiler('c').cmd_array()[0]}
1050 summary_info += {'Host C compiler': meson.get_compiler('c', native: true).cmd_array()[0]}
1051 if link_language == 'cpp'
1052 summary_info += {'C++ compiler': meson.get_compiler('cpp').cmd_array()[0]}
1054 summary_info += {'C++ compiler': false}
1056 if targetos == 'darwin'
1057 summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
1059 summary_info += {'ARFLAGS': config_host['ARFLAGS']}
1060 summary_info += {'CFLAGS': config_host['CFLAGS']}
1061 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
1062 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
1063 summary_info += {'make': config_host['MAKE']}
1064 summary_info += {'install': config_host['INSTALL']}
1065 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
1066 summary_info += {'sphinx-build': config_host['SPHINX_BUILD']}
1067 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
1068 # TODO: add back version
1069 summary_info += {'slirp support': config_host.has_key('CONFIG_SLIRP')}
1070 if config_host.has_key('CONFIG_SLIRP')
1071 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
1073 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
1074 if config_host.has_key('CONFIG_MODULES')
1075 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
1077 summary_info += {'host CPU': cpu}
1078 summary_info += {'host endianness': build_machine.endian()}
1079 summary_info += {'target list': config_host['TARGET_DIRS']}
1080 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
1081 summary_info += {'sparse enabled': meson.get_compiler('c').cmd_array().contains('cgcc')}
1082 summary_info += {'strip binaries': get_option('strip')}
1083 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
1084 summary_info += {'static build': config_host.has_key('CONFIG_TOOLS')}
1085 if targetos == 'darwin'
1086 summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
1088 # TODO: add back version
1089 summary_info += {'SDL support': config_host.has_key('CONFIG_SDL')}
1090 summary_info += {'SDL image support': config_host.has_key('CONFIG_SDL_IMAGE')}
1091 # TODO: add back version
1092 summary_info += {'GTK support': config_host.has_key('CONFIG_GTK')}
1093 summary_info += {'GTK GL support': config_host.has_key('CONFIG_GTK_GL')}
1094 # TODO: add back version
1095 summary_info += {'VTE support': config_host.has_key('CONFIG_VTE')}
1096 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
1097 summary_info += {'GNUTLS support': config_host.has_key('CONFIG_GNUTLS')}
1098 # TODO: add back version
1099 summary_info += {'libgcrypt': config_host.has_key('CONFIG_GCRYPT')}
1100 if config_host.has_key('CONFIG_GCRYPT')
1101 summary_info += {' hmac': config_host.has_key('CONFIG_GCRYPT_HMAC')}
1102 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1104 # TODO: add back version
1105 summary_info += {'nettle': config_host.has_key('CONFIG_NETTLE')}
1106 if config_host.has_key('CONFIG_NETTLE')
1107 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1109 summary_info += {'libtasn1': config_host.has_key('CONFIG_TASN1')}
1110 summary_info += {'PAM': config_host.has_key('CONFIG_AUTH_PAM')}
1111 summary_info += {'iconv support': config_host.has_key('CONFIG_ICONV')}
1112 summary_info += {'curses support': config_host.has_key('CONFIG_CURSES')}
1113 # TODO: add back version
1114 summary_info += {'virgl support': config_host.has_key('CONFIG_VIRGL')}
1115 summary_info += {'curl support': config_host.has_key('CONFIG_CURL')}
1116 summary_info += {'mingw32 support': targetos == 'windows'}
1117 summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']}
1118 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
1119 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
1120 summary_info += {'VirtFS support': config_host.has_key('CONFIG_VIRTFS')}
1121 summary_info += {'Multipath support': config_host.has_key('CONFIG_MPATH')}
1122 summary_info += {'VNC support': config_host.has_key('CONFIG_VNC')}
1123 if config_host.has_key('CONFIG_VNC')
1124 summary_info += {'VNC SASL support': config_host.has_key('CONFIG_VNC_SASL')}
1125 summary_info += {'VNC JPEG support': config_host.has_key('CONFIG_VNC_JPEG')}
1126 summary_info += {'VNC PNG support': config_host.has_key('CONFIG_VNC_PNG')}
1128 summary_info += {'xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
1129 if config_host.has_key('CONFIG_XEN_BACKEND')
1130 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
1132 summary_info += {'brlapi support': config_host.has_key('CONFIG_BRLAPI')}
1133 summary_info += {'Documentation': config_host.has_key('BUILD_DOCS')}
1134 summary_info += {'PIE': get_option('b_pie')}
1135 summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
1136 summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
1137 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
1138 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
1139 summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
1140 summary_info += {'Install blobs': config_host.has_key('INSTALL_BLOBS')}
1141 # TODO: add back KVM/HAX/HVF/WHPX/TCG
1142 #summary_info += {'KVM support': have_kvm'}
1143 #summary_info += {'HAX support': have_hax'}
1144 #summary_info += {'HVF support': have_hvf'}
1145 #summary_info += {'WHPX support': have_whpx'}
1146 #summary_info += {'TCG support': have_tcg'}
1147 #if get_option('tcg')
1148 # summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
1149 # summary_info += {'TCG interpreter': config_host.has_key('CONFIG_TCG_INTERPRETER')}
1151 summary_info += {'malloc trim support': config_host.has_key('CONFIG_MALLOC_TRIM')}
1152 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
1153 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
1154 summary_info += {'fdt support': config_host.has_key('CONFIG_FDT')}
1155 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
1156 summary_info += {'preadv support': config_host.has_key('CONFIG_PREADV')}
1157 summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')}
1158 summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')}
1159 summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')}
1160 summary_info += {'posix_memalign': config_host.has_key('CONFIG_POSIX_MEMALIGN')}
1161 summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
1162 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
1163 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
1164 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
1165 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
1166 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_KERNEL')}
1167 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
1168 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
1169 summary_info += {'Trace backends': config_host['TRACE_BACKENDS']}
1170 if config_host['TRACE_BACKENDS'].split().contains('simple')
1171 summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
1173 # TODO: add back protocol and server version
1174 summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')}
1175 summary_info += {'rbd support': config_host.has_key('CONFIG_RBD')}
1176 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
1177 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
1178 summary_info += {'libusb': config_host.has_key('CONFIG_USB_LIBUSB')}
1179 summary_info += {'usb net redir': config_host.has_key('CONFIG_USB_REDIR')}
1180 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
1181 summary_info += {'OpenGL dmabufs': config_host.has_key('CONFIG_OPENGL_DMABUF')}
1182 summary_info += {'libiscsi support': config_host.has_key('CONFIG_LIBISCSI')}
1183 summary_info += {'libnfs support': config_host.has_key('CONFIG_LIBNFS')}
1184 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
1185 if targetos == 'windows'
1186 if 'WIN_SDK' in config_host
1187 summary_info += {'Windows SDK': config_host['WIN_SDK']}
1189 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
1190 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
1191 summary_info += {'QGA MSI support': config_host.has_key('CONFIG_QGA_MSI_ENABLED')}
1193 summary_info += {'seccomp support': config_host.has_key('CONFIG_SECCOMP')}
1194 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
1195 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
1196 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
1197 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
1198 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
1199 summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
1200 summary_info += {'gcov': get_option('b_coverage')}
1201 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
1202 summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
1203 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
1204 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
1205 summary_info += {'lzo support': config_host.has_key('CONFIG_LZO')}
1206 summary_info += {'snappy support': config_host.has_key('CONFIG_SNAPPY')}
1207 summary_info += {'bzip2 support': config_host.has_key('CONFIG_BZIP2')}
1208 summary_info += {'lzfse support': config_host.has_key('CONFIG_LZFSE')}
1209 summary_info += {'zstd support': config_host.has_key('CONFIG_ZSTD')}
1210 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
1211 summary_info += {'libxml2': config_host.has_key('CONFIG_LIBXML2')}
1212 summary_info += {'tcmalloc support': config_host.has_key('CONFIG_TCMALLOC')}
1213 summary_info += {'jemalloc support': config_host.has_key('CONFIG_JEMALLOC')}
1214 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
1215 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
1216 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
1217 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
1218 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
1219 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
1220 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
1221 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
1222 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
1223 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
1224 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
1225 summary_info += {'sheepdog support': config_host.has_key('CONFIG_SHEEPDOG')}
1226 summary_info += {'capstone': config_host.has_key('CONFIG_CAPSTONE')}
1227 summary_info += {'libpmem support': config_host.has_key('CONFIG_LIBPMEM')}
1228 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
1229 summary_info += {'libudev': config_host.has_key('CONFIG_LIBUDEV')}
1230 summary_info += {'default devices': config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
1231 summary_info += {'plugin support': config_host.has_key('CONFIG_PLUGIN')}
1232 summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')}
1233 if config_host.has_key('HAVE_GDB_BIN')
1234 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
1236 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
1237 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
1238 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
1239 summary(summary_info, bool_yn: true)
1241 if not supported_cpus.contains(cpu)
1243 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
1245 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
1246 message('The QEMU project intends to remove support for this host CPU in')
1247 message('a future release if nobody volunteers to maintain it and to')
1248 message('provide a build host for our continuous integration setup.')
1249 message('configure has succeeded and you can continue to build, but')
1250 message('if you care about QEMU on this platform you should contact')
1251 message('us upstream at qemu-devel@nongnu.org.')
1254 if not supported_oses.contains(targetos)
1256 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
1258 message('Host OS ' + targetos + 'support is not currently maintained.')
1259 message('The QEMU project intends to remove support for this host OS in')
1260 message('a future release if nobody volunteers to maintain it and to')
1261 message('provide a build host for our continuous integration setup.')
1262 message('configure has succeeded and you can continue to build, but')
1263 message('if you care about QEMU on this platform you should contact')
1264 message('us upstream at qemu-devel@nongnu.org.')