rbd: convert to meson
[qemu/ar7.git] / meson.build
blobf844fc51ab146ca090066f6c058f1ced8fa21303
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
748 snappy = not_found
749 if 'CONFIG_SNAPPY' in config_host
750   snappy = declare_dependency(link_args: config_host['SNAPPY_LIBS'].split())
751 endif
752 lzo = not_found
753 if 'CONFIG_LZO' in config_host
754   lzo = declare_dependency(link_args: config_host['LZO_LIBS'].split())
755 endif
756 rdma = not_found
757 if 'CONFIG_RDMA' in config_host
758   rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
759 endif
760 numa = not_found
761 if 'CONFIG_NUMA' in config_host
762   numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
763 endif
764 xen = not_found
765 if 'CONFIG_XEN_BACKEND' in config_host
766   xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
767                            link_args: config_host['XEN_LIBS'].split())
768 endif
769 cacard = not_found
770 if 'CONFIG_SMARTCARD' in config_host
771   cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
772                               link_args: config_host['SMARTCARD_LIBS'].split())
773 endif
774 u2f = not_found
775 if have_system
776   u2f = dependency('u2f-emu', required: get_option('u2f'),
777                    method: 'pkg-config',
778                    static: enable_static)
779 endif
780 usbredir = not_found
781 if 'CONFIG_USB_REDIR' in config_host
782   usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
783                                 link_args: config_host['USB_REDIR_LIBS'].split())
784 endif
785 libusb = not_found
786 if 'CONFIG_USB_LIBUSB' in config_host
787   libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
788                               link_args: config_host['LIBUSB_LIBS'].split())
789 endif
790 libpmem = not_found
791 if 'CONFIG_LIBPMEM' in config_host
792   libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
793                                link_args: config_host['LIBPMEM_LIBS'].split())
794 endif
795 libdaxctl = not_found
796 if 'CONFIG_LIBDAXCTL' in config_host
797   libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
798 endif
799 tasn1 = not_found
800 if 'CONFIG_TASN1' in config_host
801   tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(),
802                              link_args: config_host['TASN1_LIBS'].split())
803 endif
804 keyutils = dependency('libkeyutils', required: false,
805                       method: 'pkg-config', static: enable_static)
807 has_gettid = cc.has_function('gettid')
809 # Malloc tests
811 malloc = []
812 if get_option('malloc') == 'system'
813   has_malloc_trim = \
814     not get_option('malloc_trim').disabled() and \
815     cc.links('''#include <malloc.h>
816                 int main(void) { malloc_trim(0); return 0; }''')
817 else
818   has_malloc_trim = false
819   malloc = cc.find_library(get_option('malloc'), required: true)
820 endif
821 if not has_malloc_trim and get_option('malloc_trim').enabled()
822   if get_option('malloc') == 'system'
823     error('malloc_trim not available on this platform.')
824   else
825     error('malloc_trim not available with non-libc memory allocator')
826   endif
827 endif
829 # Check whether the glibc provides statx()
831 statx_test = '''
832   #ifndef _GNU_SOURCE
833   #define _GNU_SOURCE
834   #endif
835   #include <sys/stat.h>
836   int main(void) {
837     struct statx statxbuf;
838     statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
839     return 0;
840   }'''
842 has_statx = cc.links(statx_test)
844 have_vhost_user_blk_server = (targetos == 'linux' and
845     'CONFIG_VHOST_USER' in config_host)
847 if get_option('vhost_user_blk_server').enabled()
848     if targetos != 'linux'
849         error('vhost_user_blk_server requires linux')
850     elif 'CONFIG_VHOST_USER' not in config_host
851         error('vhost_user_blk_server requires vhost-user support')
852     endif
853 elif get_option('vhost_user_blk_server').disabled() or not have_system
854     have_vhost_user_blk_server = false
855 endif
858 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
859   error('Cannot enable fuse-lseek while fuse is disabled')
860 endif
862 fuse = dependency('fuse3', required: get_option('fuse'),
863                   version: '>=3.1', method: 'pkg-config',
864                   static: enable_static)
866 fuse_lseek = not_found
867 if not get_option('fuse_lseek').disabled()
868   if fuse.version().version_compare('>=3.8')
869     # Dummy dependency
870     fuse_lseek = declare_dependency()
871   elif get_option('fuse_lseek').enabled()
872     if fuse.found()
873       error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
874     else
875       error('fuse-lseek requires libfuse, which was not found')
876     endif
877   endif
878 endif
880 if get_option('cfi')
881   cfi_flags=[]
882   # Check for dependency on LTO
883   if not get_option('b_lto')
884     error('Selected Control-Flow Integrity but LTO is disabled')
885   endif
886   if config_host.has_key('CONFIG_MODULES')
887     error('Selected Control-Flow Integrity is not compatible with modules')
888   endif
889   # Check for cfi flags. CFI requires LTO so we can't use
890   # get_supported_arguments, but need a more complex "compiles" which allows
891   # custom arguments
892   if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
893                  args: ['-flto', '-fsanitize=cfi-icall'] )
894     cfi_flags += '-fsanitize=cfi-icall'
895   else
896     error('-fsanitize=cfi-icall is not supported by the compiler')
897   endif
898   if cc.compiles('int main () { return 0; }',
899                  name: '-fsanitize-cfi-icall-generalize-pointers',
900                  args: ['-flto', '-fsanitize=cfi-icall',
901                         '-fsanitize-cfi-icall-generalize-pointers'] )
902     cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
903   else
904     error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
905   endif
906   if get_option('cfi_debug')
907     if cc.compiles('int main () { return 0; }',
908                    name: '-fno-sanitize-trap=cfi-icall',
909                    args: ['-flto', '-fsanitize=cfi-icall',
910                           '-fno-sanitize-trap=cfi-icall'] )
911       cfi_flags += '-fno-sanitize-trap=cfi-icall'
912     else
913       error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
914     endif
915   endif
916   add_project_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
917   add_project_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
918 endif
920 #################
921 # config-host.h #
922 #################
924 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
925 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
926 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
927 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
928 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
929 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
930 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
931 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
932 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
933 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
934 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
935 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
937 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
938 config_host_data.set('CONFIG_COCOA', cocoa.found())
939 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
940 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
941 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
942 config_host_data.set('CONFIG_CURL', curl.found())
943 config_host_data.set('CONFIG_CURSES', curses.found())
944 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
945 if glusterfs.found()
946   config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
947   config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
948   config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
949   config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
950   config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
951   config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
952 endif
953 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
954 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
955 config_host_data.set('CONFIG_RBD', rbd.found())
956 config_host_data.set('CONFIG_SDL', sdl.found())
957 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
958 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
959 config_host_data.set('CONFIG_VNC', vnc.found())
960 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
961 config_host_data.set('CONFIG_VNC_PNG', png.found())
962 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
963 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
964 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
965 config_host_data.set('CONFIG_GETTID', has_gettid)
966 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
967 config_host_data.set('CONFIG_STATX', has_statx)
968 config_host_data.set('CONFIG_FUSE', fuse.found())
969 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
970 config_host_data.set('CONFIG_CFI', get_option('cfi'))
971 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
972 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
973 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
974 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
976 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
977 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
978 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
979 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
980 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
981 config_host_data.set('HAVE_SYS_SIGNAL_H', cc.has_header('sys/signal.h'))
983 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
984 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
985 strings = ['HOST_DSOSUF', 'CONFIG_IASL']
986 foreach k, v: config_host
987   if ignored.contains(k)
988     # do nothing
989   elif arrays.contains(k)
990     if v != ''
991       v = '"' + '", "'.join(v.split()) + '", '
992     endif
993     config_host_data.set(k, v)
994   elif k == 'ARCH'
995     config_host_data.set('HOST_' + v.to_upper(), 1)
996   elif strings.contains(k)
997     if not k.startswith('CONFIG_')
998       k = 'CONFIG_' + k.to_upper()
999     endif
1000     config_host_data.set_quoted(k, v)
1001   elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
1002     config_host_data.set(k, v == 'y' ? 1 : v)
1003   endif
1004 endforeach
1006 ########################
1007 # Target configuration #
1008 ########################
1010 minikconf = find_program('scripts/minikconf.py')
1011 config_all = {}
1012 config_all_devices = {}
1013 config_all_disas = {}
1014 config_devices_mak_list = []
1015 config_devices_h = {}
1016 config_target_h = {}
1017 config_target_mak = {}
1019 disassemblers = {
1020   'alpha' : ['CONFIG_ALPHA_DIS'],
1021   'arm' : ['CONFIG_ARM_DIS'],
1022   'avr' : ['CONFIG_AVR_DIS'],
1023   'cris' : ['CONFIG_CRIS_DIS'],
1024   'hppa' : ['CONFIG_HPPA_DIS'],
1025   'i386' : ['CONFIG_I386_DIS'],
1026   'x86_64' : ['CONFIG_I386_DIS'],
1027   'x32' : ['CONFIG_I386_DIS'],
1028   'lm32' : ['CONFIG_LM32_DIS'],
1029   'm68k' : ['CONFIG_M68K_DIS'],
1030   'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1031   'mips' : ['CONFIG_MIPS_DIS'],
1032   'moxie' : ['CONFIG_MOXIE_DIS'],
1033   'nios2' : ['CONFIG_NIOS2_DIS'],
1034   'or1k' : ['CONFIG_OPENRISC_DIS'],
1035   'ppc' : ['CONFIG_PPC_DIS'],
1036   'riscv' : ['CONFIG_RISCV_DIS'],
1037   'rx' : ['CONFIG_RX_DIS'],
1038   's390' : ['CONFIG_S390_DIS'],
1039   'sh4' : ['CONFIG_SH4_DIS'],
1040   'sparc' : ['CONFIG_SPARC_DIS'],
1041   'xtensa' : ['CONFIG_XTENSA_DIS'],
1043 if link_language == 'cpp'
1044   disassemblers += {
1045     'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1046     'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1047     'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1048   }
1049 endif
1051 host_kconfig = \
1052   ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1053   ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
1054   ('CONFIG_IVSHMEM' in config_host ? ['CONFIG_IVSHMEM=y'] : []) + \
1055   ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1056   ('CONFIG_X11' in config_host ? ['CONFIG_X11=y'] : []) + \
1057   ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1058   ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1059   ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1060   ('CONFIG_VIRTFS' in config_host ? ['CONFIG_VIRTFS=y'] : []) + \
1061   ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1062   ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : [])
1064 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1066 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1067 actual_target_dirs = []
1068 fdt_required = []
1069 foreach target : target_dirs
1070   config_target = { 'TARGET_NAME': target.split('-')[0] }
1071   if target.endswith('linux-user')
1072     if targetos != 'linux'
1073       if default_targets
1074         continue
1075       endif
1076       error('Target @0@ is only available on a Linux host'.format(target))
1077     endif
1078     config_target += { 'CONFIG_LINUX_USER': 'y' }
1079   elif target.endswith('bsd-user')
1080     if 'CONFIG_BSD' not in config_host
1081       if default_targets
1082         continue
1083       endif
1084       error('Target @0@ is only available on a BSD host'.format(target))
1085     endif
1086     config_target += { 'CONFIG_BSD_USER': 'y' }
1087   elif target.endswith('softmmu')
1088     config_target += { 'CONFIG_SOFTMMU': 'y' }
1089   endif
1090   if target.endswith('-user')
1091     config_target += {
1092       'CONFIG_USER_ONLY': 'y',
1093       'CONFIG_QEMU_INTERP_PREFIX':
1094         config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1095     }
1096   endif
1098   accel_kconfig = []
1099   foreach sym: accelerators
1100     if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1101       config_target += { sym: 'y' }
1102       config_all += { sym: 'y' }
1103       if sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1104         config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1105       endif
1106       accel_kconfig += [ sym + '=y' ]
1107     endif
1108   endforeach
1109   if accel_kconfig.length() == 0
1110     if default_targets
1111       continue
1112     endif
1113     error('No accelerator available for target @0@'.format(target))
1114   endif
1116   actual_target_dirs += target
1117   config_target += keyval.load('default-configs/targets' / target + '.mak')
1118   config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1120   if 'TARGET_NEED_FDT' in config_target
1121     fdt_required += target
1122   endif
1124   # Add default keys
1125   if 'TARGET_BASE_ARCH' not in config_target
1126     config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1127   endif
1128   if 'TARGET_ABI_DIR' not in config_target
1129     config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1130   endif
1132   foreach k, v: disassemblers
1133     if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1134       foreach sym: v
1135         config_target += { sym: 'y' }
1136         config_all_disas += { sym: 'y' }
1137       endforeach
1138     endif
1139   endforeach
1141   config_target_data = configuration_data()
1142   foreach k, v: config_target
1143     if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1144       # do nothing
1145     elif ignored.contains(k)
1146       # do nothing
1147     elif k == 'TARGET_BASE_ARCH'
1148       # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1149       # not used to select files from sourcesets.
1150       config_target_data.set('TARGET_' + v.to_upper(), 1)
1151     elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1152       config_target_data.set_quoted(k, v)
1153     elif v == 'y'
1154       config_target_data.set(k, 1)
1155     else
1156       config_target_data.set(k, v)
1157     endif
1158   endforeach
1159   config_target_h += {target: configure_file(output: target + '-config-target.h',
1160                                                configuration: config_target_data)}
1162   if target.endswith('-softmmu')
1163     config_devices_mak = target + '-config-devices.mak'
1164     config_devices_mak = configure_file(
1165       input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
1166       output: config_devices_mak,
1167       depfile: config_devices_mak + '.d',
1168       capture: true,
1169       command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'],
1170                 config_devices_mak, '@DEPFILE@', '@INPUT@',
1171                 host_kconfig, accel_kconfig])
1173     config_devices_data = configuration_data()
1174     config_devices = keyval.load(config_devices_mak)
1175     foreach k, v: config_devices
1176       config_devices_data.set(k, 1)
1177     endforeach
1178     config_devices_mak_list += config_devices_mak
1179     config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1180                                                 configuration: config_devices_data)}
1181     config_target += config_devices
1182     config_all_devices += config_devices
1183   endif
1184   config_target_mak += {target: config_target}
1185 endforeach
1186 target_dirs = actual_target_dirs
1188 # This configuration is used to build files that are shared by
1189 # multiple binaries, and then extracted out of the "common"
1190 # static_library target.
1192 # We do not use all_sources()/all_dependencies(), because it would
1193 # build literally all source files, including devices only used by
1194 # targets that are not built for this compilation.  The CONFIG_ALL
1195 # pseudo symbol replaces it.
1197 config_all += config_all_devices
1198 config_all += config_host
1199 config_all += config_all_disas
1200 config_all += {
1201   'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1202   'CONFIG_SOFTMMU': have_system,
1203   'CONFIG_USER_ONLY': have_user,
1204   'CONFIG_ALL': true,
1207 ##############
1208 # Submodules #
1209 ##############
1211 capstone = not_found
1212 capstone_opt = get_option('capstone')
1213 if capstone_opt in ['enabled', 'auto', 'system']
1214   have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1215   capstone = dependency('capstone', version: '>=4.0',
1216                         static: enable_static, method: 'pkg-config',
1217                         required: capstone_opt == 'system' or
1218                                   capstone_opt == 'enabled' and not have_internal)
1219   if capstone.found()
1220     capstone_opt = 'system'
1221   elif have_internal
1222     capstone_opt = 'internal'
1223   else
1224     capstone_opt = 'disabled'
1225   endif
1226 endif
1227 if capstone_opt == 'internal'
1228   capstone_data = configuration_data()
1229   capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1231   capstone_files = files(
1232     'capstone/cs.c',
1233     'capstone/MCInst.c',
1234     'capstone/MCInstrDesc.c',
1235     'capstone/MCRegisterInfo.c',
1236     'capstone/SStream.c',
1237     'capstone/utils.c'
1238   )
1240   if 'CONFIG_ARM_DIS' in config_all_disas
1241     capstone_data.set('CAPSTONE_HAS_ARM', '1')
1242     capstone_files += files(
1243       'capstone/arch/ARM/ARMDisassembler.c',
1244       'capstone/arch/ARM/ARMInstPrinter.c',
1245       'capstone/arch/ARM/ARMMapping.c',
1246       'capstone/arch/ARM/ARMModule.c'
1247     )
1248   endif
1250   # FIXME: This config entry currently depends on a c++ compiler.
1251   # Which is needed for building libvixl, but not for capstone.
1252   if 'CONFIG_ARM_A64_DIS' in config_all_disas
1253     capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1254     capstone_files += files(
1255       'capstone/arch/AArch64/AArch64BaseInfo.c',
1256       'capstone/arch/AArch64/AArch64Disassembler.c',
1257       'capstone/arch/AArch64/AArch64InstPrinter.c',
1258       'capstone/arch/AArch64/AArch64Mapping.c',
1259       'capstone/arch/AArch64/AArch64Module.c'
1260     )
1261   endif
1263   if 'CONFIG_PPC_DIS' in config_all_disas
1264     capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1265     capstone_files += files(
1266       'capstone/arch/PowerPC/PPCDisassembler.c',
1267       'capstone/arch/PowerPC/PPCInstPrinter.c',
1268       'capstone/arch/PowerPC/PPCMapping.c',
1269       'capstone/arch/PowerPC/PPCModule.c'
1270     )
1271   endif
1273   if 'CONFIG_S390_DIS' in config_all_disas
1274     capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1275     capstone_files += files(
1276       'capstone/arch/SystemZ/SystemZDisassembler.c',
1277       'capstone/arch/SystemZ/SystemZInstPrinter.c',
1278       'capstone/arch/SystemZ/SystemZMapping.c',
1279       'capstone/arch/SystemZ/SystemZModule.c',
1280       'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1281     )
1282   endif
1284   if 'CONFIG_I386_DIS' in config_all_disas
1285     capstone_data.set('CAPSTONE_HAS_X86', 1)
1286     capstone_files += files(
1287       'capstone/arch/X86/X86Disassembler.c',
1288       'capstone/arch/X86/X86DisassemblerDecoder.c',
1289       'capstone/arch/X86/X86ATTInstPrinter.c',
1290       'capstone/arch/X86/X86IntelInstPrinter.c',
1291       'capstone/arch/X86/X86InstPrinterCommon.c',
1292       'capstone/arch/X86/X86Mapping.c',
1293       'capstone/arch/X86/X86Module.c'
1294     )
1295   endif
1297   configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1299   capstone_cargs = [
1300     # FIXME: There does not seem to be a way to completely replace the c_args
1301     # that come from add_project_arguments() -- we can only add to them.
1302     # So: disable all warnings with a big hammer.
1303     '-Wno-error', '-w',
1305     # Include all configuration defines via a header file, which will wind up
1306     # as a dependency on the object file, and thus changes here will result
1307     # in a rebuild.
1308     '-include', 'capstone-defs.h'
1309   ]
1311   libcapstone = static_library('capstone',
1312                                sources: capstone_files,
1313                                c_args: capstone_cargs,
1314                                include_directories: 'capstone/include')
1315   capstone = declare_dependency(link_with: libcapstone,
1316                                 include_directories: 'capstone/include/capstone')
1317 endif
1319 slirp = not_found
1320 slirp_opt = 'disabled'
1321 if have_system
1322   slirp_opt = get_option('slirp')
1323   if slirp_opt in ['enabled', 'auto', 'system']
1324     have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1325     slirp = dependency('slirp', static: enable_static,
1326                        method: 'pkg-config',
1327                        required: slirp_opt == 'system' or
1328                                  slirp_opt == 'enabled' and not have_internal)
1329     if slirp.found()
1330       slirp_opt = 'system'
1331     elif have_internal
1332       slirp_opt = 'internal'
1333     else
1334       slirp_opt = 'disabled'
1335     endif
1336   endif
1337   if slirp_opt == 'internal'
1338     slirp_deps = []
1339     if targetos == 'windows'
1340       slirp_deps = cc.find_library('iphlpapi')
1341     endif
1342     slirp_conf = configuration_data()
1343     slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1344     slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1345     slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1346     slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1347     slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1348     slirp_files = [
1349       'slirp/src/arp_table.c',
1350       'slirp/src/bootp.c',
1351       'slirp/src/cksum.c',
1352       'slirp/src/dhcpv6.c',
1353       'slirp/src/dnssearch.c',
1354       'slirp/src/if.c',
1355       'slirp/src/ip6_icmp.c',
1356       'slirp/src/ip6_input.c',
1357       'slirp/src/ip6_output.c',
1358       'slirp/src/ip_icmp.c',
1359       'slirp/src/ip_input.c',
1360       'slirp/src/ip_output.c',
1361       'slirp/src/mbuf.c',
1362       'slirp/src/misc.c',
1363       'slirp/src/ncsi.c',
1364       'slirp/src/ndp_table.c',
1365       'slirp/src/sbuf.c',
1366       'slirp/src/slirp.c',
1367       'slirp/src/socket.c',
1368       'slirp/src/state.c',
1369       'slirp/src/stream.c',
1370       'slirp/src/tcp_input.c',
1371       'slirp/src/tcp_output.c',
1372       'slirp/src/tcp_subr.c',
1373       'slirp/src/tcp_timer.c',
1374       'slirp/src/tftp.c',
1375       'slirp/src/udp.c',
1376       'slirp/src/udp6.c',
1377       'slirp/src/util.c',
1378       'slirp/src/version.c',
1379       'slirp/src/vmstate.c',
1380     ]
1382     configure_file(
1383       input : 'slirp/src/libslirp-version.h.in',
1384       output : 'libslirp-version.h',
1385       configuration: slirp_conf)
1387     slirp_inc = include_directories('slirp', 'slirp/src')
1388     libslirp = static_library('slirp',
1389                               sources: slirp_files,
1390                               c_args: slirp_cargs,
1391                               include_directories: slirp_inc)
1392     slirp = declare_dependency(link_with: libslirp,
1393                                dependencies: slirp_deps,
1394                                include_directories: slirp_inc)
1395   endif
1396 endif
1398 fdt = not_found
1399 fdt_opt = get_option('fdt')
1400 if have_system
1401   if fdt_opt in ['enabled', 'auto', 'system']
1402     have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1403     fdt = cc.find_library('fdt', static: enable_static,
1404                           required: fdt_opt == 'system' or
1405                                     fdt_opt == 'enabled' and not have_internal)
1406     if fdt.found() and cc.links('''
1407        #include <libfdt.h>
1408        #include <libfdt_env.h>
1409        int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1410          dependencies: fdt)
1411       fdt_opt = 'system'
1412     elif have_internal
1413       fdt_opt = 'internal'
1414     else
1415       fdt_opt = 'disabled'
1416     endif
1417   endif
1418   if fdt_opt == 'internal'
1419     fdt_files = files(
1420       'dtc/libfdt/fdt.c',
1421       'dtc/libfdt/fdt_ro.c',
1422       'dtc/libfdt/fdt_wip.c',
1423       'dtc/libfdt/fdt_sw.c',
1424       'dtc/libfdt/fdt_rw.c',
1425       'dtc/libfdt/fdt_strerror.c',
1426       'dtc/libfdt/fdt_empty_tree.c',
1427       'dtc/libfdt/fdt_addresses.c',
1428       'dtc/libfdt/fdt_overlay.c',
1429       'dtc/libfdt/fdt_check.c',
1430     )
1432     fdt_inc = include_directories('dtc/libfdt')
1433     libfdt = static_library('fdt',
1434                             sources: fdt_files,
1435                             include_directories: fdt_inc)
1436     fdt = declare_dependency(link_with: libfdt,
1437                              include_directories: fdt_inc)
1438   endif
1439 endif
1440 if not fdt.found() and fdt_required.length() > 0
1441   error('fdt not available but required by targets ' + ', '.join(fdt_required))
1442 endif
1444 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1445 config_host_data.set('CONFIG_FDT', fdt.found())
1446 config_host_data.set('CONFIG_SLIRP', slirp.found())
1448 #####################
1449 # Generated sources #
1450 #####################
1452 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1454 hxtool = find_program('scripts/hxtool')
1455 shaderinclude = find_program('scripts/shaderinclude.pl')
1456 qapi_gen = find_program('scripts/qapi-gen.py')
1457 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1458                      meson.source_root() / 'scripts/qapi/commands.py',
1459                      meson.source_root() / 'scripts/qapi/common.py',
1460                      meson.source_root() / 'scripts/qapi/error.py',
1461                      meson.source_root() / 'scripts/qapi/events.py',
1462                      meson.source_root() / 'scripts/qapi/expr.py',
1463                      meson.source_root() / 'scripts/qapi/gen.py',
1464                      meson.source_root() / 'scripts/qapi/introspect.py',
1465                      meson.source_root() / 'scripts/qapi/parser.py',
1466                      meson.source_root() / 'scripts/qapi/schema.py',
1467                      meson.source_root() / 'scripts/qapi/source.py',
1468                      meson.source_root() / 'scripts/qapi/types.py',
1469                      meson.source_root() / 'scripts/qapi/visit.py',
1470                      meson.source_root() / 'scripts/qapi/common.py',
1471                      meson.source_root() / 'scripts/qapi-gen.py'
1474 tracetool = [
1475   python, files('scripts/tracetool.py'),
1476    '--backend=' + config_host['TRACE_BACKENDS']
1479 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1480                     meson.current_source_dir(),
1481                     config_host['PKGVERSION'], meson.project_version()]
1482 qemu_version = custom_target('qemu-version.h',
1483                              output: 'qemu-version.h',
1484                              command: qemu_version_cmd,
1485                              capture: true,
1486                              build_by_default: true,
1487                              build_always_stale: true)
1488 genh += qemu_version
1490 hxdep = []
1491 hx_headers = [
1492   ['qemu-options.hx', 'qemu-options.def'],
1493   ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1495 if have_system
1496   hx_headers += [
1497     ['hmp-commands.hx', 'hmp-commands.h'],
1498     ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1499   ]
1500 endif
1501 foreach d : hx_headers
1502   hxdep += custom_target(d[1],
1503                 input: files(d[0]),
1504                 output: d[1],
1505                 capture: true,
1506                 build_by_default: true, # to be removed when added to a target
1507                 command: [hxtool, '-h', '@INPUT0@'])
1508 endforeach
1509 genh += hxdep
1511 ###################
1512 # Collect sources #
1513 ###################
1515 authz_ss = ss.source_set()
1516 blockdev_ss = ss.source_set()
1517 block_ss = ss.source_set()
1518 bsd_user_ss = ss.source_set()
1519 chardev_ss = ss.source_set()
1520 common_ss = ss.source_set()
1521 crypto_ss = ss.source_set()
1522 io_ss = ss.source_set()
1523 linux_user_ss = ss.source_set()
1524 qmp_ss = ss.source_set()
1525 qom_ss = ss.source_set()
1526 softmmu_ss = ss.source_set()
1527 specific_fuzz_ss = ss.source_set()
1528 specific_ss = ss.source_set()
1529 stub_ss = ss.source_set()
1530 trace_ss = ss.source_set()
1531 user_ss = ss.source_set()
1532 util_ss = ss.source_set()
1534 modules = {}
1535 hw_arch = {}
1536 target_arch = {}
1537 target_softmmu_arch = {}
1539 ###############
1540 # Trace files #
1541 ###############
1543 # TODO: add each directory to the subdirs from its own meson.build, once
1544 # we have those
1545 trace_events_subdirs = [
1546   'accel/kvm',
1547   'accel/tcg',
1548   'crypto',
1549   'monitor',
1551 if have_user
1552   trace_events_subdirs += [ 'linux-user' ]
1553 endif
1554 if have_block
1555   trace_events_subdirs += [
1556     'authz',
1557     'block',
1558     'io',
1559     'nbd',
1560     'scsi',
1561   ]
1562 endif
1563 if have_system
1564   trace_events_subdirs += [
1565     'audio',
1566     'backends',
1567     'backends/tpm',
1568     'chardev',
1569     'hw/9pfs',
1570     'hw/acpi',
1571     'hw/alpha',
1572     'hw/arm',
1573     'hw/audio',
1574     'hw/block',
1575     'hw/block/dataplane',
1576     'hw/char',
1577     'hw/display',
1578     'hw/dma',
1579     'hw/hppa',
1580     'hw/hyperv',
1581     'hw/i2c',
1582     'hw/i386',
1583     'hw/i386/xen',
1584     'hw/ide',
1585     'hw/input',
1586     'hw/intc',
1587     'hw/isa',
1588     'hw/mem',
1589     'hw/mips',
1590     'hw/misc',
1591     'hw/misc/macio',
1592     'hw/net',
1593     'hw/net/can',
1594     'hw/nvram',
1595     'hw/pci',
1596     'hw/pci-host',
1597     'hw/ppc',
1598     'hw/rdma',
1599     'hw/rdma/vmw',
1600     'hw/rtc',
1601     'hw/s390x',
1602     'hw/scsi',
1603     'hw/sd',
1604     'hw/sparc',
1605     'hw/sparc64',
1606     'hw/ssi',
1607     'hw/timer',
1608     'hw/tpm',
1609     'hw/usb',
1610     'hw/vfio',
1611     'hw/virtio',
1612     'hw/watchdog',
1613     'hw/xen',
1614     'hw/gpio',
1615     'migration',
1616     'net',
1617     'softmmu',
1618     'ui',
1619   ]
1620 endif
1621 trace_events_subdirs += [
1622   'hw/core',
1623   'qapi',
1624   'qom',
1625   'target/arm',
1626   'target/hppa',
1627   'target/i386',
1628   'target/i386/kvm',
1629   'target/mips',
1630   'target/ppc',
1631   'target/riscv',
1632   'target/s390x',
1633   'target/sparc',
1634   'util',
1637 vhost_user = not_found
1638 if 'CONFIG_VHOST_USER' in config_host
1639   libvhost_user = subproject('libvhost-user')
1640   vhost_user = libvhost_user.get_variable('vhost_user_dep')
1641 endif
1643 subdir('qapi')
1644 subdir('qobject')
1645 subdir('stubs')
1646 subdir('trace')
1647 subdir('util')
1648 subdir('qom')
1649 subdir('authz')
1650 subdir('crypto')
1651 subdir('ui')
1654 if enable_modules
1655   libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1656   modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1657 endif
1659 stub_ss = stub_ss.apply(config_all, strict: false)
1661 util_ss.add_all(trace_ss)
1662 util_ss = util_ss.apply(config_all, strict: false)
1663 libqemuutil = static_library('qemuutil',
1664                              sources: util_ss.sources() + stub_ss.sources() + genh,
1665                              dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1666 qemuutil = declare_dependency(link_with: libqemuutil,
1667                               sources: genh + version_res)
1669 decodetree = generator(find_program('scripts/decodetree.py'),
1670                        output: 'decode-@BASENAME@.c.inc',
1671                        arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1673 subdir('audio')
1674 subdir('io')
1675 subdir('chardev')
1676 subdir('fsdev')
1677 subdir('libdecnumber')
1678 subdir('target')
1679 subdir('dump')
1681 block_ss.add(files(
1682   'block.c',
1683   'blockjob.c',
1684   'job.c',
1685   'qemu-io-cmds.c',
1687 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1689 subdir('nbd')
1690 subdir('scsi')
1691 subdir('block')
1693 blockdev_ss.add(files(
1694   'blockdev.c',
1695   'blockdev-nbd.c',
1696   'iothread.c',
1697   'job-qmp.c',
1700 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1701 # os-win32.c does not
1702 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1703 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1705 common_ss.add(files('cpus-common.c'))
1707 subdir('softmmu')
1709 common_ss.add(capstone)
1710 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
1711 specific_ss.add(files('exec-vary.c'))
1712 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1713   'fpu/softfloat.c',
1714   'tcg/optimize.c',
1715   'tcg/tcg-common.c',
1716   'tcg/tcg-op-gvec.c',
1717   'tcg/tcg-op-vec.c',
1718   'tcg/tcg-op.c',
1719   'tcg/tcg.c',
1721 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1723 subdir('backends')
1724 subdir('disas')
1725 subdir('migration')
1726 subdir('monitor')
1727 subdir('net')
1728 subdir('replay')
1729 subdir('hw')
1730 subdir('accel')
1731 subdir('plugins')
1732 subdir('bsd-user')
1733 subdir('linux-user')
1735 bsd_user_ss.add(files('gdbstub.c'))
1736 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1738 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1739 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1741 # needed for fuzzing binaries
1742 subdir('tests/qtest/libqos')
1743 subdir('tests/qtest/fuzz')
1745 ########################
1746 # Library dependencies #
1747 ########################
1749 block_mods = []
1750 softmmu_mods = []
1751 foreach d, list : modules
1752   foreach m, module_ss : list
1753     if enable_modules and targetos != 'windows'
1754       module_ss = module_ss.apply(config_all, strict: false)
1755       sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1756                           dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1757       if d == 'block'
1758         block_mods += sl
1759       else
1760         softmmu_mods += sl
1761       endif
1762     else
1763       if d == 'block'
1764         block_ss.add_all(module_ss)
1765       else
1766         softmmu_ss.add_all(module_ss)
1767       endif
1768     endif
1769   endforeach
1770 endforeach
1772 nm = find_program('nm')
1773 undefsym = find_program('scripts/undefsym.py')
1774 block_syms = custom_target('block.syms', output: 'block.syms',
1775                              input: [libqemuutil, block_mods],
1776                              capture: true,
1777                              command: [undefsym, nm, '@INPUT@'])
1778 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1779                              input: [libqemuutil, softmmu_mods],
1780                              capture: true,
1781                              command: [undefsym, nm, '@INPUT@'])
1783 qom_ss = qom_ss.apply(config_host, strict: false)
1784 libqom = static_library('qom', qom_ss.sources() + genh,
1785                         dependencies: [qom_ss.dependencies()],
1786                         name_suffix: 'fa')
1788 qom = declare_dependency(link_whole: libqom)
1790 authz_ss = authz_ss.apply(config_host, strict: false)
1791 libauthz = static_library('authz', authz_ss.sources() + genh,
1792                           dependencies: [authz_ss.dependencies()],
1793                           name_suffix: 'fa',
1794                           build_by_default: false)
1796 authz = declare_dependency(link_whole: libauthz,
1797                            dependencies: qom)
1799 crypto_ss = crypto_ss.apply(config_host, strict: false)
1800 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
1801                            dependencies: [crypto_ss.dependencies()],
1802                            name_suffix: 'fa',
1803                            build_by_default: false)
1805 crypto = declare_dependency(link_whole: libcrypto,
1806                             dependencies: [authz, qom])
1808 io_ss = io_ss.apply(config_host, strict: false)
1809 libio = static_library('io', io_ss.sources() + genh,
1810                        dependencies: [io_ss.dependencies()],
1811                        link_with: libqemuutil,
1812                        name_suffix: 'fa',
1813                        build_by_default: false)
1815 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
1817 libmigration = static_library('migration', sources: migration_files + genh,
1818                               name_suffix: 'fa',
1819                               build_by_default: false)
1820 migration = declare_dependency(link_with: libmigration,
1821                                dependencies: [zlib, qom, io])
1822 softmmu_ss.add(migration)
1824 block_ss = block_ss.apply(config_host, strict: false)
1825 libblock = static_library('block', block_ss.sources() + genh,
1826                           dependencies: block_ss.dependencies(),
1827                           link_depends: block_syms,
1828                           name_suffix: 'fa',
1829                           build_by_default: false)
1831 block = declare_dependency(link_whole: [libblock],
1832                            link_args: '@block.syms',
1833                            dependencies: [crypto, io])
1835 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
1836 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
1837                              dependencies: blockdev_ss.dependencies(),
1838                              name_suffix: 'fa',
1839                              build_by_default: false)
1841 blockdev = declare_dependency(link_whole: [libblockdev],
1842                               dependencies: [block])
1844 qmp_ss = qmp_ss.apply(config_host, strict: false)
1845 libqmp = static_library('qmp', qmp_ss.sources() + genh,
1846                         dependencies: qmp_ss.dependencies(),
1847                         name_suffix: 'fa',
1848                         build_by_default: false)
1850 qmp = declare_dependency(link_whole: [libqmp])
1852 libchardev = static_library('chardev', chardev_ss.sources() + genh,
1853                             name_suffix: 'fa',
1854                             build_by_default: false)
1856 chardev = declare_dependency(link_whole: libchardev)
1858 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
1859                            name_suffix: 'fa',
1860                            build_by_default: false)
1861 hwcore = declare_dependency(link_whole: libhwcore)
1862 common_ss.add(hwcore)
1864 ###########
1865 # Targets #
1866 ###########
1868 foreach m : block_mods + softmmu_mods
1869   shared_module(m.name(),
1870                 name_prefix: '',
1871                 link_whole: m,
1872                 install: true,
1873                 install_dir: qemu_moddir)
1874 endforeach
1876 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
1877 common_ss.add(qom, qemuutil)
1879 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
1880 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
1882 common_all = common_ss.apply(config_all, strict: false)
1883 common_all = static_library('common',
1884                             build_by_default: false,
1885                             sources: common_all.sources() + genh,
1886                             dependencies: common_all.dependencies(),
1887                             name_suffix: 'fa')
1889 feature_to_c = find_program('scripts/feature_to_c.sh')
1891 emulators = {}
1892 foreach target : target_dirs
1893   config_target = config_target_mak[target]
1894   target_name = config_target['TARGET_NAME']
1895   arch = config_target['TARGET_BASE_ARCH']
1896   arch_srcs = [config_target_h[target]]
1897   arch_deps = []
1898   c_args = ['-DNEED_CPU_H',
1899             '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
1900             '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
1901   link_args = emulator_link_args
1903   config_target += config_host
1904   target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
1905   if targetos == 'linux'
1906     target_inc += include_directories('linux-headers', is_system: true)
1907   endif
1908   if target.endswith('-softmmu')
1909     qemu_target_name = 'qemu-system-' + target_name
1910     target_type='system'
1911     t = target_softmmu_arch[arch].apply(config_target, strict: false)
1912     arch_srcs += t.sources()
1913     arch_deps += t.dependencies()
1915     hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
1916     hw = hw_arch[hw_dir].apply(config_target, strict: false)
1917     arch_srcs += hw.sources()
1918     arch_deps += hw.dependencies()
1920     arch_srcs += config_devices_h[target]
1921     link_args += ['@block.syms', '@qemu.syms']
1922   else
1923     abi = config_target['TARGET_ABI_DIR']
1924     target_type='user'
1925     qemu_target_name = 'qemu-' + target_name
1926     if 'CONFIG_LINUX_USER' in config_target
1927       base_dir = 'linux-user'
1928       target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
1929     else
1930       base_dir = 'bsd-user'
1931     endif
1932     target_inc += include_directories(
1933       base_dir,
1934       base_dir / abi,
1935     )
1936     if 'CONFIG_LINUX_USER' in config_target
1937       dir = base_dir / abi
1938       arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
1939       if config_target.has_key('TARGET_SYSTBL_ABI')
1940         arch_srcs += \
1941           syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
1942                                              extra_args : config_target['TARGET_SYSTBL_ABI'])
1943       endif
1944     endif
1945   endif
1947   if 'TARGET_XML_FILES' in config_target
1948     gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
1949                                 output: target + '-gdbstub-xml.c',
1950                                 input: files(config_target['TARGET_XML_FILES'].split()),
1951                                 command: [feature_to_c, '@INPUT@'],
1952                                 capture: true)
1953     arch_srcs += gdbstub_xml
1954   endif
1956   t = target_arch[arch].apply(config_target, strict: false)
1957   arch_srcs += t.sources()
1958   arch_deps += t.dependencies()
1960   target_common = common_ss.apply(config_target, strict: false)
1961   objects = common_all.extract_objects(target_common.sources())
1962   deps = target_common.dependencies()
1964   target_specific = specific_ss.apply(config_target, strict: false)
1965   arch_srcs += target_specific.sources()
1966   arch_deps += target_specific.dependencies()
1968   lib = static_library('qemu-' + target,
1969                  sources: arch_srcs + genh,
1970                  dependencies: arch_deps,
1971                  objects: objects,
1972                  include_directories: target_inc,
1973                  c_args: c_args,
1974                  build_by_default: false,
1975                  name_suffix: 'fa')
1977   if target.endswith('-softmmu')
1978     execs = [{
1979       'name': 'qemu-system-' + target_name,
1980       'gui': false,
1981       'sources': files('softmmu/main.c'),
1982       'dependencies': []
1983     }]
1984     if targetos == 'windows' and (sdl.found() or gtk.found())
1985       execs += [{
1986         'name': 'qemu-system-' + target_name + 'w',
1987         'gui': true,
1988         'sources': files('softmmu/main.c'),
1989         'dependencies': []
1990       }]
1991     endif
1992     if config_host.has_key('CONFIG_FUZZ')
1993       specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
1994       execs += [{
1995         'name': 'qemu-fuzz-' + target_name,
1996         'gui': false,
1997         'sources': specific_fuzz.sources(),
1998         'dependencies': specific_fuzz.dependencies(),
1999       }]
2000     endif
2001   else
2002     execs = [{
2003       'name': 'qemu-' + target_name,
2004       'gui': false,
2005       'sources': [],
2006       'dependencies': []
2007     }]
2008   endif
2009   foreach exe: execs
2010     emulators += {exe['name']:
2011          executable(exe['name'], exe['sources'],
2012                install: true,
2013                c_args: c_args,
2014                dependencies: arch_deps + deps + exe['dependencies'],
2015                objects: lib.extract_all_objects(recursive: true),
2016                link_language: link_language,
2017                link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2018                link_args: link_args,
2019                gui_app: exe['gui'])
2020     }
2022     if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2023       foreach stp: [
2024         {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2025         {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2026         {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2027         {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2028       ]
2029         custom_target(exe['name'] + stp['ext'],
2030                       input: trace_events_all,
2031                       output: exe['name'] + stp['ext'],
2032                       capture: true,
2033                       install: stp['install'],
2034                       install_dir: get_option('datadir') / 'systemtap/tapset',
2035                       command: [
2036                         tracetool, '--group=all', '--format=' + stp['fmt'],
2037                         '--binary=' + stp['bin'],
2038                         '--target-name=' + target_name,
2039                         '--target-type=' + target_type,
2040                         '--probe-prefix=qemu.' + target_type + '.' + target_name,
2041                         '@INPUT@',
2042                       ])
2043       endforeach
2044     endif
2045   endforeach
2046 endforeach
2048 # Other build targets
2050 if 'CONFIG_PLUGIN' in config_host
2051   install_headers('include/qemu/qemu-plugin.h')
2052 endif
2054 if 'CONFIG_GUEST_AGENT' in config_host
2055   subdir('qga')
2056 endif
2058 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2059 # when we don't build tools or system
2060 if xkbcommon.found()
2061   # used for the update-keymaps target, so include rules even if !have_tools
2062   qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2063                            dependencies: [qemuutil, xkbcommon], install: have_tools)
2064 endif
2066 if have_tools
2067   qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2068              dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2069   qemu_io = executable('qemu-io', files('qemu-io.c'),
2070              dependencies: [block, qemuutil], install: true)
2071   qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2072                dependencies: [blockdev, qemuutil], install: true)
2074   subdir('storage-daemon')
2075   subdir('contrib/rdmacm-mux')
2076   subdir('contrib/elf2dmp')
2078   executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2079              dependencies: qemuutil,
2080              install: true)
2082   if 'CONFIG_VHOST_USER' in config_host
2083     subdir('contrib/vhost-user-blk')
2084     subdir('contrib/vhost-user-gpu')
2085     subdir('contrib/vhost-user-input')
2086     subdir('contrib/vhost-user-scsi')
2087   endif
2089   if targetos == 'linux'
2090     executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2091                dependencies: [qemuutil, libcap_ng],
2092                install: true,
2093                install_dir: get_option('libexecdir'))
2095     executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2096                dependencies: [authz, crypto, io, qom, qemuutil,
2097                               libcap_ng, mpathpersist],
2098                install: true)
2099   endif
2101   if 'CONFIG_IVSHMEM' in config_host
2102     subdir('contrib/ivshmem-client')
2103     subdir('contrib/ivshmem-server')
2104   endif
2105 endif
2107 subdir('scripts')
2108 subdir('tools')
2109 subdir('pc-bios')
2110 subdir('docs')
2111 subdir('tests')
2112 if 'CONFIG_GTK' in config_host
2113   subdir('po')
2114 endif
2116 if host_machine.system() == 'windows'
2117   nsis_cmd = [
2118     find_program('scripts/nsis.py'),
2119     '@OUTPUT@',
2120     get_option('prefix'),
2121     meson.current_source_dir(),
2122     host_machine.cpu(),
2123     '--',
2124     '-DDISPLAYVERSION=' + meson.project_version(),
2125   ]
2126   if build_docs
2127     nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2128   endif
2129   if 'CONFIG_GTK' in config_host
2130     nsis_cmd += '-DCONFIG_GTK=y'
2131   endif
2133   nsis = custom_target('nsis',
2134                        output: 'qemu-setup-' + meson.project_version() + '.exe',
2135                        input: files('qemu.nsi'),
2136                        build_always_stale: true,
2137                        command: nsis_cmd + ['@INPUT@'])
2138   alias_target('installer', nsis)
2139 endif
2141 #########################
2142 # Configuration summary #
2143 #########################
2145 summary_info = {}
2146 summary_info += {'Install prefix':    get_option('prefix')}
2147 summary_info += {'BIOS directory':    qemu_datadir}
2148 summary_info += {'firmware path':     get_option('qemu_firmwarepath')}
2149 summary_info += {'binary directory':  get_option('bindir')}
2150 summary_info += {'library directory': get_option('libdir')}
2151 summary_info += {'module directory':  qemu_moddir}
2152 summary_info += {'libexec directory': get_option('libexecdir')}
2153 summary_info += {'include directory': get_option('includedir')}
2154 summary_info += {'config directory':  get_option('sysconfdir')}
2155 if targetos != 'windows'
2156   summary_info += {'local state directory': get_option('localstatedir')}
2157   summary_info += {'Manual directory':      get_option('mandir')}
2158 else
2159   summary_info += {'local state directory': 'queried at runtime'}
2160 endif
2161 summary_info += {'Doc directory':     get_option('docdir')}
2162 summary_info += {'Build directory':   meson.current_build_dir()}
2163 summary_info += {'Source path':       meson.current_source_dir()}
2164 summary_info += {'GIT binary':        config_host['GIT']}
2165 summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
2166 summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
2167 summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
2168 if link_language == 'cpp'
2169   summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
2170 else
2171   summary_info += {'C++ compiler':      false}
2172 endif
2173 if targetos == 'darwin'
2174   summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
2175 endif
2176 summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
2177 summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
2178                                                + ['-O' + get_option('optimization')]
2179                                                + (get_option('debug') ? ['-g'] : []))}
2180 if link_language == 'cpp'
2181   summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
2182                                                + ['-O' + get_option('optimization')]
2183                                                + (get_option('debug') ? ['-g'] : []))}
2184 endif
2185 link_args = get_option(link_language + '_link_args')
2186 if link_args.length() > 0
2187   summary_info += {'LDFLAGS':         ' '.join(link_args)}
2188 endif
2189 summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
2190 summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
2191 summary_info += {'make':              config_host['MAKE']}
2192 summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2193 summary_info += {'sphinx-build':      sphinx_build.found()}
2194 summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
2195 # TODO: add back version
2196 summary_info += {'slirp support':     slirp_opt == 'disabled' ? false : slirp_opt}
2197 if slirp_opt != 'disabled'
2198   summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
2199 endif
2200 summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
2201 if config_host.has_key('CONFIG_MODULES')
2202   summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2203 endif
2204 summary_info += {'host CPU':          cpu}
2205 summary_info += {'host endianness':   build_machine.endian()}
2206 summary_info += {'target list':       ' '.join(target_dirs)}
2207 summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
2208 summary_info += {'sparse enabled':    sparse.found()}
2209 summary_info += {'strip binaries':    get_option('strip')}
2210 summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
2211 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2212 summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
2213 if targetos == 'darwin'
2214   summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
2215 endif
2216 # TODO: add back version
2217 summary_info += {'SDL support':       sdl.found()}
2218 summary_info += {'SDL image support': sdl_image.found()}
2219 # TODO: add back version
2220 summary_info += {'GTK support':       config_host.has_key('CONFIG_GTK')}
2221 summary_info += {'GTK GL support':    config_host.has_key('CONFIG_GTK_GL')}
2222 summary_info += {'pixman':            pixman.found()}
2223 # TODO: add back version
2224 summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
2225 summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
2226 summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
2227 # TODO: add back version
2228 summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
2229 if config_host.has_key('CONFIG_GCRYPT')
2230    summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
2231    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2232 endif
2233 # TODO: add back version
2234 summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
2235 if config_host.has_key('CONFIG_NETTLE')
2236    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2237 endif
2238 summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
2239 summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
2240 summary_info += {'iconv support':     iconv.found()}
2241 summary_info += {'curses support':    curses.found()}
2242 # TODO: add back version
2243 summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
2244 summary_info += {'curl support':      curl.found()}
2245 summary_info += {'mingw32 support':   targetos == 'windows'}
2246 summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
2247 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2248 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2249 summary_info += {'VirtFS support':    config_host.has_key('CONFIG_VIRTFS')}
2250 summary_info += {'build virtiofs daemon': have_virtiofsd}
2251 summary_info += {'Multipath support': mpathpersist.found()}
2252 summary_info += {'VNC support':       vnc.found()}
2253 if vnc.found()
2254   summary_info += {'VNC SASL support':  sasl.found()}
2255   summary_info += {'VNC JPEG support':  jpeg.found()}
2256   summary_info += {'VNC PNG support':   png.found()}
2257 endif
2258 summary_info += {'xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
2259 if config_host.has_key('CONFIG_XEN_BACKEND')
2260   summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2261 endif
2262 summary_info += {'brlapi support':    brlapi.found()}
2263 summary_info += {'Documentation':     build_docs}
2264 summary_info += {'PIE':               get_option('b_pie')}
2265 summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
2266 summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
2267 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2268 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2269 summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
2270 summary_info += {'Install blobs':     get_option('install_blobs')}
2271 summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
2272 summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
2273 summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
2274 summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
2275 summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
2276 if config_all.has_key('CONFIG_TCG')
2277   summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2278   summary_info += {'TCG interpreter':   config_host.has_key('CONFIG_TCG_INTERPRETER')}
2279 endif
2280 summary_info += {'malloc trim support': has_malloc_trim}
2281 summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
2282 summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
2283 summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
2284 summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
2285 summary_info += {'preadv support':    config_host.has_key('CONFIG_PREADV')}
2286 summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
2287 summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
2288 summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
2289 summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2290 summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
2291 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2292 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2293 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2294 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2295 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2296 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2297 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2298 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2299 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2300 summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
2301 if config_host['TRACE_BACKENDS'].split().contains('simple')
2302   summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2303 endif
2304 # TODO: add back protocol and server version
2305 summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
2306 summary_info += {'rbd support':       rbd.found()}
2307 summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
2308 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2309 summary_info += {'U2F support':       u2f.found()}
2310 summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
2311 summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
2312 summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
2313 summary_info += {'OpenGL dmabufs':    config_host.has_key('CONFIG_OPENGL_DMABUF')}
2314 summary_info += {'libiscsi support':  libiscsi.found()}
2315 summary_info += {'libnfs support':    libnfs.found()}
2316 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2317 if targetos == 'windows'
2318   if 'WIN_SDK' in config_host
2319     summary_info += {'Windows SDK':       config_host['WIN_SDK']}
2320   endif
2321   summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
2322   summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2323   summary_info += {'QGA MSI support':   config_host.has_key('CONFIG_QGA_MSI')}
2324 endif
2325 summary_info += {'seccomp support':   config_host.has_key('CONFIG_SECCOMP')}
2326 summary_info += {'CFI support':       get_option('cfi')}
2327 summary_info += {'CFI debug support': get_option('cfi_debug')}
2328 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2329 summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
2330 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2331 summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
2332 summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
2333 summary_info += {'GlusterFS support': glusterfs.found()}
2334 summary_info += {'gcov':              get_option('b_coverage')}
2335 summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
2336 summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
2337 summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2338 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2339 summary_info += {'lzo support':       config_host.has_key('CONFIG_LZO')}
2340 summary_info += {'snappy support':    config_host.has_key('CONFIG_SNAPPY')}
2341 summary_info += {'bzip2 support':     libbzip2.found()}
2342 summary_info += {'lzfse support':     config_host.has_key('CONFIG_LZFSE')}
2343 summary_info += {'zstd support':      config_host.has_key('CONFIG_ZSTD')}
2344 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2345 summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
2346 summary_info += {'memory allocator':  get_option('malloc')}
2347 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2348 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2349 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2350 summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
2351 summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
2352 summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
2353 summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
2354 summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
2355 summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
2356 summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
2357 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2358 summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
2359 summary_info += {'capstone':          capstone_opt == 'disabled' ? false : capstone_opt}
2360 summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
2361 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2362 summary_info += {'libudev':           libudev.found()}
2363 summary_info += {'default devices':   config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
2364 summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
2365 summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
2366 if config_host.has_key('HAVE_GDB_BIN')
2367   summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
2368 endif
2369 summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
2370 summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
2371 summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
2372 summary_info += {'FUSE exports':      fuse.found()}
2373 summary_info += {'FUSE lseek':        fuse_lseek.found()}
2374 summary(summary_info, bool_yn: true)
2376 if not supported_cpus.contains(cpu)
2377   message()
2378   warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2379   message()
2380   message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2381   message('The QEMU project intends to remove support for this host CPU in')
2382   message('a future release if nobody volunteers to maintain it and to')
2383   message('provide a build host for our continuous integration setup.')
2384   message('configure has succeeded and you can continue to build, but')
2385   message('if you care about QEMU on this platform you should contact')
2386   message('us upstream at qemu-devel@nongnu.org.')
2387 endif
2389 if not supported_oses.contains(targetos)
2390   message()
2391   warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2392   message()
2393   message('Host OS ' + targetos + 'support is not currently maintained.')
2394   message('The QEMU project intends to remove support for this host OS in')
2395   message('a future release if nobody volunteers to maintain it and to')
2396   message('provide a build host for our continuous integration setup.')
2397   message('configure has succeeded and you can continue to build, but')
2398   message('if you care about QEMU on this platform you should contact')
2399   message('us upstream at qemu-devel@nongnu.org.')
2400 endif