hw/pci: Have safer pcie_bus_realize() by checking error path
[qemu/ar7.git] / meson.build
blob05a67c20d937378c1daed73905fab59015851650
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   'hexagon' : ['CONFIG_HEXAGON_DIS'],
1192   'hppa' : ['CONFIG_HPPA_DIS'],
1193   'i386' : ['CONFIG_I386_DIS'],
1194   'x86_64' : ['CONFIG_I386_DIS'],
1195   'x32' : ['CONFIG_I386_DIS'],
1196   'lm32' : ['CONFIG_LM32_DIS'],
1197   'm68k' : ['CONFIG_M68K_DIS'],
1198   'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1199   'mips' : ['CONFIG_MIPS_DIS'],
1200   'moxie' : ['CONFIG_MOXIE_DIS'],
1201   'nios2' : ['CONFIG_NIOS2_DIS'],
1202   'or1k' : ['CONFIG_OPENRISC_DIS'],
1203   'ppc' : ['CONFIG_PPC_DIS'],
1204   'riscv' : ['CONFIG_RISCV_DIS'],
1205   'rx' : ['CONFIG_RX_DIS'],
1206   's390' : ['CONFIG_S390_DIS'],
1207   'sh4' : ['CONFIG_SH4_DIS'],
1208   'sparc' : ['CONFIG_SPARC_DIS'],
1209   'xtensa' : ['CONFIG_XTENSA_DIS'],
1211 if link_language == 'cpp'
1212   disassemblers += {
1213     'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1214     'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1215     'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1216   }
1217 endif
1219 host_kconfig = \
1220   ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1221   ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
1222   ('CONFIG_IVSHMEM' in config_host ? ['CONFIG_IVSHMEM=y'] : []) + \
1223   ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1224   (x11.found() ? ['CONFIG_X11=y'] : []) + \
1225   ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1226   ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1227   ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1228   (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1229   ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1230   ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
1231   ('CONFIG_MULTIPROCESS_ALLOWED' in config_host ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
1233 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1235 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1236 actual_target_dirs = []
1237 fdt_required = []
1238 foreach target : target_dirs
1239   config_target = { 'TARGET_NAME': target.split('-')[0] }
1240   if target.endswith('linux-user')
1241     if targetos != 'linux'
1242       if default_targets
1243         continue
1244       endif
1245       error('Target @0@ is only available on a Linux host'.format(target))
1246     endif
1247     config_target += { 'CONFIG_LINUX_USER': 'y' }
1248   elif target.endswith('bsd-user')
1249     if 'CONFIG_BSD' not in config_host
1250       if default_targets
1251         continue
1252       endif
1253       error('Target @0@ is only available on a BSD host'.format(target))
1254     endif
1255     config_target += { 'CONFIG_BSD_USER': 'y' }
1256   elif target.endswith('softmmu')
1257     config_target += { 'CONFIG_SOFTMMU': 'y' }
1258   endif
1259   if target.endswith('-user')
1260     config_target += {
1261       'CONFIG_USER_ONLY': 'y',
1262       'CONFIG_QEMU_INTERP_PREFIX':
1263         config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1264     }
1265   endif
1267   accel_kconfig = []
1268   foreach sym: accelerators
1269     if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1270       config_target += { sym: 'y' }
1271       config_all += { sym: 'y' }
1272       if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
1273         config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
1274       elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1275         config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1276       endif
1277       accel_kconfig += [ sym + '=y' ]
1278     endif
1279   endforeach
1280   if accel_kconfig.length() == 0
1281     if default_targets
1282       continue
1283     endif
1284     error('No accelerator available for target @0@'.format(target))
1285   endif
1287   actual_target_dirs += target
1288   config_target += keyval.load('default-configs/targets' / target + '.mak')
1289   config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1291   if 'TARGET_NEED_FDT' in config_target
1292     fdt_required += target
1293   endif
1295   # Add default keys
1296   if 'TARGET_BASE_ARCH' not in config_target
1297     config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1298   endif
1299   if 'TARGET_ABI_DIR' not in config_target
1300     config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1301   endif
1303   foreach k, v: disassemblers
1304     if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1305       foreach sym: v
1306         config_target += { sym: 'y' }
1307         config_all_disas += { sym: 'y' }
1308       endforeach
1309     endif
1310   endforeach
1312   config_target_data = configuration_data()
1313   foreach k, v: config_target
1314     if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1315       # do nothing
1316     elif ignored.contains(k)
1317       # do nothing
1318     elif k == 'TARGET_BASE_ARCH'
1319       # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1320       # not used to select files from sourcesets.
1321       config_target_data.set('TARGET_' + v.to_upper(), 1)
1322     elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1323       config_target_data.set_quoted(k, v)
1324     elif v == 'y'
1325       config_target_data.set(k, 1)
1326     else
1327       config_target_data.set(k, v)
1328     endif
1329   endforeach
1330   config_target_h += {target: configure_file(output: target + '-config-target.h',
1331                                                configuration: config_target_data)}
1333   if target.endswith('-softmmu')
1334     config_devices_mak = target + '-config-devices.mak'
1335     config_devices_mak = configure_file(
1336       input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
1337       output: config_devices_mak,
1338       depfile: config_devices_mak + '.d',
1339       capture: true,
1340       command: [minikconf,
1341                 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1342                 config_devices_mak, '@DEPFILE@', '@INPUT@',
1343                 host_kconfig, accel_kconfig])
1345     config_devices_data = configuration_data()
1346     config_devices = keyval.load(config_devices_mak)
1347     foreach k, v: config_devices
1348       config_devices_data.set(k, 1)
1349     endforeach
1350     config_devices_mak_list += config_devices_mak
1351     config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1352                                                 configuration: config_devices_data)}
1353     config_target += config_devices
1354     config_all_devices += config_devices
1355   endif
1356   config_target_mak += {target: config_target}
1357 endforeach
1358 target_dirs = actual_target_dirs
1360 # This configuration is used to build files that are shared by
1361 # multiple binaries, and then extracted out of the "common"
1362 # static_library target.
1364 # We do not use all_sources()/all_dependencies(), because it would
1365 # build literally all source files, including devices only used by
1366 # targets that are not built for this compilation.  The CONFIG_ALL
1367 # pseudo symbol replaces it.
1369 config_all += config_all_devices
1370 config_all += config_host
1371 config_all += config_all_disas
1372 config_all += {
1373   'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1374   'CONFIG_SOFTMMU': have_system,
1375   'CONFIG_USER_ONLY': have_user,
1376   'CONFIG_ALL': true,
1379 ##############
1380 # Submodules #
1381 ##############
1383 capstone = not_found
1384 capstone_opt = get_option('capstone')
1385 if capstone_opt in ['enabled', 'auto', 'system']
1386   have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1387   capstone = dependency('capstone', version: '>=4.0',
1388                         kwargs: static_kwargs, method: 'pkg-config',
1389                         required: capstone_opt == 'system' or
1390                                   capstone_opt == 'enabled' and not have_internal)
1391   if capstone.found()
1392     capstone_opt = 'system'
1393   elif have_internal
1394     capstone_opt = 'internal'
1395   else
1396     capstone_opt = 'disabled'
1397   endif
1398 endif
1399 if capstone_opt == 'internal'
1400   capstone_data = configuration_data()
1401   capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1403   capstone_files = files(
1404     'capstone/cs.c',
1405     'capstone/MCInst.c',
1406     'capstone/MCInstrDesc.c',
1407     'capstone/MCRegisterInfo.c',
1408     'capstone/SStream.c',
1409     'capstone/utils.c'
1410   )
1412   if 'CONFIG_ARM_DIS' in config_all_disas
1413     capstone_data.set('CAPSTONE_HAS_ARM', '1')
1414     capstone_files += files(
1415       'capstone/arch/ARM/ARMDisassembler.c',
1416       'capstone/arch/ARM/ARMInstPrinter.c',
1417       'capstone/arch/ARM/ARMMapping.c',
1418       'capstone/arch/ARM/ARMModule.c'
1419     )
1420   endif
1422   # FIXME: This config entry currently depends on a c++ compiler.
1423   # Which is needed for building libvixl, but not for capstone.
1424   if 'CONFIG_ARM_A64_DIS' in config_all_disas
1425     capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1426     capstone_files += files(
1427       'capstone/arch/AArch64/AArch64BaseInfo.c',
1428       'capstone/arch/AArch64/AArch64Disassembler.c',
1429       'capstone/arch/AArch64/AArch64InstPrinter.c',
1430       'capstone/arch/AArch64/AArch64Mapping.c',
1431       'capstone/arch/AArch64/AArch64Module.c'
1432     )
1433   endif
1435   if 'CONFIG_PPC_DIS' in config_all_disas
1436     capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1437     capstone_files += files(
1438       'capstone/arch/PowerPC/PPCDisassembler.c',
1439       'capstone/arch/PowerPC/PPCInstPrinter.c',
1440       'capstone/arch/PowerPC/PPCMapping.c',
1441       'capstone/arch/PowerPC/PPCModule.c'
1442     )
1443   endif
1445   if 'CONFIG_S390_DIS' in config_all_disas
1446     capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1447     capstone_files += files(
1448       'capstone/arch/SystemZ/SystemZDisassembler.c',
1449       'capstone/arch/SystemZ/SystemZInstPrinter.c',
1450       'capstone/arch/SystemZ/SystemZMapping.c',
1451       'capstone/arch/SystemZ/SystemZModule.c',
1452       'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1453     )
1454   endif
1456   if 'CONFIG_I386_DIS' in config_all_disas
1457     capstone_data.set('CAPSTONE_HAS_X86', 1)
1458     capstone_files += files(
1459       'capstone/arch/X86/X86Disassembler.c',
1460       'capstone/arch/X86/X86DisassemblerDecoder.c',
1461       'capstone/arch/X86/X86ATTInstPrinter.c',
1462       'capstone/arch/X86/X86IntelInstPrinter.c',
1463       'capstone/arch/X86/X86InstPrinterCommon.c',
1464       'capstone/arch/X86/X86Mapping.c',
1465       'capstone/arch/X86/X86Module.c'
1466     )
1467   endif
1469   configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1471   capstone_cargs = [
1472     # FIXME: There does not seem to be a way to completely replace the c_args
1473     # that come from add_project_arguments() -- we can only add to them.
1474     # So: disable all warnings with a big hammer.
1475     '-Wno-error', '-w',
1477     # Include all configuration defines via a header file, which will wind up
1478     # as a dependency on the object file, and thus changes here will result
1479     # in a rebuild.
1480     '-include', 'capstone-defs.h'
1481   ]
1483   libcapstone = static_library('capstone',
1484                                build_by_default: false,
1485                                sources: capstone_files,
1486                                c_args: capstone_cargs,
1487                                include_directories: 'capstone/include')
1488   capstone = declare_dependency(link_with: libcapstone,
1489                                 include_directories: 'capstone/include/capstone')
1490 endif
1492 slirp = not_found
1493 slirp_opt = 'disabled'
1494 if have_system
1495   slirp_opt = get_option('slirp')
1496   if slirp_opt in ['enabled', 'auto', 'system']
1497     have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1498     slirp = dependency('slirp', kwargs: static_kwargs,
1499                        method: 'pkg-config',
1500                        required: slirp_opt == 'system' or
1501                                  slirp_opt == 'enabled' and not have_internal)
1502     if slirp.found()
1503       slirp_opt = 'system'
1504     elif have_internal
1505       slirp_opt = 'internal'
1506     else
1507       slirp_opt = 'disabled'
1508     endif
1509   endif
1510   if slirp_opt == 'internal'
1511     slirp_deps = []
1512     if targetos == 'windows'
1513       slirp_deps = cc.find_library('iphlpapi')
1514     endif
1515     slirp_conf = configuration_data()
1516     slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1517     slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1518     slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1519     slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1520     slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1521     slirp_files = [
1522       'slirp/src/arp_table.c',
1523       'slirp/src/bootp.c',
1524       'slirp/src/cksum.c',
1525       'slirp/src/dhcpv6.c',
1526       'slirp/src/dnssearch.c',
1527       'slirp/src/if.c',
1528       'slirp/src/ip6_icmp.c',
1529       'slirp/src/ip6_input.c',
1530       'slirp/src/ip6_output.c',
1531       'slirp/src/ip_icmp.c',
1532       'slirp/src/ip_input.c',
1533       'slirp/src/ip_output.c',
1534       'slirp/src/mbuf.c',
1535       'slirp/src/misc.c',
1536       'slirp/src/ncsi.c',
1537       'slirp/src/ndp_table.c',
1538       'slirp/src/sbuf.c',
1539       'slirp/src/slirp.c',
1540       'slirp/src/socket.c',
1541       'slirp/src/state.c',
1542       'slirp/src/stream.c',
1543       'slirp/src/tcp_input.c',
1544       'slirp/src/tcp_output.c',
1545       'slirp/src/tcp_subr.c',
1546       'slirp/src/tcp_timer.c',
1547       'slirp/src/tftp.c',
1548       'slirp/src/udp.c',
1549       'slirp/src/udp6.c',
1550       'slirp/src/util.c',
1551       'slirp/src/version.c',
1552       'slirp/src/vmstate.c',
1553     ]
1555     configure_file(
1556       input : 'slirp/src/libslirp-version.h.in',
1557       output : 'libslirp-version.h',
1558       configuration: slirp_conf)
1560     slirp_inc = include_directories('slirp', 'slirp/src')
1561     libslirp = static_library('slirp',
1562                               build_by_default: false,
1563                               sources: slirp_files,
1564                               c_args: slirp_cargs,
1565                               include_directories: slirp_inc)
1566     slirp = declare_dependency(link_with: libslirp,
1567                                dependencies: slirp_deps,
1568                                include_directories: slirp_inc)
1569   endif
1570 endif
1572 fdt = not_found
1573 fdt_opt = get_option('fdt')
1574 if have_system
1575   if fdt_opt in ['enabled', 'auto', 'system']
1576     have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1577     fdt = cc.find_library('fdt', kwargs: static_kwargs,
1578                           required: fdt_opt == 'system' or
1579                                     fdt_opt == 'enabled' and not have_internal)
1580     if fdt.found() and cc.links('''
1581        #include <libfdt.h>
1582        #include <libfdt_env.h>
1583        int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1584          dependencies: fdt)
1585       fdt_opt = 'system'
1586     elif have_internal
1587       fdt_opt = 'internal'
1588     else
1589       fdt_opt = 'disabled'
1590     endif
1591   endif
1592   if fdt_opt == 'internal'
1593     fdt_files = files(
1594       'dtc/libfdt/fdt.c',
1595       'dtc/libfdt/fdt_ro.c',
1596       'dtc/libfdt/fdt_wip.c',
1597       'dtc/libfdt/fdt_sw.c',
1598       'dtc/libfdt/fdt_rw.c',
1599       'dtc/libfdt/fdt_strerror.c',
1600       'dtc/libfdt/fdt_empty_tree.c',
1601       'dtc/libfdt/fdt_addresses.c',
1602       'dtc/libfdt/fdt_overlay.c',
1603       'dtc/libfdt/fdt_check.c',
1604     )
1606     fdt_inc = include_directories('dtc/libfdt')
1607     libfdt = static_library('fdt',
1608                             build_by_default: false,
1609                             sources: fdt_files,
1610                             include_directories: fdt_inc)
1611     fdt = declare_dependency(link_with: libfdt,
1612                              include_directories: fdt_inc)
1613   endif
1614 endif
1615 if not fdt.found() and fdt_required.length() > 0
1616   error('fdt not available but required by targets ' + ', '.join(fdt_required))
1617 endif
1619 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1620 config_host_data.set('CONFIG_FDT', fdt.found())
1621 config_host_data.set('CONFIG_SLIRP', slirp.found())
1623 #####################
1624 # Generated sources #
1625 #####################
1627 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1629 hxtool = find_program('scripts/hxtool')
1630 shaderinclude = find_program('scripts/shaderinclude.pl')
1631 qapi_gen = find_program('scripts/qapi-gen.py')
1632 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1633                      meson.source_root() / 'scripts/qapi/commands.py',
1634                      meson.source_root() / 'scripts/qapi/common.py',
1635                      meson.source_root() / 'scripts/qapi/error.py',
1636                      meson.source_root() / 'scripts/qapi/events.py',
1637                      meson.source_root() / 'scripts/qapi/expr.py',
1638                      meson.source_root() / 'scripts/qapi/gen.py',
1639                      meson.source_root() / 'scripts/qapi/introspect.py',
1640                      meson.source_root() / 'scripts/qapi/parser.py',
1641                      meson.source_root() / 'scripts/qapi/schema.py',
1642                      meson.source_root() / 'scripts/qapi/source.py',
1643                      meson.source_root() / 'scripts/qapi/types.py',
1644                      meson.source_root() / 'scripts/qapi/visit.py',
1645                      meson.source_root() / 'scripts/qapi/common.py',
1646                      meson.source_root() / 'scripts/qapi-gen.py'
1649 tracetool = [
1650   python, files('scripts/tracetool.py'),
1651    '--backend=' + config_host['TRACE_BACKENDS']
1653 tracetool_depends = files(
1654   'scripts/tracetool/backend/log.py',
1655   'scripts/tracetool/backend/__init__.py',
1656   'scripts/tracetool/backend/dtrace.py',
1657   'scripts/tracetool/backend/ftrace.py',
1658   'scripts/tracetool/backend/simple.py',
1659   'scripts/tracetool/backend/syslog.py',
1660   'scripts/tracetool/backend/ust.py',
1661   'scripts/tracetool/format/tcg_h.py',
1662   'scripts/tracetool/format/ust_events_c.py',
1663   'scripts/tracetool/format/ust_events_h.py',
1664   'scripts/tracetool/format/__init__.py',
1665   'scripts/tracetool/format/d.py',
1666   'scripts/tracetool/format/tcg_helper_c.py',
1667   'scripts/tracetool/format/simpletrace_stap.py',
1668   'scripts/tracetool/format/c.py',
1669   'scripts/tracetool/format/h.py',
1670   'scripts/tracetool/format/tcg_helper_h.py',
1671   'scripts/tracetool/format/log_stap.py',
1672   'scripts/tracetool/format/stap.py',
1673   'scripts/tracetool/format/tcg_helper_wrapper_h.py',
1674   'scripts/tracetool/__init__.py',
1675   'scripts/tracetool/transform.py',
1676   'scripts/tracetool/vcpu.py'
1679 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1680                     meson.current_source_dir(),
1681                     config_host['PKGVERSION'], meson.project_version()]
1682 qemu_version = custom_target('qemu-version.h',
1683                              output: 'qemu-version.h',
1684                              command: qemu_version_cmd,
1685                              capture: true,
1686                              build_by_default: true,
1687                              build_always_stale: true)
1688 genh += qemu_version
1690 hxdep = []
1691 hx_headers = [
1692   ['qemu-options.hx', 'qemu-options.def'],
1693   ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1695 if have_system
1696   hx_headers += [
1697     ['hmp-commands.hx', 'hmp-commands.h'],
1698     ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1699   ]
1700 endif
1701 foreach d : hx_headers
1702   hxdep += custom_target(d[1],
1703                 input: files(d[0]),
1704                 output: d[1],
1705                 capture: true,
1706                 build_by_default: true, # to be removed when added to a target
1707                 command: [hxtool, '-h', '@INPUT0@'])
1708 endforeach
1709 genh += hxdep
1711 ###################
1712 # Collect sources #
1713 ###################
1715 authz_ss = ss.source_set()
1716 blockdev_ss = ss.source_set()
1717 block_ss = ss.source_set()
1718 bsd_user_ss = ss.source_set()
1719 chardev_ss = ss.source_set()
1720 common_ss = ss.source_set()
1721 crypto_ss = ss.source_set()
1722 io_ss = ss.source_set()
1723 linux_user_ss = ss.source_set()
1724 qmp_ss = ss.source_set()
1725 qom_ss = ss.source_set()
1726 softmmu_ss = ss.source_set()
1727 specific_fuzz_ss = ss.source_set()
1728 specific_ss = ss.source_set()
1729 stub_ss = ss.source_set()
1730 trace_ss = ss.source_set()
1731 user_ss = ss.source_set()
1732 util_ss = ss.source_set()
1734 modules = {}
1735 hw_arch = {}
1736 target_arch = {}
1737 target_softmmu_arch = {}
1739 ###############
1740 # Trace files #
1741 ###############
1743 # TODO: add each directory to the subdirs from its own meson.build, once
1744 # we have those
1745 trace_events_subdirs = [
1746   'crypto',
1747   'qapi',
1748   'qom',
1749   'monitor',
1750   'util',
1752 if have_user
1753   trace_events_subdirs += [ 'linux-user' ]
1754 endif
1755 if have_block
1756   trace_events_subdirs += [
1757     'authz',
1758     'block',
1759     'io',
1760     'nbd',
1761     'scsi',
1762   ]
1763 endif
1764 if have_system
1765   trace_events_subdirs += [
1766     'accel/kvm',
1767     'audio',
1768     'backends',
1769     'backends/tpm',
1770     'chardev',
1771     'hw/9pfs',
1772     'hw/acpi',
1773     'hw/adc',
1774     'hw/alpha',
1775     'hw/arm',
1776     'hw/audio',
1777     'hw/block',
1778     'hw/block/dataplane',
1779     'hw/char',
1780     'hw/display',
1781     'hw/dma',
1782     'hw/hppa',
1783     'hw/hyperv',
1784     'hw/i2c',
1785     'hw/i386',
1786     'hw/i386/xen',
1787     'hw/ide',
1788     'hw/input',
1789     'hw/intc',
1790     'hw/isa',
1791     'hw/mem',
1792     'hw/mips',
1793     'hw/misc',
1794     'hw/misc/macio',
1795     'hw/net',
1796     'hw/net/can',
1797     'hw/nvram',
1798     'hw/pci',
1799     'hw/pci-host',
1800     'hw/ppc',
1801     'hw/rdma',
1802     'hw/rdma/vmw',
1803     'hw/rtc',
1804     'hw/s390x',
1805     'hw/scsi',
1806     'hw/sd',
1807     'hw/sparc',
1808     'hw/sparc64',
1809     'hw/ssi',
1810     'hw/timer',
1811     'hw/tpm',
1812     'hw/usb',
1813     'hw/vfio',
1814     'hw/virtio',
1815     'hw/watchdog',
1816     'hw/xen',
1817     'hw/gpio',
1818     'migration',
1819     'net',
1820     'softmmu',
1821     'ui',
1822     'hw/remote',
1823   ]
1824 endif
1825 if have_system or have_user
1826   trace_events_subdirs += [
1827     'accel/tcg',
1828     'hw/core',
1829     'target/arm',
1830     'target/hppa',
1831     'target/i386',
1832     'target/i386/kvm',
1833     'target/mips',
1834     'target/ppc',
1835     'target/riscv',
1836     'target/s390x',
1837     'target/sparc',
1838   ]
1839 endif
1841 vhost_user = not_found
1842 if 'CONFIG_VHOST_USER' in config_host
1843   libvhost_user = subproject('libvhost-user')
1844   vhost_user = libvhost_user.get_variable('vhost_user_dep')
1845 endif
1847 subdir('qapi')
1848 subdir('qobject')
1849 subdir('stubs')
1850 subdir('trace')
1851 subdir('util')
1852 subdir('qom')
1853 subdir('authz')
1854 subdir('crypto')
1855 subdir('ui')
1858 if enable_modules
1859   libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1860   modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1861 endif
1863 stub_ss = stub_ss.apply(config_all, strict: false)
1865 util_ss.add_all(trace_ss)
1866 util_ss = util_ss.apply(config_all, strict: false)
1867 libqemuutil = static_library('qemuutil',
1868                              sources: util_ss.sources() + stub_ss.sources() + genh,
1869                              dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1870 qemuutil = declare_dependency(link_with: libqemuutil,
1871                               sources: genh + version_res)
1873 if have_system or have_user
1874   decodetree = generator(find_program('scripts/decodetree.py'),
1875                          output: 'decode-@BASENAME@.c.inc',
1876                          arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1877   subdir('libdecnumber')
1878   subdir('target')
1879 endif
1881 subdir('audio')
1882 subdir('io')
1883 subdir('chardev')
1884 subdir('fsdev')
1885 subdir('dump')
1887 if have_block
1888   block_ss.add(files(
1889     'block.c',
1890     'blockjob.c',
1891     'job.c',
1892     'qemu-io-cmds.c',
1893   ))
1894   block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1896   subdir('nbd')
1897   subdir('scsi')
1898   subdir('block')
1900   blockdev_ss.add(files(
1901     'blockdev.c',
1902     'blockdev-nbd.c',
1903     'iothread.c',
1904     'job-qmp.c',
1905   ), gnutls)
1907   # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1908   # os-win32.c does not
1909   blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1910   softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1911 endif
1913 common_ss.add(files('cpus-common.c'))
1915 subdir('softmmu')
1917 common_ss.add(capstone)
1918 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
1919 specific_ss.add(files('exec-vary.c'))
1920 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1921   'fpu/softfloat.c',
1922   'tcg/optimize.c',
1923   'tcg/tcg-common.c',
1924   'tcg/tcg-op-gvec.c',
1925   'tcg/tcg-op-vec.c',
1926   'tcg/tcg-op.c',
1927   'tcg/tcg.c',
1929 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1931 subdir('backends')
1932 subdir('disas')
1933 subdir('migration')
1934 subdir('monitor')
1935 subdir('net')
1936 subdir('replay')
1937 subdir('hw')
1938 subdir('accel')
1939 subdir('plugins')
1940 subdir('bsd-user')
1941 subdir('linux-user')
1943 bsd_user_ss.add(files('gdbstub.c'))
1944 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1946 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1947 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1949 # needed for fuzzing binaries
1950 subdir('tests/qtest/libqos')
1951 subdir('tests/qtest/fuzz')
1953 ########################
1954 # Library dependencies #
1955 ########################
1957 block_mods = []
1958 softmmu_mods = []
1959 foreach d, list : modules
1960   foreach m, module_ss : list
1961     if enable_modules and targetos != 'windows'
1962       module_ss = module_ss.apply(config_all, strict: false)
1963       sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1964                           dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1965       if d == 'block'
1966         block_mods += sl
1967       else
1968         softmmu_mods += sl
1969       endif
1970     else
1971       if d == 'block'
1972         block_ss.add_all(module_ss)
1973       else
1974         softmmu_ss.add_all(module_ss)
1975       endif
1976     endif
1977   endforeach
1978 endforeach
1980 nm = find_program('nm')
1981 undefsym = find_program('scripts/undefsym.py')
1982 block_syms = custom_target('block.syms', output: 'block.syms',
1983                              input: [libqemuutil, block_mods],
1984                              capture: true,
1985                              command: [undefsym, nm, '@INPUT@'])
1986 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1987                              input: [libqemuutil, softmmu_mods],
1988                              capture: true,
1989                              command: [undefsym, nm, '@INPUT@'])
1991 qom_ss = qom_ss.apply(config_host, strict: false)
1992 libqom = static_library('qom', qom_ss.sources() + genh,
1993                         dependencies: [qom_ss.dependencies()],
1994                         name_suffix: 'fa')
1996 qom = declare_dependency(link_whole: libqom)
1998 authz_ss = authz_ss.apply(config_host, strict: false)
1999 libauthz = static_library('authz', authz_ss.sources() + genh,
2000                           dependencies: [authz_ss.dependencies()],
2001                           name_suffix: 'fa',
2002                           build_by_default: false)
2004 authz = declare_dependency(link_whole: libauthz,
2005                            dependencies: qom)
2007 crypto_ss = crypto_ss.apply(config_host, strict: false)
2008 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2009                            dependencies: [crypto_ss.dependencies()],
2010                            name_suffix: 'fa',
2011                            build_by_default: false)
2013 crypto = declare_dependency(link_whole: libcrypto,
2014                             dependencies: [authz, qom])
2016 io_ss = io_ss.apply(config_host, strict: false)
2017 libio = static_library('io', io_ss.sources() + genh,
2018                        dependencies: [io_ss.dependencies()],
2019                        link_with: libqemuutil,
2020                        name_suffix: 'fa',
2021                        build_by_default: false)
2023 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2025 libmigration = static_library('migration', sources: migration_files + genh,
2026                               name_suffix: 'fa',
2027                               build_by_default: false)
2028 migration = declare_dependency(link_with: libmigration,
2029                                dependencies: [zlib, qom, io])
2030 softmmu_ss.add(migration)
2032 block_ss = block_ss.apply(config_host, strict: false)
2033 libblock = static_library('block', block_ss.sources() + genh,
2034                           dependencies: block_ss.dependencies(),
2035                           link_depends: block_syms,
2036                           name_suffix: 'fa',
2037                           build_by_default: false)
2039 block = declare_dependency(link_whole: [libblock],
2040                            link_args: '@block.syms',
2041                            dependencies: [crypto, io])
2043 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2044 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2045                              dependencies: blockdev_ss.dependencies(),
2046                              name_suffix: 'fa',
2047                              build_by_default: false)
2049 blockdev = declare_dependency(link_whole: [libblockdev],
2050                               dependencies: [block])
2052 qmp_ss = qmp_ss.apply(config_host, strict: false)
2053 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2054                         dependencies: qmp_ss.dependencies(),
2055                         name_suffix: 'fa',
2056                         build_by_default: false)
2058 qmp = declare_dependency(link_whole: [libqmp])
2060 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2061                             name_suffix: 'fa',
2062                             dependencies: [gnutls],
2063                             build_by_default: false)
2065 chardev = declare_dependency(link_whole: libchardev)
2067 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
2068                            name_suffix: 'fa',
2069                            build_by_default: false)
2070 hwcore = declare_dependency(link_whole: libhwcore)
2071 common_ss.add(hwcore)
2073 ###########
2074 # Targets #
2075 ###########
2077 foreach m : block_mods + softmmu_mods
2078   shared_module(m.name(),
2079                 name_prefix: '',
2080                 link_whole: m,
2081                 install: true,
2082                 install_dir: qemu_moddir)
2083 endforeach
2085 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2086 common_ss.add(qom, qemuutil)
2088 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2089 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2091 common_all = common_ss.apply(config_all, strict: false)
2092 common_all = static_library('common',
2093                             build_by_default: false,
2094                             sources: common_all.sources() + genh,
2095                             dependencies: common_all.dependencies(),
2096                             name_suffix: 'fa')
2098 feature_to_c = find_program('scripts/feature_to_c.sh')
2100 emulators = {}
2101 foreach target : target_dirs
2102   config_target = config_target_mak[target]
2103   target_name = config_target['TARGET_NAME']
2104   arch = config_target['TARGET_BASE_ARCH']
2105   arch_srcs = [config_target_h[target]]
2106   arch_deps = []
2107   c_args = ['-DNEED_CPU_H',
2108             '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2109             '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2110   link_args = emulator_link_args
2112   config_target += config_host
2113   target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2114   if targetos == 'linux'
2115     target_inc += include_directories('linux-headers', is_system: true)
2116   endif
2117   if target.endswith('-softmmu')
2118     qemu_target_name = 'qemu-system-' + target_name
2119     target_type='system'
2120     t = target_softmmu_arch[arch].apply(config_target, strict: false)
2121     arch_srcs += t.sources()
2122     arch_deps += t.dependencies()
2124     hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2125     hw = hw_arch[hw_dir].apply(config_target, strict: false)
2126     arch_srcs += hw.sources()
2127     arch_deps += hw.dependencies()
2129     arch_srcs += config_devices_h[target]
2130     link_args += ['@block.syms', '@qemu.syms']
2131   else
2132     abi = config_target['TARGET_ABI_DIR']
2133     target_type='user'
2134     qemu_target_name = 'qemu-' + target_name
2135     if 'CONFIG_LINUX_USER' in config_target
2136       base_dir = 'linux-user'
2137       target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2138     else
2139       base_dir = 'bsd-user'
2140       target_inc += include_directories('bsd-user/freebsd')
2141     endif
2142     target_inc += include_directories(
2143       base_dir,
2144       base_dir / abi,
2145     )
2146     if 'CONFIG_LINUX_USER' in config_target
2147       dir = base_dir / abi
2148       arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2149       if config_target.has_key('TARGET_SYSTBL_ABI')
2150         arch_srcs += \
2151           syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2152                                              extra_args : config_target['TARGET_SYSTBL_ABI'])
2153       endif
2154     endif
2155   endif
2157   if 'TARGET_XML_FILES' in config_target
2158     gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2159                                 output: target + '-gdbstub-xml.c',
2160                                 input: files(config_target['TARGET_XML_FILES'].split()),
2161                                 command: [feature_to_c, '@INPUT@'],
2162                                 capture: true)
2163     arch_srcs += gdbstub_xml
2164   endif
2166   t = target_arch[arch].apply(config_target, strict: false)
2167   arch_srcs += t.sources()
2168   arch_deps += t.dependencies()
2170   target_common = common_ss.apply(config_target, strict: false)
2171   objects = common_all.extract_objects(target_common.sources())
2172   deps = target_common.dependencies()
2174   target_specific = specific_ss.apply(config_target, strict: false)
2175   arch_srcs += target_specific.sources()
2176   arch_deps += target_specific.dependencies()
2178   lib = static_library('qemu-' + target,
2179                  sources: arch_srcs + genh,
2180                  dependencies: arch_deps,
2181                  objects: objects,
2182                  include_directories: target_inc,
2183                  c_args: c_args,
2184                  build_by_default: false,
2185                  name_suffix: 'fa')
2187   if target.endswith('-softmmu')
2188     execs = [{
2189       'name': 'qemu-system-' + target_name,
2190       'gui': false,
2191       'sources': files('softmmu/main.c'),
2192       'dependencies': []
2193     }]
2194     if targetos == 'windows' and (sdl.found() or gtk.found())
2195       execs += [{
2196         'name': 'qemu-system-' + target_name + 'w',
2197         'gui': true,
2198         'sources': files('softmmu/main.c'),
2199         'dependencies': []
2200       }]
2201     endif
2202     if config_host.has_key('CONFIG_FUZZ')
2203       specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2204       execs += [{
2205         'name': 'qemu-fuzz-' + target_name,
2206         'gui': false,
2207         'sources': specific_fuzz.sources(),
2208         'dependencies': specific_fuzz.dependencies(),
2209       }]
2210     endif
2211   else
2212     execs = [{
2213       'name': 'qemu-' + target_name,
2214       'gui': false,
2215       'sources': [],
2216       'dependencies': []
2217     }]
2218   endif
2219   foreach exe: execs
2220     exe_name = exe['name']
2221     exe_sign = 'CONFIG_HVF' in config_target
2222     if exe_sign
2223       exe_name += '-unsigned'
2224     endif
2226     emulator = executable(exe_name, exe['sources'],
2227                install: not exe_sign,
2228                c_args: c_args,
2229                dependencies: arch_deps + deps + exe['dependencies'],
2230                objects: lib.extract_all_objects(recursive: true),
2231                link_language: link_language,
2232                link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2233                link_args: link_args,
2234                gui_app: exe['gui'])
2236     if exe_sign
2237       emulators += {exe['name'] : custom_target(exe['name'],
2238                    install: true,
2239                    install_dir: get_option('bindir'),
2240                    depends: emulator,
2241                    output: exe['name'],
2242                    command: [
2243                      meson.current_source_dir() / 'scripts/entitlement.sh',
2244                      meson.current_build_dir() / exe_name,
2245                      meson.current_build_dir() / exe['name'],
2246                      meson.current_source_dir() / 'accel/hvf/entitlements.plist'
2247                    ])
2248       }
2249     else
2250       emulators += {exe['name']: emulator}
2251     endif
2253     if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2254       foreach stp: [
2255         {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2256         {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2257         {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2258         {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2259       ]
2260         custom_target(exe['name'] + stp['ext'],
2261                       input: trace_events_all,
2262                       output: exe['name'] + stp['ext'],
2263                       install: stp['install'],
2264                       install_dir: get_option('datadir') / 'systemtap/tapset',
2265                       command: [
2266                         tracetool, '--group=all', '--format=' + stp['fmt'],
2267                         '--binary=' + stp['bin'],
2268                         '--target-name=' + target_name,
2269                         '--target-type=' + target_type,
2270                         '--probe-prefix=qemu.' + target_type + '.' + target_name,
2271                         '@INPUT@', '@OUTPUT@'
2272                       ],
2273                       depend_files: tracetool_depends)
2274       endforeach
2275     endif
2276   endforeach
2277 endforeach
2279 # Other build targets
2281 if 'CONFIG_PLUGIN' in config_host
2282   install_headers('include/qemu/qemu-plugin.h')
2283 endif
2285 if 'CONFIG_GUEST_AGENT' in config_host
2286   subdir('qga')
2287 elif get_option('guest_agent_msi').enabled()
2288   error('Guest agent MSI requested, but the guest agent is not being built')
2289 endif
2291 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2292 # when we don't build tools or system
2293 if xkbcommon.found()
2294   # used for the update-keymaps target, so include rules even if !have_tools
2295   qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2296                            dependencies: [qemuutil, xkbcommon], install: have_tools)
2297 endif
2299 if have_tools
2300   qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2301              dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2302   qemu_io = executable('qemu-io', files('qemu-io.c'),
2303              dependencies: [block, qemuutil], install: true)
2304   qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2305                dependencies: [blockdev, qemuutil, gnutls], install: true)
2307   subdir('storage-daemon')
2308   subdir('contrib/rdmacm-mux')
2309   subdir('contrib/elf2dmp')
2311   executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2312              dependencies: qemuutil,
2313              install: true)
2315   if 'CONFIG_VHOST_USER' in config_host
2316     subdir('contrib/vhost-user-blk')
2317     subdir('contrib/vhost-user-gpu')
2318     subdir('contrib/vhost-user-input')
2319     subdir('contrib/vhost-user-scsi')
2320   endif
2322   if targetos == 'linux'
2323     executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2324                dependencies: [qemuutil, libcap_ng],
2325                install: true,
2326                install_dir: get_option('libexecdir'))
2328     executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2329                dependencies: [authz, crypto, io, qom, qemuutil,
2330                               libcap_ng, mpathpersist],
2331                install: true)
2332   endif
2334   if 'CONFIG_IVSHMEM' in config_host
2335     subdir('contrib/ivshmem-client')
2336     subdir('contrib/ivshmem-server')
2337   endif
2338 endif
2340 subdir('scripts')
2341 subdir('tools')
2342 subdir('pc-bios')
2343 subdir('docs')
2344 subdir('tests')
2345 if gtk.found()
2346   subdir('po')
2347 endif
2349 if host_machine.system() == 'windows'
2350   nsis_cmd = [
2351     find_program('scripts/nsis.py'),
2352     '@OUTPUT@',
2353     get_option('prefix'),
2354     meson.current_source_dir(),
2355     host_machine.cpu(),
2356     '--',
2357     '-DDISPLAYVERSION=' + meson.project_version(),
2358   ]
2359   if build_docs
2360     nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2361   endif
2362   if gtk.found()
2363     nsis_cmd += '-DCONFIG_GTK=y'
2364   endif
2366   nsis = custom_target('nsis',
2367                        output: 'qemu-setup-' + meson.project_version() + '.exe',
2368                        input: files('qemu.nsi'),
2369                        build_always_stale: true,
2370                        command: nsis_cmd + ['@INPUT@'])
2371   alias_target('installer', nsis)
2372 endif
2374 #########################
2375 # Configuration summary #
2376 #########################
2378 # Directories
2379 summary_info = {}
2380 summary_info += {'Install prefix':    get_option('prefix')}
2381 summary_info += {'BIOS directory':    qemu_datadir}
2382 summary_info += {'firmware path':     get_option('qemu_firmwarepath')}
2383 summary_info += {'binary directory':  get_option('bindir')}
2384 summary_info += {'library directory': get_option('libdir')}
2385 summary_info += {'module directory':  qemu_moddir}
2386 summary_info += {'libexec directory': get_option('libexecdir')}
2387 summary_info += {'include directory': get_option('includedir')}
2388 summary_info += {'config directory':  get_option('sysconfdir')}
2389 if targetos != 'windows'
2390   summary_info += {'local state directory': get_option('localstatedir')}
2391   summary_info += {'Manual directory':      get_option('mandir')}
2392 else
2393   summary_info += {'local state directory': 'queried at runtime'}
2394 endif
2395 summary_info += {'Doc directory':     get_option('docdir')}
2396 summary_info += {'Build directory':   meson.current_build_dir()}
2397 summary_info += {'Source path':       meson.current_source_dir()}
2398 summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
2399 summary(summary_info, bool_yn: true, section: 'Directories')
2401 # Host binaries
2402 summary_info = {}
2403 summary_info += {'git':               config_host['GIT']}
2404 summary_info += {'make':              config_host['MAKE']}
2405 summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2406 summary_info += {'sphinx-build':      sphinx_build.found()}
2407 if config_host.has_key('HAVE_GDB_BIN')
2408   summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
2409 endif
2410 summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
2411 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
2412   summary_info += {'wixl':            wixl.found() ? wixl.full_path() : false}
2413 endif
2414 if slirp_opt != 'disabled'
2415   summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
2416 endif
2417 summary(summary_info, bool_yn: true, section: 'Host binaries')
2419 # Configurable features
2420 summary_info = {}
2421 summary_info += {'Documentation':     build_docs}
2422 summary_info += {'system-mode emulation': have_system}
2423 summary_info += {'user-mode emulation': have_user}
2424 summary_info += {'block layer':       have_block}
2425 summary_info += {'Install blobs':     get_option('install_blobs')}
2426 summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
2427 if config_host.has_key('CONFIG_MODULES')
2428   summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2429 endif
2430 summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
2431 summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
2432 if have_system
2433   summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
2434 endif
2435 summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
2436 if config_host['TRACE_BACKENDS'].split().contains('simple')
2437   summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2438 endif
2439 summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2440 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2441 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2442 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2443 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2444 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2445 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2446 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2447 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2448 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2449 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2450 summary(summary_info, bool_yn: true, section: 'Configurable features')
2452 # Compilation information
2453 summary_info = {}
2454 summary_info += {'host CPU':          cpu}
2455 summary_info += {'host endianness':   build_machine.endian()}
2456 summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
2457 summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
2458 if link_language == 'cpp'
2459   summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
2460 else
2461   summary_info += {'C++ compiler':      false}
2462 endif
2463 if targetos == 'darwin'
2464   summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
2465 endif
2466 if targetos == 'windows'
2467   if 'WIN_SDK' in config_host
2468     summary_info += {'Windows SDK':   config_host['WIN_SDK']}
2469   endif
2470 endif
2471 summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
2472 summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
2473                                                + ['-O' + get_option('optimization')]
2474                                                + (get_option('debug') ? ['-g'] : []))}
2475 if link_language == 'cpp'
2476   summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
2477                                                + ['-O' + get_option('optimization')]
2478                                                + (get_option('debug') ? ['-g'] : []))}
2479 endif
2480 link_args = get_option(link_language + '_link_args')
2481 if link_args.length() > 0
2482   summary_info += {'LDFLAGS':         ' '.join(link_args)}
2483 endif
2484 summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
2485 summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
2486 summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
2487 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2488 summary_info += {'PIE':               get_option('b_pie')}
2489 summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
2490 summary_info += {'malloc trim support': has_malloc_trim}
2491 summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
2492 summary_info += {'preadv support':    config_host_data.get('CONFIG_PREADV')}
2493 summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
2494 summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
2495 summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
2496 summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2497 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2498 summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
2499 summary_info += {'memory allocator':  get_option('malloc')}
2500 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2501 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2502 summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
2503 summary_info += {'gcov':              get_option('b_coverage')}
2504 summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
2505 summary_info += {'CFI support':       get_option('cfi')}
2506 if get_option('cfi')
2507   summary_info += {'CFI debug support': get_option('cfi_debug')}
2508 endif
2509 summary_info += {'strip binaries':    get_option('strip')}
2510 summary_info += {'sparse':            sparse.found() ? sparse.full_path() : false}
2511 summary_info += {'mingw32 support':   targetos == 'windows'}
2512 summary(summary_info, bool_yn: true, section: 'Compilation')
2514 # Targets and accelerators
2515 summary_info = {}
2516 if have_system
2517   summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
2518   summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
2519   summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
2520   summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
2521   summary_info += {'Xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
2522   if config_host.has_key('CONFIG_XEN_BACKEND')
2523     summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2524   endif
2525 endif
2526 summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
2527 if config_all.has_key('CONFIG_TCG')
2528   if get_option('tcg_interpreter')
2529     summary_info += {'TCG backend':   'TCI (TCG with bytecode interpreter, experimental and slow)'}
2530   else
2531     summary_info += {'TCG backend':   'native (@0@)'.format(cpu)}
2532   endif
2533   summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2534 endif
2535 summary_info += {'target list':       ' '.join(target_dirs)}
2536 if have_system
2537   summary_info += {'default devices':   get_option('default_devices')}
2538 endif
2539 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
2541 # Block layer
2542 summary_info = {}
2543 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2544 summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
2545 if have_block
2546   summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2547   summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2548   summary_info += {'VirtFS support':    have_virtfs}
2549   summary_info += {'build virtiofs daemon': have_virtiofsd}
2550   summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2551   summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2552   summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
2553   summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
2554   summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
2555   summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
2556   summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
2557   summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
2558   summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
2559   summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2560   summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
2561   summary_info += {'FUSE exports':      fuse.found()}
2562 endif
2563 summary(summary_info, bool_yn: true, section: 'Block layer support')
2565 # Crypto
2566 summary_info = {}
2567 summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
2568 summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
2569 # TODO: add back version
2570 summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
2571 if config_host.has_key('CONFIG_GCRYPT')
2572    summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
2573    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2574 endif
2575 # TODO: add back version
2576 summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
2577 if config_host.has_key('CONFIG_NETTLE')
2578    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2579 endif
2580 summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
2581 summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
2582 summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
2583 summary(summary_info, bool_yn: true, section: 'Crypto')
2585 # Libraries
2586 summary_info = {}
2587 if targetos == 'darwin'
2588   summary_info += {'Cocoa support':   cocoa.found()}
2589 endif
2590 # TODO: add back version
2591 summary_info += {'SDL support':       sdl.found()}
2592 summary_info += {'SDL image support': sdl_image.found()}
2593 # TODO: add back version
2594 summary_info += {'GTK support':       gtk.found()}
2595 summary_info += {'pixman':            pixman.found()}
2596 # TODO: add back version
2597 summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
2598 # TODO: add back version
2599 summary_info += {'slirp support':     slirp_opt == 'disabled' ? false : slirp_opt}
2600 summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
2601 summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
2602 summary_info += {'iconv support':     iconv.found()}
2603 summary_info += {'curses support':    curses.found()}
2604 # TODO: add back version
2605 summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
2606 summary_info += {'curl support':      curl.found()}
2607 summary_info += {'Multipath support': mpathpersist.found()}
2608 summary_info += {'VNC support':       vnc.found()}
2609 if vnc.found()
2610   summary_info += {'VNC SASL support':  sasl.found()}
2611   summary_info += {'VNC JPEG support':  jpeg.found()}
2612   summary_info += {'VNC PNG support':   png.found()}
2613 endif
2614 summary_info += {'brlapi support':    brlapi.found()}
2615 summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
2616 summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
2617 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2618 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2619 summary_info += {'ATTR/XATTR support': libattr.found()}
2620 summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
2621 summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
2622 summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
2623 summary_info += {'libcap-ng support': libcap_ng.found()}
2624 # TODO: add back protocol and server version
2625 summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
2626 summary_info += {'rbd support':       rbd.found()}
2627 summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
2628 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2629 summary_info += {'U2F support':       u2f.found()}
2630 summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
2631 summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
2632 summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
2633 summary_info += {'OpenGL dmabufs':    config_host.has_key('CONFIG_OPENGL_DMABUF')}
2634 summary_info += {'libiscsi support':  libiscsi.found()}
2635 summary_info += {'libnfs support':    libnfs.found()}
2636 if targetos == 'windows'
2637   if config_host.has_key('CONFIG_GUEST_AGENT')
2638     summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
2639     summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2640   endif
2641 endif
2642 summary_info += {'seccomp support':   seccomp.found()}
2643 summary_info += {'GlusterFS support': glusterfs.found()}
2644 summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
2645 summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
2646 summary_info += {'lzo support':       lzo.found()}
2647 summary_info += {'snappy support':    snappy.found()}
2648 summary_info += {'bzip2 support':     libbzip2.found()}
2649 summary_info += {'lzfse support':     liblzfse.found()}
2650 summary_info += {'zstd support':      zstd.found()}
2651 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2652 summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
2653 summary_info += {'capstone':          capstone_opt == 'disabled' ? false : capstone_opt}
2654 summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
2655 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2656 summary_info += {'libudev':           libudev.found()}
2657 summary_info += {'FUSE lseek':        fuse_lseek.found()}
2658 summary_info += {'Multiprocess QEMU': config_host.has_key('CONFIG_MULTIPROCESS_ALLOWED')}
2659 summary(summary_info, bool_yn: true, section: 'Dependencies')
2661 if not supported_cpus.contains(cpu)
2662   message()
2663   warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2664   message()
2665   message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2666   message('The QEMU project intends to remove support for this host CPU in')
2667   message('a future release if nobody volunteers to maintain it and to')
2668   message('provide a build host for our continuous integration setup.')
2669   message('configure has succeeded and you can continue to build, but')
2670   message('if you care about QEMU on this platform you should contact')
2671   message('us upstream at qemu-devel@nongnu.org.')
2672 endif
2674 if not supported_oses.contains(targetos)
2675   message()
2676   warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2677   message()
2678   message('Host OS ' + targetos + 'support is not currently maintained.')
2679   message('The QEMU project intends to remove support for this host OS in')
2680   message('a future release if nobody volunteers to maintain it and to')
2681   message('provide a build host for our continuous integration setup.')
2682   message('configure has succeeded and you can continue to build, but')
2683   message('if you care about QEMU on this platform you should contact')
2684   message('us upstream at qemu-devel@nongnu.org.')
2685 endif