meson: convert check-block
[qemu.git] / meson.build
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())
4
5 not_found = dependency('', required: false)
6 keyval = import('unstable-keyval')
7 ss = import('sourceset')
8
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
14 build_docs = 'BUILD_DOCS' in config_host
15
16 add_project_arguments(config_host['QEMU_CFLAGS'].split(),
17                       native: false, language: ['c', 'objc'])
18 add_project_arguments(config_host['QEMU_CXXFLAGS'].split(),
19                       native: false, language: 'cpp')
20 add_project_link_arguments(config_host['QEMU_LDFLAGS'].split(),
21                            native: false, language: ['c', 'cpp', 'objc'])
22 add_project_arguments(config_host['QEMU_INCLUDES'].split(),
23                       language: ['c', 'cpp', 'objc'])
24
25 python = import('python').find_installation()
26
27 link_language = meson.get_external_property('link_language', 'cpp')
28 if link_language == 'cpp'
29   add_languages('cpp', required: true, native: false)
30 endif
31 if host_machine.system() == 'darwin'
32   add_languages('objc', required: false, native: false)
33 endif
34
35 if 'SPARSE_CFLAGS' in config_host
36   run_target('sparse',
37              command: [find_program('scripts/check_sparse.py'),
38                        config_host['SPARSE_CFLAGS'].split(),
39                        'compile_commands.json'])
40 endif
41
42 configure_file(input: files('scripts/ninjatool.py'),
43                output: 'ninjatool',
44                configuration: config_host)
45
46 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
47 supported_cpus = ['ppc', 'ppc64', 's390x', 'sparc64', 'riscv32', 'riscv64', 'x86', 'x86_64',
48   'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
49
50 cpu = host_machine.cpu_family()
51 targetos = host_machine.system()
52
53 m = cc.find_library('m', required: false)
54 util = cc.find_library('util', required: false)
55 winmm = []
56 socket = []
57 version_res = []
58 coref = []
59 iokit = []
60 cocoa = []
61 hvf = []
62 if targetos == 'windows'
63   socket = cc.find_library('ws2_32')
64   winmm = cc.find_library('winmm')
65
66   win = import('windows')
67   version_res = win.compile_resources('version.rc',
68                                       depend_files: files('pc-bios/qemu-nsis.ico'),
69                                       include_directories: include_directories('.'))
70 elif targetos == 'darwin'
71   coref = dependency('appleframeworks', modules: 'CoreFoundation')
72   iokit = dependency('appleframeworks', modules: 'IOKit')
73   cocoa = dependency('appleframeworks', modules: 'Cocoa')
74   hvf = dependency('appleframeworks', modules: 'Hypervisor')
75 elif targetos == 'sunos'
76   socket = [cc.find_library('socket'),
77             cc.find_library('nsl'),
78             cc.find_library('resolv')]
79 elif targetos == 'haiku'
80   socket = [cc.find_library('posix_error_mapper'),
81             cc.find_library('network'),
82             cc.find_library('bsd')]
83 endif
84 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
85                           link_args: config_host['GLIB_LIBS'].split())
86 gio = not_found
87 if 'CONFIG_GIO' in config_host
88   gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
89                            link_args: config_host['GIO_LIBS'].split())
90 endif
91 lttng = not_found
92 if 'CONFIG_TRACE_UST' in config_host
93   lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
94 endif
95 urcubp = not_found
96 if 'CONFIG_TRACE_UST' in config_host
97   urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
98 endif
99 nettle = not_found
100 if 'CONFIG_NETTLE' in config_host
101   nettle = declare_dependency(compile_args: config_host['NETTLE_CFLAGS'].split(),
102                               link_args: config_host['NETTLE_LIBS'].split())
103 endif
104 gnutls = not_found
105 if 'CONFIG_GNUTLS' in config_host
106   gnutls = declare_dependency(compile_args: config_host['GNUTLS_CFLAGS'].split(),
107                               link_args: config_host['GNUTLS_LIBS'].split())
108 endif
109 pixman = declare_dependency(compile_args: config_host['PIXMAN_CFLAGS'].split(),
110                             link_args: config_host['PIXMAN_LIBS'].split())
111 pam = not_found
112 if 'CONFIG_AUTH_PAM' in config_host
113   pam = cc.find_library('pam')
114 endif
115 libaio = cc.find_library('aio', required: false)
116 zlib = not_found
117 if 'CONFIG_ZLIB' in config_host
118   zlib = declare_dependency(compile_args: config_host['ZLIB_CFLAGS'].split(),
119                             link_args: config_host['ZLIB_LIBS'].split())
120 endif
121 linux_io_uring = not_found
122 if 'CONFIG_LINUX_IO_URING' in config_host
123   linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
124                                       link_args: config_host['LINUX_IO_URING_LIBS'].split())
125 endif
126 libxml2 = not_found
127 if 'CONFIG_LIBXML2' in config_host
128   libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
129                                link_args: config_host['LIBXML2_LIBS'].split())
130 endif
131 libnfs = not_found
132 if 'CONFIG_LIBNFS' in config_host
133   libnfs = declare_dependency(link_args: config_host['LIBNFS_LIBS'].split())
134 endif
135 libattr = not_found
136 if 'CONFIG_ATTR' in config_host
137   libattr = declare_dependency(link_args: config_host['LIBATTR_LIBS'].split())
138 endif
139 seccomp = not_found
140 if 'CONFIG_SECCOMP' in config_host
141   seccomp = declare_dependency(compile_args: config_host['SECCOMP_CFLAGS'].split(),
142                                link_args: config_host['SECCOMP_LIBS'].split())
143 endif
144 libcap_ng = not_found
145 if 'CONFIG_LIBCAP_NG' in config_host
146   libcap_ng = declare_dependency(link_args: config_host['LIBCAP_NG_LIBS'].split())
147 endif
148 xkbcommon = not_found
149 if 'CONFIG_XKBCOMMON' in config_host
150   xkbcommon = declare_dependency(compile_args: config_host['XKBCOMMON_CFLAGS'].split(),
151                                  link_args: config_host['XKBCOMMON_LIBS'].split())
152 endif
153 slirp = not_found
154 if config_host.has_key('CONFIG_SLIRP')
155   slirp = declare_dependency(compile_args: config_host['SLIRP_CFLAGS'].split(),
156                              link_args: config_host['SLIRP_LIBS'].split())
157 endif
158 vde = not_found
159 if config_host.has_key('CONFIG_VDE')
160   vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
161 endif
162 pulse = not_found
163 if 'CONFIG_LIBPULSE' in config_host
164   pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
165                              link_args: config_host['PULSE_LIBS'].split())
166 endif
167 alsa = not_found
168 if 'CONFIG_ALSA' in config_host
169   alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
170                             link_args: config_host['ALSA_LIBS'].split())
171 endif
172 jack = not_found
173 if 'CONFIG_LIBJACK' in config_host
174   jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
175 endif
176 spice = not_found
177 if 'CONFIG_SPICE' in config_host
178   spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
179                              link_args: config_host['SPICE_LIBS'].split())
180 endif
181 rt = cc.find_library('rt', required: false)
182 libmpathpersist = not_found
183 if config_host.has_key('CONFIG_MPATH')
184   libmpathpersist = cc.find_library('mpathpersist')
185 endif
186 libiscsi = not_found
187 if 'CONFIG_LIBISCSI' in config_host
188   libiscsi = declare_dependency(compile_args: config_host['LIBISCSI_CFLAGS'].split(),
189                                 link_args: config_host['LIBISCSI_LIBS'].split())
190 endif
191 zstd = not_found
192 if 'CONFIG_ZSTD' in config_host
193   zstd = declare_dependency(compile_args: config_host['ZSTD_CFLAGS'].split(),
194                             link_args: config_host['ZSTD_LIBS'].split())
195 endif
196 gbm = not_found
197 if 'CONFIG_GBM' in config_host
198   gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
199                            link_args: config_host['GBM_LIBS'].split())
200 endif
201 virgl = not_found
202 if 'CONFIG_VIRGL' in config_host
203   virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
204                              link_args: config_host['VIRGL_LIBS'].split())
205 endif
206 curl = not_found
207 if 'CONFIG_CURL' in config_host
208   curl = declare_dependency(compile_args: config_host['CURL_CFLAGS'].split(),
209                             link_args: config_host['CURL_LIBS'].split())
210 endif
211 libudev = not_found
212 if 'CONFIG_LIBUDEV' in config_host
213   libudev = declare_dependency(link_args: config_host['LIBUDEV_LIBS'].split())
214 endif
215 brlapi = not_found
216 if 'CONFIG_BRLAPI' in config_host
217   brlapi = declare_dependency(link_args: config_host['BRLAPI_LIBS'].split())
218 endif
219 sdlwindows = false
220 sdl = not_found
221 if 'CONFIG_SDL' in config_host
222   sdl = declare_dependency(compile_args: config_host['SDL_CFLAGS'].split(),
223                            link_args: config_host['SDL_LIBS'].split())
224   sdlwindows = config_host['SDL_LIBS'].contains('-mwindows')
225 endif
226 rbd = not_found
227 if 'CONFIG_RBD' in config_host
228   rbd = declare_dependency(link_args: config_host['RBD_LIBS'].split())
229 endif
230 glusterfs = not_found
231 if 'CONFIG_GLUSTERFS' in config_host
232   glusterfs = declare_dependency(compile_args: config_host['GLUSTERFS_CFLAGS'].split(),
233                                  link_args: config_host['GLUSTERFS_LIBS'].split())
234 endif
235 libssh = not_found
236 if 'CONFIG_LIBSSH' in config_host
237   libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
238                               link_args: config_host['LIBSSH_LIBS'].split())
239 endif
240 libbzip2 = not_found
241 if 'CONFIG_BZIP2' in config_host
242   libbzip2 = declare_dependency(link_args: config_host['BZIP2_LIBS'].split())
243 endif
244 liblzfse = not_found
245 if 'CONFIG_LZFSE' in config_host
246   liblzfse = declare_dependency(link_args: config_host['LZFSE_LIBS'].split())
247 endif
248 oss = not_found
249 if 'CONFIG_AUDIO_OSS' in config_host
250   oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
251 endif
252 dsound = not_found
253 if 'CONFIG_AUDIO_DSOUND' in config_host
254   dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
255 endif
256 coreaudio = not_found
257 if 'CONFIG_AUDIO_COREAUDIO' in config_host
258   coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
259 endif
260 opengl = not_found
261 if 'CONFIG_OPENGL' in config_host
262   opengl = declare_dependency(link_args: config_host['OPENGL_LIBS'].split())
263 else
264 endif
265 gtk = not_found
266 if 'CONFIG_GTK' in config_host
267   gtk = declare_dependency(compile_args: config_host['GTK_CFLAGS'].split(),
268                               link_args: config_host['GTK_LIBS'].split())
269 endif
270 vte = not_found
271 if 'CONFIG_VTE' in config_host
272   vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
273                            link_args: config_host['VTE_LIBS'].split())
274 endif
275 x11 = not_found
276 if 'CONFIG_X11' in config_host
277   x11 = declare_dependency(compile_args: config_host['X11_CFLAGS'].split(),
278                            link_args: config_host['X11_LIBS'].split())
279 endif
280 curses = not_found
281 if 'CONFIG_CURSES' in config_host
282   curses = declare_dependency(compile_args: config_host['CURSES_CFLAGS'].split(),
283                               link_args: config_host['CURSES_LIBS'].split())
284 endif
285 iconv = not_found
286 if 'CONFIG_ICONV' in config_host
287   iconv = declare_dependency(compile_args: config_host['ICONV_CFLAGS'].split(),
288                              link_args: config_host['ICONV_LIBS'].split())
289 endif
290 gio = not_found
291 if 'CONFIG_GIO' in config_host
292   gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
293                            link_args: config_host['GIO_LIBS'].split())
294 endif
295 png = not_found
296 if 'CONFIG_VNC_PNG' in config_host
297   png = declare_dependency(compile_args: config_host['PNG_CFLAGS'].split(),
298                            link_args: config_host['PNG_LIBS'].split())
299 endif
300 jpeg = not_found
301 if 'CONFIG_VNC_JPEG' in config_host
302   jpeg = declare_dependency(compile_args: config_host['JPEG_CFLAGS'].split(),
303                             link_args: config_host['JPEG_LIBS'].split())
304 endif
305 sasl = not_found
306 if 'CONFIG_VNC_SASL' in config_host
307   sasl = declare_dependency(compile_args: config_host['SASL_CFLAGS'].split(),
308                             link_args: config_host['SASL_LIBS'].split())
309 endif
310 fdt = not_found
311 if 'CONFIG_FDT' in config_host
312   fdt = declare_dependency(compile_args: config_host['FDT_CFLAGS'].split(),
313                            link_args: config_host['FDT_LIBS'].split())
314 endif
315 snappy = not_found
316 if 'CONFIG_SNAPPY' in config_host
317   snappy = declare_dependency(link_args: config_host['SNAPPY_LIBS'].split())
318 endif
319 lzo = not_found
320 if 'CONFIG_LZO' in config_host
321   lzo = declare_dependency(link_args: config_host['LZO_LIBS'].split())
322 endif
323 rdma = not_found
324 if 'CONFIG_RDMA' in config_host
325   rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
326 endif
327 numa = not_found
328 if 'CONFIG_NUMA' in config_host
329   numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
330 endif
331 xen = not_found
332 if 'CONFIG_XEN_BACKEND' in config_host
333   xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
334                            link_args: config_host['XEN_LIBS'].split())
335 endif
336 cacard = not_found
337 if 'CONFIG_SMARTCARD' in config_host
338   cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
339                               link_args: config_host['SMARTCARD_LIBS'].split())
340 endif
341 usbredir = not_found
342 if 'CONFIG_USB_REDIR' in config_host
343   usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
344                                 link_args: config_host['USB_REDIR_LIBS'].split())
345 endif
346 libusb = not_found
347 if 'CONFIG_USB_LIBUSB' in config_host
348   libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
349                               link_args: config_host['LIBUSB_LIBS'].split())
350 endif
351 capstone = not_found
352 if 'CONFIG_CAPSTONE' in config_host
353   capstone = declare_dependency(compile_args: config_host['CAPSTONE_CFLAGS'].split(),
354                                 link_args: config_host['CAPSTONE_LIBS'].split())
355 endif
356 libpmem = not_found
357 if 'CONFIG_LIBPMEM' in config_host
358   libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
359                                link_args: config_host['LIBPMEM_LIBS'].split())
360 endif
361
362 create_config = find_program('scripts/create_config')
363 minikconf = find_program('scripts/minikconf.py')
364 target_dirs = config_host['TARGET_DIRS'].split()
365 have_user = false
366 have_system = false
367 config_devices_mak_list = []
368 config_devices_h = {}
369 config_target_mak = {}
370 kconfig_external_symbols = [
371   'CONFIG_KVM',
372   'CONFIG_XEN',
373   'CONFIG_TPM',
374   'CONFIG_SPICE',
375   'CONFIG_IVSHMEM',
376   'CONFIG_OPENGL',
377   'CONFIG_X11',
378   'CONFIG_VHOST_USER',
379   'CONFIG_VHOST_KERNEL',
380   'CONFIG_VIRTFS',
381   'CONFIG_LINUX',
382   'CONFIG_PVRDMA',
383 ]
384 foreach target : target_dirs
385   have_user = have_user or target.endswith('-user')
386   config_target = keyval.load(meson.current_build_dir() / target / 'config-target.mak') + config_host
387
388   if target.endswith('-softmmu')
389     have_system = true
390
391     base_kconfig = []
392     foreach sym : kconfig_external_symbols
393       if sym in config_target
394         base_kconfig += '@0@=y'.format(sym)
395       endif
396     endforeach
397
398     config_devices_mak = target + '-config-devices.mak'
399     config_devices_mak = configure_file(
400       input: ['default-configs' / target + '.mak', 'Kconfig'],
401       output: config_devices_mak,
402       depfile: config_devices_mak + '.d',
403       capture: true,
404       command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'],
405                 config_devices_mak, '@DEPFILE@', '@INPUT@',
406                 base_kconfig])
407     config_devices_h += {target: custom_target(
408       target + '-config-devices.h',
409       input: config_devices_mak,
410       output: target + '-config-devices.h',
411       capture: true,
412       command: [create_config, '@INPUT@'])}
413     config_devices_mak_list += config_devices_mak
414     config_target += keyval.load(config_devices_mak)
415   endif
416   config_target_mak += {target: config_target}
417 endforeach
418 have_tools = 'CONFIG_TOOLS' in config_host
419 have_block = have_system or have_tools
420
421 grepy = find_program('scripts/grepy.sh')
422 # This configuration is used to build files that are shared by
423 # multiple binaries, and then extracted out of the "common"
424 # static_library target.
425 #
426 # We do not use all_sources()/all_dependencies(), because it would
427 # build literally all source files, including devices only used by
428 # targets that are not built for this compilation.  The CONFIG_ALL
429 # pseudo symbol replaces it.
430
431 if have_system
432   config_all_devices_mak = configure_file(
433     output: 'config-all-devices.mak',
434     input: config_devices_mak_list,
435     capture: true,
436     command: [grepy, '@INPUT@'],
437   )
438   config_all_devices = keyval.load(config_all_devices_mak)
439 else
440   config_all_devices = {}
441 endif
442 config_all = config_all_devices
443 config_all += config_host
444 config_all += config_all_disas
445 config_all += {
446   'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
447   'CONFIG_SOFTMMU': have_system,
448   'CONFIG_USER_ONLY': have_user,
449   'CONFIG_ALL': true,
450 }
451
452 # Generators
453
454 genh = []
455 hxtool = find_program('scripts/hxtool')
456 shaderinclude = find_program('scripts/shaderinclude.pl')
457 qapi_gen = find_program('scripts/qapi-gen.py')
458 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
459                      meson.source_root() / 'scripts/qapi/commands.py',
460                      meson.source_root() / 'scripts/qapi/common.py',
461                      meson.source_root() / 'scripts/qapi/doc.py',
462                      meson.source_root() / 'scripts/qapi/error.py',
463                      meson.source_root() / 'scripts/qapi/events.py',
464                      meson.source_root() / 'scripts/qapi/expr.py',
465                      meson.source_root() / 'scripts/qapi/gen.py',
466                      meson.source_root() / 'scripts/qapi/introspect.py',
467                      meson.source_root() / 'scripts/qapi/parser.py',
468                      meson.source_root() / 'scripts/qapi/schema.py',
469                      meson.source_root() / 'scripts/qapi/source.py',
470                      meson.source_root() / 'scripts/qapi/types.py',
471                      meson.source_root() / 'scripts/qapi/visit.py',
472                      meson.source_root() / 'scripts/qapi/common.py',
473                      meson.source_root() / 'scripts/qapi/doc.py',
474                      meson.source_root() / 'scripts/qapi-gen.py'
475 ]
476
477 tracetool = [
478   python, files('scripts/tracetool.py'),
479    '--backend=' + config_host['TRACE_BACKENDS']
480 ]
481
482 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
483                     meson.current_source_dir(),
484                     config_host['PKGVERSION'], config_host['VERSION']]
485 qemu_version = custom_target('qemu-version.h',
486                              output: 'qemu-version.h',
487                              command: qemu_version_cmd,
488                              capture: true,
489                              build_by_default: true,
490                              build_always_stale: true)
491 genh += qemu_version
492
493 config_host_h = custom_target('config-host.h',
494                               input: meson.current_build_dir() / 'config-host.mak',
495                               output: 'config-host.h',
496                               capture: true,
497                               command: [create_config, '@INPUT@'])
498 genh += config_host_h
499
500 hxdep = []
501 hx_headers = [
502   ['qemu-options.hx', 'qemu-options.def'],
503   ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
504 ]
505 if have_system
506   hx_headers += [
507     ['hmp-commands.hx', 'hmp-commands.h'],
508     ['hmp-commands-info.hx', 'hmp-commands-info.h'],
509   ]
510 endif
511 foreach d : hx_headers
512   hxdep += custom_target(d[1],
513                 input: files(d[0]),
514                 output: d[1],
515                 capture: true,
516                 build_by_default: true, # to be removed when added to a target
517                 command: [hxtool, '-h', '@INPUT0@'])
518 endforeach
519 genh += hxdep
520
521 # Collect sourcesets.
522
523 util_ss = ss.source_set()
524 stub_ss = ss.source_set()
525 trace_ss = ss.source_set()
526 block_ss = ss.source_set()
527 blockdev_ss = ss.source_set()
528 qmp_ss = ss.source_set()
529 common_ss = ss.source_set()
530 softmmu_ss = ss.source_set()
531 user_ss = ss.source_set()
532 bsd_user_ss = ss.source_set()
533 linux_user_ss = ss.source_set()
534 specific_ss = ss.source_set()
535 specific_fuzz_ss = ss.source_set()
536
537 modules = {}
538 hw_arch = {}
539 target_arch = {}
540 target_softmmu_arch = {}
541
542 ###############
543 # Trace files #
544 ###############
545
546 # TODO: add each directory to the subdirs from its own meson.build, once
547 # we have those
548 trace_events_subdirs = [
549   'accel/kvm',
550   'accel/tcg',
551   'crypto',
552   'monitor',
553 ]
554 if have_user
555   trace_events_subdirs += [ 'linux-user' ]
556 endif
557 if have_block
558   trace_events_subdirs += [
559     'authz',
560     'block',
561     'io',
562     'nbd',
563     'scsi',
564   ]
565 endif
566 if have_system
567   trace_events_subdirs += [
568     'audio',
569     'backends',
570     'backends/tpm',
571     'chardev',
572     'hw/9pfs',
573     'hw/acpi',
574     'hw/alpha',
575     'hw/arm',
576     'hw/audio',
577     'hw/block',
578     'hw/block/dataplane',
579     'hw/char',
580     'hw/display',
581     'hw/dma',
582     'hw/hppa',
583     'hw/hyperv',
584     'hw/i2c',
585     'hw/i386',
586     'hw/i386/xen',
587     'hw/ide',
588     'hw/input',
589     'hw/intc',
590     'hw/isa',
591     'hw/mem',
592     'hw/mips',
593     'hw/misc',
594     'hw/misc/macio',
595     'hw/net',
596     'hw/nvram',
597     'hw/pci',
598     'hw/pci-host',
599     'hw/ppc',
600     'hw/rdma',
601     'hw/rdma/vmw',
602     'hw/rtc',
603     'hw/s390x',
604     'hw/scsi',
605     'hw/sd',
606     'hw/sparc',
607     'hw/sparc64',
608     'hw/ssi',
609     'hw/timer',
610     'hw/tpm',
611     'hw/usb',
612     'hw/vfio',
613     'hw/virtio',
614     'hw/watchdog',
615     'hw/xen',
616     'hw/gpio',
617     'hw/riscv',
618     'migration',
619     'net',
620     'ui',
621   ]
622 endif
623 trace_events_subdirs += [
624   'hw/core',
625   'qapi',
626   'qom',
627   'target/arm',
628   'target/hppa',
629   'target/i386',
630   'target/mips',
631   'target/ppc',
632   'target/riscv',
633   'target/s390x',
634   'target/sparc',
635   'util',
636 ]
637
638 subdir('qapi')
639 subdir('qobject')
640 subdir('stubs')
641 subdir('trace')
642 subdir('util')
643 subdir('qom')
644 subdir('authz')
645 subdir('crypto')
646 subdir('ui')
647
648
649 if enable_modules
650   libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
651   modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
652 endif
653
654 # Build targets from sourcesets
655
656 stub_ss = stub_ss.apply(config_all, strict: false)
657
658 util_ss.add_all(trace_ss)
659 util_ss = util_ss.apply(config_all, strict: false)
660 libqemuutil = static_library('qemuutil',
661                              sources: util_ss.sources() + stub_ss.sources() + genh,
662                              dependencies: [util_ss.dependencies(), m, glib, socket])
663 qemuutil = declare_dependency(link_with: libqemuutil,
664                               sources: genh + version_res)
665
666 decodetree = generator(find_program('scripts/decodetree.py'),
667                        output: 'decode-@BASENAME@.c.inc',
668                        arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
669
670 subdir('audio')
671 subdir('io')
672 subdir('chardev')
673 subdir('fsdev')
674 subdir('libdecnumber')
675 subdir('target')
676 subdir('dump')
677
678 block_ss.add(files(
679   'block.c',
680   'blockjob.c',
681   'job.c',
682   'qemu-io-cmds.c',
683 ))
684 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
685
686 subdir('nbd')
687 subdir('scsi')
688 subdir('block')
689
690 blockdev_ss.add(files(
691   'blockdev.c',
692   'blockdev-nbd.c',
693   'iothread.c',
694   'job-qmp.c',
695 ))
696
697 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
698 # os-win32.c does not
699 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
700 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
701
702 softmmu_ss.add_all(blockdev_ss)
703 softmmu_ss.add(files(
704   'bootdevice.c',
705   'dma-helpers.c',
706   'qdev-monitor.c',
707 ), sdl)
708
709 softmmu_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c'))
710 softmmu_ss.add(when: 'CONFIG_SECCOMP', if_true: [files('qemu-seccomp.c'), seccomp])
711 softmmu_ss.add(when: ['CONFIG_FDT', fdt],  if_true: [files('device_tree.c')])
712
713 common_ss.add(files('cpus-common.c'))
714
715 subdir('softmmu')
716
717 specific_ss.add(files('disas.c', 'exec.c', 'gdbstub.c'), capstone, libpmem)
718 specific_ss.add(files('exec-vary.c'))
719 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
720   'fpu/softfloat.c',
721   'tcg/optimize.c',
722   'tcg/tcg-common.c',
723   'tcg/tcg-op-gvec.c',
724   'tcg/tcg-op-vec.c',
725   'tcg/tcg-op.c',
726   'tcg/tcg.c',
727 ))
728 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
729
730 subdir('backends')
731 subdir('disas')
732 subdir('migration')
733 subdir('monitor')
734 subdir('net')
735 subdir('replay')
736 subdir('hw')
737 subdir('accel')
738 subdir('plugins')
739 subdir('bsd-user')
740 subdir('linux-user')
741
742 bsd_user_ss.add(files('gdbstub.c'))
743 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
744
745 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
746 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
747
748 # needed for fuzzing binaries
749 subdir('tests/qtest/libqos')
750 subdir('tests/qtest/fuzz')
751
752 block_mods = []
753 softmmu_mods = []
754 foreach d, list : modules
755   foreach m, module_ss : list
756     if enable_modules and targetos != 'windows'
757       module_ss = module_ss.apply(config_host, strict: false)
758       sl = static_library(d + '-' + m, [genh, module_ss.sources()],
759                           dependencies: [modulecommon, module_ss.dependencies()], pic: true)
760       if d == 'block'
761         block_mods += sl
762       else
763         softmmu_mods += sl
764       endif
765     else
766       if d == 'block'
767         block_ss.add_all(module_ss)
768       else
769         softmmu_ss.add_all(module_ss)
770       endif
771     endif
772   endforeach
773 endforeach
774
775 nm = find_program('nm')
776 undefsym = find_program('scripts/undefsym.sh')
777 block_syms = custom_target('block.syms', output: 'block.syms',
778                              input: [libqemuutil, block_mods],
779                              capture: true,
780                              command: [undefsym, nm, '@INPUT@'])
781 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
782                              input: [libqemuutil, softmmu_mods],
783                              capture: true,
784                              command: [undefsym, nm, '@INPUT@'])
785
786 block_ss = block_ss.apply(config_host, strict: false)
787 libblock = static_library('block', block_ss.sources() + genh,
788                           dependencies: block_ss.dependencies(),
789                           link_depends: block_syms,
790                           name_suffix: 'fa',
791                           build_by_default: false)
792
793 block = declare_dependency(link_whole: [libblock],
794                            link_args: '@block.syms',
795                            dependencies: [crypto, io])
796
797 qmp_ss = qmp_ss.apply(config_host, strict: false)
798 libqmp = static_library('qmp', qmp_ss.sources() + genh,
799                         dependencies: qmp_ss.dependencies(),
800                         name_suffix: 'fa',
801                         build_by_default: false)
802
803 qmp = declare_dependency(link_whole: [libqmp])
804
805 foreach m : block_mods + softmmu_mods
806   shared_module(m.name(),
807                 name_prefix: '',
808                 link_whole: m,
809                 install: true,
810                 install_dir: config_host['qemu_moddir'])
811 endforeach
812
813 softmmu_ss.add(authz, block, chardev, crypto, io, qmp)
814 common_ss.add(qom, qemuutil)
815
816 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
817 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
818
819 common_all = common_ss.apply(config_all, strict: false)
820 common_all = static_library('common',
821                             build_by_default: false,
822                             sources: common_all.sources() + genh,
823                             dependencies: common_all.dependencies(),
824                             name_suffix: 'fa')
825
826 feature_to_c = find_program('scripts/feature_to_c.sh')
827
828 emulators = []
829 foreach target : target_dirs
830   config_target = config_target_mak[target]
831   target_name = config_target['TARGET_NAME']
832   arch = config_target['TARGET_BASE_ARCH']
833   arch_srcs = []
834   arch_deps = []
835   c_args = ['-DNEED_CPU_H',
836             '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
837             '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
838   link_args = []
839
840   target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
841   if targetos == 'linux'
842     target_inc += include_directories('linux-headers', is_system: true)
843   endif
844   if target.endswith('-softmmu')
845     qemu_target_name = 'qemu-system-' + target_name
846     target_type='system'
847     t = target_softmmu_arch[arch].apply(config_target, strict: false)
848     arch_srcs += t.sources()
849     arch_deps += t.dependencies()
850
851     hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
852     hw = hw_arch[hw_dir].apply(config_target, strict: false)
853     arch_srcs += hw.sources()
854     arch_deps += hw.dependencies()
855
856     arch_srcs += config_devices_h[target]
857     link_args += ['@block.syms', '@qemu.syms']
858   else
859     abi = config_target['TARGET_ABI_DIR']
860     target_type='user'
861     qemu_target_name = 'qemu-' + target_name
862     if 'CONFIG_LINUX_USER' in config_target
863       base_dir = 'linux-user'
864       target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
865     else
866       base_dir = 'bsd-user'
867     endif
868     target_inc += include_directories(
869       base_dir,
870       base_dir / abi,
871     )
872     if 'CONFIG_LINUX_USER' in config_target
873       dir = base_dir / abi
874       arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
875       if config_target.has_key('TARGET_SYSTBL_ABI')
876         arch_srcs += \
877           syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
878                                              extra_args : config_target['TARGET_SYSTBL_ABI'])
879       endif
880     endif
881   endif
882
883   if 'TARGET_XML_FILES' in config_target
884     gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
885                                 output: target + '-gdbstub-xml.c',
886                                 input: files(config_target['TARGET_XML_FILES'].split()),
887                                 command: [feature_to_c, '@INPUT@'],
888                                 capture: true)
889     arch_srcs += gdbstub_xml
890   endif
891
892   t = target_arch[arch].apply(config_target, strict: false)
893   arch_srcs += t.sources()
894   arch_deps += t.dependencies()
895
896   target_common = common_ss.apply(config_target, strict: false)
897   objects = common_all.extract_objects(target_common.sources())
898   deps = target_common.dependencies()
899
900   # TODO: Change to generator once obj-y goes away
901   config_target_h = custom_target(target + '-config-target.h',
902                               input: meson.current_build_dir() / target / 'config-target.mak',
903                               output: target + '-config-target.h',
904                               capture: true,
905                               command: [create_config, '@INPUT@'])
906
907   target_specific = specific_ss.apply(config_target, strict: false)
908   arch_srcs += target_specific.sources()
909   arch_deps += target_specific.dependencies()
910
911   lib = static_library('qemu-' + target,
912                  sources: arch_srcs + [config_target_h] + genh,
913                  objects: objects,
914                  include_directories: target_inc,
915                  c_args: c_args,
916                  build_by_default: false,
917                  name_suffix: 'fa')
918
919   if target.endswith('-softmmu')
920     execs = [{
921       'name': 'qemu-system-' + target_name,
922       'gui': false,
923       'sources': files('softmmu/main.c'),
924       'dependencies': []
925     }]
926     if sdlwindows
927       execs += [{
928         'name': 'qemu-system-' + target_name + 'w',
929         'gui': true,
930         'sources': files('softmmu/main.c'),
931         'dependencies': []
932       }]
933     endif
934     if config_host.has_key('CONFIG_FUZZ')
935       specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
936       execs += [{
937         'name': 'qemu-fuzz-' + target_name,
938         'gui': false,
939         'sources': specific_fuzz.sources(),
940         'dependencies': specific_fuzz.dependencies(),
941         'link_depends': [files('tests/qtest/fuzz/fork_fuzz.ld')],
942       }]
943     endif
944   else
945     execs = [{
946       'name': 'qemu-' + target_name,
947       'gui': false,
948       'sources': [],
949       'dependencies': []
950     }]
951   endif
952   foreach exe: execs
953     emulators += executable(exe['name'], exe['sources'],
954                install: true,
955                c_args: c_args,
956                dependencies: arch_deps + deps + exe['dependencies'],
957                objects: lib.extract_all_objects(recursive: true),
958                link_language: link_language,
959                link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
960                link_args: link_args,
961                gui_app: exe['gui'])
962
963     if 'CONFIG_TRACE_SYSTEMTAP' in config_host
964       foreach stp: [
965         {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe_name, 'install': false},
966         {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe_name, 'install': true},
967         {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
968         {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
969       ]
970         custom_target(exe_name + stp['ext'],
971                       input: trace_events_all,
972                       output: exe_name + stp['ext'],
973                       capture: true,
974                       install: stp['install'],
975                       install_dir: config_host['qemu_datadir'] / '../systemtap/tapset',
976                       command: [
977                         tracetool, '--group=all', '--format=' + stp['fmt'],
978                         '--binary=' + stp['bin'],
979                         '--target-name=' + target_name,
980                         '--target-type=' + target_type,
981                         '--probe-prefix=qemu.' + target_type + '.' + target_name,
982                         '@INPUT@',
983                       ])
984       endforeach
985     endif
986   endforeach
987 endforeach
988
989 # Other build targets
990
991 if 'CONFIG_PLUGIN' in config_host
992   install_headers('include/qemu/qemu-plugin.h')
993 endif
994
995 if 'CONFIG_GUEST_AGENT' in config_host
996   subdir('qga')
997 endif
998
999 if have_tools
1000   qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
1001              dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
1002   qemu_io = executable('qemu-io', files('qemu-io.c'),
1003              dependencies: [block, qemuutil], install: true)
1004   qemu_block_tools = [qemu_img, qemu_io]
1005   if targetos == 'linux' or targetos == 'sunos' or targetos.endswith('bsd')
1006     qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
1007                dependencies: [block, qemuutil], install: true)
1008     qemu_block_tools += [qemu_nbd]
1009   endif
1010
1011   subdir('storage-daemon')
1012   subdir('contrib/rdmacm-mux')
1013   subdir('contrib/elf2dmp')
1014
1015   if 'CONFIG_XKBCOMMON' in config_host
1016     executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c'),
1017                dependencies: [qemuutil, xkbcommon], install: true)
1018   endif
1019
1020   executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
1021              dependencies: qemuutil,
1022              install: true)
1023
1024   if 'CONFIG_VHOST_USER' in config_host
1025     subdir('contrib/libvhost-user')
1026     subdir('contrib/vhost-user-blk')
1027     if 'CONFIG_LINUX' in config_host
1028       subdir('contrib/vhost-user-gpu')
1029     endif
1030     subdir('contrib/vhost-user-input')
1031     subdir('contrib/vhost-user-scsi')
1032   endif
1033
1034   if targetos == 'linux'
1035     executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
1036                dependencies: [qemuutil, libcap_ng],
1037                install: true,
1038                install_dir: get_option('libexecdir'))
1039
1040     executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
1041                dependencies: [authz, crypto, io, qom, qemuutil,
1042                               libcap_ng, libudev, libmpathpersist],
1043                install: true)
1044   endif
1045
1046   if 'CONFIG_IVSHMEM' in config_host
1047     subdir('contrib/ivshmem-client')
1048     subdir('contrib/ivshmem-server')
1049   endif
1050 endif
1051
1052 subdir('tools')
1053 subdir('pc-bios')
1054 subdir('tests')
1055 subdir('docs')
1056
1057 if build_docs
1058   makeinfo = find_program('makeinfo', required: build_docs)
1059
1060   docs_inc = [
1061     '-I', meson.current_source_dir(),
1062     '-I', meson.current_build_dir() / 'docs',
1063     '-I', '@OUTDIR@',
1064   ]
1065
1066   version_texi = configure_file(output: 'version.texi',
1067                               input: 'version.texi.in',
1068                               configuration: {'VERSION': meson.project_version(),
1069                                               'qemu_confdir': config_host['qemu_confdir']})
1070
1071   texi = {
1072     'qemu-qmp-ref': ['docs/interop/qemu-qmp-ref.texi', qapi_doc_texi, version_texi],
1073   }
1074   if 'CONFIG_GUEST_AGENT' in config_host
1075     texi += {'qemu-ga-ref': ['docs/interop/qemu-ga-ref.texi', qga_qapi_doc_texi, version_texi]}
1076   endif
1077
1078   if makeinfo.found()
1079     cmd = [
1080       'env', 'LC_ALL=C', makeinfo, '--no-split', '--number-sections', docs_inc,
1081       '@INPUT0@', '-o', '@OUTPUT@',
1082     ]
1083     foreach ext, args: {
1084         'info': [],
1085         'html': ['--no-headers', '--html'],
1086         'txt': ['--no-headers', '--plaintext'],
1087     }
1088       t = []
1089       foreach doc, input: texi
1090         output = doc + '.' + ext
1091         t += custom_target(output,
1092                       input: input,
1093                       output: output,
1094                       install: true,
1095                       install_dir: config_host['qemu_docdir'] / 'interop',
1096                       command: cmd + args)
1097       endforeach
1098       alias_target(ext, t)
1099     endforeach
1100   endif
1101
1102   texi2pdf = find_program('texi2pdf', required: false)
1103
1104   if texi2pdf.found()
1105     pdfs = []
1106     foreach doc, input: texi
1107       output = doc + '.pdf'
1108       pdfs += custom_target(output,
1109                     input: input,
1110                     output: output,
1111                     command: [texi2pdf, '-q', docs_inc, '@INPUT0@', '-o', '@OUTPUT@'],
1112                     build_by_default: false)
1113     endforeach
1114     alias_target('pdf', pdfs)
1115   endif
1116
1117   texi2pod = find_program('scripts/texi2pod.pl')
1118   pod2man = find_program('pod2man', required: build_docs)
1119
1120   if pod2man.found()
1121     foreach doc, input: texi
1122       man = doc + '.7'
1123       pod = custom_target(man + '.pod',
1124                           input: input,
1125                           output: man + '.pod',
1126                           command: [texi2pod,
1127                                     '-DVERSION="' + meson.project_version() + '"',
1128                                     '-DCONFDIR="' + config_host['qemu_confdir'] + '"',
1129                                     '@INPUT0@', '@OUTPUT@'])
1130       man = custom_target(man,
1131                           input: pod,
1132                           output: man,
1133                           capture: true,
1134                           install: true,
1135                           install_dir: config_host['mandir'] / 'man7',
1136                           command: [pod2man, '--utf8', '--section=7', '--center=" "',
1137                                     '--release=" "', '@INPUT@'])
1138     endforeach
1139   endif
1140 endif
1141
1142 summary_info = {}
1143 summary_info += {'Install prefix':    config_host['prefix']}
1144 summary_info += {'BIOS directory':    config_host['qemu_datadir']}
1145 summary_info += {'firmware path':     config_host['qemu_firmwarepath']}
1146 summary_info += {'binary directory':  config_host['bindir']}
1147 summary_info += {'library directory': config_host['libdir']}
1148 summary_info += {'module directory':  config_host['qemu_moddir']}
1149 summary_info += {'libexec directory': config_host['libexecdir']}
1150 summary_info += {'include directory': config_host['includedir']}
1151 summary_info += {'config directory':  config_host['sysconfdir']}
1152 if targetos != 'windows'
1153   summary_info += {'local state directory': config_host['qemu_localstatedir']}
1154   summary_info += {'Manual directory':      config_host['mandir']}
1155 else
1156   summary_info += {'local state directory': 'queried at runtime'}
1157 endif
1158 summary_info += {'Build directory':   meson.current_build_dir()}
1159 summary_info += {'Source path':       meson.current_source_dir()}
1160 summary_info += {'GIT binary':        config_host['GIT']}
1161 summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
1162 summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
1163 summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
1164 if link_language == 'cpp'
1165   summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
1166 else
1167   summary_info += {'C++ compiler':      false}
1168 endif
1169 if targetos == 'darwin'
1170   summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
1171 endif
1172 summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
1173 summary_info += {'CFLAGS':            config_host['CFLAGS']}
1174 summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
1175 summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
1176 summary_info += {'make':              config_host['MAKE']}
1177 summary_info += {'install':           config_host['INSTALL']}
1178 summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
1179 summary_info += {'sphinx-build':      config_host['SPHINX_BUILD']}
1180 summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
1181 # TODO: add back version
1182 summary_info += {'slirp support':     config_host.has_key('CONFIG_SLIRP')}
1183 if config_host.has_key('CONFIG_SLIRP')
1184   summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
1185 endif
1186 summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
1187 if config_host.has_key('CONFIG_MODULES')
1188   summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
1189 endif
1190 summary_info += {'host CPU':          cpu}
1191 summary_info += {'host endianness':   build_machine.endian()}
1192 summary_info += {'target list':       config_host['TARGET_DIRS']}
1193 summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
1194 summary_info += {'sparse enabled':    meson.get_compiler('c').cmd_array().contains('cgcc')}
1195 summary_info += {'strip binaries':    get_option('strip')}
1196 summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
1197 summary_info += {'static build':      config_host.has_key('CONFIG_TOOLS')}
1198 if targetos == 'darwin'
1199   summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
1200 endif
1201 # TODO: add back version
1202 summary_info += {'SDL support':       config_host.has_key('CONFIG_SDL')}
1203 summary_info += {'SDL image support': config_host.has_key('CONFIG_SDL_IMAGE')}
1204 # TODO: add back version
1205 summary_info += {'GTK support':       config_host.has_key('CONFIG_GTK')}
1206 summary_info += {'GTK GL support':    config_host.has_key('CONFIG_GTK_GL')}
1207 # TODO: add back version
1208 summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
1209 summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
1210 summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
1211 # TODO: add back version
1212 summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
1213 if config_host.has_key('CONFIG_GCRYPT')
1214    summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
1215    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1216 endif
1217 # TODO: add back version
1218 summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
1219 if config_host.has_key('CONFIG_NETTLE')
1220    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1221 endif
1222 summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
1223 summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
1224 summary_info += {'iconv support':     config_host.has_key('CONFIG_ICONV')}
1225 summary_info += {'curses support':    config_host.has_key('CONFIG_CURSES')}
1226 # TODO: add back version
1227 summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
1228 summary_info += {'curl support':      config_host.has_key('CONFIG_CURL')}
1229 summary_info += {'mingw32 support':   targetos == 'windows'}
1230 summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
1231 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
1232 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
1233 summary_info += {'VirtFS support':    config_host.has_key('CONFIG_VIRTFS')}
1234 summary_info += {'Multipath support': config_host.has_key('CONFIG_MPATH')}
1235 summary_info += {'VNC support':       config_host.has_key('CONFIG_VNC')}
1236 if config_host.has_key('CONFIG_VNC')
1237   summary_info += {'VNC SASL support':  config_host.has_key('CONFIG_VNC_SASL')}
1238   summary_info += {'VNC JPEG support':  config_host.has_key('CONFIG_VNC_JPEG')}
1239   summary_info += {'VNC PNG support':   config_host.has_key('CONFIG_VNC_PNG')}
1240 endif
1241 summary_info += {'xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
1242 if config_host.has_key('CONFIG_XEN_BACKEND')
1243   summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
1244 endif
1245 summary_info += {'brlapi support':    config_host.has_key('CONFIG_BRLAPI')}
1246 summary_info += {'Documentation':     config_host.has_key('BUILD_DOCS')}
1247 summary_info += {'PIE':               get_option('b_pie')}
1248 summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
1249 summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
1250 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
1251 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
1252 summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
1253 summary_info += {'Install blobs':     config_host.has_key('INSTALL_BLOBS')}
1254 # TODO: add back KVM/HAX/HVF/WHPX/TCG
1255 #summary_info += {'KVM support':       have_kvm'}
1256 #summary_info += {'HAX support':       have_hax'}
1257 #summary_info += {'HVF support':       have_hvf'}
1258 #summary_info += {'WHPX support':      have_whpx'}
1259 #summary_info += {'TCG support':       have_tcg'}
1260 #if get_option('tcg')
1261 #  summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
1262 #  summary_info += {'TCG interpreter':   config_host.has_key('CONFIG_TCG_INTERPRETER')}
1263 #endif
1264 summary_info += {'malloc trim support': config_host.has_key('CONFIG_MALLOC_TRIM')}
1265 summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
1266 summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
1267 summary_info += {'fdt support':       config_host.has_key('CONFIG_FDT')}
1268 summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
1269 summary_info += {'preadv support':    config_host.has_key('CONFIG_PREADV')}
1270 summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
1271 summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
1272 summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
1273 summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
1274 summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
1275 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
1276 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
1277 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
1278 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
1279 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_KERNEL')}
1280 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
1281 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
1282 summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
1283 if config_host['TRACE_BACKENDS'].split().contains('simple')
1284   summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
1285 endif
1286 # TODO: add back protocol and server version
1287 summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
1288 summary_info += {'rbd support':       config_host.has_key('CONFIG_RBD')}
1289 summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
1290 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
1291 summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
1292 summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
1293 summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
1294 summary_info += {'OpenGL dmabufs':    config_host.has_key('CONFIG_OPENGL_DMABUF')}
1295 summary_info += {'libiscsi support':  config_host.has_key('CONFIG_LIBISCSI')}
1296 summary_info += {'libnfs support':    config_host.has_key('CONFIG_LIBNFS')}
1297 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
1298 if targetos == 'windows'
1299   if 'WIN_SDK' in config_host
1300     summary_info += {'Windows SDK':       config_host['WIN_SDK']}
1301   endif
1302   summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
1303   summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
1304   summary_info += {'QGA MSI support':   config_host.has_key('CONFIG_QGA_MSI_ENABLED')}
1305 endif
1306 summary_info += {'seccomp support':   config_host.has_key('CONFIG_SECCOMP')}
1307 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
1308 summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
1309 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
1310 summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
1311 summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
1312 summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
1313 summary_info += {'gcov':              get_option('b_coverage')}
1314 summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
1315 summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
1316 summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
1317 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
1318 summary_info += {'lzo support':       config_host.has_key('CONFIG_LZO')}
1319 summary_info += {'snappy support':    config_host.has_key('CONFIG_SNAPPY')}
1320 summary_info += {'bzip2 support':     config_host.has_key('CONFIG_BZIP2')}
1321 summary_info += {'lzfse support':     config_host.has_key('CONFIG_LZFSE')}
1322 summary_info += {'zstd support':      config_host.has_key('CONFIG_ZSTD')}
1323 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
1324 summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
1325 summary_info += {'tcmalloc support':  config_host.has_key('CONFIG_TCMALLOC')}
1326 summary_info += {'jemalloc support':  config_host.has_key('CONFIG_JEMALLOC')}
1327 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
1328 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
1329 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
1330 summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
1331 summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
1332 summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
1333 summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
1334 summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
1335 summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
1336 summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
1337 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
1338 summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
1339 summary_info += {'capstone':          config_host.has_key('CONFIG_CAPSTONE')}
1340 summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
1341 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
1342 summary_info += {'libudev':           config_host.has_key('CONFIG_LIBUDEV')}
1343 summary_info += {'default devices':   config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
1344 summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
1345 summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
1346 if config_host.has_key('HAVE_GDB_BIN')
1347   summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
1348 endif
1349 summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
1350 summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
1351 summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
1352 summary(summary_info, bool_yn: true)
1353
1354 if not supported_cpus.contains(cpu)
1355   message()
1356   warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
1357   message()
1358   message('CPU host architecture ' + cpu + ' support is not currently maintained.')
1359   message('The QEMU project intends to remove support for this host CPU in')
1360   message('a future release if nobody volunteers to maintain it and to')
1361   message('provide a build host for our continuous integration setup.')
1362   message('configure has succeeded and you can continue to build, but')
1363   message('if you care about QEMU on this platform you should contact')
1364   message('us upstream at qemu-devel@nongnu.org.')
1365 endif
1366
1367 if not supported_oses.contains(targetos)
1368   message()
1369   warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
1370   message()
1371   message('Host OS ' + targetos + 'support is not currently maintained.')
1372   message('The QEMU project intends to remove support for this host OS in')
1373   message('a future release if nobody volunteers to maintain it and to')
1374   message('provide a build host for our continuous integration setup.')
1375   message('configure has succeeded and you can continue to build, but')
1376   message('if you care about QEMU on this platform you should contact')
1377   message('us upstream at qemu-devel@nongnu.org.')
1378 endif