stream: rework backing-file changing
[qemu.git] / meson.build
blob35a9eddf5cf883a166b477d1809afa0fa703149c
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                                sources: capstone_files,
1464                                c_args: capstone_cargs,
1465                                include_directories: 'capstone/include')
1466   capstone = declare_dependency(link_with: libcapstone,
1467                                 include_directories: 'capstone/include/capstone')
1468 endif
1470 slirp = not_found
1471 slirp_opt = 'disabled'
1472 if have_system
1473   slirp_opt = get_option('slirp')
1474   if slirp_opt in ['enabled', 'auto', 'system']
1475     have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1476     slirp = dependency('slirp', static: enable_static,
1477                        method: 'pkg-config',
1478                        required: slirp_opt == 'system' or
1479                                  slirp_opt == 'enabled' and not have_internal)
1480     if slirp.found()
1481       slirp_opt = 'system'
1482     elif have_internal
1483       slirp_opt = 'internal'
1484     else
1485       slirp_opt = 'disabled'
1486     endif
1487   endif
1488   if slirp_opt == 'internal'
1489     slirp_deps = []
1490     if targetos == 'windows'
1491       slirp_deps = cc.find_library('iphlpapi')
1492     endif
1493     slirp_conf = configuration_data()
1494     slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1495     slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1496     slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1497     slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1498     slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1499     slirp_files = [
1500       'slirp/src/arp_table.c',
1501       'slirp/src/bootp.c',
1502       'slirp/src/cksum.c',
1503       'slirp/src/dhcpv6.c',
1504       'slirp/src/dnssearch.c',
1505       'slirp/src/if.c',
1506       'slirp/src/ip6_icmp.c',
1507       'slirp/src/ip6_input.c',
1508       'slirp/src/ip6_output.c',
1509       'slirp/src/ip_icmp.c',
1510       'slirp/src/ip_input.c',
1511       'slirp/src/ip_output.c',
1512       'slirp/src/mbuf.c',
1513       'slirp/src/misc.c',
1514       'slirp/src/ncsi.c',
1515       'slirp/src/ndp_table.c',
1516       'slirp/src/sbuf.c',
1517       'slirp/src/slirp.c',
1518       'slirp/src/socket.c',
1519       'slirp/src/state.c',
1520       'slirp/src/stream.c',
1521       'slirp/src/tcp_input.c',
1522       'slirp/src/tcp_output.c',
1523       'slirp/src/tcp_subr.c',
1524       'slirp/src/tcp_timer.c',
1525       'slirp/src/tftp.c',
1526       'slirp/src/udp.c',
1527       'slirp/src/udp6.c',
1528       'slirp/src/util.c',
1529       'slirp/src/version.c',
1530       'slirp/src/vmstate.c',
1531     ]
1533     configure_file(
1534       input : 'slirp/src/libslirp-version.h.in',
1535       output : 'libslirp-version.h',
1536       configuration: slirp_conf)
1538     slirp_inc = include_directories('slirp', 'slirp/src')
1539     libslirp = static_library('slirp',
1540                               sources: slirp_files,
1541                               c_args: slirp_cargs,
1542                               include_directories: slirp_inc)
1543     slirp = declare_dependency(link_with: libslirp,
1544                                dependencies: slirp_deps,
1545                                include_directories: slirp_inc)
1546   endif
1547 endif
1549 fdt = not_found
1550 fdt_opt = get_option('fdt')
1551 if have_system
1552   if fdt_opt in ['enabled', 'auto', 'system']
1553     have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1554     fdt = cc.find_library('fdt', static: enable_static,
1555                           required: fdt_opt == 'system' or
1556                                     fdt_opt == 'enabled' and not have_internal)
1557     if fdt.found() and cc.links('''
1558        #include <libfdt.h>
1559        #include <libfdt_env.h>
1560        int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1561          dependencies: fdt)
1562       fdt_opt = 'system'
1563     elif have_internal
1564       fdt_opt = 'internal'
1565     else
1566       fdt_opt = 'disabled'
1567     endif
1568   endif
1569   if fdt_opt == 'internal'
1570     fdt_files = files(
1571       'dtc/libfdt/fdt.c',
1572       'dtc/libfdt/fdt_ro.c',
1573       'dtc/libfdt/fdt_wip.c',
1574       'dtc/libfdt/fdt_sw.c',
1575       'dtc/libfdt/fdt_rw.c',
1576       'dtc/libfdt/fdt_strerror.c',
1577       'dtc/libfdt/fdt_empty_tree.c',
1578       'dtc/libfdt/fdt_addresses.c',
1579       'dtc/libfdt/fdt_overlay.c',
1580       'dtc/libfdt/fdt_check.c',
1581     )
1583     fdt_inc = include_directories('dtc/libfdt')
1584     libfdt = static_library('fdt',
1585                             sources: fdt_files,
1586                             include_directories: fdt_inc)
1587     fdt = declare_dependency(link_with: libfdt,
1588                              include_directories: fdt_inc)
1589   endif
1590 endif
1591 if not fdt.found() and fdt_required.length() > 0
1592   error('fdt not available but required by targets ' + ', '.join(fdt_required))
1593 endif
1595 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1596 config_host_data.set('CONFIG_FDT', fdt.found())
1597 config_host_data.set('CONFIG_SLIRP', slirp.found())
1599 #####################
1600 # Generated sources #
1601 #####################
1603 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1605 hxtool = find_program('scripts/hxtool')
1606 shaderinclude = find_program('scripts/shaderinclude.pl')
1607 qapi_gen = find_program('scripts/qapi-gen.py')
1608 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1609                      meson.source_root() / 'scripts/qapi/commands.py',
1610                      meson.source_root() / 'scripts/qapi/common.py',
1611                      meson.source_root() / 'scripts/qapi/error.py',
1612                      meson.source_root() / 'scripts/qapi/events.py',
1613                      meson.source_root() / 'scripts/qapi/expr.py',
1614                      meson.source_root() / 'scripts/qapi/gen.py',
1615                      meson.source_root() / 'scripts/qapi/introspect.py',
1616                      meson.source_root() / 'scripts/qapi/parser.py',
1617                      meson.source_root() / 'scripts/qapi/schema.py',
1618                      meson.source_root() / 'scripts/qapi/source.py',
1619                      meson.source_root() / 'scripts/qapi/types.py',
1620                      meson.source_root() / 'scripts/qapi/visit.py',
1621                      meson.source_root() / 'scripts/qapi/common.py',
1622                      meson.source_root() / 'scripts/qapi-gen.py'
1625 tracetool = [
1626   python, files('scripts/tracetool.py'),
1627    '--backend=' + config_host['TRACE_BACKENDS']
1630 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1631                     meson.current_source_dir(),
1632                     config_host['PKGVERSION'], meson.project_version()]
1633 qemu_version = custom_target('qemu-version.h',
1634                              output: 'qemu-version.h',
1635                              command: qemu_version_cmd,
1636                              capture: true,
1637                              build_by_default: true,
1638                              build_always_stale: true)
1639 genh += qemu_version
1641 hxdep = []
1642 hx_headers = [
1643   ['qemu-options.hx', 'qemu-options.def'],
1644   ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1646 if have_system
1647   hx_headers += [
1648     ['hmp-commands.hx', 'hmp-commands.h'],
1649     ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1650   ]
1651 endif
1652 foreach d : hx_headers
1653   hxdep += custom_target(d[1],
1654                 input: files(d[0]),
1655                 output: d[1],
1656                 capture: true,
1657                 build_by_default: true, # to be removed when added to a target
1658                 command: [hxtool, '-h', '@INPUT0@'])
1659 endforeach
1660 genh += hxdep
1662 ###################
1663 # Collect sources #
1664 ###################
1666 authz_ss = ss.source_set()
1667 blockdev_ss = ss.source_set()
1668 block_ss = ss.source_set()
1669 bsd_user_ss = ss.source_set()
1670 chardev_ss = ss.source_set()
1671 common_ss = ss.source_set()
1672 crypto_ss = ss.source_set()
1673 io_ss = ss.source_set()
1674 linux_user_ss = ss.source_set()
1675 qmp_ss = ss.source_set()
1676 qom_ss = ss.source_set()
1677 softmmu_ss = ss.source_set()
1678 specific_fuzz_ss = ss.source_set()
1679 specific_ss = ss.source_set()
1680 stub_ss = ss.source_set()
1681 trace_ss = ss.source_set()
1682 user_ss = ss.source_set()
1683 util_ss = ss.source_set()
1685 modules = {}
1686 hw_arch = {}
1687 target_arch = {}
1688 target_softmmu_arch = {}
1690 ###############
1691 # Trace files #
1692 ###############
1694 # TODO: add each directory to the subdirs from its own meson.build, once
1695 # we have those
1696 trace_events_subdirs = [
1697   'accel/kvm',
1698   'accel/tcg',
1699   'crypto',
1700   'monitor',
1702 if have_user
1703   trace_events_subdirs += [ 'linux-user' ]
1704 endif
1705 if have_block
1706   trace_events_subdirs += [
1707     'authz',
1708     'block',
1709     'io',
1710     'nbd',
1711     'scsi',
1712   ]
1713 endif
1714 if have_system
1715   trace_events_subdirs += [
1716     'audio',
1717     'backends',
1718     'backends/tpm',
1719     'chardev',
1720     'hw/9pfs',
1721     'hw/acpi',
1722     'hw/adc',
1723     'hw/alpha',
1724     'hw/arm',
1725     'hw/audio',
1726     'hw/block',
1727     'hw/block/dataplane',
1728     'hw/char',
1729     'hw/display',
1730     'hw/dma',
1731     'hw/hppa',
1732     'hw/hyperv',
1733     'hw/i2c',
1734     'hw/i386',
1735     'hw/i386/xen',
1736     'hw/ide',
1737     'hw/input',
1738     'hw/intc',
1739     'hw/isa',
1740     'hw/mem',
1741     'hw/mips',
1742     'hw/misc',
1743     'hw/misc/macio',
1744     'hw/net',
1745     'hw/net/can',
1746     'hw/nvram',
1747     'hw/pci',
1748     'hw/pci-host',
1749     'hw/ppc',
1750     'hw/rdma',
1751     'hw/rdma/vmw',
1752     'hw/rtc',
1753     'hw/s390x',
1754     'hw/scsi',
1755     'hw/sd',
1756     'hw/sparc',
1757     'hw/sparc64',
1758     'hw/ssi',
1759     'hw/timer',
1760     'hw/tpm',
1761     'hw/usb',
1762     'hw/vfio',
1763     'hw/virtio',
1764     'hw/watchdog',
1765     'hw/xen',
1766     'hw/gpio',
1767     'migration',
1768     'net',
1769     'softmmu',
1770     'ui',
1771   ]
1772 endif
1773 trace_events_subdirs += [
1774   'hw/core',
1775   'qapi',
1776   'qom',
1777   'target/arm',
1778   'target/hppa',
1779   'target/i386',
1780   'target/i386/kvm',
1781   'target/mips',
1782   'target/ppc',
1783   'target/riscv',
1784   'target/s390x',
1785   'target/sparc',
1786   'util',
1789 vhost_user = not_found
1790 if 'CONFIG_VHOST_USER' in config_host
1791   libvhost_user = subproject('libvhost-user')
1792   vhost_user = libvhost_user.get_variable('vhost_user_dep')
1793 endif
1795 subdir('qapi')
1796 subdir('qobject')
1797 subdir('stubs')
1798 subdir('trace')
1799 subdir('util')
1800 subdir('qom')
1801 subdir('authz')
1802 subdir('crypto')
1803 subdir('ui')
1806 if enable_modules
1807   libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1808   modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1809 endif
1811 stub_ss = stub_ss.apply(config_all, strict: false)
1813 util_ss.add_all(trace_ss)
1814 util_ss = util_ss.apply(config_all, strict: false)
1815 libqemuutil = static_library('qemuutil',
1816                              sources: util_ss.sources() + stub_ss.sources() + genh,
1817                              dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1818 qemuutil = declare_dependency(link_with: libqemuutil,
1819                               sources: genh + version_res)
1821 decodetree = generator(find_program('scripts/decodetree.py'),
1822                        output: 'decode-@BASENAME@.c.inc',
1823                        arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1825 subdir('audio')
1826 subdir('io')
1827 subdir('chardev')
1828 subdir('fsdev')
1829 subdir('libdecnumber')
1830 subdir('target')
1831 subdir('dump')
1833 block_ss.add(files(
1834   'block.c',
1835   'blockjob.c',
1836   'job.c',
1837   'qemu-io-cmds.c',
1839 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1841 subdir('nbd')
1842 subdir('scsi')
1843 subdir('block')
1845 blockdev_ss.add(files(
1846   'blockdev.c',
1847   'blockdev-nbd.c',
1848   'iothread.c',
1849   'job-qmp.c',
1850 ), gnutls)
1852 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1853 # os-win32.c does not
1854 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1855 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1857 common_ss.add(files('cpus-common.c'))
1859 subdir('softmmu')
1861 common_ss.add(capstone)
1862 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
1863 specific_ss.add(files('exec-vary.c'))
1864 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1865   'fpu/softfloat.c',
1866   'tcg/optimize.c',
1867   'tcg/tcg-common.c',
1868   'tcg/tcg-op-gvec.c',
1869   'tcg/tcg-op-vec.c',
1870   'tcg/tcg-op.c',
1871   'tcg/tcg.c',
1873 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1875 subdir('backends')
1876 subdir('disas')
1877 subdir('migration')
1878 subdir('monitor')
1879 subdir('net')
1880 subdir('replay')
1881 subdir('hw')
1882 subdir('accel')
1883 subdir('plugins')
1884 subdir('bsd-user')
1885 subdir('linux-user')
1887 bsd_user_ss.add(files('gdbstub.c'))
1888 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1890 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1891 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1893 # needed for fuzzing binaries
1894 subdir('tests/qtest/libqos')
1895 subdir('tests/qtest/fuzz')
1897 ########################
1898 # Library dependencies #
1899 ########################
1901 block_mods = []
1902 softmmu_mods = []
1903 foreach d, list : modules
1904   foreach m, module_ss : list
1905     if enable_modules and targetos != 'windows'
1906       module_ss = module_ss.apply(config_all, strict: false)
1907       sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1908                           dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1909       if d == 'block'
1910         block_mods += sl
1911       else
1912         softmmu_mods += sl
1913       endif
1914     else
1915       if d == 'block'
1916         block_ss.add_all(module_ss)
1917       else
1918         softmmu_ss.add_all(module_ss)
1919       endif
1920     endif
1921   endforeach
1922 endforeach
1924 nm = find_program('nm')
1925 undefsym = find_program('scripts/undefsym.py')
1926 block_syms = custom_target('block.syms', output: 'block.syms',
1927                              input: [libqemuutil, block_mods],
1928                              capture: true,
1929                              command: [undefsym, nm, '@INPUT@'])
1930 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1931                              input: [libqemuutil, softmmu_mods],
1932                              capture: true,
1933                              command: [undefsym, nm, '@INPUT@'])
1935 qom_ss = qom_ss.apply(config_host, strict: false)
1936 libqom = static_library('qom', qom_ss.sources() + genh,
1937                         dependencies: [qom_ss.dependencies()],
1938                         name_suffix: 'fa')
1940 qom = declare_dependency(link_whole: libqom)
1942 authz_ss = authz_ss.apply(config_host, strict: false)
1943 libauthz = static_library('authz', authz_ss.sources() + genh,
1944                           dependencies: [authz_ss.dependencies()],
1945                           name_suffix: 'fa',
1946                           build_by_default: false)
1948 authz = declare_dependency(link_whole: libauthz,
1949                            dependencies: qom)
1951 crypto_ss = crypto_ss.apply(config_host, strict: false)
1952 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
1953                            dependencies: [crypto_ss.dependencies()],
1954                            name_suffix: 'fa',
1955                            build_by_default: false)
1957 crypto = declare_dependency(link_whole: libcrypto,
1958                             dependencies: [authz, qom])
1960 io_ss = io_ss.apply(config_host, strict: false)
1961 libio = static_library('io', io_ss.sources() + genh,
1962                        dependencies: [io_ss.dependencies()],
1963                        link_with: libqemuutil,
1964                        name_suffix: 'fa',
1965                        build_by_default: false)
1967 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
1969 libmigration = static_library('migration', sources: migration_files + genh,
1970                               name_suffix: 'fa',
1971                               build_by_default: false)
1972 migration = declare_dependency(link_with: libmigration,
1973                                dependencies: [zlib, qom, io])
1974 softmmu_ss.add(migration)
1976 block_ss = block_ss.apply(config_host, strict: false)
1977 libblock = static_library('block', block_ss.sources() + genh,
1978                           dependencies: block_ss.dependencies(),
1979                           link_depends: block_syms,
1980                           name_suffix: 'fa',
1981                           build_by_default: false)
1983 block = declare_dependency(link_whole: [libblock],
1984                            link_args: '@block.syms',
1985                            dependencies: [crypto, io])
1987 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
1988 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
1989                              dependencies: blockdev_ss.dependencies(),
1990                              name_suffix: 'fa',
1991                              build_by_default: false)
1993 blockdev = declare_dependency(link_whole: [libblockdev],
1994                               dependencies: [block])
1996 qmp_ss = qmp_ss.apply(config_host, strict: false)
1997 libqmp = static_library('qmp', qmp_ss.sources() + genh,
1998                         dependencies: qmp_ss.dependencies(),
1999                         name_suffix: 'fa',
2000                         build_by_default: false)
2002 qmp = declare_dependency(link_whole: [libqmp])
2004 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2005                             name_suffix: 'fa',
2006                             dependencies: [gnutls],
2007                             build_by_default: false)
2009 chardev = declare_dependency(link_whole: libchardev)
2011 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
2012                            name_suffix: 'fa',
2013                            build_by_default: false)
2014 hwcore = declare_dependency(link_whole: libhwcore)
2015 common_ss.add(hwcore)
2017 ###########
2018 # Targets #
2019 ###########
2021 foreach m : block_mods + softmmu_mods
2022   shared_module(m.name(),
2023                 name_prefix: '',
2024                 link_whole: m,
2025                 install: true,
2026                 install_dir: qemu_moddir)
2027 endforeach
2029 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2030 common_ss.add(qom, qemuutil)
2032 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2033 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2035 common_all = common_ss.apply(config_all, strict: false)
2036 common_all = static_library('common',
2037                             build_by_default: false,
2038                             sources: common_all.sources() + genh,
2039                             dependencies: common_all.dependencies(),
2040                             name_suffix: 'fa')
2042 feature_to_c = find_program('scripts/feature_to_c.sh')
2044 emulators = {}
2045 foreach target : target_dirs
2046   config_target = config_target_mak[target]
2047   target_name = config_target['TARGET_NAME']
2048   arch = config_target['TARGET_BASE_ARCH']
2049   arch_srcs = [config_target_h[target]]
2050   arch_deps = []
2051   c_args = ['-DNEED_CPU_H',
2052             '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2053             '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2054   link_args = emulator_link_args
2056   config_target += config_host
2057   target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2058   if targetos == 'linux'
2059     target_inc += include_directories('linux-headers', is_system: true)
2060   endif
2061   if target.endswith('-softmmu')
2062     qemu_target_name = 'qemu-system-' + target_name
2063     target_type='system'
2064     t = target_softmmu_arch[arch].apply(config_target, strict: false)
2065     arch_srcs += t.sources()
2066     arch_deps += t.dependencies()
2068     hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2069     hw = hw_arch[hw_dir].apply(config_target, strict: false)
2070     arch_srcs += hw.sources()
2071     arch_deps += hw.dependencies()
2073     arch_srcs += config_devices_h[target]
2074     link_args += ['@block.syms', '@qemu.syms']
2075   else
2076     abi = config_target['TARGET_ABI_DIR']
2077     target_type='user'
2078     qemu_target_name = 'qemu-' + target_name
2079     if 'CONFIG_LINUX_USER' in config_target
2080       base_dir = 'linux-user'
2081       target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2082     else
2083       base_dir = 'bsd-user'
2084       target_inc += include_directories('bsd-user/freebsd')
2085     endif
2086     target_inc += include_directories(
2087       base_dir,
2088       base_dir / abi,
2089     )
2090     if 'CONFIG_LINUX_USER' in config_target
2091       dir = base_dir / abi
2092       arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2093       if config_target.has_key('TARGET_SYSTBL_ABI')
2094         arch_srcs += \
2095           syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2096                                              extra_args : config_target['TARGET_SYSTBL_ABI'])
2097       endif
2098     endif
2099   endif
2101   if 'TARGET_XML_FILES' in config_target
2102     gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2103                                 output: target + '-gdbstub-xml.c',
2104                                 input: files(config_target['TARGET_XML_FILES'].split()),
2105                                 command: [feature_to_c, '@INPUT@'],
2106                                 capture: true)
2107     arch_srcs += gdbstub_xml
2108   endif
2110   t = target_arch[arch].apply(config_target, strict: false)
2111   arch_srcs += t.sources()
2112   arch_deps += t.dependencies()
2114   target_common = common_ss.apply(config_target, strict: false)
2115   objects = common_all.extract_objects(target_common.sources())
2116   deps = target_common.dependencies()
2118   target_specific = specific_ss.apply(config_target, strict: false)
2119   arch_srcs += target_specific.sources()
2120   arch_deps += target_specific.dependencies()
2122   lib = static_library('qemu-' + target,
2123                  sources: arch_srcs + genh,
2124                  dependencies: arch_deps,
2125                  objects: objects,
2126                  include_directories: target_inc,
2127                  c_args: c_args,
2128                  build_by_default: false,
2129                  name_suffix: 'fa')
2131   if target.endswith('-softmmu')
2132     execs = [{
2133       'name': 'qemu-system-' + target_name,
2134       'gui': false,
2135       'sources': files('softmmu/main.c'),
2136       'dependencies': []
2137     }]
2138     if targetos == 'windows' and (sdl.found() or gtk.found())
2139       execs += [{
2140         'name': 'qemu-system-' + target_name + 'w',
2141         'gui': true,
2142         'sources': files('softmmu/main.c'),
2143         'dependencies': []
2144       }]
2145     endif
2146     if config_host.has_key('CONFIG_FUZZ')
2147       specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2148       execs += [{
2149         'name': 'qemu-fuzz-' + target_name,
2150         'gui': false,
2151         'sources': specific_fuzz.sources(),
2152         'dependencies': specific_fuzz.dependencies(),
2153       }]
2154     endif
2155   else
2156     execs = [{
2157       'name': 'qemu-' + target_name,
2158       'gui': false,
2159       'sources': [],
2160       'dependencies': []
2161     }]
2162   endif
2163   foreach exe: execs
2164     emulators += {exe['name']:
2165          executable(exe['name'], exe['sources'],
2166                install: true,
2167                c_args: c_args,
2168                dependencies: arch_deps + deps + exe['dependencies'],
2169                objects: lib.extract_all_objects(recursive: true),
2170                link_language: link_language,
2171                link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2172                link_args: link_args,
2173                gui_app: exe['gui'])
2174     }
2176     if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2177       foreach stp: [
2178         {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2179         {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2180         {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2181         {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2182       ]
2183         custom_target(exe['name'] + stp['ext'],
2184                       input: trace_events_all,
2185                       output: exe['name'] + stp['ext'],
2186                       install: stp['install'],
2187                       install_dir: get_option('datadir') / 'systemtap/tapset',
2188                       command: [
2189                         tracetool, '--group=all', '--format=' + stp['fmt'],
2190                         '--binary=' + stp['bin'],
2191                         '--target-name=' + target_name,
2192                         '--target-type=' + target_type,
2193                         '--probe-prefix=qemu.' + target_type + '.' + target_name,
2194                         '@INPUT@', '@OUTPUT@'
2195                       ])
2196       endforeach
2197     endif
2198   endforeach
2199 endforeach
2201 # Other build targets
2203 if 'CONFIG_PLUGIN' in config_host
2204   install_headers('include/qemu/qemu-plugin.h')
2205 endif
2207 if 'CONFIG_GUEST_AGENT' in config_host
2208   subdir('qga')
2209 elif get_option('guest_agent_msi').enabled()
2210   error('Guest agent MSI requested, but the guest agent is not being built')
2211 endif
2213 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2214 # when we don't build tools or system
2215 if xkbcommon.found()
2216   # used for the update-keymaps target, so include rules even if !have_tools
2217   qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2218                            dependencies: [qemuutil, xkbcommon], install: have_tools)
2219 endif
2221 if have_tools
2222   qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2223              dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2224   qemu_io = executable('qemu-io', files('qemu-io.c'),
2225              dependencies: [block, qemuutil], install: true)
2226   qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2227                dependencies: [blockdev, qemuutil, gnutls], install: true)
2229   subdir('storage-daemon')
2230   subdir('contrib/rdmacm-mux')
2231   subdir('contrib/elf2dmp')
2233   executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2234              dependencies: qemuutil,
2235              install: true)
2237   if 'CONFIG_VHOST_USER' in config_host
2238     subdir('contrib/vhost-user-blk')
2239     subdir('contrib/vhost-user-gpu')
2240     subdir('contrib/vhost-user-input')
2241     subdir('contrib/vhost-user-scsi')
2242   endif
2244   if targetos == 'linux'
2245     executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2246                dependencies: [qemuutil, libcap_ng],
2247                install: true,
2248                install_dir: get_option('libexecdir'))
2250     executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2251                dependencies: [authz, crypto, io, qom, qemuutil,
2252                               libcap_ng, mpathpersist],
2253                install: true)
2254   endif
2256   if 'CONFIG_IVSHMEM' in config_host
2257     subdir('contrib/ivshmem-client')
2258     subdir('contrib/ivshmem-server')
2259   endif
2260 endif
2262 subdir('scripts')
2263 subdir('tools')
2264 subdir('pc-bios')
2265 subdir('docs')
2266 subdir('tests')
2267 if gtk.found()
2268   subdir('po')
2269 endif
2271 if host_machine.system() == 'windows'
2272   nsis_cmd = [
2273     find_program('scripts/nsis.py'),
2274     '@OUTPUT@',
2275     get_option('prefix'),
2276     meson.current_source_dir(),
2277     host_machine.cpu(),
2278     '--',
2279     '-DDISPLAYVERSION=' + meson.project_version(),
2280   ]
2281   if build_docs
2282     nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2283   endif
2284   if gtk.found()
2285     nsis_cmd += '-DCONFIG_GTK=y'
2286   endif
2288   nsis = custom_target('nsis',
2289                        output: 'qemu-setup-' + meson.project_version() + '.exe',
2290                        input: files('qemu.nsi'),
2291                        build_always_stale: true,
2292                        command: nsis_cmd + ['@INPUT@'])
2293   alias_target('installer', nsis)
2294 endif
2296 #########################
2297 # Configuration summary #
2298 #########################
2300 # Directories
2301 summary_info = {}
2302 summary_info += {'Install prefix':    get_option('prefix')}
2303 summary_info += {'BIOS directory':    qemu_datadir}
2304 summary_info += {'firmware path':     get_option('qemu_firmwarepath')}
2305 summary_info += {'binary directory':  get_option('bindir')}
2306 summary_info += {'library directory': get_option('libdir')}
2307 summary_info += {'module directory':  qemu_moddir}
2308 summary_info += {'libexec directory': get_option('libexecdir')}
2309 summary_info += {'include directory': get_option('includedir')}
2310 summary_info += {'config directory':  get_option('sysconfdir')}
2311 if targetos != 'windows'
2312   summary_info += {'local state directory': get_option('localstatedir')}
2313   summary_info += {'Manual directory':      get_option('mandir')}
2314 else
2315   summary_info += {'local state directory': 'queried at runtime'}
2316 endif
2317 summary_info += {'Doc directory':     get_option('docdir')}
2318 summary_info += {'Build directory':   meson.current_build_dir()}
2319 summary_info += {'Source path':       meson.current_source_dir()}
2320 summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
2321 summary(summary_info, bool_yn: true, section: 'Directories')
2323 # Host binaries
2324 summary_info = {}
2325 summary_info += {'git':               config_host['GIT']}
2326 summary_info += {'make':              config_host['MAKE']}
2327 summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2328 summary_info += {'sphinx-build':      sphinx_build.found()}
2329 if config_host.has_key('HAVE_GDB_BIN')
2330   summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
2331 endif
2332 summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
2333 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
2334   summary_info += {'wixl':            wixl.found() ? wixl.full_path() : false}
2335 endif
2336 if slirp_opt != 'disabled'
2337   summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
2338 endif
2339 summary(summary_info, bool_yn: true, section: 'Host binaries')
2341 # Configurable features
2342 summary_info = {}
2343 summary_info += {'Documentation':     build_docs}
2344 summary_info += {'system-mode emulation': have_system}
2345 summary_info += {'user-mode emulation': have_user}
2346 summary_info += {'block layer':       have_block}
2347 summary_info += {'Install blobs':     get_option('install_blobs')}
2348 summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
2349 if config_host.has_key('CONFIG_MODULES')
2350   summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2351 endif
2352 summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
2353 summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
2354 if have_system
2355   summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
2356 endif
2357 summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
2358 if config_host['TRACE_BACKENDS'].split().contains('simple')
2359   summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2360 endif
2361 summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2362 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2363 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2364 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2365 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2366 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2367 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2368 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2369 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2370 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2371 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2372 summary(summary_info, bool_yn: true, section: 'Configurable features')
2374 # Compilation information
2375 summary_info = {}
2376 summary_info += {'host CPU':          cpu}
2377 summary_info += {'host endianness':   build_machine.endian()}
2378 summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
2379 summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
2380 if link_language == 'cpp'
2381   summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
2382 else
2383   summary_info += {'C++ compiler':      false}
2384 endif
2385 if targetos == 'darwin'
2386   summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
2387 endif
2388 if targetos == 'windows'
2389   if 'WIN_SDK' in config_host
2390     summary_info += {'Windows SDK':   config_host['WIN_SDK']}
2391   endif
2392 endif
2393 summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
2394 summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
2395                                                + ['-O' + get_option('optimization')]
2396                                                + (get_option('debug') ? ['-g'] : []))}
2397 if link_language == 'cpp'
2398   summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
2399                                                + ['-O' + get_option('optimization')]
2400                                                + (get_option('debug') ? ['-g'] : []))}
2401 endif
2402 link_args = get_option(link_language + '_link_args')
2403 if link_args.length() > 0
2404   summary_info += {'LDFLAGS':         ' '.join(link_args)}
2405 endif
2406 summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
2407 summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
2408 summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
2409 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2410 summary_info += {'PIE':               get_option('b_pie')}
2411 summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
2412 summary_info += {'malloc trim support': has_malloc_trim}
2413 summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
2414 summary_info += {'preadv support':    config_host.has_key('CONFIG_PREADV')}
2415 summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
2416 summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
2417 summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
2418 summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2419 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2420 summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
2421 summary_info += {'memory allocator':  get_option('malloc')}
2422 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2423 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2424 summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
2425 summary_info += {'gcov':              get_option('b_coverage')}
2426 summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
2427 summary_info += {'CFI support':       get_option('cfi')}
2428 if get_option('cfi')
2429   summary_info += {'CFI debug support': get_option('cfi_debug')}
2430 endif
2431 summary_info += {'strip binaries':    get_option('strip')}
2432 summary_info += {'sparse':            sparse.found() ? sparse.full_path() : false}
2433 summary_info += {'mingw32 support':   targetos == 'windows'}
2434 summary(summary_info, bool_yn: true, section: 'Compilation')
2436 # Targets and accelerators
2437 summary_info = {}
2438 if have_system
2439   summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
2440   summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
2441   summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
2442   summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
2443   summary_info += {'Xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
2444   if config_host.has_key('CONFIG_XEN_BACKEND')
2445     summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2446   endif
2447 endif
2448 summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
2449 if config_all.has_key('CONFIG_TCG')
2450   summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2451   summary_info += {'TCG interpreter':   tcg_arch == 'tci'}
2452 endif
2453 summary_info += {'target list':       ' '.join(target_dirs)}
2454 if have_system
2455   summary_info += {'default devices':   get_option('default_devices')}
2456 endif
2457 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
2459 # Block layer
2460 summary_info = {}
2461 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2462 summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
2463 if have_block
2464   summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2465   summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2466   summary_info += {'VirtFS support':    have_virtfs}
2467   summary_info += {'build virtiofs daemon': have_virtiofsd}
2468   summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2469   summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2470   summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
2471   summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
2472   summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
2473   summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
2474   summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
2475   summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
2476   summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
2477   summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2478   summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
2479   summary_info += {'FUSE exports':      fuse.found()}
2480 endif
2481 summary(summary_info, bool_yn: true, section: 'Block layer support')
2483 # Crypto
2484 summary_info = {}
2485 summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
2486 summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
2487 # TODO: add back version
2488 summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
2489 if config_host.has_key('CONFIG_GCRYPT')
2490    summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
2491    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2492 endif
2493 # TODO: add back version
2494 summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
2495 if config_host.has_key('CONFIG_NETTLE')
2496    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2497 endif
2498 summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
2499 summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
2500 summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
2501 summary(summary_info, bool_yn: true, section: 'Crypto')
2503 # Libraries
2504 summary_info = {}
2505 if targetos == 'darwin'
2506   summary_info += {'Cocoa support':   cocoa.found()}
2507 endif
2508 # TODO: add back version
2509 summary_info += {'SDL support':       sdl.found()}
2510 summary_info += {'SDL image support': sdl_image.found()}
2511 # TODO: add back version
2512 summary_info += {'GTK support':       gtk.found()}
2513 summary_info += {'pixman':            pixman.found()}
2514 # TODO: add back version
2515 summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
2516 # TODO: add back version
2517 summary_info += {'slirp support':     slirp_opt == 'disabled' ? false : slirp_opt}
2518 summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
2519 summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
2520 summary_info += {'iconv support':     iconv.found()}
2521 summary_info += {'curses support':    curses.found()}
2522 # TODO: add back version
2523 summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
2524 summary_info += {'curl support':      curl.found()}
2525 summary_info += {'Multipath support': mpathpersist.found()}
2526 summary_info += {'VNC support':       vnc.found()}
2527 if vnc.found()
2528   summary_info += {'VNC SASL support':  sasl.found()}
2529   summary_info += {'VNC JPEG support':  jpeg.found()}
2530   summary_info += {'VNC PNG support':   png.found()}
2531 endif
2532 summary_info += {'brlapi support':    brlapi.found()}
2533 summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
2534 summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
2535 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2536 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2537 summary_info += {'ATTR/XATTR support': libattr.found()}
2538 summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
2539 summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
2540 summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
2541 summary_info += {'libcap-ng support': libcap_ng.found()}
2542 # TODO: add back protocol and server version
2543 summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
2544 summary_info += {'rbd support':       rbd.found()}
2545 summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
2546 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2547 summary_info += {'U2F support':       u2f.found()}
2548 summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
2549 summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
2550 summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
2551 summary_info += {'OpenGL dmabufs':    config_host.has_key('CONFIG_OPENGL_DMABUF')}
2552 summary_info += {'libiscsi support':  libiscsi.found()}
2553 summary_info += {'libnfs support':    libnfs.found()}
2554 if targetos == 'windows'
2555   if config_host.has_key('CONFIG_GUEST_AGENT')
2556     summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
2557     summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2558   endif
2559 endif
2560 summary_info += {'seccomp support':   seccomp.found()}
2561 summary_info += {'GlusterFS support': glusterfs.found()}
2562 summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
2563 summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
2564 summary_info += {'lzo support':       lzo.found()}
2565 summary_info += {'snappy support':    snappy.found()}
2566 summary_info += {'bzip2 support':     libbzip2.found()}
2567 summary_info += {'lzfse support':     liblzfse.found()}
2568 summary_info += {'zstd support':      zstd.found()}
2569 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2570 summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
2571 summary_info += {'capstone':          capstone_opt == 'disabled' ? false : capstone_opt}
2572 summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
2573 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2574 summary_info += {'libudev':           libudev.found()}
2575 summary_info += {'FUSE lseek':        fuse_lseek.found()}
2576 summary(summary_info, bool_yn: true, section: 'Dependencies')
2578 if not supported_cpus.contains(cpu)
2579   message()
2580   warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2581   message()
2582   message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2583   message('The QEMU project intends to remove support for this host CPU in')
2584   message('a future release if nobody volunteers to maintain it and to')
2585   message('provide a build host for our continuous integration setup.')
2586   message('configure has succeeded and you can continue to build, but')
2587   message('if you care about QEMU on this platform you should contact')
2588   message('us upstream at qemu-devel@nongnu.org.')
2589 endif
2591 if not supported_oses.contains(targetos)
2592   message()
2593   warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2594   message()
2595   message('Host OS ' + targetos + 'support is not currently maintained.')
2596   message('The QEMU project intends to remove support for this host OS in')
2597   message('a future release if nobody volunteers to maintain it and to')
2598   message('provide a build host for our continuous integration setup.')
2599   message('configure has succeeded and you can continue to build, but')
2600   message('if you care about QEMU on this platform you should contact')
2601   message('us upstream at qemu-devel@nongnu.org.')
2602 endif