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