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