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