multi-process: Add config option for multi-process QEMU
[qemu/kevin.git] / meson.build
blobc8c07df73579237dcd9bd303ef0e8cf320455b91
1 project('qemu', ['c'], meson_version: '>=0.55.0',
2         default_options: ['warning_level=1', 'c_std=gnu99', '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_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
91   }
92 endif
94 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
95 install_edk2_blobs = false
96 if get_option('install_blobs')
97   foreach target : target_dirs
98     install_edk2_blobs = install_edk2_blobs or target in edk2_targets
99   endforeach
100 endif
102 bzip2 = find_program('bzip2', required: install_edk2_blobs)
104 ##################
105 # Compiler flags #
106 ##################
108 # Specify linker-script with add_project_link_arguments so that it is not placed
109 # within a linker --start-group/--end-group pair
110 if 'CONFIG_FUZZ' in config_host
111    add_project_link_arguments(['-Wl,-T,',
112                                (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
113                               native: false, language: ['c', 'cpp', 'objc'])
114 endif
116 add_global_arguments(config_host['QEMU_CFLAGS'].split(),
117                      native: false, language: ['c', 'objc'])
118 add_global_arguments(config_host['QEMU_CXXFLAGS'].split(),
119                      native: false, language: 'cpp')
120 add_global_link_arguments(config_host['QEMU_LDFLAGS'].split(),
121                           native: false, language: ['c', 'cpp', 'objc'])
123 if targetos == 'linux'
124   add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
125                         '-isystem', 'linux-headers',
126                         language: ['c', 'cpp'])
127 endif
129 add_project_arguments('-iquote', '.',
130                       '-iquote', meson.current_source_dir(),
131                       '-iquote', meson.current_source_dir() / 'include',
132                       '-iquote', meson.current_source_dir() / 'disas/libvixl',
133                       language: ['c', 'cpp', 'objc'])
135 link_language = meson.get_external_property('link_language', 'cpp')
136 if link_language == 'cpp'
137   add_languages('cpp', required: true, native: false)
138 endif
139 if host_machine.system() == 'darwin'
140   add_languages('objc', required: false, native: false)
141 endif
143 sparse = find_program('cgcc', required: get_option('sparse'))
144 if sparse.found()
145   run_target('sparse',
146              command: [find_program('scripts/check_sparse.py'),
147                        'compile_commands.json', sparse.full_path(), '-Wbitwise',
148                        '-Wno-transparent-union', '-Wno-old-initializer',
149                        '-Wno-non-pointer-null'])
150 endif
152 ###########################################
153 # Target-specific checks and dependencies #
154 ###########################################
156 if targetos != 'linux' and get_option('mpath').enabled()
157   error('Multipath is supported only on Linux')
158 endif
160 m = cc.find_library('m', required: false)
161 util = cc.find_library('util', required: false)
162 winmm = []
163 socket = []
164 version_res = []
165 coref = []
166 iokit = []
167 emulator_link_args = []
168 hvf = not_found
169 if targetos == 'windows'
170   socket = cc.find_library('ws2_32')
171   winmm = cc.find_library('winmm')
173   win = import('windows')
174   version_res = win.compile_resources('version.rc',
175                                       depend_files: files('pc-bios/qemu-nsis.ico'),
176                                       include_directories: include_directories('.'))
177 elif targetos == 'darwin'
178   coref = dependency('appleframeworks', modules: 'CoreFoundation')
179   iokit = dependency('appleframeworks', modules: 'IOKit')
180 elif targetos == 'sunos'
181   socket = [cc.find_library('socket'),
182             cc.find_library('nsl'),
183             cc.find_library('resolv')]
184 elif targetos == 'haiku'
185   socket = [cc.find_library('posix_error_mapper'),
186             cc.find_library('network'),
187             cc.find_library('bsd')]
188 elif targetos == 'openbsd'
189   if not get_option('tcg').disabled() and target_dirs.length() > 0
190     # Disable OpenBSD W^X if available
191     emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
192   endif
193 endif
195 accelerators = []
196 if not get_option('kvm').disabled() and targetos == 'linux'
197   accelerators += 'CONFIG_KVM'
198 endif
199 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
200   accelerators += 'CONFIG_XEN'
201   have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
202 else
203   have_xen_pci_passthrough = false
204 endif
205 if not get_option('whpx').disabled() and targetos == 'windows'
206   if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
207     error('WHPX requires 64-bit host')
208   elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
209        cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
210     accelerators += 'CONFIG_WHPX'
211   endif
212 endif
213 if not get_option('hvf').disabled()
214   hvf = dependency('appleframeworks', modules: 'Hypervisor',
215                    required: get_option('hvf'))
216   if hvf.found()
217     accelerators += 'CONFIG_HVF'
218   endif
219 endif
220 if not get_option('hax').disabled()
221   if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
222     accelerators += 'CONFIG_HAX'
223   endif
224 endif
226 tcg_arch = config_host['ARCH']
227 if not get_option('tcg').disabled()
228   if cpu not in supported_cpus
229     if get_option('tcg_interpreter')
230       warning('Unsupported CPU @0@, will use TCG with TCI (experimental and slow)'.format(cpu))
231     else
232       error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
233     endif
234   elif get_option('tcg_interpreter')
235     warning('Use of the TCG interpretor is not recommended on this host')
236     warning('architecture. There is a native TCG execution backend available')
237     warning('which provides substantially better performance and reliability.')
238     warning('It is strongly recommended to remove the --enable-tcg-interpreter')
239     warning('configuration option on this architecture to use the native')
240     warning('backend.')
241   endif
242   if get_option('tcg_interpreter')
243     tcg_arch = 'tci'
244   elif config_host['ARCH'] == 'sparc64'
245     tcg_arch = 'sparc'
246   elif config_host['ARCH'] == 's390x'
247     tcg_arch = 's390'
248   elif config_host['ARCH'] in ['x86_64', 'x32']
249     tcg_arch = 'i386'
250   elif config_host['ARCH'] == 'ppc64'
251     tcg_arch = 'ppc'
252   elif config_host['ARCH'] in ['riscv32', 'riscv64']
253     tcg_arch = 'riscv'
254   endif
255   add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
256                         '-iquote', meson.current_source_dir() / 'accel/tcg',
257                         language: ['c', 'cpp', 'objc'])
259   accelerators += 'CONFIG_TCG'
260   config_host += { 'CONFIG_TCG': 'y' }
261 endif
263 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
264   error('KVM not available on this platform')
265 endif
266 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
267   error('HVF not available on this platform')
268 endif
269 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
270   error('WHPX not available on this platform')
271 endif
272 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
273   if 'CONFIG_XEN' in accelerators
274     error('Xen PCI passthrough not available on this platform')
275   else
276     error('Xen PCI passthrough requested but Xen not enabled')
277   endif
278 endif
280 ################
281 # Dependencies #
282 ################
284 # The path to glib.h is added to all compilation commands.  This was
285 # grandfathered in from the QEMU Makefiles.
286 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
287                       native: false, language: ['c', 'cpp', 'objc'])
288 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
289                           link_args: config_host['GLIB_LIBS'].split())
290 # override glib dep with the configure results (for subprojects)
291 meson.override_dependency('glib-2.0', glib)
293 gio = not_found
294 if 'CONFIG_GIO' in config_host
295   gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
296                            link_args: config_host['GIO_LIBS'].split())
297 endif
298 lttng = not_found
299 if 'CONFIG_TRACE_UST' in config_host
300   lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
301 endif
302 urcubp = not_found
303 if 'CONFIG_TRACE_UST' in config_host
304   urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
305 endif
306 gcrypt = not_found
307 if 'CONFIG_GCRYPT' in config_host
308   gcrypt = declare_dependency(compile_args: config_host['GCRYPT_CFLAGS'].split(),
309                               link_args: config_host['GCRYPT_LIBS'].split())
310 endif
311 nettle = not_found
312 if 'CONFIG_NETTLE' in config_host
313   nettle = declare_dependency(compile_args: config_host['NETTLE_CFLAGS'].split(),
314                               link_args: config_host['NETTLE_LIBS'].split())
315 endif
316 gnutls = not_found
317 if 'CONFIG_GNUTLS' in config_host
318   gnutls = declare_dependency(compile_args: config_host['GNUTLS_CFLAGS'].split(),
319                               link_args: config_host['GNUTLS_LIBS'].split())
320 endif
321 pixman = not_found
322 if have_system or have_tools
323   pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
324                       method: 'pkg-config', kwargs: static_kwargs)
325 endif
326 pam = not_found
327 if 'CONFIG_AUTH_PAM' in config_host
328   pam = cc.find_library('pam')
329 endif
330 libaio = cc.find_library('aio', required: false)
331 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
332 linux_io_uring = not_found
333 if 'CONFIG_LINUX_IO_URING' in config_host
334   linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
335                                       link_args: config_host['LINUX_IO_URING_LIBS'].split())
336 endif
337 libxml2 = not_found
338 if 'CONFIG_LIBXML2' in config_host
339   libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
340                                link_args: config_host['LIBXML2_LIBS'].split())
341 endif
342 libnfs = not_found
343 if not get_option('libnfs').auto() or have_block
344   libnfs = dependency('libnfs', version: '>=1.9.3',
345                       required: get_option('libnfs'),
346                       method: 'pkg-config', kwargs: static_kwargs)
347 endif
349 libattr_test = '''
350   #include <stddef.h>
351   #include <sys/types.h>
352   #ifdef CONFIG_LIBATTR
353   #include <attr/xattr.h>
354   #else
355   #include <sys/xattr.h>
356   #endif
357   int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
359 libattr = not_found
360 have_old_libattr = false
361 if not get_option('attr').disabled()
362   if cc.links(libattr_test)
363     libattr = declare_dependency()
364   else
365     libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
366                               required: get_option('attr'),
367                               kwargs: static_kwargs)
368     if libattr.found() and not \
369       cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
370       libattr = not_found
371       if get_option('attr').enabled()
372         error('could not link libattr')
373       else
374         warning('could not link libattr, disabling')
375       endif
376     else
377       have_old_libattr = libattr.found()
378     endif
379   endif
380 endif
382 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
383 if cocoa.found() and get_option('sdl').enabled()
384   error('Cocoa and SDL cannot be enabled at the same time')
385 endif
386 if cocoa.found() and get_option('gtk').enabled()
387   error('Cocoa and GTK+ cannot be enabled at the same time')
388 endif
390 seccomp = not_found
391 if not get_option('seccomp').auto() or have_system or have_tools
392   seccomp = dependency('libseccomp', version: '>=2.3.0',
393                        required: get_option('seccomp'),
394                        method: 'pkg-config', kwargs: static_kwargs)
395 endif
397 libcap_ng = not_found
398 if not get_option('cap_ng').auto() or have_system or have_tools
399   libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
400                               required: get_option('cap_ng'),
401                               kwargs: static_kwargs)
402 endif
403 if libcap_ng.found() and not cc.links('''
404    #include <cap-ng.h>
405    int main(void)
406    {
407      capng_capability_to_name(CAPNG_EFFECTIVE);
408      return 0;
409    }''', dependencies: libcap_ng)
410   libcap_ng = not_found
411   if get_option('cap_ng').enabled()
412     error('could not link libcap-ng')
413   else
414     warning('could not link libcap-ng, disabling')
415   endif
416 endif
418 if get_option('xkbcommon').auto() and not have_system and not have_tools
419   xkbcommon = not_found
420 else
421   xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
422                          method: 'pkg-config', kwargs: static_kwargs)
423 endif
424 vde = not_found
425 if config_host.has_key('CONFIG_VDE')
426   vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
427 endif
428 pulse = not_found
429 if 'CONFIG_LIBPULSE' in config_host
430   pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
431                              link_args: config_host['PULSE_LIBS'].split())
432 endif
433 alsa = not_found
434 if 'CONFIG_ALSA' in config_host
435   alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
436                             link_args: config_host['ALSA_LIBS'].split())
437 endif
438 jack = not_found
439 if 'CONFIG_LIBJACK' in config_host
440   jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
441 endif
442 spice = not_found
443 spice_headers = not_found
444 if 'CONFIG_SPICE' in config_host
445   spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
446                              link_args: config_host['SPICE_LIBS'].split())
447   spice_headers = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split())
448 endif
449 rt = cc.find_library('rt', required: false)
450 libdl = not_found
451 if 'CONFIG_PLUGIN' in config_host
452   libdl = cc.find_library('dl', required: true)
453 endif
454 libiscsi = not_found
455 if not get_option('libiscsi').auto() or have_block
456   libiscsi = dependency('libiscsi', version: '>=1.9.0',
457                          required: get_option('libiscsi'),
458                          method: 'pkg-config', kwargs: static_kwargs)
459 endif
460 zstd = not_found
461 if not get_option('zstd').auto() or have_block
462   zstd = dependency('libzstd', version: '>=1.4.0',
463                     required: get_option('zstd'),
464                     method: 'pkg-config', kwargs: static_kwargs)
465 endif
466 gbm = not_found
467 if 'CONFIG_GBM' in config_host
468   gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
469                            link_args: config_host['GBM_LIBS'].split())
470 endif
471 virgl = not_found
472 if 'CONFIG_VIRGL' in config_host
473   virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
474                              link_args: config_host['VIRGL_LIBS'].split())
475 endif
476 curl = not_found
477 if not get_option('curl').auto() or have_block
478   curl = dependency('libcurl', version: '>=7.29.0',
479                     method: 'pkg-config',
480                     required: get_option('curl'),
481                     kwargs: static_kwargs)
482 endif
483 libudev = not_found
484 if targetos == 'linux' and (have_system or have_tools)
485   libudev = dependency('libudev',
486                        method: 'pkg-config',
487                        required: get_option('libudev'),
488                        kwargs: static_kwargs)
489 endif
491 mpathlibs = [libudev]
492 mpathpersist = not_found
493 mpathpersist_new_api = false
494 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
495   mpath_test_source_new = '''
496     #include <libudev.h>
497     #include <mpath_persist.h>
498     unsigned mpath_mx_alloc_len = 1024;
499     int logsink;
500     static struct config *multipath_conf;
501     extern struct udev *udev;
502     extern struct config *get_multipath_config(void);
503     extern void put_multipath_config(struct config *conf);
504     struct udev *udev;
505     struct config *get_multipath_config(void) { return multipath_conf; }
506     void put_multipath_config(struct config *conf) { }
507     int main(void) {
508         udev = udev_new();
509         multipath_conf = mpath_lib_init();
510         return 0;
511     }'''
512   mpath_test_source_old = '''
513       #include <libudev.h>
514       #include <mpath_persist.h>
515       unsigned mpath_mx_alloc_len = 1024;
516       int logsink;
517       int main(void) {
518           struct udev *udev = udev_new();
519           mpath_lib_init(udev);
520           return 0;
521       }'''
522   libmpathpersist = cc.find_library('mpathpersist',
523                                     required: get_option('mpath'),
524                                     kwargs: static_kwargs)
525   if libmpathpersist.found()
526     mpathlibs += libmpathpersist
527     if enable_static
528       mpathlibs += cc.find_library('devmapper',
529                                      required: get_option('mpath'),
530                                      kwargs: static_kwargs)
531     endif
532     mpathlibs += cc.find_library('multipath',
533                                  required: get_option('mpath'),
534                                  kwargs: static_kwargs)
535     foreach lib: mpathlibs
536       if not lib.found()
537         mpathlibs = []
538         break
539       endif
540     endforeach
541     if mpathlibs.length() == 0
542       msg = 'Dependencies missing for libmpathpersist'
543     elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
544       mpathpersist = declare_dependency(dependencies: mpathlibs)
545       mpathpersist_new_api = true
546     elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
547       mpathpersist = declare_dependency(dependencies: mpathlibs)
548     else
549       msg = 'Cannot detect libmpathpersist API'
550     endif
551     if not mpathpersist.found()
552       if get_option('mpath').enabled()
553         error(msg)
554       else
555         warning(msg + ', disabling')
556       endif
557     endif
558   endif
559 endif
561 iconv = not_found
562 curses = not_found
563 if have_system and not get_option('curses').disabled()
564   curses_test = '''
565     #include <locale.h>
566     #include <curses.h>
567     #include <wchar.h>
568     int main(void) {
569       wchar_t wch = L'w';
570       setlocale(LC_ALL, "");
571       resize_term(0, 0);
572       addwstr(L"wide chars\n");
573       addnwstr(&wch, 1);
574       add_wch(WACS_DEGREE);
575       return 0;
576     }'''
578   curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
579   foreach curses_dep : curses_dep_list
580     if not curses.found()
581       curses = dependency(curses_dep,
582                           required: false,
583                           method: 'pkg-config',
584                           kwargs: static_kwargs)
585     endif
586   endforeach
587   msg = get_option('curses').enabled() ? 'curses library not found' : ''
588   curses_compile_args = ['-DNCURSES_WIDECHAR']
589   if curses.found()
590     if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
591       curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
592     else
593       msg = 'curses package not usable'
594       curses = not_found
595     endif
596   endif
597   if not curses.found()
598     has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
599     if targetos != 'windows' and not has_curses_h
600       message('Trying with /usr/include/ncursesw')
601       curses_compile_args += ['-I/usr/include/ncursesw']
602       has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
603     endif
604     if has_curses_h
605       curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
606       foreach curses_libname : curses_libname_list
607         libcurses = cc.find_library(curses_libname,
608                                     required: false,
609                                     kwargs: static_kwargs)
610         if libcurses.found()
611           if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
612             curses = declare_dependency(compile_args: curses_compile_args,
613                                         dependencies: [libcurses])
614             break
615           else
616             msg = 'curses library not usable'
617           endif
618         endif
619       endforeach
620     endif
621   endif
622   if not get_option('iconv').disabled()
623     foreach link_args : [ ['-liconv'], [] ]
624       # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
625       # We need to use libiconv if available because mixing libiconv's headers with
626       # the system libc does not work.
627       # However, without adding glib to the dependencies -L/usr/local/lib will not be
628       # included in the command line and libiconv will not be found.
629       if cc.links('''
630         #include <iconv.h>
631         int main(void) {
632           iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
633           return conv != (iconv_t) -1;
634         }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
635         iconv = declare_dependency(link_args: link_args, dependencies: glib)
636         break
637       endif
638     endforeach
639   endif
640   if curses.found() and not iconv.found()
641     if get_option('iconv').enabled()
642       error('iconv not available')
643     endif
644     msg = 'iconv required for curses UI but not available'
645     curses = not_found
646   endif
647   if not curses.found() and msg != ''
648     if get_option('curses').enabled()
649       error(msg)
650     else
651       warning(msg + ', disabling')
652     endif
653   endif
654 endif
656 brlapi = not_found
657 if not get_option('brlapi').auto() or have_system
658   brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
659                          required: get_option('brlapi'),
660                          kwargs: static_kwargs)
661   if brlapi.found() and not cc.links('''
662      #include <brlapi.h>
663      #include <stddef.h>
664      int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
665     brlapi = not_found
666     if get_option('brlapi').enabled()
667       error('could not link brlapi')
668     else
669       warning('could not link brlapi, disabling')
670     endif
671   endif
672 endif
674 sdl = not_found
675 if not get_option('sdl').auto() or (have_system and not cocoa.found())
676   sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
677   sdl_image = not_found
678 endif
679 if sdl.found()
680   # work around 2.0.8 bug
681   sdl = declare_dependency(compile_args: '-Wno-undef',
682                            dependencies: sdl)
683   sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
684                          method: 'pkg-config', kwargs: static_kwargs)
685 else
686   if get_option('sdl_image').enabled()
687     error('sdl-image required, but SDL was @0@'.format(
688           get_option('sdl').disabled() ? 'disabled' : 'not found'))
689   endif
690   sdl_image = not_found
691 endif
693 rbd = not_found
694 if not get_option('rbd').auto() or have_block
695   librados = cc.find_library('rados', required: get_option('rbd'),
696                              kwargs: static_kwargs)
697   librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
698                            required: get_option('rbd'),
699                            kwargs: static_kwargs)
700   if librados.found() and librbd.found()
701     if cc.links('''
702       #include <stdio.h>
703       #include <rbd/librbd.h>
704       int main(void) {
705         rados_t cluster;
706         rados_create(&cluster, NULL);
707         return 0;
708       }''', dependencies: [librbd, librados])
709       rbd = declare_dependency(dependencies: [librbd, librados])
710     elif get_option('rbd').enabled()
711       error('could not link librados')
712     else
713       warning('could not link librados, disabling')
714     endif
715   endif
716 endif
718 glusterfs = not_found
719 glusterfs_ftruncate_has_stat = false
720 glusterfs_iocb_has_stat = false
721 if not get_option('glusterfs').auto() or have_block
722   glusterfs = dependency('glusterfs-api', version: '>=3',
723                          required: get_option('glusterfs'),
724                          method: 'pkg-config', kwargs: static_kwargs)
725   if glusterfs.found()
726     glusterfs_ftruncate_has_stat = cc.links('''
727       #include <glusterfs/api/glfs.h>
729       int
730       main(void)
731       {
732           /* new glfs_ftruncate() passes two additional args */
733           return glfs_ftruncate(NULL, 0, NULL, NULL);
734       }
735     ''', dependencies: glusterfs)
736     glusterfs_iocb_has_stat = cc.links('''
737       #include <glusterfs/api/glfs.h>
739       /* new glfs_io_cbk() passes two additional glfs_stat structs */
740       static void
741       glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
742       {}
744       int
745       main(void)
746       {
747           glfs_io_cbk iocb = &glusterfs_iocb;
748           iocb(NULL, 0 , NULL, NULL, NULL);
749           return 0;
750       }
751     ''', dependencies: glusterfs)
752   endif
753 endif
754 libssh = not_found
755 if 'CONFIG_LIBSSH' in config_host
756   libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
757                               link_args: config_host['LIBSSH_LIBS'].split())
758 endif
759 libbzip2 = not_found
760 if not get_option('bzip2').auto() or have_block
761   libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
762                              required: get_option('bzip2'),
763                              kwargs: static_kwargs)
764   if libbzip2.found() and not cc.links('''
765      #include <bzlib.h>
766      int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
767     libbzip2 = not_found
768     if get_option('bzip2').enabled()
769       error('could not link libbzip2')
770     else
771       warning('could not link libbzip2, disabling')
772     endif
773   endif
774 endif
776 liblzfse = not_found
777 if not get_option('lzfse').auto() or have_block
778   liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
779                              required: get_option('lzfse'),
780                              kwargs: static_kwargs)
781 endif
782 if liblzfse.found() and not cc.links('''
783    #include <lzfse.h>
784    int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
785   liblzfse = not_found
786   if get_option('lzfse').enabled()
787     error('could not link liblzfse')
788   else
789     warning('could not link liblzfse, disabling')
790   endif
791 endif
793 oss = not_found
794 if 'CONFIG_AUDIO_OSS' in config_host
795   oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
796 endif
797 dsound = not_found
798 if 'CONFIG_AUDIO_DSOUND' in config_host
799   dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
800 endif
801 coreaudio = not_found
802 if 'CONFIG_AUDIO_COREAUDIO' in config_host
803   coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
804 endif
805 opengl = not_found
806 if 'CONFIG_OPENGL' in config_host
807   opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
808                               link_args: config_host['OPENGL_LIBS'].split())
809 endif
811 gtk = not_found
812 gtkx11 = not_found
813 if not get_option('gtk').auto() or (have_system and not cocoa.found())
814   gtk = dependency('gtk+-3.0', version: '>=3.22.0',
815                    method: 'pkg-config',
816                    required: get_option('gtk'),
817                    kwargs: static_kwargs)
818   if gtk.found()
819     gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
820                         method: 'pkg-config',
821                         required: false,
822                         kwargs: static_kwargs)
823     gtk = declare_dependency(dependencies: [gtk, gtkx11])
824   endif
825 endif
827 vte = not_found
828 if 'CONFIG_VTE' in config_host
829   vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
830                            link_args: config_host['VTE_LIBS'].split())
831 endif
832 x11 = not_found
833 if gtkx11.found() or 'lm32-softmmu' in target_dirs
834   x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
835                    kwargs: static_kwargs)
836 endif
837 vnc = not_found
838 png = not_found
839 jpeg = not_found
840 sasl = not_found
841 if get_option('vnc').enabled()
842   vnc = declare_dependency() # dummy dependency
843   png = dependency('libpng', required: get_option('vnc_png'),
844                    method: 'pkg-config', kwargs: static_kwargs)
845   jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
846                     method: 'pkg-config', kwargs: static_kwargs)
847   sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
848                          required: get_option('vnc_sasl'),
849                          kwargs: static_kwargs)
850   if sasl.found()
851     sasl = declare_dependency(dependencies: sasl,
852                               compile_args: '-DSTRUCT_IOVEC_DEFINED')
853   endif
854 endif
856 snappy = not_found
857 if not get_option('snappy').auto() or have_system
858   snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
859                            required: get_option('snappy'),
860                            kwargs: static_kwargs)
861 endif
862 if snappy.found() and not cc.links('''
863    #include <snappy-c.h>
864    int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
865   snappy = not_found
866   if get_option('snappy').enabled()
867     error('could not link libsnappy')
868   else
869     warning('could not link libsnappy, disabling')
870   endif
871 endif
873 lzo = not_found
874 if not get_option('lzo').auto() or have_system
875   lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
876                         required: get_option('lzo'),
877                         kwargs: static_kwargs)
878 endif
879 if lzo.found() and not cc.links('''
880    #include <lzo/lzo1x.h>
881    int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
882   lzo = not_found
883   if get_option('lzo').enabled()
884     error('could not link liblzo2')
885   else
886     warning('could not link liblzo2, disabling')
887   endif
888 endif
890 rdma = not_found
891 if 'CONFIG_RDMA' in config_host
892   rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
893 endif
894 numa = not_found
895 if 'CONFIG_NUMA' in config_host
896   numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
897 endif
898 xen = not_found
899 if 'CONFIG_XEN_BACKEND' in config_host
900   xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
901                            link_args: config_host['XEN_LIBS'].split())
902 endif
903 cacard = not_found
904 if 'CONFIG_SMARTCARD' in config_host
905   cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
906                               link_args: config_host['SMARTCARD_LIBS'].split())
907 endif
908 u2f = not_found
909 if have_system
910   u2f = dependency('u2f-emu', required: get_option('u2f'),
911                    method: 'pkg-config',
912                    kwargs: static_kwargs)
913 endif
914 usbredir = not_found
915 if 'CONFIG_USB_REDIR' in config_host
916   usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
917                                 link_args: config_host['USB_REDIR_LIBS'].split())
918 endif
919 libusb = not_found
920 if 'CONFIG_USB_LIBUSB' in config_host
921   libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
922                               link_args: config_host['LIBUSB_LIBS'].split())
923 endif
924 libpmem = not_found
925 if 'CONFIG_LIBPMEM' in config_host
926   libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
927                                link_args: config_host['LIBPMEM_LIBS'].split())
928 endif
929 libdaxctl = not_found
930 if 'CONFIG_LIBDAXCTL' in config_host
931   libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
932 endif
933 tasn1 = not_found
934 if 'CONFIG_TASN1' in config_host
935   tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(),
936                              link_args: config_host['TASN1_LIBS'].split())
937 endif
938 keyutils = dependency('libkeyutils', required: false,
939                       method: 'pkg-config', kwargs: static_kwargs)
941 has_gettid = cc.has_function('gettid')
943 # Malloc tests
945 malloc = []
946 if get_option('malloc') == 'system'
947   has_malloc_trim = \
948     not get_option('malloc_trim').disabled() and \
949     cc.links('''#include <malloc.h>
950                 int main(void) { malloc_trim(0); return 0; }''')
951 else
952   has_malloc_trim = false
953   malloc = cc.find_library(get_option('malloc'), required: true)
954 endif
955 if not has_malloc_trim and get_option('malloc_trim').enabled()
956   if get_option('malloc') == 'system'
957     error('malloc_trim not available on this platform.')
958   else
959     error('malloc_trim not available with non-libc memory allocator')
960   endif
961 endif
963 # Check whether the glibc provides statx()
965 statx_test = '''
966   #ifndef _GNU_SOURCE
967   #define _GNU_SOURCE
968   #endif
969   #include <sys/stat.h>
970   int main(void) {
971     struct statx statxbuf;
972     statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
973     return 0;
974   }'''
976 has_statx = cc.links(statx_test)
978 have_vhost_user_blk_server = (targetos == 'linux' and
979     'CONFIG_VHOST_USER' in config_host)
981 if get_option('vhost_user_blk_server').enabled()
982     if targetos != 'linux'
983         error('vhost_user_blk_server requires linux')
984     elif 'CONFIG_VHOST_USER' not in config_host
985         error('vhost_user_blk_server requires vhost-user support')
986     endif
987 elif get_option('vhost_user_blk_server').disabled() or not have_system
988     have_vhost_user_blk_server = false
989 endif
992 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
993   error('Cannot enable fuse-lseek while fuse is disabled')
994 endif
996 fuse = dependency('fuse3', required: get_option('fuse'),
997                   version: '>=3.1', method: 'pkg-config',
998                   kwargs: static_kwargs)
1000 fuse_lseek = not_found
1001 if not get_option('fuse_lseek').disabled()
1002   if fuse.version().version_compare('>=3.8')
1003     # Dummy dependency
1004     fuse_lseek = declare_dependency()
1005   elif get_option('fuse_lseek').enabled()
1006     if fuse.found()
1007       error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1008     else
1009       error('fuse-lseek requires libfuse, which was not found')
1010     endif
1011   endif
1012 endif
1014 if get_option('cfi')
1015   cfi_flags=[]
1016   # Check for dependency on LTO
1017   if not get_option('b_lto')
1018     error('Selected Control-Flow Integrity but LTO is disabled')
1019   endif
1020   if config_host.has_key('CONFIG_MODULES')
1021     error('Selected Control-Flow Integrity is not compatible with modules')
1022   endif
1023   # Check for cfi flags. CFI requires LTO so we can't use
1024   # get_supported_arguments, but need a more complex "compiles" which allows
1025   # custom arguments
1026   if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1027                  args: ['-flto', '-fsanitize=cfi-icall'] )
1028     cfi_flags += '-fsanitize=cfi-icall'
1029   else
1030     error('-fsanitize=cfi-icall is not supported by the compiler')
1031   endif
1032   if cc.compiles('int main () { return 0; }',
1033                  name: '-fsanitize-cfi-icall-generalize-pointers',
1034                  args: ['-flto', '-fsanitize=cfi-icall',
1035                         '-fsanitize-cfi-icall-generalize-pointers'] )
1036     cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1037   else
1038     error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1039   endif
1040   if get_option('cfi_debug')
1041     if cc.compiles('int main () { return 0; }',
1042                    name: '-fno-sanitize-trap=cfi-icall',
1043                    args: ['-flto', '-fsanitize=cfi-icall',
1044                           '-fno-sanitize-trap=cfi-icall'] )
1045       cfi_flags += '-fno-sanitize-trap=cfi-icall'
1046     else
1047       error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1048     endif
1049   endif
1050   add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1051   add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1052 endif
1054 #################
1055 # config-host.h #
1056 #################
1058 have_virtfs = (targetos == 'linux' and
1059     have_system and
1060     libattr.found() and
1061     libcap_ng.found())
1063 have_virtfs_proxy_helper = have_virtfs and have_tools
1065 if get_option('virtfs').enabled()
1066   if not have_virtfs
1067     if targetos != 'linux'
1068       error('virtio-9p (virtfs) requires Linux')
1069     elif not libcap_ng.found() or not libattr.found()
1070       error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel')
1071     elif not have_system
1072       error('virtio-9p (virtfs) needs system emulation support')
1073     endif
1074   endif
1075 elif get_option('virtfs').disabled()
1076   have_virtfs = false
1077 endif
1079 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1080 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1081 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1082 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1083 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1084 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1085 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1086 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1087 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1088 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1089 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1090 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1092 config_host_data.set('CONFIG_ATTR', libattr.found())
1093 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1094 config_host_data.set('CONFIG_COCOA', cocoa.found())
1095 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1096 config_host_data.set('CONFIG_LZO', lzo.found())
1097 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1098 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1099 config_host_data.set('CONFIG_CURL', curl.found())
1100 config_host_data.set('CONFIG_CURSES', curses.found())
1101 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1102 if glusterfs.found()
1103   config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1104   config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1105   config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1106   config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1107   config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1108   config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1109 endif
1110 config_host_data.set('CONFIG_GTK', gtk.found())
1111 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1112 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1113 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1114 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1115 config_host_data.set('CONFIG_RBD', rbd.found())
1116 config_host_data.set('CONFIG_SDL', sdl.found())
1117 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1118 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1119 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1120 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1121 config_host_data.set('CONFIG_VNC', vnc.found())
1122 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1123 config_host_data.set('CONFIG_VNC_PNG', png.found())
1124 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1125 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1126 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1127 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1128 config_host_data.set('CONFIG_GETTID', has_gettid)
1129 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1130 config_host_data.set('CONFIG_STATX', has_statx)
1131 config_host_data.set('CONFIG_ZSTD', zstd.found())
1132 config_host_data.set('CONFIG_FUSE', fuse.found())
1133 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1134 config_host_data.set('CONFIG_X11', x11.found())
1135 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1136 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1137 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1138 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1139 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1141 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1142 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1143 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1144 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1145 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1146 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1148 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1150 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
1151 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1152 strings = ['HOST_DSOSUF', 'CONFIG_IASL']
1153 foreach k, v: config_host
1154   if ignored.contains(k)
1155     # do nothing
1156   elif arrays.contains(k)
1157     if v != ''
1158       v = '"' + '", "'.join(v.split()) + '", '
1159     endif
1160     config_host_data.set(k, v)
1161   elif k == 'ARCH'
1162     config_host_data.set('HOST_' + v.to_upper(), 1)
1163   elif strings.contains(k)
1164     if not k.startswith('CONFIG_')
1165       k = 'CONFIG_' + k.to_upper()
1166     endif
1167     config_host_data.set_quoted(k, v)
1168   elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
1169     config_host_data.set(k, v == 'y' ? 1 : v)
1170   endif
1171 endforeach
1173 ########################
1174 # Target configuration #
1175 ########################
1177 minikconf = find_program('scripts/minikconf.py')
1178 config_all = {}
1179 config_all_devices = {}
1180 config_all_disas = {}
1181 config_devices_mak_list = []
1182 config_devices_h = {}
1183 config_target_h = {}
1184 config_target_mak = {}
1186 disassemblers = {
1187   'alpha' : ['CONFIG_ALPHA_DIS'],
1188   'arm' : ['CONFIG_ARM_DIS'],
1189   'avr' : ['CONFIG_AVR_DIS'],
1190   'cris' : ['CONFIG_CRIS_DIS'],
1191   'hppa' : ['CONFIG_HPPA_DIS'],
1192   'i386' : ['CONFIG_I386_DIS'],
1193   'x86_64' : ['CONFIG_I386_DIS'],
1194   'x32' : ['CONFIG_I386_DIS'],
1195   'lm32' : ['CONFIG_LM32_DIS'],
1196   'm68k' : ['CONFIG_M68K_DIS'],
1197   'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1198   'mips' : ['CONFIG_MIPS_DIS'],
1199   'moxie' : ['CONFIG_MOXIE_DIS'],
1200   'nios2' : ['CONFIG_NIOS2_DIS'],
1201   'or1k' : ['CONFIG_OPENRISC_DIS'],
1202   'ppc' : ['CONFIG_PPC_DIS'],
1203   'riscv' : ['CONFIG_RISCV_DIS'],
1204   'rx' : ['CONFIG_RX_DIS'],
1205   's390' : ['CONFIG_S390_DIS'],
1206   'sh4' : ['CONFIG_SH4_DIS'],
1207   'sparc' : ['CONFIG_SPARC_DIS'],
1208   'xtensa' : ['CONFIG_XTENSA_DIS'],
1210 if link_language == 'cpp'
1211   disassemblers += {
1212     'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1213     'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1214     'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1215   }
1216 endif
1218 host_kconfig = \
1219   ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1220   ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
1221   ('CONFIG_IVSHMEM' in config_host ? ['CONFIG_IVSHMEM=y'] : []) + \
1222   ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1223   (x11.found() ? ['CONFIG_X11=y'] : []) + \
1224   ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1225   ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1226   ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1227   (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1228   ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1229   ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
1230   ('CONFIG_MULTIPROCESS_ALLOWED' in config_host ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
1232 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1234 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1235 actual_target_dirs = []
1236 fdt_required = []
1237 foreach target : target_dirs
1238   config_target = { 'TARGET_NAME': target.split('-')[0] }
1239   if target.endswith('linux-user')
1240     if targetos != 'linux'
1241       if default_targets
1242         continue
1243       endif
1244       error('Target @0@ is only available on a Linux host'.format(target))
1245     endif
1246     config_target += { 'CONFIG_LINUX_USER': 'y' }
1247   elif target.endswith('bsd-user')
1248     if 'CONFIG_BSD' not in config_host
1249       if default_targets
1250         continue
1251       endif
1252       error('Target @0@ is only available on a BSD host'.format(target))
1253     endif
1254     config_target += { 'CONFIG_BSD_USER': 'y' }
1255   elif target.endswith('softmmu')
1256     config_target += { 'CONFIG_SOFTMMU': 'y' }
1257   endif
1258   if target.endswith('-user')
1259     config_target += {
1260       'CONFIG_USER_ONLY': 'y',
1261       'CONFIG_QEMU_INTERP_PREFIX':
1262         config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1263     }
1264   endif
1266   accel_kconfig = []
1267   foreach sym: accelerators
1268     if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1269       config_target += { sym: 'y' }
1270       config_all += { sym: 'y' }
1271       if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
1272         config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
1273       elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1274         config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1275       endif
1276       accel_kconfig += [ sym + '=y' ]
1277     endif
1278   endforeach
1279   if accel_kconfig.length() == 0
1280     if default_targets
1281       continue
1282     endif
1283     error('No accelerator available for target @0@'.format(target))
1284   endif
1286   actual_target_dirs += target
1287   config_target += keyval.load('default-configs/targets' / target + '.mak')
1288   config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1290   if 'TARGET_NEED_FDT' in config_target
1291     fdt_required += target
1292   endif
1294   # Add default keys
1295   if 'TARGET_BASE_ARCH' not in config_target
1296     config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1297   endif
1298   if 'TARGET_ABI_DIR' not in config_target
1299     config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1300   endif
1302   foreach k, v: disassemblers
1303     if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1304       foreach sym: v
1305         config_target += { sym: 'y' }
1306         config_all_disas += { sym: 'y' }
1307       endforeach
1308     endif
1309   endforeach
1311   config_target_data = configuration_data()
1312   foreach k, v: config_target
1313     if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1314       # do nothing
1315     elif ignored.contains(k)
1316       # do nothing
1317     elif k == 'TARGET_BASE_ARCH'
1318       # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1319       # not used to select files from sourcesets.
1320       config_target_data.set('TARGET_' + v.to_upper(), 1)
1321     elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1322       config_target_data.set_quoted(k, v)
1323     elif v == 'y'
1324       config_target_data.set(k, 1)
1325     else
1326       config_target_data.set(k, v)
1327     endif
1328   endforeach
1329   config_target_h += {target: configure_file(output: target + '-config-target.h',
1330                                                configuration: config_target_data)}
1332   if target.endswith('-softmmu')
1333     config_devices_mak = target + '-config-devices.mak'
1334     config_devices_mak = configure_file(
1335       input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
1336       output: config_devices_mak,
1337       depfile: config_devices_mak + '.d',
1338       capture: true,
1339       command: [minikconf,
1340                 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1341                 config_devices_mak, '@DEPFILE@', '@INPUT@',
1342                 host_kconfig, accel_kconfig])
1344     config_devices_data = configuration_data()
1345     config_devices = keyval.load(config_devices_mak)
1346     foreach k, v: config_devices
1347       config_devices_data.set(k, 1)
1348     endforeach
1349     config_devices_mak_list += config_devices_mak
1350     config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1351                                                 configuration: config_devices_data)}
1352     config_target += config_devices
1353     config_all_devices += config_devices
1354   endif
1355   config_target_mak += {target: config_target}
1356 endforeach
1357 target_dirs = actual_target_dirs
1359 # This configuration is used to build files that are shared by
1360 # multiple binaries, and then extracted out of the "common"
1361 # static_library target.
1363 # We do not use all_sources()/all_dependencies(), because it would
1364 # build literally all source files, including devices only used by
1365 # targets that are not built for this compilation.  The CONFIG_ALL
1366 # pseudo symbol replaces it.
1368 config_all += config_all_devices
1369 config_all += config_host
1370 config_all += config_all_disas
1371 config_all += {
1372   'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1373   'CONFIG_SOFTMMU': have_system,
1374   'CONFIG_USER_ONLY': have_user,
1375   'CONFIG_ALL': true,
1378 ##############
1379 # Submodules #
1380 ##############
1382 capstone = not_found
1383 capstone_opt = get_option('capstone')
1384 if capstone_opt in ['enabled', 'auto', 'system']
1385   have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1386   capstone = dependency('capstone', version: '>=4.0',
1387                         kwargs: static_kwargs, method: 'pkg-config',
1388                         required: capstone_opt == 'system' or
1389                                   capstone_opt == 'enabled' and not have_internal)
1390   if capstone.found()
1391     capstone_opt = 'system'
1392   elif have_internal
1393     capstone_opt = 'internal'
1394   else
1395     capstone_opt = 'disabled'
1396   endif
1397 endif
1398 if capstone_opt == 'internal'
1399   capstone_data = configuration_data()
1400   capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1402   capstone_files = files(
1403     'capstone/cs.c',
1404     'capstone/MCInst.c',
1405     'capstone/MCInstrDesc.c',
1406     'capstone/MCRegisterInfo.c',
1407     'capstone/SStream.c',
1408     'capstone/utils.c'
1409   )
1411   if 'CONFIG_ARM_DIS' in config_all_disas
1412     capstone_data.set('CAPSTONE_HAS_ARM', '1')
1413     capstone_files += files(
1414       'capstone/arch/ARM/ARMDisassembler.c',
1415       'capstone/arch/ARM/ARMInstPrinter.c',
1416       'capstone/arch/ARM/ARMMapping.c',
1417       'capstone/arch/ARM/ARMModule.c'
1418     )
1419   endif
1421   # FIXME: This config entry currently depends on a c++ compiler.
1422   # Which is needed for building libvixl, but not for capstone.
1423   if 'CONFIG_ARM_A64_DIS' in config_all_disas
1424     capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1425     capstone_files += files(
1426       'capstone/arch/AArch64/AArch64BaseInfo.c',
1427       'capstone/arch/AArch64/AArch64Disassembler.c',
1428       'capstone/arch/AArch64/AArch64InstPrinter.c',
1429       'capstone/arch/AArch64/AArch64Mapping.c',
1430       'capstone/arch/AArch64/AArch64Module.c'
1431     )
1432   endif
1434   if 'CONFIG_PPC_DIS' in config_all_disas
1435     capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1436     capstone_files += files(
1437       'capstone/arch/PowerPC/PPCDisassembler.c',
1438       'capstone/arch/PowerPC/PPCInstPrinter.c',
1439       'capstone/arch/PowerPC/PPCMapping.c',
1440       'capstone/arch/PowerPC/PPCModule.c'
1441     )
1442   endif
1444   if 'CONFIG_S390_DIS' in config_all_disas
1445     capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1446     capstone_files += files(
1447       'capstone/arch/SystemZ/SystemZDisassembler.c',
1448       'capstone/arch/SystemZ/SystemZInstPrinter.c',
1449       'capstone/arch/SystemZ/SystemZMapping.c',
1450       'capstone/arch/SystemZ/SystemZModule.c',
1451       'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1452     )
1453   endif
1455   if 'CONFIG_I386_DIS' in config_all_disas
1456     capstone_data.set('CAPSTONE_HAS_X86', 1)
1457     capstone_files += files(
1458       'capstone/arch/X86/X86Disassembler.c',
1459       'capstone/arch/X86/X86DisassemblerDecoder.c',
1460       'capstone/arch/X86/X86ATTInstPrinter.c',
1461       'capstone/arch/X86/X86IntelInstPrinter.c',
1462       'capstone/arch/X86/X86InstPrinterCommon.c',
1463       'capstone/arch/X86/X86Mapping.c',
1464       'capstone/arch/X86/X86Module.c'
1465     )
1466   endif
1468   configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1470   capstone_cargs = [
1471     # FIXME: There does not seem to be a way to completely replace the c_args
1472     # that come from add_project_arguments() -- we can only add to them.
1473     # So: disable all warnings with a big hammer.
1474     '-Wno-error', '-w',
1476     # Include all configuration defines via a header file, which will wind up
1477     # as a dependency on the object file, and thus changes here will result
1478     # in a rebuild.
1479     '-include', 'capstone-defs.h'
1480   ]
1482   libcapstone = static_library('capstone',
1483                                build_by_default: false,
1484                                sources: capstone_files,
1485                                c_args: capstone_cargs,
1486                                include_directories: 'capstone/include')
1487   capstone = declare_dependency(link_with: libcapstone,
1488                                 include_directories: 'capstone/include/capstone')
1489 endif
1491 slirp = not_found
1492 slirp_opt = 'disabled'
1493 if have_system
1494   slirp_opt = get_option('slirp')
1495   if slirp_opt in ['enabled', 'auto', 'system']
1496     have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1497     slirp = dependency('slirp', kwargs: static_kwargs,
1498                        method: 'pkg-config',
1499                        required: slirp_opt == 'system' or
1500                                  slirp_opt == 'enabled' and not have_internal)
1501     if slirp.found()
1502       slirp_opt = 'system'
1503     elif have_internal
1504       slirp_opt = 'internal'
1505     else
1506       slirp_opt = 'disabled'
1507     endif
1508   endif
1509   if slirp_opt == 'internal'
1510     slirp_deps = []
1511     if targetos == 'windows'
1512       slirp_deps = cc.find_library('iphlpapi')
1513     endif
1514     slirp_conf = configuration_data()
1515     slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1516     slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1517     slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1518     slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1519     slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1520     slirp_files = [
1521       'slirp/src/arp_table.c',
1522       'slirp/src/bootp.c',
1523       'slirp/src/cksum.c',
1524       'slirp/src/dhcpv6.c',
1525       'slirp/src/dnssearch.c',
1526       'slirp/src/if.c',
1527       'slirp/src/ip6_icmp.c',
1528       'slirp/src/ip6_input.c',
1529       'slirp/src/ip6_output.c',
1530       'slirp/src/ip_icmp.c',
1531       'slirp/src/ip_input.c',
1532       'slirp/src/ip_output.c',
1533       'slirp/src/mbuf.c',
1534       'slirp/src/misc.c',
1535       'slirp/src/ncsi.c',
1536       'slirp/src/ndp_table.c',
1537       'slirp/src/sbuf.c',
1538       'slirp/src/slirp.c',
1539       'slirp/src/socket.c',
1540       'slirp/src/state.c',
1541       'slirp/src/stream.c',
1542       'slirp/src/tcp_input.c',
1543       'slirp/src/tcp_output.c',
1544       'slirp/src/tcp_subr.c',
1545       'slirp/src/tcp_timer.c',
1546       'slirp/src/tftp.c',
1547       'slirp/src/udp.c',
1548       'slirp/src/udp6.c',
1549       'slirp/src/util.c',
1550       'slirp/src/version.c',
1551       'slirp/src/vmstate.c',
1552     ]
1554     configure_file(
1555       input : 'slirp/src/libslirp-version.h.in',
1556       output : 'libslirp-version.h',
1557       configuration: slirp_conf)
1559     slirp_inc = include_directories('slirp', 'slirp/src')
1560     libslirp = static_library('slirp',
1561                               build_by_default: false,
1562                               sources: slirp_files,
1563                               c_args: slirp_cargs,
1564                               include_directories: slirp_inc)
1565     slirp = declare_dependency(link_with: libslirp,
1566                                dependencies: slirp_deps,
1567                                include_directories: slirp_inc)
1568   endif
1569 endif
1571 fdt = not_found
1572 fdt_opt = get_option('fdt')
1573 if have_system
1574   if fdt_opt in ['enabled', 'auto', 'system']
1575     have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1576     fdt = cc.find_library('fdt', kwargs: static_kwargs,
1577                           required: fdt_opt == 'system' or
1578                                     fdt_opt == 'enabled' and not have_internal)
1579     if fdt.found() and cc.links('''
1580        #include <libfdt.h>
1581        #include <libfdt_env.h>
1582        int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1583          dependencies: fdt)
1584       fdt_opt = 'system'
1585     elif have_internal
1586       fdt_opt = 'internal'
1587     else
1588       fdt_opt = 'disabled'
1589     endif
1590   endif
1591   if fdt_opt == 'internal'
1592     fdt_files = files(
1593       'dtc/libfdt/fdt.c',
1594       'dtc/libfdt/fdt_ro.c',
1595       'dtc/libfdt/fdt_wip.c',
1596       'dtc/libfdt/fdt_sw.c',
1597       'dtc/libfdt/fdt_rw.c',
1598       'dtc/libfdt/fdt_strerror.c',
1599       'dtc/libfdt/fdt_empty_tree.c',
1600       'dtc/libfdt/fdt_addresses.c',
1601       'dtc/libfdt/fdt_overlay.c',
1602       'dtc/libfdt/fdt_check.c',
1603     )
1605     fdt_inc = include_directories('dtc/libfdt')
1606     libfdt = static_library('fdt',
1607                             build_by_default: false,
1608                             sources: fdt_files,
1609                             include_directories: fdt_inc)
1610     fdt = declare_dependency(link_with: libfdt,
1611                              include_directories: fdt_inc)
1612   endif
1613 endif
1614 if not fdt.found() and fdt_required.length() > 0
1615   error('fdt not available but required by targets ' + ', '.join(fdt_required))
1616 endif
1618 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1619 config_host_data.set('CONFIG_FDT', fdt.found())
1620 config_host_data.set('CONFIG_SLIRP', slirp.found())
1622 #####################
1623 # Generated sources #
1624 #####################
1626 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1628 hxtool = find_program('scripts/hxtool')
1629 shaderinclude = find_program('scripts/shaderinclude.pl')
1630 qapi_gen = find_program('scripts/qapi-gen.py')
1631 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1632                      meson.source_root() / 'scripts/qapi/commands.py',
1633                      meson.source_root() / 'scripts/qapi/common.py',
1634                      meson.source_root() / 'scripts/qapi/error.py',
1635                      meson.source_root() / 'scripts/qapi/events.py',
1636                      meson.source_root() / 'scripts/qapi/expr.py',
1637                      meson.source_root() / 'scripts/qapi/gen.py',
1638                      meson.source_root() / 'scripts/qapi/introspect.py',
1639                      meson.source_root() / 'scripts/qapi/parser.py',
1640                      meson.source_root() / 'scripts/qapi/schema.py',
1641                      meson.source_root() / 'scripts/qapi/source.py',
1642                      meson.source_root() / 'scripts/qapi/types.py',
1643                      meson.source_root() / 'scripts/qapi/visit.py',
1644                      meson.source_root() / 'scripts/qapi/common.py',
1645                      meson.source_root() / 'scripts/qapi-gen.py'
1648 tracetool = [
1649   python, files('scripts/tracetool.py'),
1650    '--backend=' + config_host['TRACE_BACKENDS']
1652 tracetool_depends = files(
1653   'scripts/tracetool/backend/log.py',
1654   'scripts/tracetool/backend/__init__.py',
1655   'scripts/tracetool/backend/dtrace.py',
1656   'scripts/tracetool/backend/ftrace.py',
1657   'scripts/tracetool/backend/simple.py',
1658   'scripts/tracetool/backend/syslog.py',
1659   'scripts/tracetool/backend/ust.py',
1660   'scripts/tracetool/format/tcg_h.py',
1661   'scripts/tracetool/format/ust_events_c.py',
1662   'scripts/tracetool/format/ust_events_h.py',
1663   'scripts/tracetool/format/__init__.py',
1664   'scripts/tracetool/format/d.py',
1665   'scripts/tracetool/format/tcg_helper_c.py',
1666   'scripts/tracetool/format/simpletrace_stap.py',
1667   'scripts/tracetool/format/c.py',
1668   'scripts/tracetool/format/h.py',
1669   'scripts/tracetool/format/tcg_helper_h.py',
1670   'scripts/tracetool/format/log_stap.py',
1671   'scripts/tracetool/format/stap.py',
1672   'scripts/tracetool/format/tcg_helper_wrapper_h.py',
1673   'scripts/tracetool/__init__.py',
1674   'scripts/tracetool/transform.py',
1675   'scripts/tracetool/vcpu.py'
1678 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1679                     meson.current_source_dir(),
1680                     config_host['PKGVERSION'], meson.project_version()]
1681 qemu_version = custom_target('qemu-version.h',
1682                              output: 'qemu-version.h',
1683                              command: qemu_version_cmd,
1684                              capture: true,
1685                              build_by_default: true,
1686                              build_always_stale: true)
1687 genh += qemu_version
1689 hxdep = []
1690 hx_headers = [
1691   ['qemu-options.hx', 'qemu-options.def'],
1692   ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1694 if have_system
1695   hx_headers += [
1696     ['hmp-commands.hx', 'hmp-commands.h'],
1697     ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1698   ]
1699 endif
1700 foreach d : hx_headers
1701   hxdep += custom_target(d[1],
1702                 input: files(d[0]),
1703                 output: d[1],
1704                 capture: true,
1705                 build_by_default: true, # to be removed when added to a target
1706                 command: [hxtool, '-h', '@INPUT0@'])
1707 endforeach
1708 genh += hxdep
1710 ###################
1711 # Collect sources #
1712 ###################
1714 authz_ss = ss.source_set()
1715 blockdev_ss = ss.source_set()
1716 block_ss = ss.source_set()
1717 bsd_user_ss = ss.source_set()
1718 chardev_ss = ss.source_set()
1719 common_ss = ss.source_set()
1720 crypto_ss = ss.source_set()
1721 io_ss = ss.source_set()
1722 linux_user_ss = ss.source_set()
1723 qmp_ss = ss.source_set()
1724 qom_ss = ss.source_set()
1725 softmmu_ss = ss.source_set()
1726 specific_fuzz_ss = ss.source_set()
1727 specific_ss = ss.source_set()
1728 stub_ss = ss.source_set()
1729 trace_ss = ss.source_set()
1730 user_ss = ss.source_set()
1731 util_ss = ss.source_set()
1733 modules = {}
1734 hw_arch = {}
1735 target_arch = {}
1736 target_softmmu_arch = {}
1738 ###############
1739 # Trace files #
1740 ###############
1742 # TODO: add each directory to the subdirs from its own meson.build, once
1743 # we have those
1744 trace_events_subdirs = [
1745   'crypto',
1746   'qapi',
1747   'qom',
1748   'monitor',
1749   'util',
1751 if have_user
1752   trace_events_subdirs += [ 'linux-user' ]
1753 endif
1754 if have_block
1755   trace_events_subdirs += [
1756     'authz',
1757     'block',
1758     'io',
1759     'nbd',
1760     'scsi',
1761   ]
1762 endif
1763 if have_system
1764   trace_events_subdirs += [
1765     'accel/kvm',
1766     'audio',
1767     'backends',
1768     'backends/tpm',
1769     'chardev',
1770     'hw/9pfs',
1771     'hw/acpi',
1772     'hw/adc',
1773     'hw/alpha',
1774     'hw/arm',
1775     'hw/audio',
1776     'hw/block',
1777     'hw/block/dataplane',
1778     'hw/char',
1779     'hw/display',
1780     'hw/dma',
1781     'hw/hppa',
1782     'hw/hyperv',
1783     'hw/i2c',
1784     'hw/i386',
1785     'hw/i386/xen',
1786     'hw/ide',
1787     'hw/input',
1788     'hw/intc',
1789     'hw/isa',
1790     'hw/mem',
1791     'hw/mips',
1792     'hw/misc',
1793     'hw/misc/macio',
1794     'hw/net',
1795     'hw/net/can',
1796     'hw/nvram',
1797     'hw/pci',
1798     'hw/pci-host',
1799     'hw/ppc',
1800     'hw/rdma',
1801     'hw/rdma/vmw',
1802     'hw/rtc',
1803     'hw/s390x',
1804     'hw/scsi',
1805     'hw/sd',
1806     'hw/sparc',
1807     'hw/sparc64',
1808     'hw/ssi',
1809     'hw/timer',
1810     'hw/tpm',
1811     'hw/usb',
1812     'hw/vfio',
1813     'hw/virtio',
1814     'hw/watchdog',
1815     'hw/xen',
1816     'hw/gpio',
1817     'migration',
1818     'net',
1819     'softmmu',
1820     'ui',
1821   ]
1822 endif
1823 if have_system or have_user
1824   trace_events_subdirs += [
1825     'accel/tcg',
1826     'hw/core',
1827     'target/arm',
1828     'target/hppa',
1829     'target/i386',
1830     'target/i386/kvm',
1831     'target/mips',
1832     'target/ppc',
1833     'target/riscv',
1834     'target/s390x',
1835     'target/sparc',
1836   ]
1837 endif
1839 vhost_user = not_found
1840 if 'CONFIG_VHOST_USER' in config_host
1841   libvhost_user = subproject('libvhost-user')
1842   vhost_user = libvhost_user.get_variable('vhost_user_dep')
1843 endif
1845 subdir('qapi')
1846 subdir('qobject')
1847 subdir('stubs')
1848 subdir('trace')
1849 subdir('util')
1850 subdir('qom')
1851 subdir('authz')
1852 subdir('crypto')
1853 subdir('ui')
1856 if enable_modules
1857   libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1858   modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1859 endif
1861 stub_ss = stub_ss.apply(config_all, strict: false)
1863 util_ss.add_all(trace_ss)
1864 util_ss = util_ss.apply(config_all, strict: false)
1865 libqemuutil = static_library('qemuutil',
1866                              sources: util_ss.sources() + stub_ss.sources() + genh,
1867                              dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1868 qemuutil = declare_dependency(link_with: libqemuutil,
1869                               sources: genh + version_res)
1871 if have_system or have_user
1872   decodetree = generator(find_program('scripts/decodetree.py'),
1873                          output: 'decode-@BASENAME@.c.inc',
1874                          arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1875   subdir('libdecnumber')
1876   subdir('target')
1877 endif
1879 subdir('audio')
1880 subdir('io')
1881 subdir('chardev')
1882 subdir('fsdev')
1883 subdir('dump')
1885 if have_block
1886   block_ss.add(files(
1887     'block.c',
1888     'blockjob.c',
1889     'job.c',
1890     'qemu-io-cmds.c',
1891   ))
1892   block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1894   subdir('nbd')
1895   subdir('scsi')
1896   subdir('block')
1898   blockdev_ss.add(files(
1899     'blockdev.c',
1900     'blockdev-nbd.c',
1901     'iothread.c',
1902     'job-qmp.c',
1903   ), gnutls)
1905   # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1906   # os-win32.c does not
1907   blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1908   softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1909 endif
1911 common_ss.add(files('cpus-common.c'))
1913 subdir('softmmu')
1915 common_ss.add(capstone)
1916 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
1917 specific_ss.add(files('exec-vary.c'))
1918 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1919   'fpu/softfloat.c',
1920   'tcg/optimize.c',
1921   'tcg/tcg-common.c',
1922   'tcg/tcg-op-gvec.c',
1923   'tcg/tcg-op-vec.c',
1924   'tcg/tcg-op.c',
1925   'tcg/tcg.c',
1927 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1929 subdir('backends')
1930 subdir('disas')
1931 subdir('migration')
1932 subdir('monitor')
1933 subdir('net')
1934 subdir('replay')
1935 subdir('hw')
1936 subdir('accel')
1937 subdir('plugins')
1938 subdir('bsd-user')
1939 subdir('linux-user')
1941 bsd_user_ss.add(files('gdbstub.c'))
1942 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1944 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1945 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1947 # needed for fuzzing binaries
1948 subdir('tests/qtest/libqos')
1949 subdir('tests/qtest/fuzz')
1951 ########################
1952 # Library dependencies #
1953 ########################
1955 block_mods = []
1956 softmmu_mods = []
1957 foreach d, list : modules
1958   foreach m, module_ss : list
1959     if enable_modules and targetos != 'windows'
1960       module_ss = module_ss.apply(config_all, strict: false)
1961       sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1962                           dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1963       if d == 'block'
1964         block_mods += sl
1965       else
1966         softmmu_mods += sl
1967       endif
1968     else
1969       if d == 'block'
1970         block_ss.add_all(module_ss)
1971       else
1972         softmmu_ss.add_all(module_ss)
1973       endif
1974     endif
1975   endforeach
1976 endforeach
1978 nm = find_program('nm')
1979 undefsym = find_program('scripts/undefsym.py')
1980 block_syms = custom_target('block.syms', output: 'block.syms',
1981                              input: [libqemuutil, block_mods],
1982                              capture: true,
1983                              command: [undefsym, nm, '@INPUT@'])
1984 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1985                              input: [libqemuutil, softmmu_mods],
1986                              capture: true,
1987                              command: [undefsym, nm, '@INPUT@'])
1989 qom_ss = qom_ss.apply(config_host, strict: false)
1990 libqom = static_library('qom', qom_ss.sources() + genh,
1991                         dependencies: [qom_ss.dependencies()],
1992                         name_suffix: 'fa')
1994 qom = declare_dependency(link_whole: libqom)
1996 authz_ss = authz_ss.apply(config_host, strict: false)
1997 libauthz = static_library('authz', authz_ss.sources() + genh,
1998                           dependencies: [authz_ss.dependencies()],
1999                           name_suffix: 'fa',
2000                           build_by_default: false)
2002 authz = declare_dependency(link_whole: libauthz,
2003                            dependencies: qom)
2005 crypto_ss = crypto_ss.apply(config_host, strict: false)
2006 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2007                            dependencies: [crypto_ss.dependencies()],
2008                            name_suffix: 'fa',
2009                            build_by_default: false)
2011 crypto = declare_dependency(link_whole: libcrypto,
2012                             dependencies: [authz, qom])
2014 io_ss = io_ss.apply(config_host, strict: false)
2015 libio = static_library('io', io_ss.sources() + genh,
2016                        dependencies: [io_ss.dependencies()],
2017                        link_with: libqemuutil,
2018                        name_suffix: 'fa',
2019                        build_by_default: false)
2021 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2023 libmigration = static_library('migration', sources: migration_files + genh,
2024                               name_suffix: 'fa',
2025                               build_by_default: false)
2026 migration = declare_dependency(link_with: libmigration,
2027                                dependencies: [zlib, qom, io])
2028 softmmu_ss.add(migration)
2030 block_ss = block_ss.apply(config_host, strict: false)
2031 libblock = static_library('block', block_ss.sources() + genh,
2032                           dependencies: block_ss.dependencies(),
2033                           link_depends: block_syms,
2034                           name_suffix: 'fa',
2035                           build_by_default: false)
2037 block = declare_dependency(link_whole: [libblock],
2038                            link_args: '@block.syms',
2039                            dependencies: [crypto, io])
2041 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2042 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2043                              dependencies: blockdev_ss.dependencies(),
2044                              name_suffix: 'fa',
2045                              build_by_default: false)
2047 blockdev = declare_dependency(link_whole: [libblockdev],
2048                               dependencies: [block])
2050 qmp_ss = qmp_ss.apply(config_host, strict: false)
2051 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2052                         dependencies: qmp_ss.dependencies(),
2053                         name_suffix: 'fa',
2054                         build_by_default: false)
2056 qmp = declare_dependency(link_whole: [libqmp])
2058 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2059                             name_suffix: 'fa',
2060                             dependencies: [gnutls],
2061                             build_by_default: false)
2063 chardev = declare_dependency(link_whole: libchardev)
2065 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
2066                            name_suffix: 'fa',
2067                            build_by_default: false)
2068 hwcore = declare_dependency(link_whole: libhwcore)
2069 common_ss.add(hwcore)
2071 ###########
2072 # Targets #
2073 ###########
2075 foreach m : block_mods + softmmu_mods
2076   shared_module(m.name(),
2077                 name_prefix: '',
2078                 link_whole: m,
2079                 install: true,
2080                 install_dir: qemu_moddir)
2081 endforeach
2083 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2084 common_ss.add(qom, qemuutil)
2086 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2087 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2089 common_all = common_ss.apply(config_all, strict: false)
2090 common_all = static_library('common',
2091                             build_by_default: false,
2092                             sources: common_all.sources() + genh,
2093                             dependencies: common_all.dependencies(),
2094                             name_suffix: 'fa')
2096 feature_to_c = find_program('scripts/feature_to_c.sh')
2098 emulators = {}
2099 foreach target : target_dirs
2100   config_target = config_target_mak[target]
2101   target_name = config_target['TARGET_NAME']
2102   arch = config_target['TARGET_BASE_ARCH']
2103   arch_srcs = [config_target_h[target]]
2104   arch_deps = []
2105   c_args = ['-DNEED_CPU_H',
2106             '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2107             '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2108   link_args = emulator_link_args
2110   config_target += config_host
2111   target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2112   if targetos == 'linux'
2113     target_inc += include_directories('linux-headers', is_system: true)
2114   endif
2115   if target.endswith('-softmmu')
2116     qemu_target_name = 'qemu-system-' + target_name
2117     target_type='system'
2118     t = target_softmmu_arch[arch].apply(config_target, strict: false)
2119     arch_srcs += t.sources()
2120     arch_deps += t.dependencies()
2122     hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2123     hw = hw_arch[hw_dir].apply(config_target, strict: false)
2124     arch_srcs += hw.sources()
2125     arch_deps += hw.dependencies()
2127     arch_srcs += config_devices_h[target]
2128     link_args += ['@block.syms', '@qemu.syms']
2129   else
2130     abi = config_target['TARGET_ABI_DIR']
2131     target_type='user'
2132     qemu_target_name = 'qemu-' + target_name
2133     if 'CONFIG_LINUX_USER' in config_target
2134       base_dir = 'linux-user'
2135       target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2136     else
2137       base_dir = 'bsd-user'
2138       target_inc += include_directories('bsd-user/freebsd')
2139     endif
2140     target_inc += include_directories(
2141       base_dir,
2142       base_dir / abi,
2143     )
2144     if 'CONFIG_LINUX_USER' in config_target
2145       dir = base_dir / abi
2146       arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2147       if config_target.has_key('TARGET_SYSTBL_ABI')
2148         arch_srcs += \
2149           syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2150                                              extra_args : config_target['TARGET_SYSTBL_ABI'])
2151       endif
2152     endif
2153   endif
2155   if 'TARGET_XML_FILES' in config_target
2156     gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2157                                 output: target + '-gdbstub-xml.c',
2158                                 input: files(config_target['TARGET_XML_FILES'].split()),
2159                                 command: [feature_to_c, '@INPUT@'],
2160                                 capture: true)
2161     arch_srcs += gdbstub_xml
2162   endif
2164   t = target_arch[arch].apply(config_target, strict: false)
2165   arch_srcs += t.sources()
2166   arch_deps += t.dependencies()
2168   target_common = common_ss.apply(config_target, strict: false)
2169   objects = common_all.extract_objects(target_common.sources())
2170   deps = target_common.dependencies()
2172   target_specific = specific_ss.apply(config_target, strict: false)
2173   arch_srcs += target_specific.sources()
2174   arch_deps += target_specific.dependencies()
2176   lib = static_library('qemu-' + target,
2177                  sources: arch_srcs + genh,
2178                  dependencies: arch_deps,
2179                  objects: objects,
2180                  include_directories: target_inc,
2181                  c_args: c_args,
2182                  build_by_default: false,
2183                  name_suffix: 'fa')
2185   if target.endswith('-softmmu')
2186     execs = [{
2187       'name': 'qemu-system-' + target_name,
2188       'gui': false,
2189       'sources': files('softmmu/main.c'),
2190       'dependencies': []
2191     }]
2192     if targetos == 'windows' and (sdl.found() or gtk.found())
2193       execs += [{
2194         'name': 'qemu-system-' + target_name + 'w',
2195         'gui': true,
2196         'sources': files('softmmu/main.c'),
2197         'dependencies': []
2198       }]
2199     endif
2200     if config_host.has_key('CONFIG_FUZZ')
2201       specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2202       execs += [{
2203         'name': 'qemu-fuzz-' + target_name,
2204         'gui': false,
2205         'sources': specific_fuzz.sources(),
2206         'dependencies': specific_fuzz.dependencies(),
2207       }]
2208     endif
2209   else
2210     execs = [{
2211       'name': 'qemu-' + target_name,
2212       'gui': false,
2213       'sources': [],
2214       'dependencies': []
2215     }]
2216   endif
2217   foreach exe: execs
2218     exe_name = exe['name']
2219     exe_sign = 'CONFIG_HVF' in config_target
2220     if exe_sign
2221       exe_name += '-unsigned'
2222     endif
2224     emulator = executable(exe_name, exe['sources'],
2225                install: not exe_sign,
2226                c_args: c_args,
2227                dependencies: arch_deps + deps + exe['dependencies'],
2228                objects: lib.extract_all_objects(recursive: true),
2229                link_language: link_language,
2230                link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2231                link_args: link_args,
2232                gui_app: exe['gui'])
2234     if exe_sign
2235       emulators += {exe['name'] : custom_target(exe['name'],
2236                    install: true,
2237                    install_dir: get_option('bindir'),
2238                    depends: emulator,
2239                    output: exe['name'],
2240                    command: [
2241                      meson.current_source_dir() / 'scripts/entitlement.sh',
2242                      meson.current_build_dir() / exe_name,
2243                      meson.current_build_dir() / exe['name'],
2244                      meson.current_source_dir() / 'accel/hvf/entitlements.plist'
2245                    ])
2246       }
2247     else
2248       emulators += {exe['name']: emulator}
2249     endif
2251     if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2252       foreach stp: [
2253         {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2254         {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2255         {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2256         {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2257       ]
2258         custom_target(exe['name'] + stp['ext'],
2259                       input: trace_events_all,
2260                       output: exe['name'] + stp['ext'],
2261                       install: stp['install'],
2262                       install_dir: get_option('datadir') / 'systemtap/tapset',
2263                       command: [
2264                         tracetool, '--group=all', '--format=' + stp['fmt'],
2265                         '--binary=' + stp['bin'],
2266                         '--target-name=' + target_name,
2267                         '--target-type=' + target_type,
2268                         '--probe-prefix=qemu.' + target_type + '.' + target_name,
2269                         '@INPUT@', '@OUTPUT@'
2270                       ],
2271                       depend_files: tracetool_depends)
2272       endforeach
2273     endif
2274   endforeach
2275 endforeach
2277 # Other build targets
2279 if 'CONFIG_PLUGIN' in config_host
2280   install_headers('include/qemu/qemu-plugin.h')
2281 endif
2283 if 'CONFIG_GUEST_AGENT' in config_host
2284   subdir('qga')
2285 elif get_option('guest_agent_msi').enabled()
2286   error('Guest agent MSI requested, but the guest agent is not being built')
2287 endif
2289 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2290 # when we don't build tools or system
2291 if xkbcommon.found()
2292   # used for the update-keymaps target, so include rules even if !have_tools
2293   qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2294                            dependencies: [qemuutil, xkbcommon], install: have_tools)
2295 endif
2297 if have_tools
2298   qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2299              dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2300   qemu_io = executable('qemu-io', files('qemu-io.c'),
2301              dependencies: [block, qemuutil], install: true)
2302   qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2303                dependencies: [blockdev, qemuutil, gnutls], install: true)
2305   subdir('storage-daemon')
2306   subdir('contrib/rdmacm-mux')
2307   subdir('contrib/elf2dmp')
2309   executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2310              dependencies: qemuutil,
2311              install: true)
2313   if 'CONFIG_VHOST_USER' in config_host
2314     subdir('contrib/vhost-user-blk')
2315     subdir('contrib/vhost-user-gpu')
2316     subdir('contrib/vhost-user-input')
2317     subdir('contrib/vhost-user-scsi')
2318   endif
2320   if targetos == 'linux'
2321     executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2322                dependencies: [qemuutil, libcap_ng],
2323                install: true,
2324                install_dir: get_option('libexecdir'))
2326     executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2327                dependencies: [authz, crypto, io, qom, qemuutil,
2328                               libcap_ng, mpathpersist],
2329                install: true)
2330   endif
2332   if 'CONFIG_IVSHMEM' in config_host
2333     subdir('contrib/ivshmem-client')
2334     subdir('contrib/ivshmem-server')
2335   endif
2336 endif
2338 subdir('scripts')
2339 subdir('tools')
2340 subdir('pc-bios')
2341 subdir('docs')
2342 subdir('tests')
2343 if gtk.found()
2344   subdir('po')
2345 endif
2347 if host_machine.system() == 'windows'
2348   nsis_cmd = [
2349     find_program('scripts/nsis.py'),
2350     '@OUTPUT@',
2351     get_option('prefix'),
2352     meson.current_source_dir(),
2353     host_machine.cpu(),
2354     '--',
2355     '-DDISPLAYVERSION=' + meson.project_version(),
2356   ]
2357   if build_docs
2358     nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2359   endif
2360   if gtk.found()
2361     nsis_cmd += '-DCONFIG_GTK=y'
2362   endif
2364   nsis = custom_target('nsis',
2365                        output: 'qemu-setup-' + meson.project_version() + '.exe',
2366                        input: files('qemu.nsi'),
2367                        build_always_stale: true,
2368                        command: nsis_cmd + ['@INPUT@'])
2369   alias_target('installer', nsis)
2370 endif
2372 #########################
2373 # Configuration summary #
2374 #########################
2376 # Directories
2377 summary_info = {}
2378 summary_info += {'Install prefix':    get_option('prefix')}
2379 summary_info += {'BIOS directory':    qemu_datadir}
2380 summary_info += {'firmware path':     get_option('qemu_firmwarepath')}
2381 summary_info += {'binary directory':  get_option('bindir')}
2382 summary_info += {'library directory': get_option('libdir')}
2383 summary_info += {'module directory':  qemu_moddir}
2384 summary_info += {'libexec directory': get_option('libexecdir')}
2385 summary_info += {'include directory': get_option('includedir')}
2386 summary_info += {'config directory':  get_option('sysconfdir')}
2387 if targetos != 'windows'
2388   summary_info += {'local state directory': get_option('localstatedir')}
2389   summary_info += {'Manual directory':      get_option('mandir')}
2390 else
2391   summary_info += {'local state directory': 'queried at runtime'}
2392 endif
2393 summary_info += {'Doc directory':     get_option('docdir')}
2394 summary_info += {'Build directory':   meson.current_build_dir()}
2395 summary_info += {'Source path':       meson.current_source_dir()}
2396 summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
2397 summary(summary_info, bool_yn: true, section: 'Directories')
2399 # Host binaries
2400 summary_info = {}
2401 summary_info += {'git':               config_host['GIT']}
2402 summary_info += {'make':              config_host['MAKE']}
2403 summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2404 summary_info += {'sphinx-build':      sphinx_build.found()}
2405 if config_host.has_key('HAVE_GDB_BIN')
2406   summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
2407 endif
2408 summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
2409 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
2410   summary_info += {'wixl':            wixl.found() ? wixl.full_path() : false}
2411 endif
2412 if slirp_opt != 'disabled'
2413   summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
2414 endif
2415 summary(summary_info, bool_yn: true, section: 'Host binaries')
2417 # Configurable features
2418 summary_info = {}
2419 summary_info += {'Documentation':     build_docs}
2420 summary_info += {'system-mode emulation': have_system}
2421 summary_info += {'user-mode emulation': have_user}
2422 summary_info += {'block layer':       have_block}
2423 summary_info += {'Install blobs':     get_option('install_blobs')}
2424 summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
2425 if config_host.has_key('CONFIG_MODULES')
2426   summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2427 endif
2428 summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
2429 summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
2430 if have_system
2431   summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
2432 endif
2433 summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
2434 if config_host['TRACE_BACKENDS'].split().contains('simple')
2435   summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2436 endif
2437 summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2438 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2439 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2440 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2441 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2442 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2443 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2444 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2445 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2446 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2447 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2448 summary(summary_info, bool_yn: true, section: 'Configurable features')
2450 # Compilation information
2451 summary_info = {}
2452 summary_info += {'host CPU':          cpu}
2453 summary_info += {'host endianness':   build_machine.endian()}
2454 summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
2455 summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
2456 if link_language == 'cpp'
2457   summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
2458 else
2459   summary_info += {'C++ compiler':      false}
2460 endif
2461 if targetos == 'darwin'
2462   summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
2463 endif
2464 if targetos == 'windows'
2465   if 'WIN_SDK' in config_host
2466     summary_info += {'Windows SDK':   config_host['WIN_SDK']}
2467   endif
2468 endif
2469 summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
2470 summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
2471                                                + ['-O' + get_option('optimization')]
2472                                                + (get_option('debug') ? ['-g'] : []))}
2473 if link_language == 'cpp'
2474   summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
2475                                                + ['-O' + get_option('optimization')]
2476                                                + (get_option('debug') ? ['-g'] : []))}
2477 endif
2478 link_args = get_option(link_language + '_link_args')
2479 if link_args.length() > 0
2480   summary_info += {'LDFLAGS':         ' '.join(link_args)}
2481 endif
2482 summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
2483 summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
2484 summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
2485 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2486 summary_info += {'PIE':               get_option('b_pie')}
2487 summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
2488 summary_info += {'malloc trim support': has_malloc_trim}
2489 summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
2490 summary_info += {'preadv support':    config_host_data.get('CONFIG_PREADV')}
2491 summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
2492 summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
2493 summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
2494 summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2495 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2496 summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
2497 summary_info += {'memory allocator':  get_option('malloc')}
2498 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2499 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2500 summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
2501 summary_info += {'gcov':              get_option('b_coverage')}
2502 summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
2503 summary_info += {'CFI support':       get_option('cfi')}
2504 if get_option('cfi')
2505   summary_info += {'CFI debug support': get_option('cfi_debug')}
2506 endif
2507 summary_info += {'strip binaries':    get_option('strip')}
2508 summary_info += {'sparse':            sparse.found() ? sparse.full_path() : false}
2509 summary_info += {'mingw32 support':   targetos == 'windows'}
2510 summary(summary_info, bool_yn: true, section: 'Compilation')
2512 # Targets and accelerators
2513 summary_info = {}
2514 if have_system
2515   summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
2516   summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
2517   summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
2518   summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
2519   summary_info += {'Xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
2520   if config_host.has_key('CONFIG_XEN_BACKEND')
2521     summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2522   endif
2523 endif
2524 summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
2525 if config_all.has_key('CONFIG_TCG')
2526   if get_option('tcg_interpreter')
2527     summary_info += {'TCG backend':   'TCI (TCG with bytecode interpreter, experimental and slow)'}
2528   else
2529     summary_info += {'TCG backend':   'native (@0@)'.format(cpu)}
2530   endif
2531   summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2532 endif
2533 summary_info += {'target list':       ' '.join(target_dirs)}
2534 if have_system
2535   summary_info += {'default devices':   get_option('default_devices')}
2536 endif
2537 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
2539 # Block layer
2540 summary_info = {}
2541 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2542 summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
2543 if have_block
2544   summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2545   summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2546   summary_info += {'VirtFS support':    have_virtfs}
2547   summary_info += {'build virtiofs daemon': have_virtiofsd}
2548   summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2549   summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2550   summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
2551   summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
2552   summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
2553   summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
2554   summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
2555   summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
2556   summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
2557   summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2558   summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
2559   summary_info += {'FUSE exports':      fuse.found()}
2560 endif
2561 summary(summary_info, bool_yn: true, section: 'Block layer support')
2563 # Crypto
2564 summary_info = {}
2565 summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
2566 summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
2567 # TODO: add back version
2568 summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
2569 if config_host.has_key('CONFIG_GCRYPT')
2570    summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
2571    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2572 endif
2573 # TODO: add back version
2574 summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
2575 if config_host.has_key('CONFIG_NETTLE')
2576    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2577 endif
2578 summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
2579 summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
2580 summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
2581 summary(summary_info, bool_yn: true, section: 'Crypto')
2583 # Libraries
2584 summary_info = {}
2585 if targetos == 'darwin'
2586   summary_info += {'Cocoa support':   cocoa.found()}
2587 endif
2588 # TODO: add back version
2589 summary_info += {'SDL support':       sdl.found()}
2590 summary_info += {'SDL image support': sdl_image.found()}
2591 # TODO: add back version
2592 summary_info += {'GTK support':       gtk.found()}
2593 summary_info += {'pixman':            pixman.found()}
2594 # TODO: add back version
2595 summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
2596 # TODO: add back version
2597 summary_info += {'slirp support':     slirp_opt == 'disabled' ? false : slirp_opt}
2598 summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
2599 summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
2600 summary_info += {'iconv support':     iconv.found()}
2601 summary_info += {'curses support':    curses.found()}
2602 # TODO: add back version
2603 summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
2604 summary_info += {'curl support':      curl.found()}
2605 summary_info += {'Multipath support': mpathpersist.found()}
2606 summary_info += {'VNC support':       vnc.found()}
2607 if vnc.found()
2608   summary_info += {'VNC SASL support':  sasl.found()}
2609   summary_info += {'VNC JPEG support':  jpeg.found()}
2610   summary_info += {'VNC PNG support':   png.found()}
2611 endif
2612 summary_info += {'brlapi support':    brlapi.found()}
2613 summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
2614 summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
2615 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2616 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2617 summary_info += {'ATTR/XATTR support': libattr.found()}
2618 summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
2619 summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
2620 summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
2621 summary_info += {'libcap-ng support': libcap_ng.found()}
2622 # TODO: add back protocol and server version
2623 summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
2624 summary_info += {'rbd support':       rbd.found()}
2625 summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
2626 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2627 summary_info += {'U2F support':       u2f.found()}
2628 summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
2629 summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
2630 summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
2631 summary_info += {'OpenGL dmabufs':    config_host.has_key('CONFIG_OPENGL_DMABUF')}
2632 summary_info += {'libiscsi support':  libiscsi.found()}
2633 summary_info += {'libnfs support':    libnfs.found()}
2634 if targetos == 'windows'
2635   if config_host.has_key('CONFIG_GUEST_AGENT')
2636     summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
2637     summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2638   endif
2639 endif
2640 summary_info += {'seccomp support':   seccomp.found()}
2641 summary_info += {'GlusterFS support': glusterfs.found()}
2642 summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
2643 summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
2644 summary_info += {'lzo support':       lzo.found()}
2645 summary_info += {'snappy support':    snappy.found()}
2646 summary_info += {'bzip2 support':     libbzip2.found()}
2647 summary_info += {'lzfse support':     liblzfse.found()}
2648 summary_info += {'zstd support':      zstd.found()}
2649 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2650 summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
2651 summary_info += {'capstone':          capstone_opt == 'disabled' ? false : capstone_opt}
2652 summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
2653 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2654 summary_info += {'libudev':           libudev.found()}
2655 summary_info += {'FUSE lseek':        fuse_lseek.found()}
2656 summary_info += {'Multiprocess QEMU': config_host.has_key('CONFIG_MULTIPROCESS_ALLOWED')}
2657 summary(summary_info, bool_yn: true, section: 'Dependencies')
2659 if not supported_cpus.contains(cpu)
2660   message()
2661   warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2662   message()
2663   message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2664   message('The QEMU project intends to remove support for this host CPU in')
2665   message('a future release if nobody volunteers to maintain it and to')
2666   message('provide a build host for our continuous integration setup.')
2667   message('configure has succeeded and you can continue to build, but')
2668   message('if you care about QEMU on this platform you should contact')
2669   message('us upstream at qemu-devel@nongnu.org.')
2670 endif
2672 if not supported_oses.contains(targetos)
2673   message()
2674   warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2675   message()
2676   message('Host OS ' + targetos + 'support is not currently maintained.')
2677   message('The QEMU project intends to remove support for this host OS in')
2678   message('a future release if nobody volunteers to maintain it and to')
2679   message('provide a build host for our continuous integration setup.')
2680   message('configure has succeeded and you can continue to build, but')
2681   message('if you care about QEMU on this platform you should contact')
2682   message('us upstream at qemu-devel@nongnu.org.')
2683 endif