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