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