OSDN Git Service

Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20211006' into staging
[qmiga/qemu.git] / meson.build
1 project('qemu', ['c'], meson_version: '>=0.58.2',
2         default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto',
3                           'b_staticpic=false'],
4         version: files('VERSION'))
5
6 not_found = dependency('', required: false)
7 keyval = import('keyval')
8 ss = import('sourceset')
9 fs = import('fs')
10
11 sh = find_program('sh')
12 cc = meson.get_compiler('c')
13 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
14 enable_modules = 'CONFIG_MODULES' in config_host
15 enable_static = 'CONFIG_STATIC' in config_host
16
17 # Allow both shared and static libraries unless --enable-static
18 static_kwargs = enable_static ? {'static': true} : {}
19
20 # Temporary directory used for files created while
21 # configure runs. Since it is in the build directory
22 # we can safely blow away any previous version of it
23 # (and we need not jump through hoops to try to delete
24 # it when configure exits.)
25 tmpdir = meson.current_build_dir() / 'meson-private/temp'
26
27 if get_option('qemu_suffix').startswith('/')
28   error('qemu_suffix cannot start with a /')
29 endif
30
31 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
32 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
33 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
34 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
35
36 qemu_desktopdir = get_option('datadir') / 'applications'
37 qemu_icondir = get_option('datadir') / 'icons'
38
39 config_host_data = configuration_data()
40 genh = []
41
42 target_dirs = config_host['TARGET_DIRS'].split()
43 have_user = false
44 have_system = false
45 foreach target : target_dirs
46   have_user = have_user or target.endswith('-user')
47   have_system = have_system or target.endswith('-softmmu')
48 endforeach
49 have_tools = 'CONFIG_TOOLS' in config_host
50 have_block = have_system or have_tools
51
52 python = import('python').find_installation()
53
54 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
55 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
56   'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
57
58 cpu = host_machine.cpu_family()
59 targetos = host_machine.system()
60
61 if cpu in ['x86', 'x86_64']
62   kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
63 elif cpu == 'aarch64'
64   kvm_targets = ['aarch64-softmmu']
65 elif cpu == 's390x'
66   kvm_targets = ['s390x-softmmu']
67 elif cpu in ['ppc', 'ppc64']
68   kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
69 elif cpu in ['mips', 'mips64']
70   kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
71 else
72   kvm_targets = []
73 endif
74
75 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
76
77 if cpu in ['aarch64']
78   accelerator_targets += {
79     'CONFIG_HVF': ['aarch64-softmmu']
80   }
81 endif
82
83 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
84   # i386 emulator provides xenpv machine type for multiple architectures
85   accelerator_targets += {
86     'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
87   }
88 endif
89 if cpu in ['x86', 'x86_64']
90   accelerator_targets += {
91     'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
92     'CONFIG_HVF': ['x86_64-softmmu'],
93     'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
94     'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
95   }
96 endif
97
98 modular_tcg = []
99 # Darwin does not support references to thread-local variables in modules
100 if targetos != 'darwin'
101   modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
102 endif
103
104 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
105 unpack_edk2_blobs = false
106 foreach target : edk2_targets
107   if target in target_dirs
108     bzip2 = find_program('bzip2', required: get_option('install_blobs'))
109     unpack_edk2_blobs = bzip2.found()
110     break
111   endif
112 endforeach
113
114 ##################
115 # Compiler flags #
116 ##################
117
118 # Specify linker-script with add_project_link_arguments so that it is not placed
119 # within a linker --start-group/--end-group pair
120 if 'CONFIG_FUZZ' in config_host
121    add_project_link_arguments(['-Wl,-T,',
122                                (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
123                               native: false, language: ['c', 'cpp', 'objc'])
124 endif
125
126 add_global_arguments(config_host['QEMU_CFLAGS'].split(),
127                      native: false, language: ['c', 'objc'])
128 add_global_arguments(config_host['QEMU_CXXFLAGS'].split(),
129                      native: false, language: 'cpp')
130 add_global_link_arguments(config_host['QEMU_LDFLAGS'].split(),
131                           native: false, language: ['c', 'cpp', 'objc'])
132
133 if targetos == 'linux'
134   add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
135                         '-isystem', 'linux-headers',
136                         language: ['c', 'cpp'])
137 endif
138
139 add_project_arguments('-iquote', '.',
140                       '-iquote', meson.current_source_dir(),
141                       '-iquote', meson.current_source_dir() / 'include',
142                       '-iquote', meson.current_source_dir() / 'disas/libvixl',
143                       language: ['c', 'cpp', 'objc'])
144
145 link_language = meson.get_external_property('link_language', 'cpp')
146 if link_language == 'cpp'
147   add_languages('cpp', required: true, native: false)
148 endif
149 if host_machine.system() == 'darwin'
150   add_languages('objc', required: false, native: false)
151 endif
152
153 sparse = find_program('cgcc', required: get_option('sparse'))
154 if sparse.found()
155   run_target('sparse',
156              command: [find_program('scripts/check_sparse.py'),
157                        'compile_commands.json', sparse.full_path(), '-Wbitwise',
158                        '-Wno-transparent-union', '-Wno-old-initializer',
159                        '-Wno-non-pointer-null'])
160 endif
161
162 ###########################################
163 # Target-specific checks and dependencies #
164 ###########################################
165
166 if targetos != 'linux' and get_option('mpath').enabled()
167   error('Multipath is supported only on Linux')
168 endif
169
170 if targetos != 'linux' and get_option('multiprocess').enabled()
171   error('Multiprocess QEMU is supported only on Linux')
172 endif
173 multiprocess_allowed = targetos == 'linux' and not get_option('multiprocess').disabled()
174
175 libm = cc.find_library('m', required: false)
176 threads = dependency('threads')
177 util = cc.find_library('util', required: false)
178 winmm = []
179 socket = []
180 version_res = []
181 coref = []
182 iokit = []
183 emulator_link_args = []
184 nvmm =not_found
185 hvf = not_found
186 if targetos == 'windows'
187   socket = cc.find_library('ws2_32')
188   winmm = cc.find_library('winmm')
189
190   win = import('windows')
191   version_res = win.compile_resources('version.rc',
192                                       depend_files: files('pc-bios/qemu-nsis.ico'),
193                                       include_directories: include_directories('.'))
194 elif targetos == 'darwin'
195   coref = dependency('appleframeworks', modules: 'CoreFoundation')
196   iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
197 elif targetos == 'sunos'
198   socket = [cc.find_library('socket'),
199             cc.find_library('nsl'),
200             cc.find_library('resolv')]
201 elif targetos == 'haiku'
202   socket = [cc.find_library('posix_error_mapper'),
203             cc.find_library('network'),
204             cc.find_library('bsd')]
205 elif targetos == 'openbsd'
206   if not get_option('tcg').disabled() and target_dirs.length() > 0
207     # Disable OpenBSD W^X if available
208     emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
209   endif
210 endif
211
212 accelerators = []
213 if not get_option('kvm').disabled() and targetos == 'linux'
214   accelerators += 'CONFIG_KVM'
215 endif
216 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
217   accelerators += 'CONFIG_XEN'
218   have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
219 else
220   have_xen_pci_passthrough = false
221 endif
222 if not get_option('whpx').disabled() and targetos == 'windows'
223   if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
224     error('WHPX requires 64-bit host')
225   elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
226        cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
227     accelerators += 'CONFIG_WHPX'
228   endif
229 endif
230 if not get_option('hvf').disabled()
231   hvf = dependency('appleframeworks', modules: 'Hypervisor',
232                    required: get_option('hvf'))
233   if hvf.found()
234     accelerators += 'CONFIG_HVF'
235   endif
236 endif
237 if not get_option('hax').disabled()
238   if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
239     accelerators += 'CONFIG_HAX'
240   endif
241 endif
242 if targetos == 'netbsd'
243   if cc.has_header_symbol('nvmm.h', 'nvmm_cpu_stop', required: get_option('nvmm'))
244     nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
245   endif
246   if nvmm.found()
247     accelerators += 'CONFIG_NVMM'
248   endif
249 endif
250
251 tcg_arch = config_host['ARCH']
252 if not get_option('tcg').disabled()
253   if cpu not in supported_cpus
254     if get_option('tcg_interpreter')
255       warning('Unsupported CPU @0@, will use TCG with TCI (experimental and slow)'.format(cpu))
256     else
257       error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
258     endif
259   elif get_option('tcg_interpreter')
260     warning('Use of the TCG interpretor is not recommended on this host')
261     warning('architecture. There is a native TCG execution backend available')
262     warning('which provides substantially better performance and reliability.')
263     warning('It is strongly recommended to remove the --enable-tcg-interpreter')
264     warning('configuration option on this architecture to use the native')
265     warning('backend.')
266   endif
267   if get_option('tcg_interpreter')
268     tcg_arch = 'tci'
269   elif config_host['ARCH'] == 'sparc64'
270     tcg_arch = 'sparc'
271   elif config_host['ARCH'] in ['x86_64', 'x32']
272     tcg_arch = 'i386'
273   elif config_host['ARCH'] == 'ppc64'
274     tcg_arch = 'ppc'
275   elif config_host['ARCH'] in ['riscv32', 'riscv64']
276     tcg_arch = 'riscv'
277   endif
278   add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
279                         language: ['c', 'cpp', 'objc'])
280
281   accelerators += 'CONFIG_TCG'
282   config_host += { 'CONFIG_TCG': 'y' }
283 endif
284
285 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
286   error('KVM not available on this platform')
287 endif
288 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
289   error('HVF not available on this platform')
290 endif
291 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
292   error('NVMM not available on this platform')
293 endif
294 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
295   error('WHPX not available on this platform')
296 endif
297 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
298   if 'CONFIG_XEN' in accelerators
299     error('Xen PCI passthrough not available on this platform')
300   else
301     error('Xen PCI passthrough requested but Xen not enabled')
302   endif
303 endif
304
305 ################
306 # Dependencies #
307 ################
308
309 # The path to glib.h is added to all compilation commands.  This was
310 # grandfathered in from the QEMU Makefiles.
311 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
312                       native: false, language: ['c', 'cpp', 'objc'])
313 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
314                           link_args: config_host['GLIB_LIBS'].split())
315 # override glib dep with the configure results (for subprojects)
316 meson.override_dependency('glib-2.0', glib)
317
318 gio = not_found
319 if 'CONFIG_GIO' in config_host
320   gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
321                            link_args: config_host['GIO_LIBS'].split())
322 endif
323 lttng = not_found
324 if 'CONFIG_TRACE_UST' in config_host
325   lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
326 endif
327 pixman = not_found
328 if have_system or have_tools
329   pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
330                       method: 'pkg-config', kwargs: static_kwargs)
331 endif
332 libaio = cc.find_library('aio', required: false)
333 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
334
335 linux_io_uring = not_found
336 if not get_option('linux_io_uring').auto() or have_block
337   linux_io_uring = dependency('liburing', required: get_option('linux_io_uring'),
338                               method: 'pkg-config', kwargs: static_kwargs)
339 endif
340 libxml2 = not_found
341 if not get_option('libxml2').auto() or have_block
342   libxml2 = dependency('libxml-2.0', required: get_option('libxml2'),
343                        method: 'pkg-config', kwargs: static_kwargs)
344 endif
345 libnfs = not_found
346 if not get_option('libnfs').auto() or have_block
347   libnfs = dependency('libnfs', version: '>=1.9.3',
348                       required: get_option('libnfs'),
349                       method: 'pkg-config', kwargs: static_kwargs)
350 endif
351
352 libattr_test = '''
353   #include <stddef.h>
354   #include <sys/types.h>
355   #ifdef CONFIG_LIBATTR
356   #include <attr/xattr.h>
357   #else
358   #include <sys/xattr.h>
359   #endif
360   int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
361
362 libattr = not_found
363 have_old_libattr = false
364 if not get_option('attr').disabled()
365   if cc.links(libattr_test)
366     libattr = declare_dependency()
367   else
368     libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
369                               required: get_option('attr'),
370                               kwargs: static_kwargs)
371     if libattr.found() and not \
372       cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
373       libattr = not_found
374       if get_option('attr').enabled()
375         error('could not link libattr')
376       else
377         warning('could not link libattr, disabling')
378       endif
379     else
380       have_old_libattr = libattr.found()
381     endif
382   endif
383 endif
384
385 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
386 if cocoa.found() and get_option('sdl').enabled()
387   error('Cocoa and SDL cannot be enabled at the same time')
388 endif
389 if cocoa.found() and get_option('gtk').enabled()
390   error('Cocoa and GTK+ cannot be enabled at the same time')
391 endif
392
393 seccomp = not_found
394 if not get_option('seccomp').auto() or have_system or have_tools
395   seccomp = dependency('libseccomp', version: '>=2.3.0',
396                        required: get_option('seccomp'),
397                        method: 'pkg-config', kwargs: static_kwargs)
398 endif
399
400 libcap_ng = not_found
401 if not get_option('cap_ng').auto() or have_system or have_tools
402   libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
403                               required: get_option('cap_ng'),
404                               kwargs: static_kwargs)
405 endif
406 if libcap_ng.found() and not cc.links('''
407    #include <cap-ng.h>
408    int main(void)
409    {
410      capng_capability_to_name(CAPNG_EFFECTIVE);
411      return 0;
412    }''', dependencies: libcap_ng)
413   libcap_ng = not_found
414   if get_option('cap_ng').enabled()
415     error('could not link libcap-ng')
416   else
417     warning('could not link libcap-ng, disabling')
418   endif
419 endif
420
421 if get_option('xkbcommon').auto() and not have_system and not have_tools
422   xkbcommon = not_found
423 else
424   xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
425                          method: 'pkg-config', kwargs: static_kwargs)
426 endif
427 vde = not_found
428 if config_host.has_key('CONFIG_VDE')
429   vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
430 endif
431 pulse = not_found
432 if 'CONFIG_LIBPULSE' in config_host
433   pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
434                              link_args: config_host['PULSE_LIBS'].split())
435 endif
436 alsa = not_found
437 if 'CONFIG_ALSA' in config_host
438   alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
439                             link_args: config_host['ALSA_LIBS'].split())
440 endif
441 jack = not_found
442 if 'CONFIG_LIBJACK' in config_host
443   jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
444 endif
445 spice = not_found
446 spice_headers = not_found
447 spice_protocol = not_found
448 if 'CONFIG_SPICE' in config_host
449   spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
450                              link_args: config_host['SPICE_LIBS'].split())
451   spice_headers = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split())
452 endif
453 if 'CONFIG_SPICE_PROTOCOL' in config_host
454   spice_protocol = declare_dependency(compile_args: config_host['SPICE_PROTOCOL_CFLAGS'].split())
455 endif
456 rt = cc.find_library('rt', required: false)
457 libdl = not_found
458 if 'CONFIG_PLUGIN' in config_host
459   libdl = cc.find_library('dl', required: false)
460   if not cc.has_function('dlopen', dependencies: libdl)
461     error('dlopen not found')
462   endif
463 endif
464 libiscsi = not_found
465 if not get_option('libiscsi').auto() or have_block
466   libiscsi = dependency('libiscsi', version: '>=1.9.0',
467                          required: get_option('libiscsi'),
468                          method: 'pkg-config', kwargs: static_kwargs)
469 endif
470 zstd = not_found
471 if not get_option('zstd').auto() or have_block
472   zstd = dependency('libzstd', version: '>=1.4.0',
473                     required: get_option('zstd'),
474                     method: 'pkg-config', kwargs: static_kwargs)
475 endif
476 virgl = not_found
477 if not get_option('virglrenderer').auto() or have_system
478   virgl = dependency('virglrenderer',
479                      method: 'pkg-config',
480                      required: get_option('virglrenderer'),
481                      kwargs: static_kwargs)
482 endif
483 curl = not_found
484 if not get_option('curl').auto() or have_block
485   curl = dependency('libcurl', version: '>=7.29.0',
486                     method: 'pkg-config',
487                     required: get_option('curl'),
488                     kwargs: static_kwargs)
489 endif
490 libudev = not_found
491 if targetos == 'linux' and (have_system or have_tools)
492   libudev = dependency('libudev',
493                        method: 'pkg-config',
494                        required: get_option('libudev'),
495                        kwargs: static_kwargs)
496 endif
497
498 mpathlibs = [libudev]
499 mpathpersist = not_found
500 mpathpersist_new_api = false
501 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
502   mpath_test_source_new = '''
503     #include <libudev.h>
504     #include <mpath_persist.h>
505     unsigned mpath_mx_alloc_len = 1024;
506     int logsink;
507     static struct config *multipath_conf;
508     extern struct udev *udev;
509     extern struct config *get_multipath_config(void);
510     extern void put_multipath_config(struct config *conf);
511     struct udev *udev;
512     struct config *get_multipath_config(void) { return multipath_conf; }
513     void put_multipath_config(struct config *conf) { }
514     int main(void) {
515         udev = udev_new();
516         multipath_conf = mpath_lib_init();
517         return 0;
518     }'''
519   mpath_test_source_old = '''
520       #include <libudev.h>
521       #include <mpath_persist.h>
522       unsigned mpath_mx_alloc_len = 1024;
523       int logsink;
524       int main(void) {
525           struct udev *udev = udev_new();
526           mpath_lib_init(udev);
527           return 0;
528       }'''
529   libmpathpersist = cc.find_library('mpathpersist',
530                                     required: get_option('mpath'),
531                                     kwargs: static_kwargs)
532   if libmpathpersist.found()
533     mpathlibs += libmpathpersist
534     if enable_static
535       mpathlibs += cc.find_library('devmapper',
536                                      required: get_option('mpath'),
537                                      kwargs: static_kwargs)
538     endif
539     mpathlibs += cc.find_library('multipath',
540                                  required: get_option('mpath'),
541                                  kwargs: static_kwargs)
542     foreach lib: mpathlibs
543       if not lib.found()
544         mpathlibs = []
545         break
546       endif
547     endforeach
548     if mpathlibs.length() == 0
549       msg = 'Dependencies missing for libmpathpersist'
550     elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
551       mpathpersist = declare_dependency(dependencies: mpathlibs)
552       mpathpersist_new_api = true
553     elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
554       mpathpersist = declare_dependency(dependencies: mpathlibs)
555     else
556       msg = 'Cannot detect libmpathpersist API'
557     endif
558     if not mpathpersist.found()
559       if get_option('mpath').enabled()
560         error(msg)
561       else
562         warning(msg + ', disabling')
563       endif
564     endif
565   endif
566 endif
567
568 iconv = not_found
569 curses = not_found
570 if have_system and not get_option('curses').disabled()
571   curses_test = '''
572     #include <locale.h>
573     #include <curses.h>
574     #include <wchar.h>
575     int main(void) {
576       wchar_t wch = L'w';
577       setlocale(LC_ALL, "");
578       resize_term(0, 0);
579       addwstr(L"wide chars\n");
580       addnwstr(&wch, 1);
581       add_wch(WACS_DEGREE);
582       return 0;
583     }'''
584
585   curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
586   foreach curses_dep : curses_dep_list
587     if not curses.found()
588       curses = dependency(curses_dep,
589                           required: false,
590                           method: 'pkg-config',
591                           kwargs: static_kwargs)
592     endif
593   endforeach
594   msg = get_option('curses').enabled() ? 'curses library not found' : ''
595   curses_compile_args = ['-DNCURSES_WIDECHAR']
596   if curses.found()
597     if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
598       curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
599     else
600       msg = 'curses package not usable'
601       curses = not_found
602     endif
603   endif
604   if not curses.found()
605     has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
606     if targetos != 'windows' and not has_curses_h
607       message('Trying with /usr/include/ncursesw')
608       curses_compile_args += ['-I/usr/include/ncursesw']
609       has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
610     endif
611     if has_curses_h
612       curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
613       foreach curses_libname : curses_libname_list
614         libcurses = cc.find_library(curses_libname,
615                                     required: false,
616                                     kwargs: static_kwargs)
617         if libcurses.found()
618           if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
619             curses = declare_dependency(compile_args: curses_compile_args,
620                                         dependencies: [libcurses])
621             break
622           else
623             msg = 'curses library not usable'
624           endif
625         endif
626       endforeach
627     endif
628   endif
629   if not get_option('iconv').disabled()
630     foreach link_args : [ ['-liconv'], [] ]
631       # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
632       # We need to use libiconv if available because mixing libiconv's headers with
633       # the system libc does not work.
634       # However, without adding glib to the dependencies -L/usr/local/lib will not be
635       # included in the command line and libiconv will not be found.
636       if cc.links('''
637         #include <iconv.h>
638         int main(void) {
639           iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
640           return conv != (iconv_t) -1;
641         }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
642         iconv = declare_dependency(link_args: link_args, dependencies: glib)
643         break
644       endif
645     endforeach
646   endif
647   if curses.found() and not iconv.found()
648     if get_option('iconv').enabled()
649       error('iconv not available')
650     endif
651     msg = 'iconv required for curses UI but not available'
652     curses = not_found
653   endif
654   if not curses.found() and msg != ''
655     if get_option('curses').enabled()
656       error(msg)
657     else
658       warning(msg + ', disabling')
659     endif
660   endif
661 endif
662
663 brlapi = not_found
664 if not get_option('brlapi').auto() or have_system
665   brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
666                          required: get_option('brlapi'),
667                          kwargs: static_kwargs)
668   if brlapi.found() and not cc.links('''
669      #include <brlapi.h>
670      #include <stddef.h>
671      int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
672     brlapi = not_found
673     if get_option('brlapi').enabled()
674       error('could not link brlapi')
675     else
676       warning('could not link brlapi, disabling')
677     endif
678   endif
679 endif
680
681 sdl = not_found
682 if not get_option('sdl').auto() or (have_system and not cocoa.found())
683   sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
684   sdl_image = not_found
685 endif
686 if sdl.found()
687   # work around 2.0.8 bug
688   sdl = declare_dependency(compile_args: '-Wno-undef',
689                            dependencies: sdl)
690   sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
691                          method: 'pkg-config', kwargs: static_kwargs)
692 else
693   if get_option('sdl_image').enabled()
694     error('sdl-image required, but SDL was @0@'.format(
695           get_option('sdl').disabled() ? 'disabled' : 'not found'))
696   endif
697   sdl_image = not_found
698 endif
699
700 rbd = not_found
701 if not get_option('rbd').auto() or have_block
702   librados = cc.find_library('rados', required: get_option('rbd'),
703                              kwargs: static_kwargs)
704   librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
705                            required: get_option('rbd'),
706                            kwargs: static_kwargs)
707   if librados.found() and librbd.found()
708     if cc.links('''
709       #include <stdio.h>
710       #include <rbd/librbd.h>
711       int main(void) {
712         rados_t cluster;
713         rados_create(&cluster, NULL);
714         #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
715         #error
716         #endif
717         return 0;
718       }''', dependencies: [librbd, librados])
719       rbd = declare_dependency(dependencies: [librbd, librados])
720     elif get_option('rbd').enabled()
721       error('librbd >= 1.12.0 required')
722     else
723       warning('librbd >= 1.12.0 not found, disabling')
724     endif
725   endif
726 endif
727
728 glusterfs = not_found
729 glusterfs_ftruncate_has_stat = false
730 glusterfs_iocb_has_stat = false
731 if not get_option('glusterfs').auto() or have_block
732   glusterfs = dependency('glusterfs-api', version: '>=3',
733                          required: get_option('glusterfs'),
734                          method: 'pkg-config', kwargs: static_kwargs)
735   if glusterfs.found()
736     glusterfs_ftruncate_has_stat = cc.links('''
737       #include <glusterfs/api/glfs.h>
738
739       int
740       main(void)
741       {
742           /* new glfs_ftruncate() passes two additional args */
743           return glfs_ftruncate(NULL, 0, NULL, NULL);
744       }
745     ''', dependencies: glusterfs)
746     glusterfs_iocb_has_stat = cc.links('''
747       #include <glusterfs/api/glfs.h>
748
749       /* new glfs_io_cbk() passes two additional glfs_stat structs */
750       static void
751       glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
752       {}
753
754       int
755       main(void)
756       {
757           glfs_io_cbk iocb = &glusterfs_iocb;
758           iocb(NULL, 0 , NULL, NULL, NULL);
759           return 0;
760       }
761     ''', dependencies: glusterfs)
762   endif
763 endif
764 libssh = not_found
765 if 'CONFIG_LIBSSH' in config_host
766   libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
767                               link_args: config_host['LIBSSH_LIBS'].split())
768 endif
769 libbzip2 = not_found
770 if not get_option('bzip2').auto() or have_block
771   libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
772                              required: get_option('bzip2'),
773                              kwargs: static_kwargs)
774   if libbzip2.found() and not cc.links('''
775      #include <bzlib.h>
776      int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
777     libbzip2 = not_found
778     if get_option('bzip2').enabled()
779       error('could not link libbzip2')
780     else
781       warning('could not link libbzip2, disabling')
782     endif
783   endif
784 endif
785
786 liblzfse = not_found
787 if not get_option('lzfse').auto() or have_block
788   liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
789                              required: get_option('lzfse'),
790                              kwargs: static_kwargs)
791 endif
792 if liblzfse.found() and not cc.links('''
793    #include <lzfse.h>
794    int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
795   liblzfse = not_found
796   if get_option('lzfse').enabled()
797     error('could not link liblzfse')
798   else
799     warning('could not link liblzfse, disabling')
800   endif
801 endif
802
803 oss = not_found
804 if 'CONFIG_AUDIO_OSS' in config_host
805   oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
806 endif
807 dsound = not_found
808 if 'CONFIG_AUDIO_DSOUND' in config_host
809   dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
810 endif
811 coreaudio = not_found
812 if 'CONFIG_AUDIO_COREAUDIO' in config_host
813   coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
814 endif
815
816 opengl = not_found
817 if 'CONFIG_OPENGL' in config_host
818   opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
819                               link_args: config_host['OPENGL_LIBS'].split())
820 endif
821 gbm = not_found
822 if (have_system or have_tools) and (virgl.found() or opengl.found())
823   gbm = dependency('gbm', method: 'pkg-config', required: false,
824                    kwargs: static_kwargs)
825 endif
826
827 gnutls = not_found
828 gnutls_crypto = not_found
829 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
830   # For general TLS support our min gnutls matches
831   # that implied by our platform support matrix
832   #
833   # For the crypto backends, we look for a newer
834   # gnutls:
835   #
836   #   Version 3.6.8  is needed to get XTS
837   #   Version 3.6.13 is needed to get PBKDF
838   #   Version 3.6.14 is needed to get HW accelerated XTS
839   #
840   # If newer enough gnutls isn't available, we can
841   # still use a different crypto backend to satisfy
842   # the platform support requirements
843   gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
844                              method: 'pkg-config',
845                              required: false,
846                              kwargs: static_kwargs)
847   if gnutls_crypto.found()
848     gnutls = gnutls_crypto
849   else
850     # Our min version if all we need is TLS
851     gnutls = dependency('gnutls', version: '>=3.5.18',
852                         method: 'pkg-config',
853                         required: get_option('gnutls'),
854                         kwargs: static_kwargs)
855   endif
856 endif
857
858 # We prefer use of gnutls for crypto, unless the options
859 # explicitly asked for nettle or gcrypt.
860 #
861 # If gnutls isn't available for crypto, then we'll prefer
862 # gcrypt over nettle for performance reasons.
863 gcrypt = not_found
864 nettle = not_found
865 xts = 'none'
866
867 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
868   error('Only one of gcrypt & nettle can be enabled')
869 endif
870
871 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
872 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
873   gnutls_crypto = not_found
874 endif
875
876 if not gnutls_crypto.found()
877   if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
878     gcrypt = dependency('libgcrypt', version: '>=1.8',
879                         method: 'config-tool',
880                         required: get_option('gcrypt'),
881                         kwargs: static_kwargs)
882     # Debian has removed -lgpg-error from libgcrypt-config
883     # as it "spreads unnecessary dependencies" which in
884     # turn breaks static builds...
885     if gcrypt.found() and enable_static
886       gcrypt = declare_dependency(dependencies: [
887         gcrypt,
888         cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
889     endif
890   endif
891   if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
892     nettle = dependency('nettle', version: '>=3.4',
893                         method: 'pkg-config',
894                         required: get_option('nettle'),
895                         kwargs: static_kwargs)
896     if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
897       xts = 'private'
898     endif
899   endif
900 endif
901
902 gtk = not_found
903 gtkx11 = not_found
904 vte = not_found
905 if not get_option('gtk').auto() or (have_system and not cocoa.found())
906   gtk = dependency('gtk+-3.0', version: '>=3.22.0',
907                    method: 'pkg-config',
908                    required: get_option('gtk'),
909                    kwargs: static_kwargs)
910   if gtk.found()
911     gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
912                         method: 'pkg-config',
913                         required: false,
914                         kwargs: static_kwargs)
915     gtk = declare_dependency(dependencies: [gtk, gtkx11])
916
917     if not get_option('vte').auto() or have_system
918       vte = dependency('vte-2.91',
919                        method: 'pkg-config',
920                        required: get_option('vte'),
921                        kwargs: static_kwargs)
922     endif
923   endif
924 endif
925
926 x11 = not_found
927 if gtkx11.found()
928   x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
929                    kwargs: static_kwargs)
930 endif
931 vnc = not_found
932 png = not_found
933 jpeg = not_found
934 sasl = not_found
935 if have_system and not get_option('vnc').disabled()
936   vnc = declare_dependency() # dummy dependency
937   png = dependency('libpng', required: get_option('vnc_png'),
938                    method: 'pkg-config', kwargs: static_kwargs)
939   jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
940                     method: 'pkg-config', kwargs: static_kwargs)
941   sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
942                          required: get_option('vnc_sasl'),
943                          kwargs: static_kwargs)
944   if sasl.found()
945     sasl = declare_dependency(dependencies: sasl,
946                               compile_args: '-DSTRUCT_IOVEC_DEFINED')
947   endif
948 endif
949
950 pam = not_found
951 if not get_option('auth_pam').auto() or have_system
952   pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
953                         required: get_option('auth_pam'),
954                         kwargs: static_kwargs)
955 endif
956 if pam.found() and not cc.links('''
957    #include <stddef.h>
958    #include <security/pam_appl.h>
959    int main(void) {
960      const char *service_name = "qemu";
961      const char *user = "frank";
962      const struct pam_conv pam_conv = { 0 };
963      pam_handle_t *pamh = NULL;
964      pam_start(service_name, user, &pam_conv, &pamh);
965      return 0;
966    }''', dependencies: pam)
967   pam = not_found
968   if get_option('auth_pam').enabled()
969     error('could not link libpam')
970   else
971     warning('could not link libpam, disabling')
972   endif
973 endif
974
975 snappy = not_found
976 if not get_option('snappy').auto() or have_system
977   snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
978                            required: get_option('snappy'),
979                            kwargs: static_kwargs)
980 endif
981 if snappy.found() and not cc.links('''
982    #include <snappy-c.h>
983    int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
984   snappy = not_found
985   if get_option('snappy').enabled()
986     error('could not link libsnappy')
987   else
988     warning('could not link libsnappy, disabling')
989   endif
990 endif
991
992 lzo = not_found
993 if not get_option('lzo').auto() or have_system
994   lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
995                         required: get_option('lzo'),
996                         kwargs: static_kwargs)
997 endif
998 if lzo.found() and not cc.links('''
999    #include <lzo/lzo1x.h>
1000    int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1001   lzo = not_found
1002   if get_option('lzo').enabled()
1003     error('could not link liblzo2')
1004   else
1005     warning('could not link liblzo2, disabling')
1006   endif
1007 endif
1008
1009 rdma = not_found
1010 if 'CONFIG_RDMA' in config_host
1011   rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
1012 endif
1013 numa = not_found
1014 if 'CONFIG_NUMA' in config_host
1015   numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
1016 endif
1017 xen = not_found
1018 if 'CONFIG_XEN_BACKEND' in config_host
1019   xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
1020                            link_args: config_host['XEN_LIBS'].split())
1021 endif
1022 cacard = not_found
1023 if not get_option('smartcard').auto() or have_system
1024   cacard = dependency('libcacard', required: get_option('smartcard'),
1025                       version: '>=2.5.1', method: 'pkg-config',
1026                       kwargs: static_kwargs)
1027 endif
1028 u2f = not_found
1029 if have_system
1030   u2f = dependency('u2f-emu', required: get_option('u2f'),
1031                    method: 'pkg-config',
1032                    kwargs: static_kwargs)
1033 endif
1034 usbredir = not_found
1035 if not get_option('usb_redir').auto() or have_system
1036   usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1037                         version: '>=0.6', method: 'pkg-config',
1038                         kwargs: static_kwargs)
1039 endif
1040 libusb = not_found
1041 if not get_option('libusb').auto() or have_system
1042   libusb = dependency('libusb-1.0', required: get_option('libusb'),
1043                       version: '>=1.0.13', method: 'pkg-config',
1044                       kwargs: static_kwargs)
1045 endif
1046
1047 libpmem = not_found
1048 if not get_option('libpmem').auto() or have_system
1049   libpmem = dependency('libpmem', required: get_option('libpmem'),
1050                        method: 'pkg-config', kwargs: static_kwargs)
1051 endif
1052 libdaxctl = not_found
1053 if not get_option('libdaxctl').auto() or have_system
1054   libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1055                          version: '>=57', method: 'pkg-config',
1056                          kwargs: static_kwargs)
1057 endif
1058 tasn1 = not_found
1059 if gnutls.found()
1060   tasn1 = dependency('libtasn1',
1061                      method: 'pkg-config',
1062                      kwargs: static_kwargs)
1063 endif
1064 keyutils = dependency('libkeyutils', required: false,
1065                       method: 'pkg-config', kwargs: static_kwargs)
1066
1067 has_gettid = cc.has_function('gettid')
1068
1069 # Malloc tests
1070
1071 malloc = []
1072 if get_option('malloc') == 'system'
1073   has_malloc_trim = \
1074     not get_option('malloc_trim').disabled() and \
1075     cc.links('''#include <malloc.h>
1076                 int main(void) { malloc_trim(0); return 0; }''')
1077 else
1078   has_malloc_trim = false
1079   malloc = cc.find_library(get_option('malloc'), required: true)
1080 endif
1081 if not has_malloc_trim and get_option('malloc_trim').enabled()
1082   if get_option('malloc') == 'system'
1083     error('malloc_trim not available on this platform.')
1084   else
1085     error('malloc_trim not available with non-libc memory allocator')
1086   endif
1087 endif
1088
1089 # Check whether the glibc provides statx()
1090
1091 gnu_source_prefix = '''
1092   #ifndef _GNU_SOURCE
1093   #define _GNU_SOURCE
1094   #endif
1095 '''
1096 statx_test = gnu_source_prefix + '''
1097   #include <sys/stat.h>
1098   int main(void) {
1099     struct statx statxbuf;
1100     statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1101     return 0;
1102   }'''
1103
1104 has_statx = cc.links(statx_test)
1105
1106 have_vhost_user_blk_server = (targetos == 'linux' and
1107     'CONFIG_VHOST_USER' in config_host)
1108
1109 if get_option('vhost_user_blk_server').enabled()
1110     if targetos != 'linux'
1111         error('vhost_user_blk_server requires linux')
1112     elif 'CONFIG_VHOST_USER' not in config_host
1113         error('vhost_user_blk_server requires vhost-user support')
1114     endif
1115 elif get_option('vhost_user_blk_server').disabled() or not have_system
1116     have_vhost_user_blk_server = false
1117 endif
1118
1119
1120 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1121   error('Cannot enable fuse-lseek while fuse is disabled')
1122 endif
1123
1124 fuse = dependency('fuse3', required: get_option('fuse'),
1125                   version: '>=3.1', method: 'pkg-config',
1126                   kwargs: static_kwargs)
1127
1128 fuse_lseek = not_found
1129 if not get_option('fuse_lseek').disabled()
1130   if fuse.version().version_compare('>=3.8')
1131     # Dummy dependency
1132     fuse_lseek = declare_dependency()
1133   elif get_option('fuse_lseek').enabled()
1134     if fuse.found()
1135       error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1136     else
1137       error('fuse-lseek requires libfuse, which was not found')
1138     endif
1139   endif
1140 endif
1141
1142 # libbpf
1143 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1144 if libbpf.found() and not cc.links('''
1145    #include <bpf/libbpf.h>
1146    int main(void)
1147    {
1148      bpf_object__destroy_skeleton(NULL);
1149      return 0;
1150    }''', dependencies: libbpf)
1151   libbpf = not_found
1152   if get_option('bpf').enabled()
1153     error('libbpf skeleton test failed')
1154   else
1155     warning('libbpf skeleton test failed, disabling')
1156   endif
1157 endif
1158
1159 if get_option('cfi')
1160   cfi_flags=[]
1161   # Check for dependency on LTO
1162   if not get_option('b_lto')
1163     error('Selected Control-Flow Integrity but LTO is disabled')
1164   endif
1165   if config_host.has_key('CONFIG_MODULES')
1166     error('Selected Control-Flow Integrity is not compatible with modules')
1167   endif
1168   # Check for cfi flags. CFI requires LTO so we can't use
1169   # get_supported_arguments, but need a more complex "compiles" which allows
1170   # custom arguments
1171   if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1172                  args: ['-flto', '-fsanitize=cfi-icall'] )
1173     cfi_flags += '-fsanitize=cfi-icall'
1174   else
1175     error('-fsanitize=cfi-icall is not supported by the compiler')
1176   endif
1177   if cc.compiles('int main () { return 0; }',
1178                  name: '-fsanitize-cfi-icall-generalize-pointers',
1179                  args: ['-flto', '-fsanitize=cfi-icall',
1180                         '-fsanitize-cfi-icall-generalize-pointers'] )
1181     cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1182   else
1183     error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1184   endif
1185   if get_option('cfi_debug')
1186     if cc.compiles('int main () { return 0; }',
1187                    name: '-fno-sanitize-trap=cfi-icall',
1188                    args: ['-flto', '-fsanitize=cfi-icall',
1189                           '-fno-sanitize-trap=cfi-icall'] )
1190       cfi_flags += '-fno-sanitize-trap=cfi-icall'
1191     else
1192       error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1193     endif
1194   endif
1195   add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1196   add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1197 endif
1198
1199 have_host_block_device = (targetos != 'darwin' or
1200     cc.has_header('IOKit/storage/IOMedia.h'))
1201
1202 #################
1203 # config-host.h #
1204 #################
1205
1206 have_virtfs = (targetos == 'linux' and
1207     have_system and
1208     libattr.found() and
1209     libcap_ng.found())
1210
1211 have_virtfs_proxy_helper = have_virtfs and have_tools
1212
1213 if get_option('virtfs').enabled()
1214   if not have_virtfs
1215     if targetos != 'linux'
1216       error('virtio-9p (virtfs) requires Linux')
1217     elif not libcap_ng.found() or not libattr.found()
1218       error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel')
1219     elif not have_system
1220       error('virtio-9p (virtfs) needs system emulation support')
1221     endif
1222   endif
1223 elif get_option('virtfs').disabled()
1224   have_virtfs = false
1225 endif
1226
1227 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1228 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1229 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1230 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1231 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1232 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1233 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1234 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1235 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1236 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1237 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1238 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1239
1240 config_host_data.set('CONFIG_ATTR', libattr.found())
1241 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1242 config_host_data.set('CONFIG_COCOA', cocoa.found())
1243 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1244 config_host_data.set('CONFIG_LZO', lzo.found())
1245 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1246 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1247 config_host_data.set('CONFIG_CURL', curl.found())
1248 config_host_data.set('CONFIG_CURSES', curses.found())
1249 config_host_data.set('CONFIG_GBM', gbm.found())
1250 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1251 if glusterfs.found()
1252   config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1253   config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1254   config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1255   config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1256   config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1257   config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1258 endif
1259 config_host_data.set('CONFIG_GTK', gtk.found())
1260 config_host_data.set('CONFIG_VTE', vte.found())
1261 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1262 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1263 config_host_data.set('CONFIG_EBPF', libbpf.found())
1264 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1265 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1266 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1267 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1268 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1269 config_host_data.set('CONFIG_RBD', rbd.found())
1270 config_host_data.set('CONFIG_SDL', sdl.found())
1271 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1272 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1273 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1274 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1275 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1276 config_host_data.set('CONFIG_VNC', vnc.found())
1277 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1278 config_host_data.set('CONFIG_VNC_PNG', png.found())
1279 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1280 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1281 config_host_data.set('CONFIG_VTE', vte.found())
1282 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1283 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1284 config_host_data.set('CONFIG_GETTID', has_gettid)
1285 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1286 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1287 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1288 config_host_data.set('CONFIG_NETTLE', nettle.found())
1289 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1290 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1291 config_host_data.set('CONFIG_STATX', has_statx)
1292 config_host_data.set('CONFIG_ZSTD', zstd.found())
1293 config_host_data.set('CONFIG_FUSE', fuse.found())
1294 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1295 config_host_data.set('CONFIG_X11', x11.found())
1296 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1297 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1298 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1299 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1300 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1301
1302 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1303
1304 # has_header
1305 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1306 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1307 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1308 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1309 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1310 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1311 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1312 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1313 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1314
1315 # has_function
1316 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1317 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1318 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1319 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1320 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1321 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign'))
1322 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1323 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1324 config_host_data.set('CONFIG_SEM_TIMEDWAIT', cc.has_function('sem_timedwait', dependencies: threads))
1325 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1326 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1327 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1328 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1329 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1330 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1331 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1332 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1333 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1334
1335 # has_header_symbol
1336 config_host_data.set('CONFIG_BYTESWAP_H',
1337                      cc.has_header_symbol('byteswap.h', 'bswap_32'))
1338 config_host_data.set('CONFIG_EPOLL_CREATE1',
1339                      cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1340 config_host_data.set('CONFIG_HAS_ENVIRON',
1341                      cc.has_header_symbol('unistd.h', 'environ', prefix: gnu_source_prefix))
1342 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1343                      cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1344                      cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1345 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1346                      cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1347 config_host_data.set('CONFIG_FIEMAP',
1348                      cc.has_header('linux/fiemap.h') and
1349                      cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1350 config_host_data.set('CONFIG_GETRANDOM',
1351                      cc.has_function('getrandom') and
1352                      cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1353 config_host_data.set('CONFIG_INOTIFY',
1354                      cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1355 config_host_data.set('CONFIG_INOTIFY1',
1356                      cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1357 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1358                      cc.has_header_symbol('machine/bswap.h', 'bswap32',
1359                                           prefix: '''#include <sys/endian.h>
1360                                                      #include <sys/types.h>'''))
1361 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1362                      cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1363 config_host_data.set('CONFIG_RTNETLINK',
1364                      cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1365 config_host_data.set('CONFIG_SYSMACROS',
1366                      cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1367 config_host_data.set('HAVE_OPTRESET',
1368                      cc.has_header_symbol('getopt.h', 'optreset'))
1369 config_host_data.set('HAVE_UTMPX',
1370                      cc.has_header_symbol('utmpx.h', 'struct utmpx'))
1371 config_host_data.set('HAVE_IPPROTO_MPTCP',
1372                      cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
1373
1374 # has_member
1375 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1376                      cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1377                                    prefix: '#include <signal.h>'))
1378 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1379                      cc.has_member('struct stat', 'st_atim',
1380                                    prefix: '#include <sys/stat.h>'))
1381
1382 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1383   #include <sys/eventfd.h>
1384   int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1385 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1386   #include <unistd.h>
1387   int main(void) {
1388   #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1389   return fdatasync(0);
1390   #else
1391   #error Not supported
1392   #endif
1393   }'''))
1394 config_host_data.set('CONFIG_MADVISE', cc.links(gnu_source_prefix + '''
1395   #include <sys/types.h>
1396   #include <sys/mman.h>
1397   #include <stddef.h>
1398   int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }'''))
1399 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
1400   #include <sys/mman.h>
1401   int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
1402 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
1403   #include <fcntl.h>
1404   #if !defined(AT_EMPTY_PATH)
1405   # error missing definition
1406   #else
1407   int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
1408   #endif'''))
1409 config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
1410   #include <unistd.h>
1411   #include <fcntl.h>
1412
1413   int main(void)
1414   {
1415       int pipefd[2];
1416       return pipe2(pipefd, O_CLOEXEC);
1417   }'''))
1418 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
1419   #include <sys/mman.h>
1420   #include <stddef.h>
1421   int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
1422 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
1423   #include <unistd.h>
1424   #include <sys/syscall.h>
1425   #include <signal.h>
1426   int main(void) { return syscall(SYS_signalfd, -1, NULL, _NSIG / 8); }'''))
1427 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
1428   #include <unistd.h>
1429   #include <fcntl.h>
1430   #include <limits.h>
1431
1432   int main(void)
1433   {
1434     int len, fd = 0;
1435     len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
1436     splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
1437     return 0;
1438   }'''))
1439
1440 # Some versions of Mac OS X incorrectly define SIZE_MAX
1441 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
1442     #include <stdint.h>
1443     #include <stdio.h>
1444     int main(int argc, char *argv[]) {
1445         return printf("%zu", SIZE_MAX);
1446     }''', args: ['-Werror']))
1447
1448
1449 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
1450 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1451 strings = ['HOST_DSOSUF', 'CONFIG_IASL']
1452 foreach k, v: config_host
1453   if ignored.contains(k)
1454     # do nothing
1455   elif arrays.contains(k)
1456     if v != ''
1457       v = '"' + '", "'.join(v.split()) + '", '
1458     endif
1459     config_host_data.set(k, v)
1460   elif k == 'ARCH'
1461     config_host_data.set('HOST_' + v.to_upper(), 1)
1462   elif strings.contains(k)
1463     if not k.startswith('CONFIG_')
1464       k = 'CONFIG_' + k.to_upper()
1465     endif
1466     config_host_data.set_quoted(k, v)
1467   elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
1468     config_host_data.set(k, v == 'y' ? 1 : v)
1469   endif
1470 endforeach
1471
1472 ########################
1473 # Target configuration #
1474 ########################
1475
1476 minikconf = find_program('scripts/minikconf.py')
1477 config_all = {}
1478 config_all_devices = {}
1479 config_all_disas = {}
1480 config_devices_mak_list = []
1481 config_devices_h = {}
1482 config_target_h = {}
1483 config_target_mak = {}
1484
1485 disassemblers = {
1486   'alpha' : ['CONFIG_ALPHA_DIS'],
1487   'arm' : ['CONFIG_ARM_DIS'],
1488   'avr' : ['CONFIG_AVR_DIS'],
1489   'cris' : ['CONFIG_CRIS_DIS'],
1490   'hexagon' : ['CONFIG_HEXAGON_DIS'],
1491   'hppa' : ['CONFIG_HPPA_DIS'],
1492   'i386' : ['CONFIG_I386_DIS'],
1493   'x86_64' : ['CONFIG_I386_DIS'],
1494   'x32' : ['CONFIG_I386_DIS'],
1495   'm68k' : ['CONFIG_M68K_DIS'],
1496   'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1497   'mips' : ['CONFIG_MIPS_DIS'],
1498   'nios2' : ['CONFIG_NIOS2_DIS'],
1499   'or1k' : ['CONFIG_OPENRISC_DIS'],
1500   'ppc' : ['CONFIG_PPC_DIS'],
1501   'riscv' : ['CONFIG_RISCV_DIS'],
1502   'rx' : ['CONFIG_RX_DIS'],
1503   's390' : ['CONFIG_S390_DIS'],
1504   'sh4' : ['CONFIG_SH4_DIS'],
1505   'sparc' : ['CONFIG_SPARC_DIS'],
1506   'xtensa' : ['CONFIG_XTENSA_DIS'],
1507 }
1508 if link_language == 'cpp'
1509   disassemblers += {
1510     'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1511     'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1512     'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1513   }
1514 endif
1515
1516 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
1517 host_kconfig = \
1518   ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1519   ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
1520   (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
1521   ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1522   (x11.found() ? ['CONFIG_X11=y'] : []) + \
1523   ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1524   ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1525   ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1526   (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1527   ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1528   ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
1529   (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
1530
1531 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1532
1533 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1534 actual_target_dirs = []
1535 fdt_required = []
1536 foreach target : target_dirs
1537   config_target = { 'TARGET_NAME': target.split('-')[0] }
1538   if target.endswith('linux-user')
1539     if targetos != 'linux'
1540       if default_targets
1541         continue
1542       endif
1543       error('Target @0@ is only available on a Linux host'.format(target))
1544     endif
1545     config_target += { 'CONFIG_LINUX_USER': 'y' }
1546   elif target.endswith('bsd-user')
1547     if 'CONFIG_BSD' not in config_host
1548       if default_targets
1549         continue
1550       endif
1551       error('Target @0@ is only available on a BSD host'.format(target))
1552     endif
1553     config_target += { 'CONFIG_BSD_USER': 'y' }
1554   elif target.endswith('softmmu')
1555     config_target += { 'CONFIG_SOFTMMU': 'y' }
1556   endif
1557   if target.endswith('-user')
1558     config_target += {
1559       'CONFIG_USER_ONLY': 'y',
1560       'CONFIG_QEMU_INTERP_PREFIX':
1561         config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1562     }
1563   endif
1564
1565   accel_kconfig = []
1566   foreach sym: accelerators
1567     if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1568       config_target += { sym: 'y' }
1569       config_all += { sym: 'y' }
1570       if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
1571         config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
1572       elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1573         config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1574       endif
1575       if target in modular_tcg
1576         config_target += { 'CONFIG_TCG_MODULAR': 'y' }
1577       else
1578         config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
1579       endif
1580       accel_kconfig += [ sym + '=y' ]
1581     endif
1582   endforeach
1583   if accel_kconfig.length() == 0
1584     if default_targets
1585       continue
1586     endif
1587     error('No accelerator available for target @0@'.format(target))
1588   endif
1589
1590   actual_target_dirs += target
1591   config_target += keyval.load('configs/targets' / target + '.mak')
1592   config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1593
1594   if 'TARGET_NEED_FDT' in config_target
1595     fdt_required += target
1596   endif
1597
1598   # Add default keys
1599   if 'TARGET_BASE_ARCH' not in config_target
1600     config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1601   endif
1602   if 'TARGET_ABI_DIR' not in config_target
1603     config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1604   endif
1605
1606   foreach k, v: disassemblers
1607     if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1608       foreach sym: v
1609         config_target += { sym: 'y' }
1610         config_all_disas += { sym: 'y' }
1611       endforeach
1612     endif
1613   endforeach
1614
1615   config_target_data = configuration_data()
1616   foreach k, v: config_target
1617     if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1618       # do nothing
1619     elif ignored.contains(k)
1620       # do nothing
1621     elif k == 'TARGET_BASE_ARCH'
1622       # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1623       # not used to select files from sourcesets.
1624       config_target_data.set('TARGET_' + v.to_upper(), 1)
1625     elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1626       config_target_data.set_quoted(k, v)
1627     elif v == 'y'
1628       config_target_data.set(k, 1)
1629     else
1630       config_target_data.set(k, v)
1631     endif
1632   endforeach
1633   config_target_data.set('QEMU_ARCH',
1634                          'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
1635   config_target_h += {target: configure_file(output: target + '-config-target.h',
1636                                                configuration: config_target_data)}
1637
1638   if target.endswith('-softmmu')
1639     config_input = meson.get_external_property(target, 'default')
1640     config_devices_mak = target + '-config-devices.mak'
1641     config_devices_mak = configure_file(
1642       input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
1643       output: config_devices_mak,
1644       depfile: config_devices_mak + '.d',
1645       capture: true,
1646       command: [minikconf,
1647                 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1648                 config_devices_mak, '@DEPFILE@', '@INPUT@',
1649                 host_kconfig, accel_kconfig,
1650                 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
1651
1652     config_devices_data = configuration_data()
1653     config_devices = keyval.load(config_devices_mak)
1654     foreach k, v: config_devices
1655       config_devices_data.set(k, 1)
1656     endforeach
1657     config_devices_mak_list += config_devices_mak
1658     config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1659                                                 configuration: config_devices_data)}
1660     config_target += config_devices
1661     config_all_devices += config_devices
1662   endif
1663   config_target_mak += {target: config_target}
1664 endforeach
1665 target_dirs = actual_target_dirs
1666
1667 # This configuration is used to build files that are shared by
1668 # multiple binaries, and then extracted out of the "common"
1669 # static_library target.
1670 #
1671 # We do not use all_sources()/all_dependencies(), because it would
1672 # build literally all source files, including devices only used by
1673 # targets that are not built for this compilation.  The CONFIG_ALL
1674 # pseudo symbol replaces it.
1675
1676 config_all += config_all_devices
1677 config_all += config_host
1678 config_all += config_all_disas
1679 config_all += {
1680   'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1681   'CONFIG_SOFTMMU': have_system,
1682   'CONFIG_USER_ONLY': have_user,
1683   'CONFIG_ALL': true,
1684 }
1685
1686 ##############
1687 # Submodules #
1688 ##############
1689
1690 capstone = not_found
1691 capstone_opt = get_option('capstone')
1692 if capstone_opt in ['enabled', 'auto', 'system']
1693   have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1694   capstone = dependency('capstone', version: '>=4.0',
1695                         kwargs: static_kwargs, method: 'pkg-config',
1696                         required: capstone_opt == 'system' or
1697                                   capstone_opt == 'enabled' and not have_internal)
1698
1699   # Some versions of capstone have broken pkg-config file
1700   # that reports a wrong -I path, causing the #include to
1701   # fail later. If the system has such a broken version
1702   # do not use it.
1703   if capstone.found() and not cc.compiles('#include <capstone.h>',
1704                                           dependencies: [capstone])
1705     capstone = not_found
1706     if capstone_opt == 'system'
1707       error('system capstone requested, it does not appear to work')
1708     endif
1709   endif
1710
1711   if capstone.found()
1712     capstone_opt = 'system'
1713   elif have_internal
1714     capstone_opt = 'internal'
1715   else
1716     capstone_opt = 'disabled'
1717   endif
1718 endif
1719 if capstone_opt == 'internal'
1720   capstone_data = configuration_data()
1721   capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1722
1723   capstone_files = files(
1724     'capstone/cs.c',
1725     'capstone/MCInst.c',
1726     'capstone/MCInstrDesc.c',
1727     'capstone/MCRegisterInfo.c',
1728     'capstone/SStream.c',
1729     'capstone/utils.c'
1730   )
1731
1732   if 'CONFIG_ARM_DIS' in config_all_disas
1733     capstone_data.set('CAPSTONE_HAS_ARM', '1')
1734     capstone_files += files(
1735       'capstone/arch/ARM/ARMDisassembler.c',
1736       'capstone/arch/ARM/ARMInstPrinter.c',
1737       'capstone/arch/ARM/ARMMapping.c',
1738       'capstone/arch/ARM/ARMModule.c'
1739     )
1740   endif
1741
1742   # FIXME: This config entry currently depends on a c++ compiler.
1743   # Which is needed for building libvixl, but not for capstone.
1744   if 'CONFIG_ARM_A64_DIS' in config_all_disas
1745     capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1746     capstone_files += files(
1747       'capstone/arch/AArch64/AArch64BaseInfo.c',
1748       'capstone/arch/AArch64/AArch64Disassembler.c',
1749       'capstone/arch/AArch64/AArch64InstPrinter.c',
1750       'capstone/arch/AArch64/AArch64Mapping.c',
1751       'capstone/arch/AArch64/AArch64Module.c'
1752     )
1753   endif
1754
1755   if 'CONFIG_PPC_DIS' in config_all_disas
1756     capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1757     capstone_files += files(
1758       'capstone/arch/PowerPC/PPCDisassembler.c',
1759       'capstone/arch/PowerPC/PPCInstPrinter.c',
1760       'capstone/arch/PowerPC/PPCMapping.c',
1761       'capstone/arch/PowerPC/PPCModule.c'
1762     )
1763   endif
1764
1765   if 'CONFIG_S390_DIS' in config_all_disas
1766     capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1767     capstone_files += files(
1768       'capstone/arch/SystemZ/SystemZDisassembler.c',
1769       'capstone/arch/SystemZ/SystemZInstPrinter.c',
1770       'capstone/arch/SystemZ/SystemZMapping.c',
1771       'capstone/arch/SystemZ/SystemZModule.c',
1772       'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1773     )
1774   endif
1775
1776   if 'CONFIG_I386_DIS' in config_all_disas
1777     capstone_data.set('CAPSTONE_HAS_X86', 1)
1778     capstone_files += files(
1779       'capstone/arch/X86/X86Disassembler.c',
1780       'capstone/arch/X86/X86DisassemblerDecoder.c',
1781       'capstone/arch/X86/X86ATTInstPrinter.c',
1782       'capstone/arch/X86/X86IntelInstPrinter.c',
1783       'capstone/arch/X86/X86InstPrinterCommon.c',
1784       'capstone/arch/X86/X86Mapping.c',
1785       'capstone/arch/X86/X86Module.c'
1786     )
1787   endif
1788
1789   configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1790
1791   capstone_cargs = [
1792     # FIXME: There does not seem to be a way to completely replace the c_args
1793     # that come from add_project_arguments() -- we can only add to them.
1794     # So: disable all warnings with a big hammer.
1795     '-Wno-error', '-w',
1796
1797     # Include all configuration defines via a header file, which will wind up
1798     # as a dependency on the object file, and thus changes here will result
1799     # in a rebuild.
1800     '-include', 'capstone-defs.h'
1801   ]
1802
1803   libcapstone = static_library('capstone',
1804                                build_by_default: false,
1805                                sources: capstone_files,
1806                                c_args: capstone_cargs,
1807                                include_directories: 'capstone/include')
1808   capstone = declare_dependency(link_with: libcapstone,
1809                                 include_directories: 'capstone/include/capstone')
1810 endif
1811
1812 slirp = not_found
1813 slirp_opt = 'disabled'
1814 if have_system
1815   slirp_opt = get_option('slirp')
1816   if slirp_opt in ['enabled', 'auto', 'system']
1817     have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1818     slirp = dependency('slirp', kwargs: static_kwargs,
1819                        method: 'pkg-config',
1820                        required: slirp_opt == 'system' or
1821                                  slirp_opt == 'enabled' and not have_internal)
1822     if slirp.found()
1823       slirp_opt = 'system'
1824     elif have_internal
1825       slirp_opt = 'internal'
1826     else
1827       slirp_opt = 'disabled'
1828     endif
1829   endif
1830   if slirp_opt == 'internal'
1831     slirp_deps = []
1832     if targetos == 'windows'
1833       slirp_deps = cc.find_library('iphlpapi')
1834     elif targetos == 'darwin'
1835       slirp_deps = cc.find_library('resolv')
1836     endif
1837     slirp_conf = configuration_data()
1838     slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1839     slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1840     slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1841     slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1842     slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1843     slirp_files = [
1844       'slirp/src/arp_table.c',
1845       'slirp/src/bootp.c',
1846       'slirp/src/cksum.c',
1847       'slirp/src/dhcpv6.c',
1848       'slirp/src/dnssearch.c',
1849       'slirp/src/if.c',
1850       'slirp/src/ip6_icmp.c',
1851       'slirp/src/ip6_input.c',
1852       'slirp/src/ip6_output.c',
1853       'slirp/src/ip_icmp.c',
1854       'slirp/src/ip_input.c',
1855       'slirp/src/ip_output.c',
1856       'slirp/src/mbuf.c',
1857       'slirp/src/misc.c',
1858       'slirp/src/ncsi.c',
1859       'slirp/src/ndp_table.c',
1860       'slirp/src/sbuf.c',
1861       'slirp/src/slirp.c',
1862       'slirp/src/socket.c',
1863       'slirp/src/state.c',
1864       'slirp/src/stream.c',
1865       'slirp/src/tcp_input.c',
1866       'slirp/src/tcp_output.c',
1867       'slirp/src/tcp_subr.c',
1868       'slirp/src/tcp_timer.c',
1869       'slirp/src/tftp.c',
1870       'slirp/src/udp.c',
1871       'slirp/src/udp6.c',
1872       'slirp/src/util.c',
1873       'slirp/src/version.c',
1874       'slirp/src/vmstate.c',
1875     ]
1876
1877     configure_file(
1878       input : 'slirp/src/libslirp-version.h.in',
1879       output : 'libslirp-version.h',
1880       configuration: slirp_conf)
1881
1882     slirp_inc = include_directories('slirp', 'slirp/src')
1883     libslirp = static_library('slirp',
1884                               build_by_default: false,
1885                               sources: slirp_files,
1886                               c_args: slirp_cargs,
1887                               include_directories: slirp_inc)
1888     slirp = declare_dependency(link_with: libslirp,
1889                                dependencies: slirp_deps,
1890                                include_directories: slirp_inc)
1891   endif
1892 endif
1893
1894 # For CFI, we need to compile slirp as a static library together with qemu.
1895 # This is because we register slirp functions as callbacks for QEMU Timers.
1896 # When using a system-wide shared libslirp, the type information for the
1897 # callback is missing and the timer call produces a false positive with CFI.
1898 #
1899 # Now that slirp_opt has been defined, check if the selected slirp is compatible
1900 # with control-flow integrity.
1901 if get_option('cfi') and slirp_opt == 'system'
1902   error('Control-Flow Integrity is not compatible with system-wide slirp.' \
1903          + ' Please configure with --enable-slirp=git')
1904 endif
1905
1906 fdt = not_found
1907 fdt_opt = get_option('fdt')
1908 if have_system
1909   if fdt_opt in ['enabled', 'auto', 'system']
1910     have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1911     fdt = cc.find_library('fdt', kwargs: static_kwargs,
1912                           required: fdt_opt == 'system' or
1913                                     fdt_opt == 'enabled' and not have_internal)
1914     if fdt.found() and cc.links('''
1915        #include <libfdt.h>
1916        #include <libfdt_env.h>
1917        int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1918          dependencies: fdt)
1919       fdt_opt = 'system'
1920     elif fdt_opt == 'system'
1921        error('system libfdt requested, but it is too old (1.5.1 or newer required)')
1922     elif have_internal
1923       fdt_opt = 'internal'
1924     else
1925       fdt_opt = 'disabled'
1926       fdt = not_found
1927     endif
1928   endif
1929   if fdt_opt == 'internal'
1930     fdt_files = files(
1931       'dtc/libfdt/fdt.c',
1932       'dtc/libfdt/fdt_ro.c',
1933       'dtc/libfdt/fdt_wip.c',
1934       'dtc/libfdt/fdt_sw.c',
1935       'dtc/libfdt/fdt_rw.c',
1936       'dtc/libfdt/fdt_strerror.c',
1937       'dtc/libfdt/fdt_empty_tree.c',
1938       'dtc/libfdt/fdt_addresses.c',
1939       'dtc/libfdt/fdt_overlay.c',
1940       'dtc/libfdt/fdt_check.c',
1941     )
1942
1943     fdt_inc = include_directories('dtc/libfdt')
1944     libfdt = static_library('fdt',
1945                             build_by_default: false,
1946                             sources: fdt_files,
1947                             include_directories: fdt_inc)
1948     fdt = declare_dependency(link_with: libfdt,
1949                              include_directories: fdt_inc)
1950   endif
1951 endif
1952 if not fdt.found() and fdt_required.length() > 0
1953   error('fdt not available but required by targets ' + ', '.join(fdt_required))
1954 endif
1955
1956 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1957 config_host_data.set('CONFIG_FDT', fdt.found())
1958 config_host_data.set('CONFIG_SLIRP', slirp.found())
1959
1960 #####################
1961 # Generated sources #
1962 #####################
1963
1964 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1965
1966 hxtool = find_program('scripts/hxtool')
1967 shaderinclude = find_program('scripts/shaderinclude.pl')
1968 qapi_gen = find_program('scripts/qapi-gen.py')
1969 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
1970                      meson.current_source_dir() / 'scripts/qapi/commands.py',
1971                      meson.current_source_dir() / 'scripts/qapi/common.py',
1972                      meson.current_source_dir() / 'scripts/qapi/error.py',
1973                      meson.current_source_dir() / 'scripts/qapi/events.py',
1974                      meson.current_source_dir() / 'scripts/qapi/expr.py',
1975                      meson.current_source_dir() / 'scripts/qapi/gen.py',
1976                      meson.current_source_dir() / 'scripts/qapi/introspect.py',
1977                      meson.current_source_dir() / 'scripts/qapi/parser.py',
1978                      meson.current_source_dir() / 'scripts/qapi/schema.py',
1979                      meson.current_source_dir() / 'scripts/qapi/source.py',
1980                      meson.current_source_dir() / 'scripts/qapi/types.py',
1981                      meson.current_source_dir() / 'scripts/qapi/visit.py',
1982                      meson.current_source_dir() / 'scripts/qapi/common.py',
1983                      meson.current_source_dir() / 'scripts/qapi-gen.py'
1984 ]
1985
1986 tracetool = [
1987   python, files('scripts/tracetool.py'),
1988    '--backend=' + config_host['TRACE_BACKENDS']
1989 ]
1990 tracetool_depends = files(
1991   'scripts/tracetool/backend/log.py',
1992   'scripts/tracetool/backend/__init__.py',
1993   'scripts/tracetool/backend/dtrace.py',
1994   'scripts/tracetool/backend/ftrace.py',
1995   'scripts/tracetool/backend/simple.py',
1996   'scripts/tracetool/backend/syslog.py',
1997   'scripts/tracetool/backend/ust.py',
1998   'scripts/tracetool/format/tcg_h.py',
1999   'scripts/tracetool/format/ust_events_c.py',
2000   'scripts/tracetool/format/ust_events_h.py',
2001   'scripts/tracetool/format/__init__.py',
2002   'scripts/tracetool/format/d.py',
2003   'scripts/tracetool/format/tcg_helper_c.py',
2004   'scripts/tracetool/format/simpletrace_stap.py',
2005   'scripts/tracetool/format/c.py',
2006   'scripts/tracetool/format/h.py',
2007   'scripts/tracetool/format/tcg_helper_h.py',
2008   'scripts/tracetool/format/log_stap.py',
2009   'scripts/tracetool/format/stap.py',
2010   'scripts/tracetool/format/tcg_helper_wrapper_h.py',
2011   'scripts/tracetool/__init__.py',
2012   'scripts/tracetool/transform.py',
2013   'scripts/tracetool/vcpu.py'
2014 )
2015
2016 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2017                     meson.current_source_dir(),
2018                     config_host['PKGVERSION'], meson.project_version()]
2019 qemu_version = custom_target('qemu-version.h',
2020                              output: 'qemu-version.h',
2021                              command: qemu_version_cmd,
2022                              capture: true,
2023                              build_by_default: true,
2024                              build_always_stale: true)
2025 genh += qemu_version
2026
2027 hxdep = []
2028 hx_headers = [
2029   ['qemu-options.hx', 'qemu-options.def'],
2030   ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2031 ]
2032 if have_system
2033   hx_headers += [
2034     ['hmp-commands.hx', 'hmp-commands.h'],
2035     ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2036   ]
2037 endif
2038 foreach d : hx_headers
2039   hxdep += custom_target(d[1],
2040                 input: files(d[0]),
2041                 output: d[1],
2042                 capture: true,
2043                 build_by_default: true, # to be removed when added to a target
2044                 command: [hxtool, '-h', '@INPUT0@'])
2045 endforeach
2046 genh += hxdep
2047
2048 ###################
2049 # Collect sources #
2050 ###################
2051
2052 authz_ss = ss.source_set()
2053 blockdev_ss = ss.source_set()
2054 block_ss = ss.source_set()
2055 bsd_user_ss = ss.source_set()
2056 chardev_ss = ss.source_set()
2057 common_ss = ss.source_set()
2058 crypto_ss = ss.source_set()
2059 io_ss = ss.source_set()
2060 linux_user_ss = ss.source_set()
2061 qmp_ss = ss.source_set()
2062 qom_ss = ss.source_set()
2063 softmmu_ss = ss.source_set()
2064 specific_fuzz_ss = ss.source_set()
2065 specific_ss = ss.source_set()
2066 stub_ss = ss.source_set()
2067 trace_ss = ss.source_set()
2068 user_ss = ss.source_set()
2069 util_ss = ss.source_set()
2070
2071 # accel modules
2072 qtest_module_ss = ss.source_set()
2073 tcg_module_ss = ss.source_set()
2074
2075 modules = {}
2076 target_modules = {}
2077 hw_arch = {}
2078 target_arch = {}
2079 target_softmmu_arch = {}
2080 target_user_arch = {}
2081
2082 ###############
2083 # Trace files #
2084 ###############
2085
2086 # TODO: add each directory to the subdirs from its own meson.build, once
2087 # we have those
2088 trace_events_subdirs = [
2089   'crypto',
2090   'qapi',
2091   'qom',
2092   'monitor',
2093   'util',
2094 ]
2095 if have_user
2096   trace_events_subdirs += [ 'linux-user' ]
2097 endif
2098 if have_block
2099   trace_events_subdirs += [
2100     'authz',
2101     'block',
2102     'io',
2103     'nbd',
2104     'scsi',
2105   ]
2106 endif
2107 if have_system
2108   trace_events_subdirs += [
2109     'accel/kvm',
2110     'audio',
2111     'backends',
2112     'backends/tpm',
2113     'chardev',
2114     'ebpf',
2115     'hw/9pfs',
2116     'hw/acpi',
2117     'hw/adc',
2118     'hw/alpha',
2119     'hw/arm',
2120     'hw/audio',
2121     'hw/block',
2122     'hw/block/dataplane',
2123     'hw/char',
2124     'hw/display',
2125     'hw/dma',
2126     'hw/hppa',
2127     'hw/hyperv',
2128     'hw/i2c',
2129     'hw/i386',
2130     'hw/i386/xen',
2131     'hw/ide',
2132     'hw/input',
2133     'hw/intc',
2134     'hw/isa',
2135     'hw/mem',
2136     'hw/mips',
2137     'hw/misc',
2138     'hw/misc/macio',
2139     'hw/net',
2140     'hw/net/can',
2141     'hw/nubus',
2142     'hw/nvme',
2143     'hw/nvram',
2144     'hw/pci',
2145     'hw/pci-host',
2146     'hw/ppc',
2147     'hw/rdma',
2148     'hw/rdma/vmw',
2149     'hw/rtc',
2150     'hw/s390x',
2151     'hw/scsi',
2152     'hw/sd',
2153     'hw/sparc',
2154     'hw/sparc64',
2155     'hw/ssi',
2156     'hw/timer',
2157     'hw/tpm',
2158     'hw/usb',
2159     'hw/vfio',
2160     'hw/virtio',
2161     'hw/watchdog',
2162     'hw/xen',
2163     'hw/gpio',
2164     'migration',
2165     'net',
2166     'softmmu',
2167     'ui',
2168     'hw/remote',
2169   ]
2170 endif
2171 if have_system or have_user
2172   trace_events_subdirs += [
2173     'accel/tcg',
2174     'hw/core',
2175     'target/arm',
2176     'target/arm/hvf',
2177     'target/hppa',
2178     'target/i386',
2179     'target/i386/kvm',
2180     'target/mips/tcg',
2181     'target/ppc',
2182     'target/riscv',
2183     'target/s390x',
2184     'target/s390x/kvm',
2185     'target/sparc',
2186   ]
2187 endif
2188
2189 vhost_user = not_found
2190 if 'CONFIG_VHOST_USER' in config_host
2191   libvhost_user = subproject('libvhost-user')
2192   vhost_user = libvhost_user.get_variable('vhost_user_dep')
2193 endif
2194
2195 subdir('qapi')
2196 subdir('qobject')
2197 subdir('stubs')
2198 subdir('trace')
2199 subdir('util')
2200 subdir('qom')
2201 subdir('authz')
2202 subdir('crypto')
2203 subdir('ui')
2204
2205
2206 if enable_modules
2207   libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
2208   modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
2209 endif
2210
2211 stub_ss = stub_ss.apply(config_all, strict: false)
2212
2213 util_ss.add_all(trace_ss)
2214 util_ss = util_ss.apply(config_all, strict: false)
2215 libqemuutil = static_library('qemuutil',
2216                              sources: util_ss.sources() + stub_ss.sources() + genh,
2217                              dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
2218 qemuutil = declare_dependency(link_with: libqemuutil,
2219                               sources: genh + version_res)
2220
2221 if have_system or have_user
2222   decodetree = generator(find_program('scripts/decodetree.py'),
2223                          output: 'decode-@BASENAME@.c.inc',
2224                          arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
2225   subdir('libdecnumber')
2226   subdir('target')
2227 endif
2228
2229 subdir('audio')
2230 subdir('io')
2231 subdir('chardev')
2232 subdir('fsdev')
2233 subdir('dump')
2234
2235 if have_block
2236   block_ss.add(files(
2237     'block.c',
2238     'blockjob.c',
2239     'job.c',
2240     'qemu-io-cmds.c',
2241   ))
2242   block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
2243
2244   subdir('nbd')
2245   subdir('scsi')
2246   subdir('block')
2247
2248   blockdev_ss.add(files(
2249     'blockdev.c',
2250     'blockdev-nbd.c',
2251     'iothread.c',
2252     'job-qmp.c',
2253   ), gnutls)
2254
2255   # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
2256   # os-win32.c does not
2257   blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
2258   softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
2259 endif
2260
2261 common_ss.add(files('cpus-common.c'))
2262
2263 subdir('softmmu')
2264
2265 common_ss.add(capstone)
2266 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
2267
2268 # Work around a gcc bug/misfeature wherein constant propagation looks
2269 # through an alias:
2270 #   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
2271 # to guess that a const variable is always zero.  Without lto, this is
2272 # impossible, as the alias is restricted to page-vary-common.c.  Indeed,
2273 # without lto, not even the alias is required -- we simply use different
2274 # declarations in different compilation units.
2275 pagevary = files('page-vary-common.c')
2276 if get_option('b_lto')
2277   pagevary_flags = ['-fno-lto']
2278   if get_option('cfi')
2279     pagevary_flags += '-fno-sanitize=cfi-icall'
2280   endif
2281   pagevary = static_library('page-vary-common', sources: pagevary,
2282                             c_args: pagevary_flags)
2283   pagevary = declare_dependency(link_with: pagevary)
2284 endif
2285 common_ss.add(pagevary)
2286 specific_ss.add(files('page-vary.c'))
2287
2288 subdir('backends')
2289 subdir('disas')
2290 subdir('migration')
2291 subdir('monitor')
2292 subdir('net')
2293 subdir('replay')
2294 subdir('semihosting')
2295 subdir('hw')
2296 subdir('tcg')
2297 subdir('fpu')
2298 subdir('accel')
2299 subdir('plugins')
2300 subdir('bsd-user')
2301 subdir('linux-user')
2302 subdir('ebpf')
2303
2304 common_ss.add(libbpf)
2305
2306 bsd_user_ss.add(files('gdbstub.c'))
2307 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
2308
2309 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
2310 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
2311
2312 # needed for fuzzing binaries
2313 subdir('tests/qtest/libqos')
2314 subdir('tests/qtest/fuzz')
2315
2316 # accel modules
2317 tcg_real_module_ss = ss.source_set()
2318 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
2319 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
2320 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
2321                                 'tcg': tcg_real_module_ss }}
2322
2323 ########################
2324 # Library dependencies #
2325 ########################
2326
2327 modinfo_collect = find_program('scripts/modinfo-collect.py')
2328 modinfo_generate = find_program('scripts/modinfo-generate.py')
2329 modinfo_files = []
2330
2331 block_mods = []
2332 softmmu_mods = []
2333 foreach d, list : modules
2334   foreach m, module_ss : list
2335     if enable_modules and targetos != 'windows'
2336       module_ss = module_ss.apply(config_all, strict: false)
2337       sl = static_library(d + '-' + m, [genh, module_ss.sources()],
2338                           dependencies: [modulecommon, module_ss.dependencies()], pic: true)
2339       if d == 'block'
2340         block_mods += sl
2341       else
2342         softmmu_mods += sl
2343       endif
2344       if module_ss.sources() != []
2345         # FIXME: Should use sl.extract_all_objects(recursive: true) as
2346         # input. Sources can be used multiple times but objects are
2347         # unique when it comes to lookup in compile_commands.json.
2348         # Depnds on a mesion version with
2349         # https://github.com/mesonbuild/meson/pull/8900
2350         modinfo_files += custom_target(d + '-' + m + '.modinfo',
2351                                        output: d + '-' + m + '.modinfo',
2352                                        input: module_ss.sources() + genh,
2353                                        capture: true,
2354                                        command: [modinfo_collect, module_ss.sources()])
2355       endif
2356     else
2357       if d == 'block'
2358         block_ss.add_all(module_ss)
2359       else
2360         softmmu_ss.add_all(module_ss)
2361       endif
2362     endif
2363   endforeach
2364 endforeach
2365
2366 foreach d, list : target_modules
2367   foreach m, module_ss : list
2368     if enable_modules and targetos != 'windows'
2369       foreach target : target_dirs
2370         if target.endswith('-softmmu')
2371           config_target = config_target_mak[target]
2372           config_target += config_host
2373           target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2374           c_args = ['-DNEED_CPU_H',
2375                     '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2376                     '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2377           target_module_ss = module_ss.apply(config_target, strict: false)
2378           if target_module_ss.sources() != []
2379             module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
2380             sl = static_library(module_name,
2381                                 [genh, target_module_ss.sources()],
2382                                 dependencies: [modulecommon, target_module_ss.dependencies()],
2383                                 include_directories: target_inc,
2384                                 c_args: c_args,
2385                                 pic: true)
2386             softmmu_mods += sl
2387             # FIXME: Should use sl.extract_all_objects(recursive: true) too.
2388             modinfo_files += custom_target(module_name + '.modinfo',
2389                                            output: module_name + '.modinfo',
2390                                            input: target_module_ss.sources() + genh,
2391                                            capture: true,
2392                                            command: [modinfo_collect, '--target', target, target_module_ss.sources()])
2393           endif
2394         endif
2395       endforeach
2396     else
2397       specific_ss.add_all(module_ss)
2398     endif
2399   endforeach
2400 endforeach
2401
2402 if enable_modules
2403   modinfo_src = custom_target('modinfo.c',
2404                               output: 'modinfo.c',
2405                               input: modinfo_files,
2406                               command: [modinfo_generate, '@INPUT@'],
2407                               capture: true)
2408   modinfo_lib = static_library('modinfo', modinfo_src)
2409   modinfo_dep = declare_dependency(link_whole: modinfo_lib)
2410   softmmu_ss.add(modinfo_dep)
2411 endif
2412
2413 nm = find_program('nm')
2414 undefsym = find_program('scripts/undefsym.py')
2415 block_syms = custom_target('block.syms', output: 'block.syms',
2416                              input: [libqemuutil, block_mods],
2417                              capture: true,
2418                              command: [undefsym, nm, '@INPUT@'])
2419 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
2420                              input: [libqemuutil, softmmu_mods],
2421                              capture: true,
2422                              command: [undefsym, nm, '@INPUT@'])
2423
2424 qom_ss = qom_ss.apply(config_host, strict: false)
2425 libqom = static_library('qom', qom_ss.sources() + genh,
2426                         dependencies: [qom_ss.dependencies()],
2427                         name_suffix: 'fa')
2428
2429 qom = declare_dependency(link_whole: libqom)
2430
2431 authz_ss = authz_ss.apply(config_host, strict: false)
2432 libauthz = static_library('authz', authz_ss.sources() + genh,
2433                           dependencies: [authz_ss.dependencies()],
2434                           name_suffix: 'fa',
2435                           build_by_default: false)
2436
2437 authz = declare_dependency(link_whole: libauthz,
2438                            dependencies: qom)
2439
2440 crypto_ss = crypto_ss.apply(config_host, strict: false)
2441 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2442                            dependencies: [crypto_ss.dependencies()],
2443                            name_suffix: 'fa',
2444                            build_by_default: false)
2445
2446 crypto = declare_dependency(link_whole: libcrypto,
2447                             dependencies: [authz, qom])
2448
2449 io_ss = io_ss.apply(config_host, strict: false)
2450 libio = static_library('io', io_ss.sources() + genh,
2451                        dependencies: [io_ss.dependencies()],
2452                        link_with: libqemuutil,
2453                        name_suffix: 'fa',
2454                        build_by_default: false)
2455
2456 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2457
2458 libmigration = static_library('migration', sources: migration_files + genh,
2459                               name_suffix: 'fa',
2460                               build_by_default: false)
2461 migration = declare_dependency(link_with: libmigration,
2462                                dependencies: [zlib, qom, io])
2463 softmmu_ss.add(migration)
2464
2465 block_ss = block_ss.apply(config_host, strict: false)
2466 libblock = static_library('block', block_ss.sources() + genh,
2467                           dependencies: block_ss.dependencies(),
2468                           link_depends: block_syms,
2469                           name_suffix: 'fa',
2470                           build_by_default: false)
2471
2472 block = declare_dependency(link_whole: [libblock],
2473                            link_args: '@block.syms',
2474                            dependencies: [crypto, io])
2475
2476 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2477 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2478                              dependencies: blockdev_ss.dependencies(),
2479                              name_suffix: 'fa',
2480                              build_by_default: false)
2481
2482 blockdev = declare_dependency(link_whole: [libblockdev],
2483                               dependencies: [block])
2484
2485 qmp_ss = qmp_ss.apply(config_host, strict: false)
2486 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2487                         dependencies: qmp_ss.dependencies(),
2488                         name_suffix: 'fa',
2489                         build_by_default: false)
2490
2491 qmp = declare_dependency(link_whole: [libqmp])
2492
2493 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2494                             name_suffix: 'fa',
2495                             dependencies: [gnutls],
2496                             build_by_default: false)
2497
2498 chardev = declare_dependency(link_whole: libchardev)
2499
2500 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
2501                            name_suffix: 'fa',
2502                            build_by_default: false)
2503 hwcore = declare_dependency(link_whole: libhwcore)
2504 common_ss.add(hwcore)
2505
2506 ###########
2507 # Targets #
2508 ###########
2509
2510 foreach m : block_mods + softmmu_mods
2511   shared_module(m.name(),
2512                 name_prefix: '',
2513                 link_whole: m,
2514                 install: true,
2515                 install_dir: qemu_moddir)
2516 endforeach
2517
2518 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2519 common_ss.add(qom, qemuutil)
2520
2521 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2522 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2523
2524 common_all = common_ss.apply(config_all, strict: false)
2525 common_all = static_library('common',
2526                             build_by_default: false,
2527                             sources: common_all.sources() + genh,
2528                             implicit_include_directories: false,
2529                             dependencies: common_all.dependencies(),
2530                             name_suffix: 'fa')
2531
2532 feature_to_c = find_program('scripts/feature_to_c.sh')
2533
2534 emulators = {}
2535 foreach target : target_dirs
2536   config_target = config_target_mak[target]
2537   target_name = config_target['TARGET_NAME']
2538   arch = config_target['TARGET_BASE_ARCH']
2539   arch_srcs = [config_target_h[target]]
2540   arch_deps = []
2541   c_args = ['-DNEED_CPU_H',
2542             '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2543             '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2544   link_args = emulator_link_args
2545
2546   config_target += config_host
2547   target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2548   if targetos == 'linux'
2549     target_inc += include_directories('linux-headers', is_system: true)
2550   endif
2551   if target.endswith('-softmmu')
2552     qemu_target_name = 'qemu-system-' + target_name
2553     target_type='system'
2554     t = target_softmmu_arch[arch].apply(config_target, strict: false)
2555     arch_srcs += t.sources()
2556     arch_deps += t.dependencies()
2557
2558     hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2559     hw = hw_arch[hw_dir].apply(config_target, strict: false)
2560     arch_srcs += hw.sources()
2561     arch_deps += hw.dependencies()
2562
2563     arch_srcs += config_devices_h[target]
2564     link_args += ['@block.syms', '@qemu.syms']
2565   else
2566     abi = config_target['TARGET_ABI_DIR']
2567     target_type='user'
2568     qemu_target_name = 'qemu-' + target_name
2569     if arch in target_user_arch
2570       t = target_user_arch[arch].apply(config_target, strict: false)
2571       arch_srcs += t.sources()
2572       arch_deps += t.dependencies()
2573     endif
2574     if 'CONFIG_LINUX_USER' in config_target
2575       base_dir = 'linux-user'
2576       target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2577     endif
2578     if 'CONFIG_BSD_USER' in config_target
2579       base_dir = 'bsd-user'
2580       target_inc += include_directories('bsd-user/' / targetos)
2581       dir = base_dir / abi
2582       arch_srcs += files(dir / 'target_arch_cpu.c')
2583     endif
2584     target_inc += include_directories(
2585       base_dir,
2586       base_dir / abi,
2587     )
2588     if 'CONFIG_LINUX_USER' in config_target
2589       dir = base_dir / abi
2590       arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2591       if config_target.has_key('TARGET_SYSTBL_ABI')
2592         arch_srcs += \
2593           syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2594                                              extra_args : config_target['TARGET_SYSTBL_ABI'])
2595       endif
2596     endif
2597   endif
2598
2599   if 'TARGET_XML_FILES' in config_target
2600     gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2601                                 output: target + '-gdbstub-xml.c',
2602                                 input: files(config_target['TARGET_XML_FILES'].split()),
2603                                 command: [feature_to_c, '@INPUT@'],
2604                                 capture: true)
2605     arch_srcs += gdbstub_xml
2606   endif
2607
2608   t = target_arch[arch].apply(config_target, strict: false)
2609   arch_srcs += t.sources()
2610   arch_deps += t.dependencies()
2611
2612   target_common = common_ss.apply(config_target, strict: false)
2613   objects = common_all.extract_objects(target_common.sources())
2614   deps = target_common.dependencies()
2615
2616   target_specific = specific_ss.apply(config_target, strict: false)
2617   arch_srcs += target_specific.sources()
2618   arch_deps += target_specific.dependencies()
2619
2620   lib = static_library('qemu-' + target,
2621                  sources: arch_srcs + genh,
2622                  dependencies: arch_deps,
2623                  objects: objects,
2624                  include_directories: target_inc,
2625                  c_args: c_args,
2626                  build_by_default: false,
2627                  name_suffix: 'fa')
2628
2629   if target.endswith('-softmmu')
2630     execs = [{
2631       'name': 'qemu-system-' + target_name,
2632       'win_subsystem': 'console',
2633       'sources': files('softmmu/main.c'),
2634       'dependencies': []
2635     }]
2636     if targetos == 'windows' and (sdl.found() or gtk.found())
2637       execs += [{
2638         'name': 'qemu-system-' + target_name + 'w',
2639         'win_subsystem': 'windows',
2640         'sources': files('softmmu/main.c'),
2641         'dependencies': []
2642       }]
2643     endif
2644     if config_host.has_key('CONFIG_FUZZ')
2645       specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2646       execs += [{
2647         'name': 'qemu-fuzz-' + target_name,
2648         'win_subsystem': 'console',
2649         'sources': specific_fuzz.sources(),
2650         'dependencies': specific_fuzz.dependencies(),
2651       }]
2652     endif
2653   else
2654     execs = [{
2655       'name': 'qemu-' + target_name,
2656       'win_subsystem': 'console',
2657       'sources': [],
2658       'dependencies': []
2659     }]
2660   endif
2661   foreach exe: execs
2662     exe_name = exe['name']
2663     if targetos == 'darwin'
2664       exe_name += '-unsigned'
2665     endif
2666
2667     emulator = executable(exe_name, exe['sources'],
2668                install: true,
2669                c_args: c_args,
2670                dependencies: arch_deps + deps + exe['dependencies'],
2671                objects: lib.extract_all_objects(recursive: true),
2672                link_language: link_language,
2673                link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2674                link_args: link_args,
2675                win_subsystem: exe['win_subsystem'])
2676
2677     if targetos == 'darwin'
2678       icon = 'pc-bios/qemu.rsrc'
2679       build_input = [emulator, files(icon)]
2680       install_input = [
2681         get_option('bindir') / exe_name,
2682         meson.current_source_dir() / icon
2683       ]
2684       if 'CONFIG_HVF' in config_target
2685         entitlements = 'accel/hvf/entitlements.plist'
2686         build_input += files(entitlements)
2687         install_input += meson.current_source_dir() / entitlements
2688       endif
2689
2690       emulators += {exe['name'] : custom_target(exe['name'],
2691                    input: build_input,
2692                    output: exe['name'],
2693                    command: [
2694                      files('scripts/entitlement.sh'),
2695                      '@OUTPUT@',
2696                      '@INPUT@'
2697                    ])
2698       }
2699
2700       meson.add_install_script('scripts/entitlement.sh', '--install',
2701                                get_option('bindir') / exe['name'],
2702                                install_input)
2703     else
2704       emulators += {exe['name']: emulator}
2705     endif
2706
2707     if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2708       foreach stp: [
2709         {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2710         {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2711         {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2712         {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2713       ]
2714         custom_target(exe['name'] + stp['ext'],
2715                       input: trace_events_all,
2716                       output: exe['name'] + stp['ext'],
2717                       install: stp['install'],
2718                       install_dir: get_option('datadir') / 'systemtap/tapset',
2719                       command: [
2720                         tracetool, '--group=all', '--format=' + stp['fmt'],
2721                         '--binary=' + stp['bin'],
2722                         '--target-name=' + target_name,
2723                         '--target-type=' + target_type,
2724                         '--probe-prefix=qemu.' + target_type + '.' + target_name,
2725                         '@INPUT@', '@OUTPUT@'
2726                       ],
2727                       depend_files: tracetool_depends)
2728       endforeach
2729     endif
2730   endforeach
2731 endforeach
2732
2733 # Other build targets
2734
2735 if 'CONFIG_PLUGIN' in config_host
2736   install_headers('include/qemu/qemu-plugin.h')
2737 endif
2738
2739 if 'CONFIG_GUEST_AGENT' in config_host
2740   subdir('qga')
2741 elif get_option('guest_agent_msi').enabled()
2742   error('Guest agent MSI requested, but the guest agent is not being built')
2743 endif
2744
2745 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2746 # when we don't build tools or system
2747 if xkbcommon.found()
2748   # used for the update-keymaps target, so include rules even if !have_tools
2749   qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2750                            dependencies: [qemuutil, xkbcommon], install: have_tools)
2751 endif
2752
2753 if have_tools
2754   qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2755              dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2756   qemu_io = executable('qemu-io', files('qemu-io.c'),
2757              dependencies: [block, qemuutil], install: true)
2758   qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2759                dependencies: [blockdev, qemuutil, gnutls], install: true)
2760
2761   subdir('storage-daemon')
2762   subdir('contrib/rdmacm-mux')
2763   subdir('contrib/elf2dmp')
2764
2765   executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2766              dependencies: qemuutil,
2767              install: true)
2768
2769   if 'CONFIG_VHOST_USER' in config_host
2770     subdir('contrib/vhost-user-blk')
2771     subdir('contrib/vhost-user-gpu')
2772     subdir('contrib/vhost-user-input')
2773     subdir('contrib/vhost-user-scsi')
2774   endif
2775
2776   if targetos == 'linux'
2777     executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2778                dependencies: [qemuutil, libcap_ng],
2779                install: true,
2780                install_dir: get_option('libexecdir'))
2781
2782     executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2783                dependencies: [authz, crypto, io, qom, qemuutil,
2784                               libcap_ng, mpathpersist],
2785                install: true)
2786   endif
2787
2788   if have_ivshmem
2789     subdir('contrib/ivshmem-client')
2790     subdir('contrib/ivshmem-server')
2791   endif
2792 endif
2793
2794 subdir('scripts')
2795 subdir('tools')
2796 subdir('pc-bios')
2797 subdir('docs')
2798 subdir('tests')
2799 if gtk.found()
2800   subdir('po')
2801 endif
2802
2803 if host_machine.system() == 'windows'
2804   nsis_cmd = [
2805     find_program('scripts/nsis.py'),
2806     '@OUTPUT@',
2807     get_option('prefix'),
2808     meson.current_source_dir(),
2809     host_machine.cpu(),
2810     '--',
2811     '-DDISPLAYVERSION=' + meson.project_version(),
2812   ]
2813   if build_docs
2814     nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2815   endif
2816   if gtk.found()
2817     nsis_cmd += '-DCONFIG_GTK=y'
2818   endif
2819
2820   nsis = custom_target('nsis',
2821                        output: 'qemu-setup-' + meson.project_version() + '.exe',
2822                        input: files('qemu.nsi'),
2823                        build_always_stale: true,
2824                        command: nsis_cmd + ['@INPUT@'])
2825   alias_target('installer', nsis)
2826 endif
2827
2828 #########################
2829 # Configuration summary #
2830 #########################
2831
2832 # Directories
2833 summary_info = {}
2834 summary_info += {'Install prefix':    get_option('prefix')}
2835 summary_info += {'BIOS directory':    qemu_datadir}
2836 summary_info += {'firmware path':     get_option('qemu_firmwarepath')}
2837 summary_info += {'binary directory':  get_option('bindir')}
2838 summary_info += {'library directory': get_option('libdir')}
2839 summary_info += {'module directory':  qemu_moddir}
2840 summary_info += {'libexec directory': get_option('libexecdir')}
2841 summary_info += {'include directory': get_option('includedir')}
2842 summary_info += {'config directory':  get_option('sysconfdir')}
2843 if targetos != 'windows'
2844   summary_info += {'local state directory': get_option('localstatedir')}
2845   summary_info += {'Manual directory':      get_option('mandir')}
2846 else
2847   summary_info += {'local state directory': 'queried at runtime'}
2848 endif
2849 summary_info += {'Doc directory':     get_option('docdir')}
2850 summary_info += {'Build directory':   meson.current_build_dir()}
2851 summary_info += {'Source path':       meson.current_source_dir()}
2852 summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
2853 summary(summary_info, bool_yn: true, section: 'Directories')
2854
2855 # Host binaries
2856 summary_info = {}
2857 summary_info += {'git':               config_host['GIT']}
2858 summary_info += {'make':              config_host['MAKE']}
2859 summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2860 summary_info += {'sphinx-build':      sphinx_build}
2861 if config_host.has_key('HAVE_GDB_BIN')
2862   summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
2863 endif
2864 summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
2865 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
2866   summary_info += {'wixl':            wixl}
2867 endif
2868 if slirp_opt != 'disabled' and 'CONFIG_SLIRP_SMBD' in config_host
2869   summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
2870 endif
2871 summary(summary_info, bool_yn: true, section: 'Host binaries')
2872
2873 # Configurable features
2874 summary_info = {}
2875 summary_info += {'Documentation':     build_docs}
2876 summary_info += {'system-mode emulation': have_system}
2877 summary_info += {'user-mode emulation': have_user}
2878 summary_info += {'block layer':       have_block}
2879 summary_info += {'Install blobs':     get_option('install_blobs')}
2880 summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
2881 if config_host.has_key('CONFIG_MODULES')
2882   summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2883 endif
2884 summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
2885 if have_system
2886   summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
2887 endif
2888 summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
2889 if config_host['TRACE_BACKENDS'].split().contains('simple')
2890   summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2891 endif
2892 summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2893 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2894 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2895 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2896 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2897 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2898 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2899 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2900 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2901 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2902 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2903 summary(summary_info, bool_yn: true, section: 'Configurable features')
2904
2905 # Compilation information
2906 summary_info = {}
2907 summary_info += {'host CPU':          cpu}
2908 summary_info += {'host endianness':   build_machine.endian()}
2909 summary_info += {'C compiler':        ' '.join(meson.get_compiler('c').cmd_array())}
2910 summary_info += {'Host C compiler':   ' '.join(meson.get_compiler('c', native: true).cmd_array())}
2911 if link_language == 'cpp'
2912   summary_info += {'C++ compiler':    ' '.join(meson.get_compiler('cpp').cmd_array())}
2913 else
2914   summary_info += {'C++ compiler':      false}
2915 endif
2916 if targetos == 'darwin'
2917   summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
2918 endif
2919 if targetos == 'windows'
2920   if 'WIN_SDK' in config_host
2921     summary_info += {'Windows SDK':   config_host['WIN_SDK']}
2922   endif
2923 endif
2924 summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
2925                                                + ['-O' + get_option('optimization')]
2926                                                + (get_option('debug') ? ['-g'] : []))}
2927 if link_language == 'cpp'
2928   summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
2929                                                + ['-O' + get_option('optimization')]
2930                                                + (get_option('debug') ? ['-g'] : []))}
2931 endif
2932 link_args = get_option(link_language + '_link_args')
2933 if link_args.length() > 0
2934   summary_info += {'LDFLAGS':         ' '.join(link_args)}
2935 endif
2936 summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
2937 summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
2938 summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
2939 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2940 summary_info += {'PIE':               get_option('b_pie')}
2941 summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
2942 summary_info += {'malloc trim support': has_malloc_trim}
2943 summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
2944 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2945 summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
2946 summary_info += {'memory allocator':  get_option('malloc')}
2947 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2948 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2949 summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
2950 summary_info += {'gcov':              get_option('b_coverage')}
2951 summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
2952 summary_info += {'CFI support':       get_option('cfi')}
2953 if get_option('cfi')
2954   summary_info += {'CFI debug support': get_option('cfi_debug')}
2955 endif
2956 summary_info += {'strip binaries':    get_option('strip')}
2957 summary_info += {'sparse':            sparse}
2958 summary_info += {'mingw32 support':   targetos == 'windows'}
2959
2960 # snarf the cross-compilation information for tests
2961 foreach target: target_dirs
2962   tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
2963   if fs.exists(tcg_mak)
2964     config_cross_tcg = keyval.load(tcg_mak)
2965     target = config_cross_tcg['TARGET_NAME']
2966     compiler = ''
2967     if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
2968       summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
2969                                           ' via ' + config_cross_tcg['DOCKER_IMAGE']}
2970     elif 'CROSS_CC_GUEST' in config_cross_tcg
2971       summary_info += {target + ' tests'
2972                                 : config_cross_tcg['CROSS_CC_GUEST'] }
2973     endif
2974    endif
2975 endforeach
2976
2977 summary(summary_info, bool_yn: true, section: 'Compilation')
2978
2979 # Targets and accelerators
2980 summary_info = {}
2981 if have_system
2982   summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
2983   summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
2984   summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
2985   summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
2986   summary_info += {'NVMM support':      config_all.has_key('CONFIG_NVMM')}
2987   summary_info += {'Xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
2988   if config_host.has_key('CONFIG_XEN_BACKEND')
2989     summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2990   endif
2991 endif
2992 summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
2993 if config_all.has_key('CONFIG_TCG')
2994   if get_option('tcg_interpreter')
2995     summary_info += {'TCG backend':   'TCI (TCG with bytecode interpreter, experimental and slow)'}
2996   else
2997     summary_info += {'TCG backend':   'native (@0@)'.format(cpu)}
2998   endif
2999   summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3000   summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3001 endif
3002 summary_info += {'target list':       ' '.join(target_dirs)}
3003 if have_system
3004   summary_info += {'default devices':   get_option('default_devices')}
3005   summary_info += {'out of process emulation': multiprocess_allowed}
3006 endif
3007 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3008
3009 # Block layer
3010 summary_info = {}
3011 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3012 summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
3013 if have_block
3014   summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
3015   summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
3016   summary_info += {'Use block whitelist in tools': config_host.has_key('CONFIG_BDRV_WHITELIST_TOOLS')}
3017   summary_info += {'VirtFS support':    have_virtfs}
3018   summary_info += {'build virtiofs daemon': have_virtiofsd}
3019   summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
3020   summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
3021   summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
3022   summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
3023   summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
3024   summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
3025   summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
3026   summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
3027   summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
3028   summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
3029   summary_info += {'FUSE exports':      fuse}
3030 endif
3031 summary(summary_info, bool_yn: true, section: 'Block layer support')
3032
3033 # Crypto
3034 summary_info = {}
3035 summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
3036 summary_info += {'GNUTLS support':    gnutls}
3037 if gnutls.found()
3038   summary_info += {'  GNUTLS crypto':   gnutls_crypto.found()}
3039 endif
3040 summary_info += {'libgcrypt':         gcrypt}
3041 summary_info += {'nettle':            nettle}
3042 if nettle.found()
3043    summary_info += {'  XTS':             xts != 'private'}
3044 endif
3045 summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
3046 summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
3047 summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
3048 summary(summary_info, bool_yn: true, section: 'Crypto')
3049
3050 # Libraries
3051 summary_info = {}
3052 if targetos == 'darwin'
3053   summary_info += {'Cocoa support':   cocoa}
3054 endif
3055 summary_info += {'SDL support':       sdl}
3056 summary_info += {'SDL image support': sdl_image}
3057 summary_info += {'GTK support':       gtk}
3058 summary_info += {'pixman':            pixman}
3059 summary_info += {'VTE support':       vte}
3060 summary_info += {'slirp support':     slirp_opt == 'internal' ? slirp_opt : slirp}
3061 summary_info += {'libtasn1':          tasn1}
3062 summary_info += {'PAM':               pam}
3063 summary_info += {'iconv support':     iconv}
3064 summary_info += {'curses support':    curses}
3065 summary_info += {'virgl support':     virgl}
3066 summary_info += {'curl support':      curl}
3067 summary_info += {'Multipath support': mpathpersist}
3068 summary_info += {'VNC support':       vnc}
3069 if vnc.found()
3070   summary_info += {'VNC SASL support':  sasl}
3071   summary_info += {'VNC JPEG support':  jpeg}
3072   summary_info += {'VNC PNG support':   png}
3073 endif
3074 summary_info += {'brlapi support':    brlapi}
3075 summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
3076 summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
3077 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
3078 summary_info += {'Linux io_uring support': linux_io_uring}
3079 summary_info += {'ATTR/XATTR support': libattr}
3080 summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
3081 summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
3082 summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
3083 summary_info += {'libcap-ng support': libcap_ng}
3084 summary_info += {'bpf support':       libbpf}
3085 # TODO: add back protocol and server version
3086 summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
3087 summary_info += {'rbd support':       rbd}
3088 summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
3089 summary_info += {'smartcard support': cacard}
3090 summary_info += {'U2F support':       u2f}
3091 summary_info += {'libusb':            libusb}
3092 summary_info += {'usb net redir':     usbredir}
3093 summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
3094 summary_info += {'GBM':               gbm}
3095 summary_info += {'libiscsi support':  libiscsi}
3096 summary_info += {'libnfs support':    libnfs}
3097 if targetos == 'windows'
3098   if config_host.has_key('CONFIG_GUEST_AGENT')
3099     summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
3100     summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
3101   endif
3102 endif
3103 summary_info += {'seccomp support':   seccomp}
3104 summary_info += {'GlusterFS support': glusterfs}
3105 summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
3106 summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
3107 summary_info += {'lzo support':       lzo}
3108 summary_info += {'snappy support':    snappy}
3109 summary_info += {'bzip2 support':     libbzip2}
3110 summary_info += {'lzfse support':     liblzfse}
3111 summary_info += {'zstd support':      zstd}
3112 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
3113 summary_info += {'libxml2':           libxml2}
3114 summary_info += {'capstone':          capstone_opt == 'internal' ? capstone_opt : capstone}
3115 summary_info += {'libpmem support':   libpmem}
3116 summary_info += {'libdaxctl support': libdaxctl}
3117 summary_info += {'libudev':           libudev}
3118 # Dummy dependency, keep .found()
3119 summary_info += {'FUSE lseek':        fuse_lseek.found()}
3120 summary(summary_info, bool_yn: true, section: 'Dependencies')
3121
3122 if not supported_cpus.contains(cpu)
3123   message()
3124   warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3125   message()
3126   message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3127   message('The QEMU project intends to remove support for this host CPU in')
3128   message('a future release if nobody volunteers to maintain it and to')
3129   message('provide a build host for our continuous integration setup.')
3130   message('configure has succeeded and you can continue to build, but')
3131   message('if you care about QEMU on this platform you should contact')
3132   message('us upstream at qemu-devel@nongnu.org.')
3133 endif
3134
3135 if not supported_oses.contains(targetos)
3136   message()
3137   warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3138   message()
3139   message('Host OS ' + targetos + 'support is not currently maintained.')
3140   message('The QEMU project intends to remove support for this host OS in')
3141   message('a future release if nobody volunteers to maintain it and to')
3142   message('provide a build host for our continuous integration setup.')
3143   message('configure has succeeded and you can continue to build, but')
3144   message('if you care about QEMU on this platform you should contact')
3145   message('us upstream at qemu-devel@nongnu.org.')
3146 endif