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