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