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())
219 if 'CONFIG_SDL' in config_host
220 sdl = declare_dependency(compile_args: config_host['SDL_CFLAGS'].split(),
221 link_args: config_host['SDL_LIBS'].split())
224 if 'CONFIG_RBD' in config_host
225 rbd = declare_dependency(link_args: config_host['RBD_LIBS'].split())
227 glusterfs = not_found
228 if 'CONFIG_GLUSTERFS' in config_host
229 glusterfs = declare_dependency(compile_args: config_host['GLUSTERFS_CFLAGS'].split(),
230 link_args: config_host['GLUSTERFS_LIBS'].split())
233 if 'CONFIG_LIBSSH' in config_host
234 libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
235 link_args: config_host['LIBSSH_LIBS'].split())
238 if 'CONFIG_BZIP2' in config_host
239 libbzip2 = declare_dependency(link_args: config_host['BZIP2_LIBS'].split())
242 if 'CONFIG_LZFSE' in config_host
243 liblzfse = declare_dependency(link_args: config_host['LZFSE_LIBS'].split())
246 if 'CONFIG_AUDIO_OSS' in config_host
247 oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
250 if 'CONFIG_AUDIO_DSOUND' in config_host
251 dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
253 coreaudio = not_found
254 if 'CONFIG_AUDIO_COREAUDIO' in config_host
255 coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
258 if 'CONFIG_OPENGL' in config_host
259 opengl = declare_dependency(link_args: config_host['OPENGL_LIBS'].split())
263 if 'CONFIG_GTK' in config_host
264 gtk = declare_dependency(compile_args: config_host['GTK_CFLAGS'].split(),
265 link_args: config_host['GTK_LIBS'].split())
268 if 'CONFIG_VTE' in config_host
269 vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
270 link_args: config_host['VTE_LIBS'].split())
273 if 'CONFIG_X11' in config_host
274 x11 = declare_dependency(compile_args: config_host['X11_CFLAGS'].split(),
275 link_args: config_host['X11_LIBS'].split())
278 if 'CONFIG_CURSES' in config_host
279 curses = declare_dependency(compile_args: config_host['CURSES_CFLAGS'].split(),
280 link_args: config_host['CURSES_LIBS'].split())
283 if 'CONFIG_ICONV' in config_host
284 iconv = declare_dependency(compile_args: config_host['ICONV_CFLAGS'].split(),
285 link_args: config_host['ICONV_LIBS'].split())
288 if 'CONFIG_GIO' in config_host
289 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
290 link_args: config_host['GIO_LIBS'].split())
293 if 'CONFIG_VNC_PNG' in config_host
294 png = declare_dependency(compile_args: config_host['PNG_CFLAGS'].split(),
295 link_args: config_host['PNG_LIBS'].split())
298 if 'CONFIG_VNC_JPEG' in config_host
299 jpeg = declare_dependency(compile_args: config_host['JPEG_CFLAGS'].split(),
300 link_args: config_host['JPEG_LIBS'].split())
303 if 'CONFIG_VNC_SASL' in config_host
304 sasl = declare_dependency(compile_args: config_host['SASL_CFLAGS'].split(),
305 link_args: config_host['SASL_LIBS'].split())
308 if 'CONFIG_FDT' in config_host
309 fdt = declare_dependency(compile_args: config_host['FDT_CFLAGS'].split(),
310 link_args: config_host['FDT_LIBS'].split())
313 if 'CONFIG_SNAPPY' in config_host
314 snappy = declare_dependency(link_args: config_host['SNAPPY_LIBS'].split())
317 if 'CONFIG_LZO' in config_host
318 lzo = declare_dependency(link_args: config_host['LZO_LIBS'].split())
321 if 'CONFIG_RDMA' in config_host
322 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
325 if 'CONFIG_NUMA' in config_host
326 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
329 if 'CONFIG_XEN_BACKEND' in config_host
330 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
331 link_args: config_host['XEN_LIBS'].split())
334 if 'CONFIG_SMARTCARD' in config_host
335 cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
336 link_args: config_host['SMARTCARD_LIBS'].split())
339 if 'CONFIG_USB_REDIR' in config_host
340 usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
341 link_args: config_host['USB_REDIR_LIBS'].split())
344 if 'CONFIG_USB_LIBUSB' in config_host
345 libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
346 link_args: config_host['LIBUSB_LIBS'].split())
349 if 'CONFIG_CAPSTONE' in config_host
350 capstone = declare_dependency(compile_args: config_host['CAPSTONE_CFLAGS'].split(),
351 link_args: config_host['CAPSTONE_LIBS'].split())
354 if 'CONFIG_LIBPMEM' in config_host
355 libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
356 link_args: config_host['LIBPMEM_LIBS'].split())
359 create_config = find_program('scripts/create_config')
360 minikconf = find_program('scripts/minikconf.py')
361 target_dirs = config_host['TARGET_DIRS'].split()
364 config_devices_mak_list = []
365 config_devices_h = {}
366 config_target_mak = {}
367 kconfig_external_symbols = [
376 'CONFIG_VHOST_KERNEL',
381 foreach target : target_dirs
382 have_user = have_user or target.endswith('-user')
383 config_target = keyval.load(meson.current_build_dir() / target / 'config-target.mak') + config_host
385 if target.endswith('-softmmu')
389 foreach sym : kconfig_external_symbols
390 if sym in config_target
391 base_kconfig += '@0@=y'.format(sym)
395 config_devices_mak = target + '-config-devices.mak'
396 config_devices_mak = configure_file(
397 input: ['default-configs' / target + '.mak', 'Kconfig'],
398 output: config_devices_mak,
399 depfile: config_devices_mak + '.d',
401 command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'],
402 config_devices_mak, '@DEPFILE@', '@INPUT@',
404 config_devices_h += {target: custom_target(
405 target + '-config-devices.h',
406 input: config_devices_mak,
407 output: target + '-config-devices.h',
409 command: [create_config, '@INPUT@'])}
410 config_devices_mak_list += config_devices_mak
411 config_target += keyval.load(config_devices_mak)
413 config_target_mak += {target: config_target}
415 have_tools = 'CONFIG_TOOLS' in config_host
416 have_block = have_system or have_tools
418 grepy = find_program('scripts/grepy.sh')
419 # This configuration is used to build files that are shared by
420 # multiple binaries, and then extracted out of the "common"
421 # static_library target.
423 # We do not use all_sources()/all_dependencies(), because it would
424 # build literally all source files, including devices only used by
425 # targets that are not built for this compilation. The CONFIG_ALL
426 # pseudo symbol replaces it.
429 config_all_devices_mak = configure_file(
430 output: 'config-all-devices.mak',
431 input: config_devices_mak_list,
433 command: [grepy, '@INPUT@'],
435 config_all_devices = keyval.load(config_all_devices_mak)
437 config_all_devices = {}
439 config_all = config_all_devices
440 config_all += config_host
441 config_all += config_all_disas
443 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
444 'CONFIG_SOFTMMU': have_system,
445 'CONFIG_USER_ONLY': have_user,
452 hxtool = find_program('scripts/hxtool')
453 shaderinclude = find_program('scripts/shaderinclude.pl')
454 qapi_gen = find_program('scripts/qapi-gen.py')
455 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
456 meson.source_root() / 'scripts/qapi/commands.py',
457 meson.source_root() / 'scripts/qapi/common.py',
458 meson.source_root() / 'scripts/qapi/doc.py',
459 meson.source_root() / 'scripts/qapi/error.py',
460 meson.source_root() / 'scripts/qapi/events.py',
461 meson.source_root() / 'scripts/qapi/expr.py',
462 meson.source_root() / 'scripts/qapi/gen.py',
463 meson.source_root() / 'scripts/qapi/introspect.py',
464 meson.source_root() / 'scripts/qapi/parser.py',
465 meson.source_root() / 'scripts/qapi/schema.py',
466 meson.source_root() / 'scripts/qapi/source.py',
467 meson.source_root() / 'scripts/qapi/types.py',
468 meson.source_root() / 'scripts/qapi/visit.py',
469 meson.source_root() / 'scripts/qapi/common.py',
470 meson.source_root() / 'scripts/qapi/doc.py',
471 meson.source_root() / 'scripts/qapi-gen.py'
475 python, files('scripts/tracetool.py'),
476 '--backend=' + config_host['TRACE_BACKENDS']
479 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
480 meson.current_source_dir(),
481 config_host['PKGVERSION'], config_host['VERSION']]
482 qemu_version = custom_target('qemu-version.h',
483 output: 'qemu-version.h',
484 command: qemu_version_cmd,
486 build_by_default: true,
487 build_always_stale: true)
490 config_host_h = custom_target('config-host.h',
491 input: meson.current_build_dir() / 'config-host.mak',
492 output: 'config-host.h',
494 command: [create_config, '@INPUT@'])
495 genh += config_host_h
499 ['qemu-options.hx', 'qemu-options.def'],
500 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
504 ['hmp-commands.hx', 'hmp-commands.h'],
505 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
508 foreach d : hx_headers
509 hxdep += custom_target(d[1],
513 build_by_default: true, # to be removed when added to a target
514 command: [hxtool, '-h', '@INPUT0@'])
518 # Collect sourcesets.
520 util_ss = ss.source_set()
521 stub_ss = ss.source_set()
522 trace_ss = ss.source_set()
523 block_ss = ss.source_set()
524 blockdev_ss = ss.source_set()
525 qmp_ss = ss.source_set()
526 common_ss = ss.source_set()
527 softmmu_ss = ss.source_set()
528 user_ss = ss.source_set()
529 bsd_user_ss = ss.source_set()
530 linux_user_ss = ss.source_set()
531 specific_ss = ss.source_set()
536 target_softmmu_arch = {}
542 # TODO: add each directory to the subdirs from its own meson.build, once
544 trace_events_subdirs = [
551 trace_events_subdirs += [ 'linux-user' ]
554 trace_events_subdirs += [
563 trace_events_subdirs += [
574 'hw/block/dataplane',
619 trace_events_subdirs += [
646 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
647 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
650 # Build targets from sourcesets
652 stub_ss = stub_ss.apply(config_all, strict: false)
654 util_ss.add_all(trace_ss)
655 util_ss = util_ss.apply(config_all, strict: false)
656 libqemuutil = static_library('qemuutil',
657 sources: util_ss.sources() + stub_ss.sources() + genh,
658 dependencies: [util_ss.dependencies(), m, glib, socket])
659 qemuutil = declare_dependency(link_with: libqemuutil,
660 sources: genh + version_res)
662 decodetree = generator(find_program('scripts/decodetree.py'),
663 output: 'decode-@BASENAME@.c.inc',
664 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
670 subdir('libdecnumber')
680 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
686 blockdev_ss.add(files(
693 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
694 # os-win32.c does not
695 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
696 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
698 softmmu_ss.add_all(blockdev_ss)
699 softmmu_ss.add(files(
705 softmmu_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c'))
706 softmmu_ss.add(when: 'CONFIG_SECCOMP', if_true: [files('qemu-seccomp.c'), seccomp])
707 softmmu_ss.add(when: ['CONFIG_FDT', fdt], if_true: [files('device_tree.c')])
709 common_ss.add(files('cpus-common.c'))
713 specific_ss.add(files('disas.c', 'exec.c', 'gdbstub.c'), capstone, libpmem)
714 specific_ss.add(files('exec-vary.c'))
715 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
724 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
738 bsd_user_ss.add(files('gdbstub.c'))
739 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
741 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
742 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
744 # needed for fuzzing binaries
745 subdir('tests/qtest/libqos')
749 foreach d, list : modules
750 foreach m, module_ss : list
751 if enable_modules and targetos != 'windows'
752 module_ss = module_ss.apply(config_host, strict: false)
753 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
754 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
762 block_ss.add_all(module_ss)
764 softmmu_ss.add_all(module_ss)
770 nm = find_program('nm')
771 undefsym = find_program('scripts/undefsym.sh')
772 block_syms = custom_target('block.syms', output: 'block.syms',
773 input: [libqemuutil, block_mods],
775 command: [undefsym, nm, '@INPUT@'])
776 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
777 input: [libqemuutil, softmmu_mods],
779 command: [undefsym, nm, '@INPUT@'])
781 block_ss = block_ss.apply(config_host, strict: false)
782 libblock = static_library('block', block_ss.sources() + genh,
783 dependencies: block_ss.dependencies(),
784 link_depends: block_syms,
786 build_by_default: false)
788 block = declare_dependency(link_whole: [libblock],
789 link_args: '@block.syms',
790 dependencies: [crypto, io])
792 qmp_ss = qmp_ss.apply(config_host, strict: false)
793 libqmp = static_library('qmp', qmp_ss.sources() + genh,
794 dependencies: qmp_ss.dependencies(),
796 build_by_default: false)
798 qmp = declare_dependency(link_whole: [libqmp])
800 foreach m : block_mods + softmmu_mods
801 shared_module(m.name(),
805 install_dir: config_host['qemu_moddir'])
808 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: softmmu_ss)
809 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
811 common_all = common_ss.apply(config_all, strict: false)
812 common_all = static_library('common',
813 build_by_default: false,
814 sources: common_all.sources() + genh,
815 dependencies: common_all.dependencies(),
818 feature_to_c = find_program('scripts/feature_to_c.sh')
820 foreach target : target_dirs
821 config_target = config_target_mak[target]
822 target_name = config_target['TARGET_NAME']
823 arch = config_target['TARGET_BASE_ARCH']
826 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
827 if targetos == 'linux'
828 target_inc += include_directories('linux-headers', is_system: true)
830 if target.endswith('-softmmu')
831 qemu_target_name = 'qemu-system-' + target_name
833 t = target_softmmu_arch[arch].apply(config_target, strict: false)
834 arch_srcs += t.sources()
836 hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
837 hw = hw_arch[hw_dir].apply(config_target, strict: false)
838 arch_srcs += hw.sources()
840 arch_srcs += config_devices_h[target]
842 abi = config_target['TARGET_ABI_DIR']
844 qemu_target_name = 'qemu-' + target_name
845 if 'CONFIG_LINUX_USER' in config_target
846 base_dir = 'linux-user'
847 target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
849 base_dir = 'bsd-user'
851 target_inc += include_directories(
855 if 'CONFIG_LINUX_USER' in config_target
857 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
858 if config_target.has_key('TARGET_SYSTBL_ABI')
860 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
861 extra_args : config_target['TARGET_SYSTBL_ABI'])
866 if 'TARGET_XML_FILES' in config_target
867 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
868 output: target + '-gdbstub-xml.c',
869 input: files(config_target['TARGET_XML_FILES'].split()),
870 command: [feature_to_c, '@INPUT@'],
872 arch_srcs += gdbstub_xml
875 t = target_arch[arch].apply(config_target, strict: false)
876 arch_srcs += t.sources()
878 target_common = common_ss.apply(config_target, strict: false)
879 objects = common_all.extract_objects(target_common.sources())
881 # TODO: Change to generator once obj-y goes away
882 config_target_h = custom_target(target + '-config-target.h',
883 input: meson.current_build_dir() / target / 'config-target.mak',
884 output: target + '-config-target.h',
886 command: [create_config, '@INPUT@'])
888 target_specific = specific_ss.apply(config_target, strict: false)
889 arch_srcs += target_specific.sources()
891 static_library('qemu-' + target,
892 sources: arch_srcs + [config_target_h] + genh,
894 include_directories: target_inc,
895 c_args: ['-DNEED_CPU_H',
896 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
897 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)],
901 # Other build targets
903 if 'CONFIG_PLUGIN' in config_host
904 install_headers('include/qemu/qemu-plugin.h')
907 if 'CONFIG_GUEST_AGENT' in config_host
912 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
913 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
914 qemu_io = executable('qemu-io', files('qemu-io.c'),
915 dependencies: [block, qemuutil], install: true)
916 if targetos == 'linux' or targetos == 'sunos' or targetos.endswith('bsd')
917 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
918 dependencies: [block, qemuutil], install: true)
921 subdir('storage-daemon')
922 subdir('contrib/rdmacm-mux')
923 subdir('contrib/elf2dmp')
925 if 'CONFIG_XKBCOMMON' in config_host
926 executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c'),
927 dependencies: [qemuutil, xkbcommon], install: true)
930 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
931 dependencies: qemuutil,
934 if 'CONFIG_VHOST_USER' in config_host
935 subdir('contrib/libvhost-user')
936 subdir('contrib/vhost-user-blk')
937 if 'CONFIG_LINUX' in config_host
938 subdir('contrib/vhost-user-gpu')
940 subdir('contrib/vhost-user-input')
941 subdir('contrib/vhost-user-scsi')
944 if targetos == 'linux'
945 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
946 dependencies: [qemuutil, libcap_ng],
948 install_dir: get_option('libexecdir'))
950 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
951 dependencies: [authz, crypto, io, qom, qemuutil,
952 libcap_ng, libudev, libmpathpersist],
956 if 'CONFIG_IVSHMEM' in config_host
957 subdir('contrib/ivshmem-client')
958 subdir('contrib/ivshmem-server')
967 summary_info += {'Install prefix': config_host['prefix']}
968 summary_info += {'BIOS directory': config_host['qemu_datadir']}
969 summary_info += {'firmware path': config_host['qemu_firmwarepath']}
970 summary_info += {'binary directory': config_host['bindir']}
971 summary_info += {'library directory': config_host['libdir']}
972 summary_info += {'module directory': config_host['qemu_moddir']}
973 summary_info += {'libexec directory': config_host['libexecdir']}
974 summary_info += {'include directory': config_host['includedir']}
975 summary_info += {'config directory': config_host['sysconfdir']}
976 if targetos != 'windows'
977 summary_info += {'local state directory': config_host['qemu_localstatedir']}
978 summary_info += {'Manual directory': config_host['mandir']}
980 summary_info += {'local state directory': 'queried at runtime'}
982 summary_info += {'Build directory': meson.current_build_dir()}
983 summary_info += {'Source path': meson.current_source_dir()}
984 summary_info += {'GIT binary': config_host['GIT']}
985 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
986 summary_info += {'C compiler': meson.get_compiler('c').cmd_array()[0]}
987 summary_info += {'Host C compiler': meson.get_compiler('c', native: true).cmd_array()[0]}
988 if link_language == 'cpp'
989 summary_info += {'C++ compiler': meson.get_compiler('cpp').cmd_array()[0]}
991 summary_info += {'C++ compiler': false}
993 if targetos == 'darwin'
994 summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
996 summary_info += {'ARFLAGS': config_host['ARFLAGS']}
997 summary_info += {'CFLAGS': config_host['CFLAGS']}
998 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
999 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
1000 summary_info += {'make': config_host['MAKE']}
1001 summary_info += {'install': config_host['INSTALL']}
1002 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
1003 summary_info += {'sphinx-build': config_host['SPHINX_BUILD']}
1004 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
1005 # TODO: add back version
1006 summary_info += {'slirp support': config_host.has_key('CONFIG_SLIRP')}
1007 if config_host.has_key('CONFIG_SLIRP')
1008 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
1010 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
1011 if config_host.has_key('CONFIG_MODULES')
1012 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
1014 summary_info += {'host CPU': cpu}
1015 summary_info += {'host endianness': build_machine.endian()}
1016 summary_info += {'target list': config_host['TARGET_DIRS']}
1017 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
1018 summary_info += {'sparse enabled': meson.get_compiler('c').cmd_array().contains('cgcc')}
1019 summary_info += {'strip binaries': get_option('strip')}
1020 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
1021 summary_info += {'static build': config_host.has_key('CONFIG_TOOLS')}
1022 if targetos == 'darwin'
1023 summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
1025 # TODO: add back version
1026 summary_info += {'SDL support': config_host.has_key('CONFIG_SDL')}
1027 summary_info += {'SDL image support': config_host.has_key('CONFIG_SDL_IMAGE')}
1028 # TODO: add back version
1029 summary_info += {'GTK support': config_host.has_key('CONFIG_GTK')}
1030 summary_info += {'GTK GL support': config_host.has_key('CONFIG_GTK_GL')}
1031 # TODO: add back version
1032 summary_info += {'VTE support': config_host.has_key('CONFIG_VTE')}
1033 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
1034 summary_info += {'GNUTLS support': config_host.has_key('CONFIG_GNUTLS')}
1035 # TODO: add back version
1036 summary_info += {'libgcrypt': config_host.has_key('CONFIG_GCRYPT')}
1037 if config_host.has_key('CONFIG_GCRYPT')
1038 summary_info += {' hmac': config_host.has_key('CONFIG_GCRYPT_HMAC')}
1039 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1041 # TODO: add back version
1042 summary_info += {'nettle': config_host.has_key('CONFIG_NETTLE')}
1043 if config_host.has_key('CONFIG_NETTLE')
1044 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1046 summary_info += {'libtasn1': config_host.has_key('CONFIG_TASN1')}
1047 summary_info += {'PAM': config_host.has_key('CONFIG_AUTH_PAM')}
1048 summary_info += {'iconv support': config_host.has_key('CONFIG_ICONV')}
1049 summary_info += {'curses support': config_host.has_key('CONFIG_CURSES')}
1050 # TODO: add back version
1051 summary_info += {'virgl support': config_host.has_key('CONFIG_VIRGL')}
1052 summary_info += {'curl support': config_host.has_key('CONFIG_CURL')}
1053 summary_info += {'mingw32 support': targetos == 'windows'}
1054 summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']}
1055 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
1056 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
1057 summary_info += {'VirtFS support': config_host.has_key('CONFIG_VIRTFS')}
1058 summary_info += {'Multipath support': config_host.has_key('CONFIG_MPATH')}
1059 summary_info += {'VNC support': config_host.has_key('CONFIG_VNC')}
1060 if config_host.has_key('CONFIG_VNC')
1061 summary_info += {'VNC SASL support': config_host.has_key('CONFIG_VNC_SASL')}
1062 summary_info += {'VNC JPEG support': config_host.has_key('CONFIG_VNC_JPEG')}
1063 summary_info += {'VNC PNG support': config_host.has_key('CONFIG_VNC_PNG')}
1065 summary_info += {'xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
1066 if config_host.has_key('CONFIG_XEN_BACKEND')
1067 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
1069 summary_info += {'brlapi support': config_host.has_key('CONFIG_BRLAPI')}
1070 summary_info += {'Documentation': config_host.has_key('BUILD_DOCS')}
1071 summary_info += {'PIE': get_option('b_pie')}
1072 summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
1073 summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
1074 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
1075 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
1076 summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
1077 summary_info += {'Install blobs': config_host.has_key('INSTALL_BLOBS')}
1078 # TODO: add back KVM/HAX/HVF/WHPX/TCG
1079 #summary_info += {'KVM support': have_kvm'}
1080 #summary_info += {'HAX support': have_hax'}
1081 #summary_info += {'HVF support': have_hvf'}
1082 #summary_info += {'WHPX support': have_whpx'}
1083 #summary_info += {'TCG support': have_tcg'}
1084 #if get_option('tcg')
1085 # summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
1086 # summary_info += {'TCG interpreter': config_host.has_key('CONFIG_TCG_INTERPRETER')}
1088 summary_info += {'malloc trim support': config_host.has_key('CONFIG_MALLOC_TRIM')}
1089 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
1090 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
1091 summary_info += {'fdt support': config_host.has_key('CONFIG_FDT')}
1092 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
1093 summary_info += {'preadv support': config_host.has_key('CONFIG_PREADV')}
1094 summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')}
1095 summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')}
1096 summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')}
1097 summary_info += {'posix_memalign': config_host.has_key('CONFIG_POSIX_MEMALIGN')}
1098 summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
1099 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
1100 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
1101 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
1102 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
1103 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_KERNEL')}
1104 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
1105 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
1106 summary_info += {'Trace backends': config_host['TRACE_BACKENDS']}
1107 if config_host['TRACE_BACKENDS'].split().contains('simple')
1108 summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
1110 # TODO: add back protocol and server version
1111 summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')}
1112 summary_info += {'rbd support': config_host.has_key('CONFIG_RBD')}
1113 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
1114 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
1115 summary_info += {'libusb': config_host.has_key('CONFIG_USB_LIBUSB')}
1116 summary_info += {'usb net redir': config_host.has_key('CONFIG_USB_REDIR')}
1117 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
1118 summary_info += {'OpenGL dmabufs': config_host.has_key('CONFIG_OPENGL_DMABUF')}
1119 summary_info += {'libiscsi support': config_host.has_key('CONFIG_LIBISCSI')}
1120 summary_info += {'libnfs support': config_host.has_key('CONFIG_LIBNFS')}
1121 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
1122 if targetos == 'windows'
1123 if 'WIN_SDK' in config_host
1124 summary_info += {'Windows SDK': config_host['WIN_SDK']}
1126 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
1127 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
1128 summary_info += {'QGA MSI support': config_host.has_key('CONFIG_QGA_MSI_ENABLED')}
1130 summary_info += {'seccomp support': config_host.has_key('CONFIG_SECCOMP')}
1131 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
1132 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
1133 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
1134 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
1135 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
1136 summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
1137 summary_info += {'gcov': get_option('b_coverage')}
1138 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
1139 summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
1140 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
1141 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
1142 summary_info += {'lzo support': config_host.has_key('CONFIG_LZO')}
1143 summary_info += {'snappy support': config_host.has_key('CONFIG_SNAPPY')}
1144 summary_info += {'bzip2 support': config_host.has_key('CONFIG_BZIP2')}
1145 summary_info += {'lzfse support': config_host.has_key('CONFIG_LZFSE')}
1146 summary_info += {'zstd support': config_host.has_key('CONFIG_ZSTD')}
1147 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
1148 summary_info += {'libxml2': config_host.has_key('CONFIG_LIBXML2')}
1149 summary_info += {'tcmalloc support': config_host.has_key('CONFIG_TCMALLOC')}
1150 summary_info += {'jemalloc support': config_host.has_key('CONFIG_JEMALLOC')}
1151 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
1152 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
1153 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
1154 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
1155 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
1156 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
1157 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
1158 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
1159 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
1160 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
1161 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
1162 summary_info += {'sheepdog support': config_host.has_key('CONFIG_SHEEPDOG')}
1163 summary_info += {'capstone': config_host.has_key('CONFIG_CAPSTONE')}
1164 summary_info += {'libpmem support': config_host.has_key('CONFIG_LIBPMEM')}
1165 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
1166 summary_info += {'libudev': config_host.has_key('CONFIG_LIBUDEV')}
1167 summary_info += {'default devices': config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
1168 summary_info += {'plugin support': config_host.has_key('CONFIG_PLUGIN')}
1169 summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')}
1170 if config_host.has_key('HAVE_GDB_BIN')
1171 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
1173 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
1174 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
1175 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
1176 summary(summary_info, bool_yn: true)
1178 if not supported_cpus.contains(cpu)
1180 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
1182 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
1183 message('The QEMU project intends to remove support for this host CPU in')
1184 message('a future release if nobody volunteers to maintain it and to')
1185 message('provide a build host for our continuous integration setup.')
1186 message('configure has succeeded and you can continue to build, but')
1187 message('if you care about QEMU on this platform you should contact')
1188 message('us upstream at qemu-devel@nongnu.org.')
1191 if not supported_oses.contains(targetos)
1193 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
1195 message('Host OS ' + targetos + 'support is not currently maintained.')
1196 message('The QEMU project intends to remove support for this host OS in')
1197 message('a future release if nobody volunteers to maintain it and to')
1198 message('provide a build host for our continuous integration setup.')
1199 message('configure has succeeded and you can continue to build, but')
1200 message('if you care about QEMU on this platform you should contact')
1201 message('us upstream at qemu-devel@nongnu.org.')