target/ppc: Move 601 hflags adjustment to hreg_compute_hflags
[qemu/ar7.git] / meson.build
blobd8bb1ec5aa97d5f05f57a9c04c59b902aa77d511
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 = {}
1755 ###############
1756 # Trace files #
1757 ###############
1759 # TODO: add each directory to the subdirs from its own meson.build, once
1760 # we have those
1761 trace_events_subdirs = [
1762   'crypto',
1763   'qapi',
1764   'qom',
1765   'monitor',
1766   'util',
1768 if have_user
1769   trace_events_subdirs += [ 'linux-user' ]
1770 endif
1771 if have_block
1772   trace_events_subdirs += [
1773     'authz',
1774     'block',
1775     'io',
1776     'nbd',
1777     'scsi',
1778   ]
1779 endif
1780 if have_system
1781   trace_events_subdirs += [
1782     'accel/kvm',
1783     'audio',
1784     'backends',
1785     'backends/tpm',
1786     'chardev',
1787     'hw/9pfs',
1788     'hw/acpi',
1789     'hw/adc',
1790     'hw/alpha',
1791     'hw/arm',
1792     'hw/audio',
1793     'hw/block',
1794     'hw/block/dataplane',
1795     'hw/char',
1796     'hw/display',
1797     'hw/dma',
1798     'hw/hppa',
1799     'hw/hyperv',
1800     'hw/i2c',
1801     'hw/i386',
1802     'hw/i386/xen',
1803     'hw/ide',
1804     'hw/input',
1805     'hw/intc',
1806     'hw/isa',
1807     'hw/mem',
1808     'hw/mips',
1809     'hw/misc',
1810     'hw/misc/macio',
1811     'hw/net',
1812     'hw/net/can',
1813     'hw/nvram',
1814     'hw/pci',
1815     'hw/pci-host',
1816     'hw/ppc',
1817     'hw/rdma',
1818     'hw/rdma/vmw',
1819     'hw/rtc',
1820     'hw/s390x',
1821     'hw/scsi',
1822     'hw/sd',
1823     'hw/sparc',
1824     'hw/sparc64',
1825     'hw/ssi',
1826     'hw/timer',
1827     'hw/tpm',
1828     'hw/usb',
1829     'hw/vfio',
1830     'hw/virtio',
1831     'hw/watchdog',
1832     'hw/xen',
1833     'hw/gpio',
1834     'migration',
1835     'net',
1836     'softmmu',
1837     'ui',
1838     'hw/remote',
1839   ]
1840 endif
1841 if have_system or have_user
1842   trace_events_subdirs += [
1843     'accel/tcg',
1844     'hw/core',
1845     'target/arm',
1846     'target/hppa',
1847     'target/i386',
1848     'target/i386/kvm',
1849     'target/mips',
1850     'target/ppc',
1851     'target/riscv',
1852     'target/s390x',
1853     'target/sparc',
1854   ]
1855 endif
1857 vhost_user = not_found
1858 if 'CONFIG_VHOST_USER' in config_host
1859   libvhost_user = subproject('libvhost-user')
1860   vhost_user = libvhost_user.get_variable('vhost_user_dep')
1861 endif
1863 subdir('qapi')
1864 subdir('qobject')
1865 subdir('stubs')
1866 subdir('trace')
1867 subdir('util')
1868 subdir('qom')
1869 subdir('authz')
1870 subdir('crypto')
1871 subdir('ui')
1874 if enable_modules
1875   libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1876   modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1877 endif
1879 stub_ss = stub_ss.apply(config_all, strict: false)
1881 util_ss.add_all(trace_ss)
1882 util_ss = util_ss.apply(config_all, strict: false)
1883 libqemuutil = static_library('qemuutil',
1884                              sources: util_ss.sources() + stub_ss.sources() + genh,
1885                              dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1886 qemuutil = declare_dependency(link_with: libqemuutil,
1887                               sources: genh + version_res)
1889 if have_system or have_user
1890   decodetree = generator(find_program('scripts/decodetree.py'),
1891                          output: 'decode-@BASENAME@.c.inc',
1892                          arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1893   subdir('libdecnumber')
1894   subdir('target')
1895 endif
1897 subdir('audio')
1898 subdir('io')
1899 subdir('chardev')
1900 subdir('fsdev')
1901 subdir('dump')
1903 if have_block
1904   block_ss.add(files(
1905     'block.c',
1906     'blockjob.c',
1907     'job.c',
1908     'qemu-io-cmds.c',
1909   ))
1910   block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1912   subdir('nbd')
1913   subdir('scsi')
1914   subdir('block')
1916   blockdev_ss.add(files(
1917     'blockdev.c',
1918     'blockdev-nbd.c',
1919     'iothread.c',
1920     'job-qmp.c',
1921   ), gnutls)
1923   # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1924   # os-win32.c does not
1925   blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1926   softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1927 endif
1929 common_ss.add(files('cpus-common.c'))
1931 subdir('softmmu')
1933 common_ss.add(capstone)
1934 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
1935 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1936   'fpu/softfloat.c',
1937   'tcg/optimize.c',
1938   'tcg/tcg-common.c',
1939   'tcg/tcg-op-gvec.c',
1940   'tcg/tcg-op-vec.c',
1941   'tcg/tcg-op.c',
1942   'tcg/tcg.c',
1944 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('tcg/tci.c'))
1946 # Work around a gcc bug/misfeature wherein constant propagation looks
1947 # through an alias:
1948 #   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
1949 # to guess that a const variable is always zero.  Without lto, this is
1950 # impossible, as the alias is restricted to page-vary-common.c.  Indeed,
1951 # without lto, not even the alias is required -- we simply use different
1952 # declarations in different compilation units.
1953 pagevary = files('page-vary-common.c')
1954 if get_option('b_lto')
1955   pagevary_flags = ['-fno-lto']
1956   if get_option('cfi')
1957     pagevary_flags += '-fno-sanitize=cfi-icall'
1958   endif
1959   pagevary = static_library('page-vary-common', sources: pagevary,
1960                             c_args: pagevary_flags)
1961   pagevary = declare_dependency(link_with: pagevary)
1962 endif
1963 common_ss.add(pagevary)
1964 specific_ss.add(files('page-vary.c'))
1966 subdir('backends')
1967 subdir('disas')
1968 subdir('migration')
1969 subdir('monitor')
1970 subdir('net')
1971 subdir('replay')
1972 subdir('semihosting')
1973 subdir('hw')
1974 subdir('accel')
1975 subdir('plugins')
1976 subdir('bsd-user')
1977 subdir('linux-user')
1979 bsd_user_ss.add(files('gdbstub.c'))
1980 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1982 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1983 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1985 # needed for fuzzing binaries
1986 subdir('tests/qtest/libqos')
1987 subdir('tests/qtest/fuzz')
1989 ########################
1990 # Library dependencies #
1991 ########################
1993 block_mods = []
1994 softmmu_mods = []
1995 foreach d, list : modules
1996   foreach m, module_ss : list
1997     if enable_modules and targetos != 'windows'
1998       module_ss = module_ss.apply(config_all, strict: false)
1999       sl = static_library(d + '-' + m, [genh, module_ss.sources()],
2000                           dependencies: [modulecommon, module_ss.dependencies()], pic: true)
2001       if d == 'block'
2002         block_mods += sl
2003       else
2004         softmmu_mods += sl
2005       endif
2006     else
2007       if d == 'block'
2008         block_ss.add_all(module_ss)
2009       else
2010         softmmu_ss.add_all(module_ss)
2011       endif
2012     endif
2013   endforeach
2014 endforeach
2016 nm = find_program('nm')
2017 undefsym = find_program('scripts/undefsym.py')
2018 block_syms = custom_target('block.syms', output: 'block.syms',
2019                              input: [libqemuutil, block_mods],
2020                              capture: true,
2021                              command: [undefsym, nm, '@INPUT@'])
2022 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
2023                              input: [libqemuutil, softmmu_mods],
2024                              capture: true,
2025                              command: [undefsym, nm, '@INPUT@'])
2027 qom_ss = qom_ss.apply(config_host, strict: false)
2028 libqom = static_library('qom', qom_ss.sources() + genh,
2029                         dependencies: [qom_ss.dependencies()],
2030                         name_suffix: 'fa')
2032 qom = declare_dependency(link_whole: libqom)
2034 authz_ss = authz_ss.apply(config_host, strict: false)
2035 libauthz = static_library('authz', authz_ss.sources() + genh,
2036                           dependencies: [authz_ss.dependencies()],
2037                           name_suffix: 'fa',
2038                           build_by_default: false)
2040 authz = declare_dependency(link_whole: libauthz,
2041                            dependencies: qom)
2043 crypto_ss = crypto_ss.apply(config_host, strict: false)
2044 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2045                            dependencies: [crypto_ss.dependencies()],
2046                            name_suffix: 'fa',
2047                            build_by_default: false)
2049 crypto = declare_dependency(link_whole: libcrypto,
2050                             dependencies: [authz, qom])
2052 io_ss = io_ss.apply(config_host, strict: false)
2053 libio = static_library('io', io_ss.sources() + genh,
2054                        dependencies: [io_ss.dependencies()],
2055                        link_with: libqemuutil,
2056                        name_suffix: 'fa',
2057                        build_by_default: false)
2059 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2061 libmigration = static_library('migration', sources: migration_files + genh,
2062                               name_suffix: 'fa',
2063                               build_by_default: false)
2064 migration = declare_dependency(link_with: libmigration,
2065                                dependencies: [zlib, qom, io])
2066 softmmu_ss.add(migration)
2068 block_ss = block_ss.apply(config_host, strict: false)
2069 libblock = static_library('block', block_ss.sources() + genh,
2070                           dependencies: block_ss.dependencies(),
2071                           link_depends: block_syms,
2072                           name_suffix: 'fa',
2073                           build_by_default: false)
2075 block = declare_dependency(link_whole: [libblock],
2076                            link_args: '@block.syms',
2077                            dependencies: [crypto, io])
2079 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2080 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2081                              dependencies: blockdev_ss.dependencies(),
2082                              name_suffix: 'fa',
2083                              build_by_default: false)
2085 blockdev = declare_dependency(link_whole: [libblockdev],
2086                               dependencies: [block])
2088 qmp_ss = qmp_ss.apply(config_host, strict: false)
2089 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2090                         dependencies: qmp_ss.dependencies(),
2091                         name_suffix: 'fa',
2092                         build_by_default: false)
2094 qmp = declare_dependency(link_whole: [libqmp])
2096 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2097                             name_suffix: 'fa',
2098                             dependencies: [gnutls],
2099                             build_by_default: false)
2101 chardev = declare_dependency(link_whole: libchardev)
2103 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
2104                            name_suffix: 'fa',
2105                            build_by_default: false)
2106 hwcore = declare_dependency(link_whole: libhwcore)
2107 common_ss.add(hwcore)
2109 ###########
2110 # Targets #
2111 ###########
2113 foreach m : block_mods + softmmu_mods
2114   shared_module(m.name(),
2115                 name_prefix: '',
2116                 link_whole: m,
2117                 install: true,
2118                 install_dir: qemu_moddir)
2119 endforeach
2121 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2122 common_ss.add(qom, qemuutil)
2124 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2125 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2127 common_all = common_ss.apply(config_all, strict: false)
2128 common_all = static_library('common',
2129                             build_by_default: false,
2130                             sources: common_all.sources() + genh,
2131                             dependencies: common_all.dependencies(),
2132                             name_suffix: 'fa')
2134 feature_to_c = find_program('scripts/feature_to_c.sh')
2136 emulators = {}
2137 foreach target : target_dirs
2138   config_target = config_target_mak[target]
2139   target_name = config_target['TARGET_NAME']
2140   arch = config_target['TARGET_BASE_ARCH']
2141   arch_srcs = [config_target_h[target]]
2142   arch_deps = []
2143   c_args = ['-DNEED_CPU_H',
2144             '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2145             '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2146   link_args = emulator_link_args
2148   config_target += config_host
2149   target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2150   if targetos == 'linux'
2151     target_inc += include_directories('linux-headers', is_system: true)
2152   endif
2153   if target.endswith('-softmmu')
2154     qemu_target_name = 'qemu-system-' + target_name
2155     target_type='system'
2156     t = target_softmmu_arch[arch].apply(config_target, strict: false)
2157     arch_srcs += t.sources()
2158     arch_deps += t.dependencies()
2160     hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2161     hw = hw_arch[hw_dir].apply(config_target, strict: false)
2162     arch_srcs += hw.sources()
2163     arch_deps += hw.dependencies()
2165     arch_srcs += config_devices_h[target]
2166     link_args += ['@block.syms', '@qemu.syms']
2167   else
2168     abi = config_target['TARGET_ABI_DIR']
2169     target_type='user'
2170     qemu_target_name = 'qemu-' + target_name
2171     if 'CONFIG_LINUX_USER' in config_target
2172       base_dir = 'linux-user'
2173       target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2174     else
2175       base_dir = 'bsd-user'
2176       target_inc += include_directories('bsd-user/freebsd')
2177     endif
2178     target_inc += include_directories(
2179       base_dir,
2180       base_dir / abi,
2181     )
2182     if 'CONFIG_LINUX_USER' in config_target
2183       dir = base_dir / abi
2184       arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2185       if config_target.has_key('TARGET_SYSTBL_ABI')
2186         arch_srcs += \
2187           syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2188                                              extra_args : config_target['TARGET_SYSTBL_ABI'])
2189       endif
2190     endif
2191   endif
2193   if 'TARGET_XML_FILES' in config_target
2194     gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2195                                 output: target + '-gdbstub-xml.c',
2196                                 input: files(config_target['TARGET_XML_FILES'].split()),
2197                                 command: [feature_to_c, '@INPUT@'],
2198                                 capture: true)
2199     arch_srcs += gdbstub_xml
2200   endif
2202   t = target_arch[arch].apply(config_target, strict: false)
2203   arch_srcs += t.sources()
2204   arch_deps += t.dependencies()
2206   target_common = common_ss.apply(config_target, strict: false)
2207   objects = common_all.extract_objects(target_common.sources())
2208   deps = target_common.dependencies()
2210   target_specific = specific_ss.apply(config_target, strict: false)
2211   arch_srcs += target_specific.sources()
2212   arch_deps += target_specific.dependencies()
2214   lib = static_library('qemu-' + target,
2215                  sources: arch_srcs + genh,
2216                  dependencies: arch_deps,
2217                  objects: objects,
2218                  include_directories: target_inc,
2219                  c_args: c_args,
2220                  build_by_default: false,
2221                  name_suffix: 'fa')
2223   if target.endswith('-softmmu')
2224     execs = [{
2225       'name': 'qemu-system-' + target_name,
2226       'gui': false,
2227       'sources': files('softmmu/main.c'),
2228       'dependencies': []
2229     }]
2230     if targetos == 'windows' and (sdl.found() or gtk.found())
2231       execs += [{
2232         'name': 'qemu-system-' + target_name + 'w',
2233         'gui': true,
2234         'sources': files('softmmu/main.c'),
2235         'dependencies': []
2236       }]
2237     endif
2238     if config_host.has_key('CONFIG_FUZZ')
2239       specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2240       execs += [{
2241         'name': 'qemu-fuzz-' + target_name,
2242         'gui': false,
2243         'sources': specific_fuzz.sources(),
2244         'dependencies': specific_fuzz.dependencies(),
2245       }]
2246     endif
2247   else
2248     execs = [{
2249       'name': 'qemu-' + target_name,
2250       'gui': false,
2251       'sources': [],
2252       'dependencies': []
2253     }]
2254   endif
2255   foreach exe: execs
2256     exe_name = exe['name']
2257     exe_sign = 'CONFIG_HVF' in config_target
2258     if exe_sign
2259       exe_name += '-unsigned'
2260     endif
2262     emulator = executable(exe_name, exe['sources'],
2263                install: true,
2264                c_args: c_args,
2265                dependencies: arch_deps + deps + exe['dependencies'],
2266                objects: lib.extract_all_objects(recursive: true),
2267                link_language: link_language,
2268                link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2269                link_args: link_args,
2270                gui_app: exe['gui'])
2272     if exe_sign
2273       emulators += {exe['name'] : custom_target(exe['name'],
2274                    depends: emulator,
2275                    output: exe['name'],
2276                    command: [
2277                      meson.current_source_dir() / 'scripts/entitlement.sh',
2278                      meson.current_build_dir() / exe_name,
2279                      meson.current_build_dir() / exe['name'],
2280                      meson.current_source_dir() / 'accel/hvf/entitlements.plist'
2281                    ])
2282       }
2284       meson.add_install_script('scripts/entitlement.sh', '--install',
2285                                get_option('bindir') / exe_name,
2286                                get_option('bindir') / exe['name'],
2287                                meson.current_source_dir() / 'accel/hvf/entitlements.plist')
2288     else
2289       emulators += {exe['name']: emulator}
2290     endif
2292     if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2293       foreach stp: [
2294         {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2295         {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2296         {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2297         {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2298       ]
2299         custom_target(exe['name'] + stp['ext'],
2300                       input: trace_events_all,
2301                       output: exe['name'] + stp['ext'],
2302                       install: stp['install'],
2303                       install_dir: get_option('datadir') / 'systemtap/tapset',
2304                       command: [
2305                         tracetool, '--group=all', '--format=' + stp['fmt'],
2306                         '--binary=' + stp['bin'],
2307                         '--target-name=' + target_name,
2308                         '--target-type=' + target_type,
2309                         '--probe-prefix=qemu.' + target_type + '.' + target_name,
2310                         '@INPUT@', '@OUTPUT@'
2311                       ],
2312                       depend_files: tracetool_depends)
2313       endforeach
2314     endif
2315   endforeach
2316 endforeach
2318 # Other build targets
2320 if 'CONFIG_PLUGIN' in config_host
2321   install_headers('include/qemu/qemu-plugin.h')
2322 endif
2324 if 'CONFIG_GUEST_AGENT' in config_host
2325   subdir('qga')
2326 elif get_option('guest_agent_msi').enabled()
2327   error('Guest agent MSI requested, but the guest agent is not being built')
2328 endif
2330 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2331 # when we don't build tools or system
2332 if xkbcommon.found()
2333   # used for the update-keymaps target, so include rules even if !have_tools
2334   qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2335                            dependencies: [qemuutil, xkbcommon], install: have_tools)
2336 endif
2338 if have_tools
2339   qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2340              dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2341   qemu_io = executable('qemu-io', files('qemu-io.c'),
2342              dependencies: [block, qemuutil], install: true)
2343   qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2344                dependencies: [blockdev, qemuutil, gnutls], install: true)
2346   subdir('storage-daemon')
2347   subdir('contrib/rdmacm-mux')
2348   subdir('contrib/elf2dmp')
2350   executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2351              dependencies: qemuutil,
2352              install: true)
2354   if 'CONFIG_VHOST_USER' in config_host
2355     subdir('contrib/vhost-user-blk')
2356     subdir('contrib/vhost-user-gpu')
2357     subdir('contrib/vhost-user-input')
2358     subdir('contrib/vhost-user-scsi')
2359   endif
2361   if targetos == 'linux'
2362     executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2363                dependencies: [qemuutil, libcap_ng],
2364                install: true,
2365                install_dir: get_option('libexecdir'))
2367     executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2368                dependencies: [authz, crypto, io, qom, qemuutil,
2369                               libcap_ng, mpathpersist],
2370                install: true)
2371   endif
2373   if 'CONFIG_IVSHMEM' in config_host
2374     subdir('contrib/ivshmem-client')
2375     subdir('contrib/ivshmem-server')
2376   endif
2377 endif
2379 subdir('scripts')
2380 subdir('tools')
2381 subdir('pc-bios')
2382 subdir('docs')
2383 subdir('tests')
2384 if gtk.found()
2385   subdir('po')
2386 endif
2388 if host_machine.system() == 'windows'
2389   nsis_cmd = [
2390     find_program('scripts/nsis.py'),
2391     '@OUTPUT@',
2392     get_option('prefix'),
2393     meson.current_source_dir(),
2394     host_machine.cpu(),
2395     '--',
2396     '-DDISPLAYVERSION=' + meson.project_version(),
2397   ]
2398   if build_docs
2399     nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2400   endif
2401   if gtk.found()
2402     nsis_cmd += '-DCONFIG_GTK=y'
2403   endif
2405   nsis = custom_target('nsis',
2406                        output: 'qemu-setup-' + meson.project_version() + '.exe',
2407                        input: files('qemu.nsi'),
2408                        build_always_stale: true,
2409                        command: nsis_cmd + ['@INPUT@'])
2410   alias_target('installer', nsis)
2411 endif
2413 #########################
2414 # Configuration summary #
2415 #########################
2417 # Directories
2418 summary_info = {}
2419 summary_info += {'Install prefix':    get_option('prefix')}
2420 summary_info += {'BIOS directory':    qemu_datadir}
2421 summary_info += {'firmware path':     get_option('qemu_firmwarepath')}
2422 summary_info += {'binary directory':  get_option('bindir')}
2423 summary_info += {'library directory': get_option('libdir')}
2424 summary_info += {'module directory':  qemu_moddir}
2425 summary_info += {'libexec directory': get_option('libexecdir')}
2426 summary_info += {'include directory': get_option('includedir')}
2427 summary_info += {'config directory':  get_option('sysconfdir')}
2428 if targetos != 'windows'
2429   summary_info += {'local state directory': get_option('localstatedir')}
2430   summary_info += {'Manual directory':      get_option('mandir')}
2431 else
2432   summary_info += {'local state directory': 'queried at runtime'}
2433 endif
2434 summary_info += {'Doc directory':     get_option('docdir')}
2435 summary_info += {'Build directory':   meson.current_build_dir()}
2436 summary_info += {'Source path':       meson.current_source_dir()}
2437 summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
2438 summary(summary_info, bool_yn: true, section: 'Directories')
2440 # Host binaries
2441 summary_info = {}
2442 summary_info += {'git':               config_host['GIT']}
2443 summary_info += {'make':              config_host['MAKE']}
2444 summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2445 summary_info += {'sphinx-build':      sphinx_build.found()}
2446 if config_host.has_key('HAVE_GDB_BIN')
2447   summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
2448 endif
2449 summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
2450 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
2451   summary_info += {'wixl':            wixl.found() ? wixl.full_path() : false}
2452 endif
2453 if slirp_opt != 'disabled'
2454   summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
2455 endif
2456 summary(summary_info, bool_yn: true, section: 'Host binaries')
2458 # Configurable features
2459 summary_info = {}
2460 summary_info += {'Documentation':     build_docs}
2461 summary_info += {'system-mode emulation': have_system}
2462 summary_info += {'user-mode emulation': have_user}
2463 summary_info += {'block layer':       have_block}
2464 summary_info += {'Install blobs':     get_option('install_blobs')}
2465 summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
2466 if config_host.has_key('CONFIG_MODULES')
2467   summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2468 endif
2469 summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
2470 summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
2471 if have_system
2472   summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
2473 endif
2474 summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
2475 if config_host['TRACE_BACKENDS'].split().contains('simple')
2476   summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2477 endif
2478 summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2479 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2480 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2481 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2482 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2483 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2484 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2485 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2486 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2487 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2488 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2489 summary(summary_info, bool_yn: true, section: 'Configurable features')
2491 # Compilation information
2492 summary_info = {}
2493 summary_info += {'host CPU':          cpu}
2494 summary_info += {'host endianness':   build_machine.endian()}
2495 summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
2496 summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
2497 if link_language == 'cpp'
2498   summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
2499 else
2500   summary_info += {'C++ compiler':      false}
2501 endif
2502 if targetos == 'darwin'
2503   summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
2504 endif
2505 if targetos == 'windows'
2506   if 'WIN_SDK' in config_host
2507     summary_info += {'Windows SDK':   config_host['WIN_SDK']}
2508   endif
2509 endif
2510 summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
2511 summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
2512                                                + ['-O' + get_option('optimization')]
2513                                                + (get_option('debug') ? ['-g'] : []))}
2514 if link_language == 'cpp'
2515   summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
2516                                                + ['-O' + get_option('optimization')]
2517                                                + (get_option('debug') ? ['-g'] : []))}
2518 endif
2519 link_args = get_option(link_language + '_link_args')
2520 if link_args.length() > 0
2521   summary_info += {'LDFLAGS':         ' '.join(link_args)}
2522 endif
2523 summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
2524 summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
2525 summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
2526 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2527 summary_info += {'PIE':               get_option('b_pie')}
2528 summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
2529 summary_info += {'malloc trim support': has_malloc_trim}
2530 summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
2531 summary_info += {'preadv support':    config_host_data.get('CONFIG_PREADV')}
2532 summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
2533 summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
2534 summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
2535 summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2536 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2537 summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
2538 summary_info += {'memory allocator':  get_option('malloc')}
2539 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2540 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2541 summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
2542 summary_info += {'gcov':              get_option('b_coverage')}
2543 summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
2544 summary_info += {'CFI support':       get_option('cfi')}
2545 if get_option('cfi')
2546   summary_info += {'CFI debug support': get_option('cfi_debug')}
2547 endif
2548 summary_info += {'strip binaries':    get_option('strip')}
2549 summary_info += {'sparse':            sparse.found() ? sparse.full_path() : false}
2550 summary_info += {'mingw32 support':   targetos == 'windows'}
2552 # snarf the cross-compilation information for tests
2553 foreach target: target_dirs
2554   tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
2555   if fs.exists(tcg_mak)
2556     config_cross_tcg = keyval.load(tcg_mak)
2557     target = config_cross_tcg['TARGET_NAME']
2558     compiler = ''
2559     if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
2560       summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
2561                                           ' via ' + config_cross_tcg['DOCKER_IMAGE']}
2562     elif 'CROSS_CC_GUEST' in config_cross_tcg
2563       summary_info += {target + ' tests'
2564                                 : config_cross_tcg['CROSS_CC_GUEST'] }
2565     endif
2566    endif
2567 endforeach
2569 summary(summary_info, bool_yn: true, section: 'Compilation')
2571 # Targets and accelerators
2572 summary_info = {}
2573 if have_system
2574   summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
2575   summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
2576   summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
2577   summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
2578   summary_info += {'Xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
2579   if config_host.has_key('CONFIG_XEN_BACKEND')
2580     summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2581   endif
2582 endif
2583 summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
2584 if config_all.has_key('CONFIG_TCG')
2585   if get_option('tcg_interpreter')
2586     summary_info += {'TCG backend':   'TCI (TCG with bytecode interpreter, experimental and slow)'}
2587   else
2588     summary_info += {'TCG backend':   'native (@0@)'.format(cpu)}
2589   endif
2590   summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2591 endif
2592 summary_info += {'target list':       ' '.join(target_dirs)}
2593 if have_system
2594   summary_info += {'default devices':   get_option('default_devices')}
2595   summary_info += {'out of process emulation': multiprocess_allowed}
2596 endif
2597 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
2599 # Block layer
2600 summary_info = {}
2601 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2602 summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
2603 if have_block
2604   summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2605   summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2606   summary_info += {'VirtFS support':    have_virtfs}
2607   summary_info += {'build virtiofs daemon': have_virtiofsd}
2608   summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2609   summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2610   summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
2611   summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
2612   summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
2613   summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
2614   summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
2615   summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
2616   summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
2617   summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2618   summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
2619   summary_info += {'FUSE exports':      fuse.found()}
2620 endif
2621 summary(summary_info, bool_yn: true, section: 'Block layer support')
2623 # Crypto
2624 summary_info = {}
2625 summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
2626 summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
2627 # TODO: add back version
2628 summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
2629 if config_host.has_key('CONFIG_GCRYPT')
2630    summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
2631    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2632 endif
2633 # TODO: add back version
2634 summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
2635 if config_host.has_key('CONFIG_NETTLE')
2636    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2637 endif
2638 summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
2639 summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
2640 summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
2641 summary(summary_info, bool_yn: true, section: 'Crypto')
2643 # Libraries
2644 summary_info = {}
2645 if targetos == 'darwin'
2646   summary_info += {'Cocoa support':   cocoa.found()}
2647 endif
2648 # TODO: add back version
2649 summary_info += {'SDL support':       sdl.found()}
2650 summary_info += {'SDL image support': sdl_image.found()}
2651 # TODO: add back version
2652 summary_info += {'GTK support':       gtk.found()}
2653 summary_info += {'pixman':            pixman.found()}
2654 # TODO: add back version
2655 summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
2656 # TODO: add back version
2657 summary_info += {'slirp support':     slirp_opt == 'disabled' ? false : slirp_opt}
2658 summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
2659 summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
2660 summary_info += {'iconv support':     iconv.found()}
2661 summary_info += {'curses support':    curses.found()}
2662 # TODO: add back version
2663 summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
2664 summary_info += {'curl support':      curl.found()}
2665 summary_info += {'Multipath support': mpathpersist.found()}
2666 summary_info += {'VNC support':       vnc.found()}
2667 if vnc.found()
2668   summary_info += {'VNC SASL support':  sasl.found()}
2669   summary_info += {'VNC JPEG support':  jpeg.found()}
2670   summary_info += {'VNC PNG support':   png.found()}
2671 endif
2672 summary_info += {'brlapi support':    brlapi.found()}
2673 summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
2674 summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
2675 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2676 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2677 summary_info += {'ATTR/XATTR support': libattr.found()}
2678 summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
2679 summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
2680 summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
2681 summary_info += {'libcap-ng support': libcap_ng.found()}
2682 # TODO: add back protocol and server version
2683 summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
2684 summary_info += {'rbd support':       rbd.found()}
2685 summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
2686 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2687 summary_info += {'U2F support':       u2f.found()}
2688 summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
2689 summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
2690 summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
2691 summary_info += {'GBM':               config_host.has_key('CONFIG_GBM')}
2692 summary_info += {'libiscsi support':  libiscsi.found()}
2693 summary_info += {'libnfs support':    libnfs.found()}
2694 if targetos == 'windows'
2695   if config_host.has_key('CONFIG_GUEST_AGENT')
2696     summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
2697     summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2698   endif
2699 endif
2700 summary_info += {'seccomp support':   seccomp.found()}
2701 summary_info += {'GlusterFS support': glusterfs.found()}
2702 summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
2703 summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
2704 summary_info += {'lzo support':       lzo.found()}
2705 summary_info += {'snappy support':    snappy.found()}
2706 summary_info += {'bzip2 support':     libbzip2.found()}
2707 summary_info += {'lzfse support':     liblzfse.found()}
2708 summary_info += {'zstd support':      zstd.found()}
2709 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2710 summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
2711 summary_info += {'capstone':          capstone_opt == 'disabled' ? false : capstone_opt}
2712 summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
2713 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2714 summary_info += {'libudev':           libudev.found()}
2715 summary_info += {'FUSE lseek':        fuse_lseek.found()}
2716 summary(summary_info, bool_yn: true, section: 'Dependencies')
2718 if not supported_cpus.contains(cpu)
2719   message()
2720   warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2721   message()
2722   message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2723   message('The QEMU project intends to remove support for this host CPU in')
2724   message('a future release if nobody volunteers to maintain it and to')
2725   message('provide a build host for our continuous integration setup.')
2726   message('configure has succeeded and you can continue to build, but')
2727   message('if you care about QEMU on this platform you should contact')
2728   message('us upstream at qemu-devel@nongnu.org.')
2729 endif
2731 if not supported_oses.contains(targetos)
2732   message()
2733   warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2734   message()
2735   message('Host OS ' + targetos + 'support is not currently maintained.')
2736   message('The QEMU project intends to remove support for this host OS in')
2737   message('a future release if nobody volunteers to maintain it and to')
2738   message('provide a build host for our continuous integration setup.')
2739   message('configure has succeeded and you can continue to build, but')
2740   message('if you care about QEMU on this platform you should contact')
2741   message('us upstream at qemu-devel@nongnu.org.')
2742 endif