meson: move sparse detection to Meson and rewrite check_sparse.py
[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',
3                           'b_colorout=auto'],
4         version: run_command('head', meson.source_root() / 'VERSION').stdout().strip())
5
6 not_found = dependency('', required: false)
7 if meson.version().version_compare('>=0.56.0')
8   keyval = import('keyval')
9 else
10   keyval = import('unstable-keyval')
11 endif
12 ss = import('sourceset')
13
14 sh = find_program('sh')
15 cc = meson.get_compiler('c')
16 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
17 enable_modules = 'CONFIG_MODULES' in config_host
18 enable_static = 'CONFIG_STATIC' in config_host
19 build_docs = 'BUILD_DOCS' in config_host
20
21 if get_option('qemu_suffix').startswith('/')
22   error('qemu_suffix cannot start with a /')
23 endif
24
25 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
26 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
27 config_host_data = configuration_data()
28 genh = []
29
30 target_dirs = config_host['TARGET_DIRS'].split()
31 have_user = false
32 have_system = false
33 foreach target : target_dirs
34   have_user = have_user or target.endswith('-user')
35   have_system = have_system or target.endswith('-softmmu')
36 endforeach
37 have_tools = 'CONFIG_TOOLS' in config_host
38 have_block = have_system or have_tools
39
40 python = import('python').find_installation()
41
42 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
43 supported_cpus = ['ppc', 'ppc64', 's390x', 'sparc64', 'riscv32', 'riscv64', 'x86', 'x86_64',
44   'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
45
46 cpu = host_machine.cpu_family()
47 targetos = host_machine.system()
48
49 configure_file(input: files('scripts/ninjatool.py'),
50                output: 'ninjatool',
51                configuration: config_host)
52
53 if cpu in ['x86', 'x86_64']
54   kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
55 elif cpu == 'aarch64'
56   kvm_targets = ['aarch64-softmmu']
57 elif cpu == 's390x'
58   kvm_targets = ['s390x-softmmu']
59 elif cpu in ['ppc', 'ppc64']
60   kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
61 else
62   kvm_targets = []
63 endif
64
65 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
66 if cpu in ['x86', 'x86_64']
67   accelerator_targets += {
68     'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
69     'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
70     'CONFIG_HVF': ['x86_64-softmmu'],
71     'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
72   }
73 endif
74
75 ##################
76 # Compiler flags #
77 ##################
78
79 # Specify linker-script with add_project_link_arguments so that it is not placed
80 # within a linker --start-group/--end-group pair
81 if 'CONFIG_FUZZ' in config_host
82    add_project_link_arguments(['-Wl,-T,',
83                                (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
84                               native: false, language: ['c', 'cpp', 'objc'])
85 endif
86
87 add_project_arguments(config_host['QEMU_CFLAGS'].split(),
88                       native: false, language: ['c', 'objc'])
89 add_project_arguments(config_host['QEMU_CXXFLAGS'].split(),
90                       native: false, language: 'cpp')
91 add_project_link_arguments(config_host['QEMU_LDFLAGS'].split(),
92                            native: false, language: ['c', 'cpp', 'objc'])
93 add_project_arguments(config_host['QEMU_INCLUDES'].split(),
94                       language: ['c', 'cpp', 'objc'])
95
96
97 link_language = meson.get_external_property('link_language', 'cpp')
98 if link_language == 'cpp'
99   add_languages('cpp', required: true, native: false)
100 endif
101 if host_machine.system() == 'darwin'
102   add_languages('objc', required: false, native: false)
103 endif
104
105 sparse = find_program('cgcc', required: get_option('sparse'))
106 if sparse.found()
107   run_target('sparse',
108              command: [find_program('scripts/check_sparse.py'),
109                        'compile_commands.json', sparse.full_path(), '-Wbitwise',
110                        '-Wno-transparent-union', '-Wno-old-initializer',
111                        '-Wno-non-pointer-null'])
112 endif
113
114 ###########################################
115 # Target-specific checks and dependencies #
116 ###########################################
117
118 if targetos != 'linux' and get_option('mpath').enabled()
119   error('Multipath is supported only on Linux')
120 endif
121
122 m = cc.find_library('m', required: false)
123 util = cc.find_library('util', required: false)
124 winmm = []
125 socket = []
126 version_res = []
127 coref = []
128 iokit = []
129 emulator_link_args = []
130 cocoa = not_found
131 hvf = not_found
132 if targetos == 'windows'
133   socket = cc.find_library('ws2_32')
134   winmm = cc.find_library('winmm')
135
136   win = import('windows')
137   version_res = win.compile_resources('version.rc',
138                                       depend_files: files('pc-bios/qemu-nsis.ico'),
139                                       include_directories: include_directories('.'))
140 elif targetos == 'darwin'
141   coref = dependency('appleframeworks', modules: 'CoreFoundation')
142   iokit = dependency('appleframeworks', modules: 'IOKit')
143   cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
144 elif targetos == 'sunos'
145   socket = [cc.find_library('socket'),
146             cc.find_library('nsl'),
147             cc.find_library('resolv')]
148 elif targetos == 'haiku'
149   socket = [cc.find_library('posix_error_mapper'),
150             cc.find_library('network'),
151             cc.find_library('bsd')]
152 elif targetos == 'openbsd'
153   if not get_option('tcg').disabled() and target_dirs.length() > 0
154     # Disable OpenBSD W^X if available
155     emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
156   endif
157 endif
158
159 accelerators = []
160 if not get_option('kvm').disabled() and targetos == 'linux'
161   accelerators += 'CONFIG_KVM'
162 endif
163 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
164   accelerators += 'CONFIG_XEN'
165   have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
166 else
167   have_xen_pci_passthrough = false
168 endif
169 if not get_option('whpx').disabled() and targetos == 'windows'
170   if get_option('whpx').enabled() and cpu != 'x86_64'
171     error('WHPX requires 64-bit host')
172   elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
173        cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
174     accelerators += 'CONFIG_WHPX'
175   endif
176 endif
177 if not get_option('hvf').disabled()
178   hvf = dependency('appleframeworks', modules: 'Hypervisor',
179                    required: get_option('hvf'))
180   if hvf.found()
181     accelerators += 'CONFIG_HVF'
182   endif
183 endif
184 if not get_option('hax').disabled()
185   if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
186     accelerators += 'CONFIG_HAX'
187   endif
188 endif
189 if not get_option('tcg').disabled()
190   if cpu not in supported_cpus
191     if 'CONFIG_TCG_INTERPRETER' in config_host
192       warning('Unsupported CPU @0@, will use TCG with TCI (experimental)'.format(cpu))
193     else
194       error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
195     endif
196   endif
197   accelerators += 'CONFIG_TCG'
198   config_host += { 'CONFIG_TCG': 'y' }
199 endif
200
201 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
202   error('KVM not available on this platform')
203 endif
204 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
205   error('HVF not available on this platform')
206 endif
207 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
208   error('WHPX not available on this platform')
209 endif
210 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
211   if 'CONFIG_XEN' in accelerators
212     error('Xen PCI passthrough not available on this platform')
213   else
214     error('Xen PCI passthrough requested but Xen not enabled')
215   endif
216 endif
217 if not cocoa.found() and get_option('cocoa').enabled()
218   error('Cocoa not available on this platform')
219 endif
220
221 ################
222 # Dependencies #
223 ################
224
225 # The path to glib.h is added to all compilation commands.  This was
226 # grandfathered in from the QEMU Makefiles.
227 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
228                       native: false, language: ['c', 'cpp', 'objc'])
229 glib = declare_dependency(link_args: config_host['GLIB_LIBS'].split())
230 gio = not_found
231 if 'CONFIG_GIO' in config_host
232   gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
233                            link_args: config_host['GIO_LIBS'].split())
234 endif
235 lttng = not_found
236 if 'CONFIG_TRACE_UST' in config_host
237   lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
238 endif
239 urcubp = not_found
240 if 'CONFIG_TRACE_UST' in config_host
241   urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
242 endif
243 gcrypt = not_found
244 if 'CONFIG_GCRYPT' in config_host
245   gcrypt = declare_dependency(compile_args: config_host['GCRYPT_CFLAGS'].split(),
246                               link_args: config_host['GCRYPT_LIBS'].split())
247 endif
248 nettle = not_found
249 if 'CONFIG_NETTLE' in config_host
250   nettle = declare_dependency(compile_args: config_host['NETTLE_CFLAGS'].split(),
251                               link_args: config_host['NETTLE_LIBS'].split())
252 endif
253 gnutls = not_found
254 if 'CONFIG_GNUTLS' in config_host
255   gnutls = declare_dependency(compile_args: config_host['GNUTLS_CFLAGS'].split(),
256                               link_args: config_host['GNUTLS_LIBS'].split())
257 endif
258 pixman = not_found
259 if have_system or have_tools
260   pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
261                       method: 'pkg-config', static: enable_static)
262 endif
263 pam = not_found
264 if 'CONFIG_AUTH_PAM' in config_host
265   pam = cc.find_library('pam')
266 endif
267 libaio = cc.find_library('aio', required: false)
268 zlib = dependency('zlib', required: true, static: enable_static)
269 linux_io_uring = not_found
270 if 'CONFIG_LINUX_IO_URING' in config_host
271   linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
272                                       link_args: config_host['LINUX_IO_URING_LIBS'].split())
273 endif
274 libxml2 = not_found
275 if 'CONFIG_LIBXML2' in config_host
276   libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
277                                link_args: config_host['LIBXML2_LIBS'].split())
278 endif
279 libnfs = not_found
280 if 'CONFIG_LIBNFS' in config_host
281   libnfs = declare_dependency(link_args: config_host['LIBNFS_LIBS'].split())
282 endif
283 libattr = not_found
284 if 'CONFIG_ATTR' in config_host
285   libattr = declare_dependency(link_args: config_host['LIBATTR_LIBS'].split())
286 endif
287 seccomp = not_found
288 if 'CONFIG_SECCOMP' in config_host
289   seccomp = declare_dependency(compile_args: config_host['SECCOMP_CFLAGS'].split(),
290                                link_args: config_host['SECCOMP_LIBS'].split())
291 endif
292 libcap_ng = not_found
293 if 'CONFIG_LIBCAP_NG' in config_host
294   libcap_ng = declare_dependency(link_args: config_host['LIBCAP_NG_LIBS'].split())
295 endif
296 if get_option('xkbcommon').auto() and not have_system and not have_tools
297   xkbcommon = not_found
298 else
299   xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
300                          method: 'pkg-config', static: enable_static)
301 endif
302 slirp = not_found
303 if config_host.has_key('CONFIG_SLIRP')
304   slirp = declare_dependency(compile_args: config_host['SLIRP_CFLAGS'].split(),
305                              link_args: config_host['SLIRP_LIBS'].split())
306 endif
307 vde = not_found
308 if config_host.has_key('CONFIG_VDE')
309   vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
310 endif
311 pulse = not_found
312 if 'CONFIG_LIBPULSE' in config_host
313   pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
314                              link_args: config_host['PULSE_LIBS'].split())
315 endif
316 alsa = not_found
317 if 'CONFIG_ALSA' in config_host
318   alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
319                             link_args: config_host['ALSA_LIBS'].split())
320 endif
321 jack = not_found
322 if 'CONFIG_LIBJACK' in config_host
323   jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
324 endif
325 spice = not_found
326 if 'CONFIG_SPICE' in config_host
327   spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
328                              link_args: config_host['SPICE_LIBS'].split())
329 endif
330 rt = cc.find_library('rt', required: false)
331 libdl = not_found
332 if 'CONFIG_PLUGIN' in config_host
333   libdl = cc.find_library('dl', required: true)
334 endif
335 libiscsi = not_found
336 if 'CONFIG_LIBISCSI' in config_host
337   libiscsi = declare_dependency(compile_args: config_host['LIBISCSI_CFLAGS'].split(),
338                                 link_args: config_host['LIBISCSI_LIBS'].split())
339 endif
340 zstd = not_found
341 if 'CONFIG_ZSTD' in config_host
342   zstd = declare_dependency(compile_args: config_host['ZSTD_CFLAGS'].split(),
343                             link_args: config_host['ZSTD_LIBS'].split())
344 endif
345 gbm = not_found
346 if 'CONFIG_GBM' in config_host
347   gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
348                            link_args: config_host['GBM_LIBS'].split())
349 endif
350 virgl = not_found
351 if 'CONFIG_VIRGL' in config_host
352   virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
353                              link_args: config_host['VIRGL_LIBS'].split())
354 endif
355 curl = not_found
356 if 'CONFIG_CURL' in config_host
357   curl = declare_dependency(compile_args: config_host['CURL_CFLAGS'].split(),
358                             link_args: config_host['CURL_LIBS'].split())
359 endif
360 libudev = not_found
361 if targetos == 'linux' and (have_system or have_tools)
362   libudev = dependency('libudev',
363                        required: get_option('mpath').enabled(),
364                        static: enable_static)
365 endif
366
367 mpathpersist = not_found
368 mpathpersist_new_api = false
369 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
370   mpath_test_source_new = '''
371     #include <libudev.h>
372     #include <mpath_persist.h>
373     unsigned mpath_mx_alloc_len = 1024;
374     int logsink;
375     static struct config *multipath_conf;
376     extern struct udev *udev;
377     extern struct config *get_multipath_config(void);
378     extern void put_multipath_config(struct config *conf);
379     struct udev *udev;
380     struct config *get_multipath_config(void) { return multipath_conf; }
381     void put_multipath_config(struct config *conf) { }
382     int main(void) {
383         udev = udev_new();
384         multipath_conf = mpath_lib_init();
385         return 0;
386     }'''
387   mpath_test_source_old = '''
388       #include <libudev.h>
389       #include <mpath_persist.h>
390       unsigned mpath_mx_alloc_len = 1024;
391       int logsink;
392       int main(void) {
393           struct udev *udev = udev_new();
394           mpath_lib_init(udev);
395           return 0;
396       }'''
397   mpathlibs = [libudev]
398   if enable_static
399     mpathlibs += cc.find_library('devmapper',
400                                    required: get_option('mpath'),
401                                    static: enable_static)
402   endif
403   mpathlibs += cc.find_library('multipath',
404                                required: get_option('mpath'),
405                                static: enable_static)
406   mpathlibs += cc.find_library('mpathpersist',
407                                required: get_option('mpath'),
408                                static: enable_static)
409   foreach lib: mpathlibs
410     if not lib.found()
411       mpathlibs = []
412       break
413     endif
414   endforeach
415   if mpathlibs.length() > 0
416     if cc.links(mpath_test_source_new, dependencies: mpathlibs)
417       mpathpersist = declare_dependency(dependencies: mpathlibs)
418       mpathpersist_new_api = true
419     elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
420       mpathpersist = declare_dependency(dependencies: mpathlibs)
421     else
422       if get_option('mpath').enabled()
423         error('Cannot detect libmpathpersist API')
424       else
425         warning('Cannot detect libmpathpersist API, disabling')
426       endif
427     endif
428   endif
429 endif
430
431 brlapi = not_found
432 if 'CONFIG_BRLAPI' in config_host
433   brlapi = declare_dependency(link_args: config_host['BRLAPI_LIBS'].split())
434 endif
435
436 sdl = not_found
437 if have_system
438   sdl = dependency('sdl2', required: get_option('sdl'), static: enable_static)
439   sdl_image = not_found
440 endif
441 if sdl.found()
442   # work around 2.0.8 bug
443   sdl = declare_dependency(compile_args: '-Wno-undef',
444                            dependencies: sdl)
445   sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
446                          method: 'pkg-config', static: enable_static)
447 else
448   if get_option('sdl_image').enabled()
449     error('sdl-image required, but SDL was @0@'.format(
450           get_option('sdl').disabled() ? 'disabled' : 'not found'))
451   endif
452   sdl_image = not_found
453 endif
454
455 rbd = not_found
456 if 'CONFIG_RBD' in config_host
457   rbd = declare_dependency(link_args: config_host['RBD_LIBS'].split())
458 endif
459 glusterfs = not_found
460 if 'CONFIG_GLUSTERFS' in config_host
461   glusterfs = declare_dependency(compile_args: config_host['GLUSTERFS_CFLAGS'].split(),
462                                  link_args: config_host['GLUSTERFS_LIBS'].split())
463 endif
464 libssh = not_found
465 if 'CONFIG_LIBSSH' in config_host
466   libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
467                               link_args: config_host['LIBSSH_LIBS'].split())
468 endif
469 libbzip2 = not_found
470 if 'CONFIG_BZIP2' in config_host
471   libbzip2 = declare_dependency(link_args: config_host['BZIP2_LIBS'].split())
472 endif
473 liblzfse = not_found
474 if 'CONFIG_LZFSE' in config_host
475   liblzfse = declare_dependency(link_args: config_host['LZFSE_LIBS'].split())
476 endif
477 oss = not_found
478 if 'CONFIG_AUDIO_OSS' in config_host
479   oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
480 endif
481 dsound = not_found
482 if 'CONFIG_AUDIO_DSOUND' in config_host
483   dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
484 endif
485 coreaudio = not_found
486 if 'CONFIG_AUDIO_COREAUDIO' in config_host
487   coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
488 endif
489 opengl = not_found
490 if 'CONFIG_OPENGL' in config_host
491   opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
492                               link_args: config_host['OPENGL_LIBS'].split())
493 endif
494 gtk = not_found
495 if 'CONFIG_GTK' in config_host
496   gtk = declare_dependency(compile_args: config_host['GTK_CFLAGS'].split(),
497                               link_args: config_host['GTK_LIBS'].split())
498 endif
499 vte = not_found
500 if 'CONFIG_VTE' in config_host
501   vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
502                            link_args: config_host['VTE_LIBS'].split())
503 endif
504 x11 = not_found
505 if 'CONFIG_X11' in config_host
506   x11 = declare_dependency(compile_args: config_host['X11_CFLAGS'].split(),
507                            link_args: config_host['X11_LIBS'].split())
508 endif
509 curses = not_found
510 if 'CONFIG_CURSES' in config_host
511   curses = declare_dependency(compile_args: config_host['CURSES_CFLAGS'].split(),
512                               link_args: config_host['CURSES_LIBS'].split())
513 endif
514 iconv = not_found
515 if 'CONFIG_ICONV' in config_host
516   iconv = declare_dependency(compile_args: config_host['ICONV_CFLAGS'].split(),
517                              link_args: config_host['ICONV_LIBS'].split())
518 endif
519 vnc = not_found
520 png = not_found
521 jpeg = not_found
522 sasl = not_found
523 if get_option('vnc').enabled()
524   vnc = declare_dependency() # dummy dependency
525   png = dependency('libpng', required: get_option('vnc_png'),
526                    method: 'pkg-config', static: enable_static)
527   jpeg = cc.find_library('jpeg', has_headers: ['jpeglib.h'],
528                          required: get_option('vnc_jpeg'),
529                          static: enable_static)
530   sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
531                          required: get_option('vnc_sasl'),
532                          static: enable_static)
533   if sasl.found()
534     sasl = declare_dependency(dependencies: sasl,
535                               compile_args: '-DSTRUCT_IOVEC_DEFINED')
536   endif
537 endif
538 fdt = not_found
539 if 'CONFIG_FDT' in config_host
540   fdt = declare_dependency(compile_args: config_host['FDT_CFLAGS'].split(),
541                            link_args: config_host['FDT_LIBS'].split())
542 endif
543 snappy = not_found
544 if 'CONFIG_SNAPPY' in config_host
545   snappy = declare_dependency(link_args: config_host['SNAPPY_LIBS'].split())
546 endif
547 lzo = not_found
548 if 'CONFIG_LZO' in config_host
549   lzo = declare_dependency(link_args: config_host['LZO_LIBS'].split())
550 endif
551 rdma = not_found
552 if 'CONFIG_RDMA' in config_host
553   rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
554 endif
555 numa = not_found
556 if 'CONFIG_NUMA' in config_host
557   numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
558 endif
559 xen = not_found
560 if 'CONFIG_XEN_BACKEND' in config_host
561   xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
562                            link_args: config_host['XEN_LIBS'].split())
563 endif
564 cacard = not_found
565 if 'CONFIG_SMARTCARD' in config_host
566   cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
567                               link_args: config_host['SMARTCARD_LIBS'].split())
568 endif
569 u2f = not_found
570 if have_system
571   u2f = dependency('u2f-emu', required: get_option('u2f'),
572                    method: 'pkg-config',
573                    static: enable_static)
574 endif
575 usbredir = not_found
576 if 'CONFIG_USB_REDIR' in config_host
577   usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
578                                 link_args: config_host['USB_REDIR_LIBS'].split())
579 endif
580 libusb = not_found
581 if 'CONFIG_USB_LIBUSB' in config_host
582   libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
583                               link_args: config_host['LIBUSB_LIBS'].split())
584 endif
585 capstone = not_found
586 if 'CONFIG_CAPSTONE' in config_host
587   capstone = declare_dependency(compile_args: config_host['CAPSTONE_CFLAGS'].split(),
588                                 link_args: config_host['CAPSTONE_LIBS'].split())
589 endif
590 libpmem = not_found
591 if 'CONFIG_LIBPMEM' in config_host
592   libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
593                                link_args: config_host['LIBPMEM_LIBS'].split())
594 endif
595 libdaxctl = not_found
596 if 'CONFIG_LIBDAXCTL' in config_host
597   libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
598 endif
599 tasn1 = not_found
600 if 'CONFIG_TASN1' in config_host
601   tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(),
602                              link_args: config_host['TASN1_LIBS'].split())
603 endif
604 keyutils = dependency('libkeyutils', required: false,
605                       method: 'pkg-config', static: enable_static)
606
607 has_gettid = cc.has_function('gettid')
608
609 # Malloc tests
610
611 malloc = []
612 if get_option('malloc') == 'system'
613   has_malloc_trim = \
614     not get_option('malloc_trim').disabled() and \
615     cc.links('''#include <malloc.h>
616                 int main(void) { malloc_trim(0); return 0; }''')
617 else
618   has_malloc_trim = false
619   malloc = cc.find_library(get_option('malloc'), required: true)
620 endif
621 if not has_malloc_trim and get_option('malloc_trim').enabled()
622   if get_option('malloc') == 'system'
623     error('malloc_trim not available on this platform.')
624   else
625     error('malloc_trim not available with non-libc memory allocator')
626   endif
627 endif
628
629 # Create config-host.h
630
631 config_host_data.set('CONFIG_COCOA', cocoa.found())
632 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
633 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
634 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
635 config_host_data.set('CONFIG_SDL', sdl.found())
636 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
637 config_host_data.set('CONFIG_VNC', vnc.found())
638 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
639 config_host_data.set('CONFIG_VNC_PNG', png.found())
640 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
641 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
642 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
643 config_host_data.set('CONFIG_GETTID', has_gettid)
644 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
645 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
646 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
647 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
648 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
649
650 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
651 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
652 strings = ['HOST_DSOSUF', 'CONFIG_IASL', 'bindir', 'prefix', 'qemu_confdir', 'qemu_datadir',
653            'qemu_moddir', 'qemu_localstatedir', 'qemu_helperdir', 'qemu_localedir',
654            'qemu_icondir', 'qemu_desktopdir', 'qemu_firmwarepath', 'sysconfdir']
655 foreach k, v: config_host
656   if ignored.contains(k)
657     # do nothing
658   elif arrays.contains(k)
659     if v != ''
660       v = '"' + '", "'.join(v.split()) + '", '
661     endif
662     config_host_data.set(k, v)
663   elif k == 'ARCH'
664     config_host_data.set('HOST_' + v.to_upper(), 1)
665   elif strings.contains(k)
666     if not k.startswith('CONFIG_')
667       k = 'CONFIG_' + k.to_upper()
668     endif
669     config_host_data.set_quoted(k, v)
670   elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
671     config_host_data.set(k, v == 'y' ? 1 : v)
672   endif
673 endforeach
674 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
675
676 minikconf = find_program('scripts/minikconf.py')
677 config_all = {}
678 config_all_devices = {}
679 config_all_disas = {}
680 config_devices_mak_list = []
681 config_devices_h = {}
682 config_target_h = {}
683 config_target_mak = {}
684
685 disassemblers = {
686   'alpha' : ['CONFIG_ALPHA_DIS'],
687   'arm' : ['CONFIG_ARM_DIS'],
688   'avr' : ['CONFIG_AVR_DIS'],
689   'cris' : ['CONFIG_CRIS_DIS'],
690   'hppa' : ['CONFIG_HPPA_DIS'],
691   'i386' : ['CONFIG_I386_DIS'],
692   'x86_64' : ['CONFIG_I386_DIS'],
693   'x32' : ['CONFIG_I386_DIS'],
694   'lm32' : ['CONFIG_LM32_DIS'],
695   'm68k' : ['CONFIG_M68K_DIS'],
696   'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
697   'mips' : ['CONFIG_MIPS_DIS'],
698   'moxie' : ['CONFIG_MOXIE_DIS'],
699   'nios2' : ['CONFIG_NIOS2_DIS'],
700   'or1k' : ['CONFIG_OPENRISC_DIS'],
701   'ppc' : ['CONFIG_PPC_DIS'],
702   'riscv' : ['CONFIG_RISCV_DIS'],
703   'rx' : ['CONFIG_RX_DIS'],
704   's390' : ['CONFIG_S390_DIS'],
705   'sh4' : ['CONFIG_SH4_DIS'],
706   'sparc' : ['CONFIG_SPARC_DIS'],
707   'xtensa' : ['CONFIG_XTENSA_DIS'],
708 }
709 if link_language == 'cpp'
710   disassemblers += {
711     'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
712     'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
713     'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
714   }
715 endif
716
717 kconfig_external_symbols = [
718   'CONFIG_KVM',
719   'CONFIG_XEN',
720   'CONFIG_TPM',
721   'CONFIG_SPICE',
722   'CONFIG_IVSHMEM',
723   'CONFIG_OPENGL',
724   'CONFIG_X11',
725   'CONFIG_VHOST_USER',
726   'CONFIG_VHOST_VDPA',
727   'CONFIG_VHOST_KERNEL',
728   'CONFIG_VIRTFS',
729   'CONFIG_LINUX',
730   'CONFIG_PVRDMA',
731 ]
732 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
733
734 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
735 actual_target_dirs = []
736 foreach target : target_dirs
737   config_target = { 'TARGET_NAME': target.split('-')[0] }
738   if target.endswith('linux-user')
739     if targetos != 'linux'
740       if default_targets
741         continue
742       endif
743       error('Target @0@ is only available on a Linux host'.format(target))
744     endif
745     config_target += { 'CONFIG_LINUX_USER': 'y' }
746   elif target.endswith('bsd-user')
747     if 'CONFIG_BSD' not in config_host
748       if default_targets
749         continue
750       endif
751       error('Target @0@ is only available on a BSD host'.format(target))
752     endif
753     config_target += { 'CONFIG_BSD_USER': 'y' }
754   elif target.endswith('softmmu')
755     config_target += { 'CONFIG_SOFTMMU': 'y' }
756   endif
757   if target.endswith('-user')
758     config_target += {
759       'CONFIG_USER_ONLY': 'y',
760       'CONFIG_QEMU_INTERP_PREFIX':
761         config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
762     }
763   endif
764
765   have_accel = false
766   foreach sym: accelerators
767     if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
768       config_target += { sym: 'y' }
769       config_all += { sym: 'y' }
770       if sym == 'CONFIG_XEN' and have_xen_pci_passthrough
771         config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
772       endif
773       have_accel = true
774     endif
775   endforeach
776   if not have_accel
777     if default_targets
778       continue
779     endif
780     error('No accelerator available for target @0@'.format(target))
781   endif
782
783   actual_target_dirs += target
784   config_target += keyval.load('default-configs/targets' / target + '.mak')
785   config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
786
787   # Add default keys
788   if 'TARGET_BASE_ARCH' not in config_target
789     config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
790   endif
791   if 'TARGET_ABI_DIR' not in config_target
792     config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
793   endif
794
795   foreach k, v: disassemblers
796     if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
797       foreach sym: v
798         config_target += { sym: 'y' }
799         config_all_disas += { sym: 'y' }
800       endforeach
801     endif
802   endforeach
803
804   config_target_data = configuration_data()
805   foreach k, v: config_target
806     if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
807       # do nothing
808     elif ignored.contains(k)
809       # do nothing
810     elif k == 'TARGET_BASE_ARCH'
811       # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
812       # not used to select files from sourcesets.
813       config_target_data.set('TARGET_' + v.to_upper(), 1)
814     elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
815       config_target_data.set_quoted(k, v)
816     elif v == 'y'
817       config_target_data.set(k, 1)
818     else
819       config_target_data.set(k, v)
820     endif
821   endforeach
822   config_target_h += {target: configure_file(output: target + '-config-target.h',
823                                                configuration: config_target_data)}
824
825   if target.endswith('-softmmu')
826     base_kconfig = []
827     foreach sym : kconfig_external_symbols
828       if sym in config_target or sym in config_host
829         base_kconfig += '@0@=y'.format(sym)
830       endif
831     endforeach
832
833     config_devices_mak = target + '-config-devices.mak'
834     config_devices_mak = configure_file(
835       input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
836       output: config_devices_mak,
837       depfile: config_devices_mak + '.d',
838       capture: true,
839       command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'],
840                 config_devices_mak, '@DEPFILE@', '@INPUT@',
841                 base_kconfig])
842
843     config_devices_data = configuration_data()
844     config_devices = keyval.load(config_devices_mak)
845     foreach k, v: config_devices
846       config_devices_data.set(k, 1)
847     endforeach
848     config_devices_mak_list += config_devices_mak
849     config_devices_h += {target: configure_file(output: target + '-config-devices.h',
850                                                 configuration: config_devices_data)}
851     config_target += config_devices
852     config_all_devices += config_devices
853   endif
854   config_target_mak += {target: config_target}
855 endforeach
856 target_dirs = actual_target_dirs
857
858 # This configuration is used to build files that are shared by
859 # multiple binaries, and then extracted out of the "common"
860 # static_library target.
861 #
862 # We do not use all_sources()/all_dependencies(), because it would
863 # build literally all source files, including devices only used by
864 # targets that are not built for this compilation.  The CONFIG_ALL
865 # pseudo symbol replaces it.
866
867 config_all += config_all_devices
868 config_all += config_host
869 config_all += config_all_disas
870 config_all += {
871   'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
872   'CONFIG_SOFTMMU': have_system,
873   'CONFIG_USER_ONLY': have_user,
874   'CONFIG_ALL': true,
875 }
876
877 # Generators
878
879 hxtool = find_program('scripts/hxtool')
880 shaderinclude = find_program('scripts/shaderinclude.pl')
881 qapi_gen = find_program('scripts/qapi-gen.py')
882 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
883                      meson.source_root() / 'scripts/qapi/commands.py',
884                      meson.source_root() / 'scripts/qapi/common.py',
885                      meson.source_root() / 'scripts/qapi/error.py',
886                      meson.source_root() / 'scripts/qapi/events.py',
887                      meson.source_root() / 'scripts/qapi/expr.py',
888                      meson.source_root() / 'scripts/qapi/gen.py',
889                      meson.source_root() / 'scripts/qapi/introspect.py',
890                      meson.source_root() / 'scripts/qapi/parser.py',
891                      meson.source_root() / 'scripts/qapi/schema.py',
892                      meson.source_root() / 'scripts/qapi/source.py',
893                      meson.source_root() / 'scripts/qapi/types.py',
894                      meson.source_root() / 'scripts/qapi/visit.py',
895                      meson.source_root() / 'scripts/qapi/common.py',
896                      meson.source_root() / 'scripts/qapi-gen.py'
897 ]
898
899 tracetool = [
900   python, files('scripts/tracetool.py'),
901    '--backend=' + config_host['TRACE_BACKENDS']
902 ]
903
904 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
905                     meson.current_source_dir(),
906                     config_host['PKGVERSION'], meson.project_version()]
907 qemu_version = custom_target('qemu-version.h',
908                              output: 'qemu-version.h',
909                              command: qemu_version_cmd,
910                              capture: true,
911                              build_by_default: true,
912                              build_always_stale: true)
913 genh += qemu_version
914
915 hxdep = []
916 hx_headers = [
917   ['qemu-options.hx', 'qemu-options.def'],
918   ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
919 ]
920 if have_system
921   hx_headers += [
922     ['hmp-commands.hx', 'hmp-commands.h'],
923     ['hmp-commands-info.hx', 'hmp-commands-info.h'],
924   ]
925 endif
926 foreach d : hx_headers
927   hxdep += custom_target(d[1],
928                 input: files(d[0]),
929                 output: d[1],
930                 capture: true,
931                 build_by_default: true, # to be removed when added to a target
932                 command: [hxtool, '-h', '@INPUT0@'])
933 endforeach
934 genh += hxdep
935
936 SPHINX_ARGS = [config_host['SPHINX_BUILD'],
937                '-Dversion=' + meson.project_version(),
938                '-Drelease=' + config_host['PKGVERSION']]
939
940 if get_option('werror')
941   SPHINX_ARGS += [ '-W' ]
942 endif
943
944 sphinx_extn_depends = [ meson.source_root() / 'docs/sphinx/depfile.py',
945                         meson.source_root() / 'docs/sphinx/hxtool.py',
946                         meson.source_root() / 'docs/sphinx/kerneldoc.py',
947                         meson.source_root() / 'docs/sphinx/kernellog.py',
948                         meson.source_root() / 'docs/sphinx/qapidoc.py',
949                         meson.source_root() / 'docs/sphinx/qmp_lexer.py',
950                         qapi_gen_depends ]
951
952 # Collect sourcesets.
953
954 util_ss = ss.source_set()
955 stub_ss = ss.source_set()
956 trace_ss = ss.source_set()
957 block_ss = ss.source_set()
958 blockdev_ss = ss.source_set()
959 qmp_ss = ss.source_set()
960 common_ss = ss.source_set()
961 softmmu_ss = ss.source_set()
962 user_ss = ss.source_set()
963 bsd_user_ss = ss.source_set()
964 linux_user_ss = ss.source_set()
965 specific_ss = ss.source_set()
966 specific_fuzz_ss = ss.source_set()
967
968 modules = {}
969 hw_arch = {}
970 target_arch = {}
971 target_softmmu_arch = {}
972
973 ###############
974 # Trace files #
975 ###############
976
977 # TODO: add each directory to the subdirs from its own meson.build, once
978 # we have those
979 trace_events_subdirs = [
980   'accel/kvm',
981   'accel/tcg',
982   'crypto',
983   'monitor',
984 ]
985 if have_user
986   trace_events_subdirs += [ 'linux-user' ]
987 endif
988 if have_block
989   trace_events_subdirs += [
990     'authz',
991     'block',
992     'io',
993     'nbd',
994     'scsi',
995   ]
996 endif
997 if have_system
998   trace_events_subdirs += [
999     'audio',
1000     'backends',
1001     'backends/tpm',
1002     'chardev',
1003     'hw/9pfs',
1004     'hw/acpi',
1005     'hw/alpha',
1006     'hw/arm',
1007     'hw/audio',
1008     'hw/block',
1009     'hw/block/dataplane',
1010     'hw/char',
1011     'hw/display',
1012     'hw/dma',
1013     'hw/hppa',
1014     'hw/hyperv',
1015     'hw/i2c',
1016     'hw/i386',
1017     'hw/i386/xen',
1018     'hw/ide',
1019     'hw/input',
1020     'hw/intc',
1021     'hw/isa',
1022     'hw/mem',
1023     'hw/mips',
1024     'hw/misc',
1025     'hw/misc/macio',
1026     'hw/net',
1027     'hw/nvram',
1028     'hw/pci',
1029     'hw/pci-host',
1030     'hw/ppc',
1031     'hw/rdma',
1032     'hw/rdma/vmw',
1033     'hw/rtc',
1034     'hw/s390x',
1035     'hw/scsi',
1036     'hw/sd',
1037     'hw/sparc',
1038     'hw/sparc64',
1039     'hw/ssi',
1040     'hw/timer',
1041     'hw/tpm',
1042     'hw/usb',
1043     'hw/vfio',
1044     'hw/virtio',
1045     'hw/watchdog',
1046     'hw/xen',
1047     'hw/gpio',
1048     'migration',
1049     'net',
1050     'softmmu',
1051     'ui',
1052   ]
1053 endif
1054 trace_events_subdirs += [
1055   'hw/core',
1056   'qapi',
1057   'qom',
1058   'target/arm',
1059   'target/hppa',
1060   'target/i386',
1061   'target/mips',
1062   'target/ppc',
1063   'target/riscv',
1064   'target/s390x',
1065   'target/sparc',
1066   'util',
1067 ]
1068
1069 subdir('qapi')
1070 subdir('qobject')
1071 subdir('stubs')
1072 subdir('trace')
1073 subdir('util')
1074 subdir('qom')
1075 subdir('authz')
1076 subdir('crypto')
1077 subdir('ui')
1078
1079
1080 if enable_modules
1081   libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1082   modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1083 endif
1084
1085 # Build targets from sourcesets
1086
1087 stub_ss = stub_ss.apply(config_all, strict: false)
1088
1089 util_ss.add_all(trace_ss)
1090 util_ss = util_ss.apply(config_all, strict: false)
1091 libqemuutil = static_library('qemuutil',
1092                              sources: util_ss.sources() + stub_ss.sources() + genh,
1093                              dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1094 qemuutil = declare_dependency(link_with: libqemuutil,
1095                               sources: genh + version_res)
1096
1097 decodetree = generator(find_program('scripts/decodetree.py'),
1098                        output: 'decode-@BASENAME@.c.inc',
1099                        arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1100
1101 subdir('audio')
1102 subdir('io')
1103 subdir('chardev')
1104 subdir('fsdev')
1105 subdir('libdecnumber')
1106 subdir('target')
1107 subdir('dump')
1108
1109 block_ss.add(files(
1110   'block.c',
1111   'blockdev-nbd.c',
1112   'blockjob.c',
1113   'job.c',
1114   'qemu-io-cmds.c',
1115 ))
1116 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1117
1118 subdir('nbd')
1119 subdir('scsi')
1120 subdir('block')
1121
1122 blockdev_ss.add(files(
1123   'blockdev.c',
1124   'iothread.c',
1125   'job-qmp.c',
1126 ))
1127
1128 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1129 # os-win32.c does not
1130 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1131 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1132
1133 softmmu_ss.add_all(blockdev_ss)
1134 softmmu_ss.add(files(
1135   'bootdevice.c',
1136   'dma-helpers.c',
1137   'qdev-monitor.c',
1138 ), sdl)
1139
1140 softmmu_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c'))
1141 softmmu_ss.add(when: 'CONFIG_SECCOMP', if_true: [files('qemu-seccomp.c'), seccomp])
1142 softmmu_ss.add(when: ['CONFIG_FDT', fdt],  if_true: [files('device_tree.c')])
1143
1144 common_ss.add(files('cpus-common.c'))
1145
1146 subdir('softmmu')
1147
1148 specific_ss.add(files('disas.c', 'exec.c', 'gdbstub.c'), capstone, libpmem, libdaxctl)
1149 specific_ss.add(files('exec-vary.c'))
1150 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1151   'fpu/softfloat.c',
1152   'tcg/optimize.c',
1153   'tcg/tcg-common.c',
1154   'tcg/tcg-op-gvec.c',
1155   'tcg/tcg-op-vec.c',
1156   'tcg/tcg-op.c',
1157   'tcg/tcg.c',
1158 ))
1159 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1160
1161 subdir('backends')
1162 subdir('disas')
1163 subdir('migration')
1164 subdir('monitor')
1165 subdir('net')
1166 subdir('replay')
1167 subdir('hw')
1168 subdir('accel')
1169 subdir('plugins')
1170 subdir('bsd-user')
1171 subdir('linux-user')
1172
1173 bsd_user_ss.add(files('gdbstub.c'))
1174 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1175
1176 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1177 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1178
1179 # needed for fuzzing binaries
1180 subdir('tests/qtest/libqos')
1181 subdir('tests/qtest/fuzz')
1182
1183 block_mods = []
1184 softmmu_mods = []
1185 foreach d, list : modules
1186   foreach m, module_ss : list
1187     if enable_modules and targetos != 'windows'
1188       module_ss = module_ss.apply(config_all, strict: false)
1189       sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1190                           dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1191       if d == 'block'
1192         block_mods += sl
1193       else
1194         softmmu_mods += sl
1195       endif
1196     else
1197       if d == 'block'
1198         block_ss.add_all(module_ss)
1199       else
1200         softmmu_ss.add_all(module_ss)
1201       endif
1202     endif
1203   endforeach
1204 endforeach
1205
1206 nm = find_program('nm')
1207 undefsym = find_program('scripts/undefsym.py')
1208 block_syms = custom_target('block.syms', output: 'block.syms',
1209                              input: [libqemuutil, block_mods],
1210                              capture: true,
1211                              command: [undefsym, nm, '@INPUT@'])
1212 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1213                              input: [libqemuutil, softmmu_mods],
1214                              capture: true,
1215                              command: [undefsym, nm, '@INPUT@'])
1216
1217 block_ss = block_ss.apply(config_host, strict: false)
1218 libblock = static_library('block', block_ss.sources() + genh,
1219                           dependencies: block_ss.dependencies(),
1220                           link_depends: block_syms,
1221                           name_suffix: 'fa',
1222                           build_by_default: false)
1223
1224 block = declare_dependency(link_whole: [libblock],
1225                            link_args: '@block.syms',
1226                            dependencies: [crypto, io])
1227
1228 qmp_ss = qmp_ss.apply(config_host, strict: false)
1229 libqmp = static_library('qmp', qmp_ss.sources() + genh,
1230                         dependencies: qmp_ss.dependencies(),
1231                         name_suffix: 'fa',
1232                         build_by_default: false)
1233
1234 qmp = declare_dependency(link_whole: [libqmp])
1235
1236 foreach m : block_mods + softmmu_mods
1237   shared_module(m.name(),
1238                 name_prefix: '',
1239                 link_whole: m,
1240                 install: true,
1241                 install_dir: config_host['qemu_moddir'])
1242 endforeach
1243
1244 softmmu_ss.add(authz, block, chardev, crypto, io, qmp)
1245 common_ss.add(qom, qemuutil)
1246
1247 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
1248 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
1249
1250 common_all = common_ss.apply(config_all, strict: false)
1251 common_all = static_library('common',
1252                             build_by_default: false,
1253                             sources: common_all.sources() + genh,
1254                             dependencies: common_all.dependencies(),
1255                             name_suffix: 'fa')
1256
1257 feature_to_c = find_program('scripts/feature_to_c.sh')
1258
1259 emulators = {}
1260 foreach target : target_dirs
1261   config_target = config_target_mak[target]
1262   target_name = config_target['TARGET_NAME']
1263   arch = config_target['TARGET_BASE_ARCH']
1264   arch_srcs = [config_target_h[target]]
1265   arch_deps = []
1266   c_args = ['-DNEED_CPU_H',
1267             '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
1268             '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
1269   link_args = emulator_link_args
1270
1271   config_target += config_host
1272   target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
1273   if targetos == 'linux'
1274     target_inc += include_directories('linux-headers', is_system: true)
1275   endif
1276   if target.endswith('-softmmu')
1277     qemu_target_name = 'qemu-system-' + target_name
1278     target_type='system'
1279     t = target_softmmu_arch[arch].apply(config_target, strict: false)
1280     arch_srcs += t.sources()
1281     arch_deps += t.dependencies()
1282
1283     hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
1284     hw = hw_arch[hw_dir].apply(config_target, strict: false)
1285     arch_srcs += hw.sources()
1286     arch_deps += hw.dependencies()
1287
1288     arch_srcs += config_devices_h[target]
1289     link_args += ['@block.syms', '@qemu.syms']
1290   else
1291     abi = config_target['TARGET_ABI_DIR']
1292     target_type='user'
1293     qemu_target_name = 'qemu-' + target_name
1294     if 'CONFIG_LINUX_USER' in config_target
1295       base_dir = 'linux-user'
1296       target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
1297     else
1298       base_dir = 'bsd-user'
1299     endif
1300     target_inc += include_directories(
1301       base_dir,
1302       base_dir / abi,
1303     )
1304     if 'CONFIG_LINUX_USER' in config_target
1305       dir = base_dir / abi
1306       arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
1307       if config_target.has_key('TARGET_SYSTBL_ABI')
1308         arch_srcs += \
1309           syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
1310                                              extra_args : config_target['TARGET_SYSTBL_ABI'])
1311       endif
1312     endif
1313   endif
1314
1315   if 'TARGET_XML_FILES' in config_target
1316     gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
1317                                 output: target + '-gdbstub-xml.c',
1318                                 input: files(config_target['TARGET_XML_FILES'].split()),
1319                                 command: [feature_to_c, '@INPUT@'],
1320                                 capture: true)
1321     arch_srcs += gdbstub_xml
1322   endif
1323
1324   t = target_arch[arch].apply(config_target, strict: false)
1325   arch_srcs += t.sources()
1326   arch_deps += t.dependencies()
1327
1328   target_common = common_ss.apply(config_target, strict: false)
1329   objects = common_all.extract_objects(target_common.sources())
1330   deps = target_common.dependencies()
1331
1332   target_specific = specific_ss.apply(config_target, strict: false)
1333   arch_srcs += target_specific.sources()
1334   arch_deps += target_specific.dependencies()
1335
1336   lib = static_library('qemu-' + target,
1337                  sources: arch_srcs + genh,
1338                  dependencies: arch_deps,
1339                  objects: objects,
1340                  include_directories: target_inc,
1341                  c_args: c_args,
1342                  build_by_default: false,
1343                  name_suffix: 'fa')
1344
1345   if target.endswith('-softmmu')
1346     execs = [{
1347       'name': 'qemu-system-' + target_name,
1348       'gui': false,
1349       'sources': files('softmmu/main.c'),
1350       'dependencies': []
1351     }]
1352     if targetos == 'windows' and (sdl.found() or gtk.found())
1353       execs += [{
1354         'name': 'qemu-system-' + target_name + 'w',
1355         'gui': true,
1356         'sources': files('softmmu/main.c'),
1357         'dependencies': []
1358       }]
1359     endif
1360     if config_host.has_key('CONFIG_FUZZ')
1361       specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
1362       execs += [{
1363         'name': 'qemu-fuzz-' + target_name,
1364         'gui': false,
1365         'sources': specific_fuzz.sources(),
1366         'dependencies': specific_fuzz.dependencies(),
1367       }]
1368     endif
1369   else
1370     execs = [{
1371       'name': 'qemu-' + target_name,
1372       'gui': false,
1373       'sources': [],
1374       'dependencies': []
1375     }]
1376   endif
1377   foreach exe: execs
1378     emulators += {exe['name']:
1379          executable(exe['name'], exe['sources'],
1380                install: true,
1381                c_args: c_args,
1382                dependencies: arch_deps + deps + exe['dependencies'],
1383                objects: lib.extract_all_objects(recursive: true),
1384                link_language: link_language,
1385                link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
1386                link_args: link_args,
1387                gui_app: exe['gui'])
1388     }
1389
1390     if 'CONFIG_TRACE_SYSTEMTAP' in config_host
1391       foreach stp: [
1392         {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
1393         {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
1394         {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
1395         {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
1396       ]
1397         custom_target(exe['name'] + stp['ext'],
1398                       input: trace_events_all,
1399                       output: exe['name'] + stp['ext'],
1400                       capture: true,
1401                       install: stp['install'],
1402                       install_dir: qemu_datadir / '../systemtap/tapset',
1403                       command: [
1404                         tracetool, '--group=all', '--format=' + stp['fmt'],
1405                         '--binary=' + stp['bin'],
1406                         '--target-name=' + target_name,
1407                         '--target-type=' + target_type,
1408                         '--probe-prefix=qemu.' + target_type + '.' + target_name,
1409                         '@INPUT@',
1410                       ])
1411       endforeach
1412     endif
1413   endforeach
1414 endforeach
1415
1416 # Other build targets
1417
1418 if 'CONFIG_PLUGIN' in config_host
1419   install_headers('include/qemu/qemu-plugin.h')
1420 endif
1421
1422 if 'CONFIG_GUEST_AGENT' in config_host
1423   subdir('qga')
1424 endif
1425
1426 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
1427 # when we don't build tools or system
1428 if xkbcommon.found()
1429   # used for the update-keymaps target, so include rules even if !have_tools
1430   qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
1431                            dependencies: [qemuutil, xkbcommon], install: have_tools)
1432 endif
1433
1434 if have_tools
1435   qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
1436              dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
1437   qemu_io = executable('qemu-io', files('qemu-io.c'),
1438              dependencies: [block, qemuutil], install: true)
1439   qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
1440                dependencies: [block, qemuutil], install: true)
1441
1442   subdir('storage-daemon')
1443   subdir('contrib/rdmacm-mux')
1444   subdir('contrib/elf2dmp')
1445
1446   executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
1447              dependencies: qemuutil,
1448              install: true)
1449
1450   if 'CONFIG_VHOST_USER' in config_host
1451     subdir('contrib/libvhost-user')
1452     subdir('contrib/vhost-user-blk')
1453     subdir('contrib/vhost-user-gpu')
1454     subdir('contrib/vhost-user-input')
1455     subdir('contrib/vhost-user-scsi')
1456   endif
1457
1458   if targetos == 'linux'
1459     executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
1460                dependencies: [qemuutil, libcap_ng],
1461                install: true,
1462                install_dir: get_option('libexecdir'))
1463
1464     executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
1465                dependencies: [authz, crypto, io, qom, qemuutil,
1466                               libcap_ng, mpathpersist],
1467                install: true)
1468   endif
1469
1470   if 'CONFIG_IVSHMEM' in config_host
1471     subdir('contrib/ivshmem-client')
1472     subdir('contrib/ivshmem-server')
1473   endif
1474 endif
1475
1476 subdir('scripts')
1477 subdir('tools')
1478 subdir('pc-bios')
1479 subdir('tests')
1480 subdir('docs')
1481 if 'CONFIG_GTK' in config_host
1482   subdir('po')
1483 endif
1484
1485 if host_machine.system() == 'windows'
1486   nsis_cmd = [
1487     find_program('scripts/nsis.py'),
1488     '@OUTPUT@',
1489     get_option('prefix'),
1490     meson.current_source_dir(),
1491     host_machine.cpu_family(),
1492     '--',
1493     '-DDISPLAYVERSION=' + meson.project_version(),
1494   ]
1495   if build_docs
1496     nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
1497   endif
1498   if 'CONFIG_GTK' in config_host
1499     nsis_cmd += '-DCONFIG_GTK=y'
1500   endif
1501
1502   nsis = custom_target('nsis',
1503                        output: 'qemu-setup-' + meson.project_version() + '.exe',
1504                        input: files('qemu.nsi'),
1505                        build_always_stale: true,
1506                        command: nsis_cmd + ['@INPUT@'])
1507   alias_target('installer', nsis)
1508 endif
1509
1510 summary_info = {}
1511 summary_info += {'Install prefix':    config_host['prefix']}
1512 summary_info += {'BIOS directory':    config_host['qemu_datadir']}
1513 summary_info += {'firmware path':     config_host['qemu_firmwarepath']}
1514 summary_info += {'binary directory':  config_host['bindir']}
1515 summary_info += {'library directory': config_host['libdir']}
1516 summary_info += {'module directory':  config_host['qemu_moddir']}
1517 summary_info += {'libexec directory': config_host['libexecdir']}
1518 summary_info += {'include directory': config_host['includedir']}
1519 summary_info += {'config directory':  config_host['sysconfdir']}
1520 if targetos != 'windows'
1521   summary_info += {'local state directory': config_host['qemu_localstatedir']}
1522   summary_info += {'Manual directory':      get_option('mandir')}
1523 else
1524   summary_info += {'local state directory': 'queried at runtime'}
1525 endif
1526 summary_info += {'Doc directory':     get_option('docdir')}
1527 summary_info += {'Build directory':   meson.current_build_dir()}
1528 summary_info += {'Source path':       meson.current_source_dir()}
1529 summary_info += {'GIT binary':        config_host['GIT']}
1530 summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
1531 summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
1532 summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
1533 if link_language == 'cpp'
1534   summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
1535 else
1536   summary_info += {'C++ compiler':      false}
1537 endif
1538 if targetos == 'darwin'
1539   summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
1540 endif
1541 summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
1542 summary_info += {'CFLAGS':            config_host['CFLAGS']}
1543 summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
1544 summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
1545 summary_info += {'make':              config_host['MAKE']}
1546 summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
1547 summary_info += {'sphinx-build':      config_host['SPHINX_BUILD']}
1548 summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
1549 # TODO: add back version
1550 summary_info += {'slirp support':     config_host.has_key('CONFIG_SLIRP')}
1551 if config_host.has_key('CONFIG_SLIRP')
1552   summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
1553 endif
1554 summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
1555 if config_host.has_key('CONFIG_MODULES')
1556   summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
1557 endif
1558 summary_info += {'host CPU':          cpu}
1559 summary_info += {'host endianness':   build_machine.endian()}
1560 summary_info += {'target list':       ' '.join(target_dirs)}
1561 summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
1562 summary_info += {'sparse enabled':    sparse.found()}
1563 summary_info += {'strip binaries':    get_option('strip')}
1564 summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
1565 summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
1566 if targetos == 'darwin'
1567   summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
1568 endif
1569 # TODO: add back version
1570 summary_info += {'SDL support':       sdl.found()}
1571 summary_info += {'SDL image support': sdl_image.found()}
1572 # TODO: add back version
1573 summary_info += {'GTK support':       config_host.has_key('CONFIG_GTK')}
1574 summary_info += {'GTK GL support':    config_host.has_key('CONFIG_GTK_GL')}
1575 summary_info += {'pixman':            pixman.found()}
1576 # TODO: add back version
1577 summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
1578 summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
1579 summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
1580 # TODO: add back version
1581 summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
1582 if config_host.has_key('CONFIG_GCRYPT')
1583    summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
1584    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1585 endif
1586 # TODO: add back version
1587 summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
1588 if config_host.has_key('CONFIG_NETTLE')
1589    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1590 endif
1591 summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
1592 summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
1593 summary_info += {'iconv support':     config_host.has_key('CONFIG_ICONV')}
1594 summary_info += {'curses support':    config_host.has_key('CONFIG_CURSES')}
1595 # TODO: add back version
1596 summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
1597 summary_info += {'curl support':      config_host.has_key('CONFIG_CURL')}
1598 summary_info += {'mingw32 support':   targetos == 'windows'}
1599 summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
1600 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
1601 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
1602 summary_info += {'VirtFS support':    config_host.has_key('CONFIG_VIRTFS')}
1603 summary_info += {'Multipath support': mpathpersist.found()}
1604 summary_info += {'VNC support':       vnc.found()}
1605 if vnc.found()
1606   summary_info += {'VNC SASL support':  sasl.found()}
1607   summary_info += {'VNC JPEG support':  jpeg.found()}
1608   summary_info += {'VNC PNG support':   png.found()}
1609 endif
1610 summary_info += {'xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
1611 if config_host.has_key('CONFIG_XEN_BACKEND')
1612   summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
1613 endif
1614 summary_info += {'brlapi support':    config_host.has_key('CONFIG_BRLAPI')}
1615 summary_info += {'Documentation':     config_host.has_key('BUILD_DOCS')}
1616 summary_info += {'PIE':               get_option('b_pie')}
1617 summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
1618 summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
1619 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
1620 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
1621 summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
1622 summary_info += {'Install blobs':     config_host.has_key('INSTALL_BLOBS')}
1623 summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
1624 summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
1625 summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
1626 summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
1627 summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
1628 if config_all.has_key('CONFIG_TCG')
1629   summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
1630   summary_info += {'TCG interpreter':   config_host.has_key('CONFIG_TCG_INTERPRETER')}
1631 endif
1632 summary_info += {'malloc trim support': has_malloc_trim}
1633 summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
1634 summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
1635 summary_info += {'fdt support':       config_host.has_key('CONFIG_FDT')}
1636 summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
1637 summary_info += {'preadv support':    config_host.has_key('CONFIG_PREADV')}
1638 summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
1639 summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
1640 summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
1641 summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
1642 summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
1643 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
1644 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
1645 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
1646 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
1647 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_KERNEL')}
1648 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
1649 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
1650 summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
1651 if config_host['TRACE_BACKENDS'].split().contains('simple')
1652   summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
1653 endif
1654 # TODO: add back protocol and server version
1655 summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
1656 summary_info += {'rbd support':       config_host.has_key('CONFIG_RBD')}
1657 summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
1658 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
1659 summary_info += {'U2F support':       u2f.found()}
1660 summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
1661 summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
1662 summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
1663 summary_info += {'OpenGL dmabufs':    config_host.has_key('CONFIG_OPENGL_DMABUF')}
1664 summary_info += {'libiscsi support':  config_host.has_key('CONFIG_LIBISCSI')}
1665 summary_info += {'libnfs support':    config_host.has_key('CONFIG_LIBNFS')}
1666 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
1667 if targetos == 'windows'
1668   if 'WIN_SDK' in config_host
1669     summary_info += {'Windows SDK':       config_host['WIN_SDK']}
1670   endif
1671   summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
1672   summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
1673   summary_info += {'QGA MSI support':   config_host.has_key('CONFIG_QGA_MSI')}
1674 endif
1675 summary_info += {'seccomp support':   config_host.has_key('CONFIG_SECCOMP')}
1676 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
1677 summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
1678 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
1679 summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
1680 summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
1681 summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
1682 summary_info += {'gcov':              get_option('b_coverage')}
1683 summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
1684 summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
1685 summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
1686 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
1687 summary_info += {'lzo support':       config_host.has_key('CONFIG_LZO')}
1688 summary_info += {'snappy support':    config_host.has_key('CONFIG_SNAPPY')}
1689 summary_info += {'bzip2 support':     config_host.has_key('CONFIG_BZIP2')}
1690 summary_info += {'lzfse support':     config_host.has_key('CONFIG_LZFSE')}
1691 summary_info += {'zstd support':      config_host.has_key('CONFIG_ZSTD')}
1692 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
1693 summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
1694 summary_info += {'memory allocator':  get_option('malloc')}
1695 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
1696 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
1697 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
1698 summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
1699 summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
1700 summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
1701 summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
1702 summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
1703 summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
1704 summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
1705 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
1706 summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
1707 summary_info += {'capstone':          config_host.has_key('CONFIG_CAPSTONE')}
1708 summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
1709 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
1710 summary_info += {'libudev':           libudev.found()}
1711 summary_info += {'default devices':   config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
1712 summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
1713 summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
1714 if config_host.has_key('HAVE_GDB_BIN')
1715   summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
1716 endif
1717 summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
1718 summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
1719 summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
1720 summary(summary_info, bool_yn: true)
1721
1722 if not supported_cpus.contains(cpu)
1723   message()
1724   warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
1725   message()
1726   message('CPU host architecture ' + cpu + ' support is not currently maintained.')
1727   message('The QEMU project intends to remove support for this host CPU in')
1728   message('a future release if nobody volunteers to maintain it and to')
1729   message('provide a build host for our continuous integration setup.')
1730   message('configure has succeeded and you can continue to build, but')
1731   message('if you care about QEMU on this platform you should contact')
1732   message('us upstream at qemu-devel@nongnu.org.')
1733 endif
1734
1735 if not supported_oses.contains(targetos)
1736   message()
1737   warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
1738   message()
1739   message('Host OS ' + targetos + 'support is not currently maintained.')
1740   message('The QEMU project intends to remove support for this host OS in')
1741   message('a future release if nobody volunteers to maintain it and to')
1742   message('provide a build host for our continuous integration setup.')
1743   message('configure has succeeded and you can continue to build, but')
1744   message('if you care about QEMU on this platform you should contact')
1745   message('us upstream at qemu-devel@nongnu.org.')
1746 endif