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