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