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