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