scsi-generic: pass max_segments via max_iov field in BlockLimits
[qemu/rayw.git] / meson.build
blob64e23175abd9aa9d75f9cd39de51992f162c8fe4
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')
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 if not get_option('gtk').auto() or (have_system and not cocoa.found())
864   gtk = dependency('gtk+-3.0', version: '>=3.22.0',
865                    method: 'pkg-config',
866                    required: get_option('gtk'),
867                    kwargs: static_kwargs)
868   if gtk.found()
869     gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
870                         method: 'pkg-config',
871                         required: false,
872                         kwargs: static_kwargs)
873     gtk = declare_dependency(dependencies: [gtk, gtkx11])
874   endif
875 endif
877 vte = not_found
878 if 'CONFIG_VTE' in config_host
879   vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
880                            link_args: config_host['VTE_LIBS'].split())
881 endif
882 x11 = not_found
883 if gtkx11.found()
884   x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
885                    kwargs: static_kwargs)
886 endif
887 vnc = not_found
888 png = not_found
889 jpeg = not_found
890 sasl = not_found
891 if get_option('vnc').enabled()
892   vnc = declare_dependency() # dummy dependency
893   png = dependency('libpng', required: get_option('vnc_png'),
894                    method: 'pkg-config', kwargs: static_kwargs)
895   jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
896                     method: 'pkg-config', kwargs: static_kwargs)
897   sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
898                          required: get_option('vnc_sasl'),
899                          kwargs: static_kwargs)
900   if sasl.found()
901     sasl = declare_dependency(dependencies: sasl,
902                               compile_args: '-DSTRUCT_IOVEC_DEFINED')
903   endif
904 endif
906 pam = not_found
907 if not get_option('auth_pam').auto() or have_system
908   pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
909                         required: get_option('auth_pam'),
910                         kwargs: static_kwargs)
911 endif
912 if pam.found() and not cc.links('''
913    #include <stddef.h>
914    #include <security/pam_appl.h>
915    int main(void) {
916      const char *service_name = "qemu";
917      const char *user = "frank";
918      const struct pam_conv pam_conv = { 0 };
919      pam_handle_t *pamh = NULL;
920      pam_start(service_name, user, &pam_conv, &pamh);
921      return 0;
922    }''', dependencies: pam)
923   pam = not_found
924   if get_option('auth_pam').enabled()
925     error('could not link libpam')
926   else
927     warning('could not link libpam, disabling')
928   endif
929 endif
931 snappy = not_found
932 if not get_option('snappy').auto() or have_system
933   snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
934                            required: get_option('snappy'),
935                            kwargs: static_kwargs)
936 endif
937 if snappy.found() and not cc.links('''
938    #include <snappy-c.h>
939    int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
940   snappy = not_found
941   if get_option('snappy').enabled()
942     error('could not link libsnappy')
943   else
944     warning('could not link libsnappy, disabling')
945   endif
946 endif
948 lzo = not_found
949 if not get_option('lzo').auto() or have_system
950   lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
951                         required: get_option('lzo'),
952                         kwargs: static_kwargs)
953 endif
954 if lzo.found() and not cc.links('''
955    #include <lzo/lzo1x.h>
956    int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
957   lzo = not_found
958   if get_option('lzo').enabled()
959     error('could not link liblzo2')
960   else
961     warning('could not link liblzo2, disabling')
962   endif
963 endif
965 rdma = not_found
966 if 'CONFIG_RDMA' in config_host
967   rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
968 endif
969 numa = not_found
970 if 'CONFIG_NUMA' in config_host
971   numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
972 endif
973 xen = not_found
974 if 'CONFIG_XEN_BACKEND' in config_host
975   xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
976                            link_args: config_host['XEN_LIBS'].split())
977 endif
978 cacard = not_found
979 if not get_option('smartcard').auto() or have_system
980   cacard = dependency('libcacard', required: get_option('smartcard'),
981                       version: '>=2.5.1', method: 'pkg-config',
982                       kwargs: static_kwargs)
983 endif
984 u2f = not_found
985 if have_system
986   u2f = dependency('u2f-emu', required: get_option('u2f'),
987                    method: 'pkg-config',
988                    kwargs: static_kwargs)
989 endif
990 usbredir = not_found
991 if not get_option('usb_redir').auto() or have_system
992   usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
993                         version: '>=0.6', method: 'pkg-config',
994                         kwargs: static_kwargs)
995 endif
996 libusb = not_found
997 if not get_option('libusb').auto() or have_system
998   libusb = dependency('libusb-1.0', required: get_option('libusb'),
999                       version: '>=1.0.13', method: 'pkg-config',
1000                       kwargs: static_kwargs)
1001 endif
1003 libpmem = not_found
1004 if 'CONFIG_LIBPMEM' in config_host
1005   libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
1006                                link_args: config_host['LIBPMEM_LIBS'].split())
1007 endif
1008 libdaxctl = not_found
1009 if 'CONFIG_LIBDAXCTL' in config_host
1010   libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
1011 endif
1012 tasn1 = not_found
1013 if gnutls.found()
1014   tasn1 = dependency('libtasn1',
1015                      method: 'pkg-config',
1016                      kwargs: static_kwargs)
1017 endif
1018 keyutils = dependency('libkeyutils', required: false,
1019                       method: 'pkg-config', kwargs: static_kwargs)
1021 has_gettid = cc.has_function('gettid')
1023 # Malloc tests
1025 malloc = []
1026 if get_option('malloc') == 'system'
1027   has_malloc_trim = \
1028     not get_option('malloc_trim').disabled() and \
1029     cc.links('''#include <malloc.h>
1030                 int main(void) { malloc_trim(0); return 0; }''')
1031 else
1032   has_malloc_trim = false
1033   malloc = cc.find_library(get_option('malloc'), required: true)
1034 endif
1035 if not has_malloc_trim and get_option('malloc_trim').enabled()
1036   if get_option('malloc') == 'system'
1037     error('malloc_trim not available on this platform.')
1038   else
1039     error('malloc_trim not available with non-libc memory allocator')
1040   endif
1041 endif
1043 # Check whether the glibc provides statx()
1045 statx_test = '''
1046   #ifndef _GNU_SOURCE
1047   #define _GNU_SOURCE
1048   #endif
1049   #include <sys/stat.h>
1050   int main(void) {
1051     struct statx statxbuf;
1052     statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1053     return 0;
1054   }'''
1056 has_statx = cc.links(statx_test)
1058 have_vhost_user_blk_server = (targetos == 'linux' and
1059     'CONFIG_VHOST_USER' in config_host)
1061 if get_option('vhost_user_blk_server').enabled()
1062     if targetos != 'linux'
1063         error('vhost_user_blk_server requires linux')
1064     elif 'CONFIG_VHOST_USER' not in config_host
1065         error('vhost_user_blk_server requires vhost-user support')
1066     endif
1067 elif get_option('vhost_user_blk_server').disabled() or not have_system
1068     have_vhost_user_blk_server = false
1069 endif
1072 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1073   error('Cannot enable fuse-lseek while fuse is disabled')
1074 endif
1076 fuse = dependency('fuse3', required: get_option('fuse'),
1077                   version: '>=3.1', method: 'pkg-config',
1078                   kwargs: static_kwargs)
1080 fuse_lseek = not_found
1081 if not get_option('fuse_lseek').disabled()
1082   if fuse.version().version_compare('>=3.8')
1083     # Dummy dependency
1084     fuse_lseek = declare_dependency()
1085   elif get_option('fuse_lseek').enabled()
1086     if fuse.found()
1087       error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1088     else
1089       error('fuse-lseek requires libfuse, which was not found')
1090     endif
1091   endif
1092 endif
1094 # libbpf
1095 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1096 if libbpf.found() and not cc.links('''
1097    #include <bpf/libbpf.h>
1098    int main(void)
1099    {
1100      bpf_object__destroy_skeleton(NULL);
1101      return 0;
1102    }''', dependencies: libbpf)
1103   libbpf = not_found
1104   if get_option('bpf').enabled()
1105     error('libbpf skeleton test failed')
1106   else
1107     warning('libbpf skeleton test failed, disabling')
1108   endif
1109 endif
1111 if get_option('cfi')
1112   cfi_flags=[]
1113   # Check for dependency on LTO
1114   if not get_option('b_lto')
1115     error('Selected Control-Flow Integrity but LTO is disabled')
1116   endif
1117   if config_host.has_key('CONFIG_MODULES')
1118     error('Selected Control-Flow Integrity is not compatible with modules')
1119   endif
1120   # Check for cfi flags. CFI requires LTO so we can't use
1121   # get_supported_arguments, but need a more complex "compiles" which allows
1122   # custom arguments
1123   if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1124                  args: ['-flto', '-fsanitize=cfi-icall'] )
1125     cfi_flags += '-fsanitize=cfi-icall'
1126   else
1127     error('-fsanitize=cfi-icall is not supported by the compiler')
1128   endif
1129   if cc.compiles('int main () { return 0; }',
1130                  name: '-fsanitize-cfi-icall-generalize-pointers',
1131                  args: ['-flto', '-fsanitize=cfi-icall',
1132                         '-fsanitize-cfi-icall-generalize-pointers'] )
1133     cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1134   else
1135     error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1136   endif
1137   if get_option('cfi_debug')
1138     if cc.compiles('int main () { return 0; }',
1139                    name: '-fno-sanitize-trap=cfi-icall',
1140                    args: ['-flto', '-fsanitize=cfi-icall',
1141                           '-fno-sanitize-trap=cfi-icall'] )
1142       cfi_flags += '-fno-sanitize-trap=cfi-icall'
1143     else
1144       error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1145     endif
1146   endif
1147   add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1148   add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1149 endif
1151 #################
1152 # config-host.h #
1153 #################
1155 have_virtfs = (targetos == 'linux' and
1156     have_system and
1157     libattr.found() and
1158     libcap_ng.found())
1160 have_virtfs_proxy_helper = have_virtfs and have_tools
1162 if get_option('virtfs').enabled()
1163   if not have_virtfs
1164     if targetos != 'linux'
1165       error('virtio-9p (virtfs) requires Linux')
1166     elif not libcap_ng.found() or not libattr.found()
1167       error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel')
1168     elif not have_system
1169       error('virtio-9p (virtfs) needs system emulation support')
1170     endif
1171   endif
1172 elif get_option('virtfs').disabled()
1173   have_virtfs = false
1174 endif
1176 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1177 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1178 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1179 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1180 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1181 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1182 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1183 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1184 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1185 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1186 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1187 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1189 config_host_data.set('CONFIG_ATTR', libattr.found())
1190 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1191 config_host_data.set('CONFIG_COCOA', cocoa.found())
1192 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1193 config_host_data.set('CONFIG_LZO', lzo.found())
1194 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1195 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1196 config_host_data.set('CONFIG_CURL', curl.found())
1197 config_host_data.set('CONFIG_CURSES', curses.found())
1198 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1199 if glusterfs.found()
1200   config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1201   config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1202   config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1203   config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1204   config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1205   config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1206 endif
1207 config_host_data.set('CONFIG_GTK', gtk.found())
1208 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1209 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1210 config_host_data.set('CONFIG_EBPF', libbpf.found())
1211 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1212 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1213 config_host_data.set('CONFIG_RBD', rbd.found())
1214 config_host_data.set('CONFIG_SDL', sdl.found())
1215 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1216 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1217 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1218 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1219 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1220 config_host_data.set('CONFIG_VNC', vnc.found())
1221 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1222 config_host_data.set('CONFIG_VNC_PNG', png.found())
1223 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1224 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1225 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1226 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1227 config_host_data.set('CONFIG_GETTID', has_gettid)
1228 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1229 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1230 config_host_data.set('CONFIG_NETTLE', nettle.found())
1231 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1232 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1233 config_host_data.set('CONFIG_STATX', has_statx)
1234 config_host_data.set('CONFIG_ZSTD', zstd.found())
1235 config_host_data.set('CONFIG_FUSE', fuse.found())
1236 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1237 config_host_data.set('CONFIG_X11', x11.found())
1238 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1239 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1240 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1241 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1242 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1244 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1245 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1246 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1247 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1248 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1249 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1251 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1253 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
1254 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1255 strings = ['HOST_DSOSUF', 'CONFIG_IASL']
1256 foreach k, v: config_host
1257   if ignored.contains(k)
1258     # do nothing
1259   elif arrays.contains(k)
1260     if v != ''
1261       v = '"' + '", "'.join(v.split()) + '", '
1262     endif
1263     config_host_data.set(k, v)
1264   elif k == 'ARCH'
1265     config_host_data.set('HOST_' + v.to_upper(), 1)
1266   elif strings.contains(k)
1267     if not k.startswith('CONFIG_')
1268       k = 'CONFIG_' + k.to_upper()
1269     endif
1270     config_host_data.set_quoted(k, v)
1271   elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
1272     config_host_data.set(k, v == 'y' ? 1 : v)
1273   endif
1274 endforeach
1276 ########################
1277 # Target configuration #
1278 ########################
1280 minikconf = find_program('scripts/minikconf.py')
1281 config_all = {}
1282 config_all_devices = {}
1283 config_all_disas = {}
1284 config_devices_mak_list = []
1285 config_devices_h = {}
1286 config_target_h = {}
1287 config_target_mak = {}
1289 disassemblers = {
1290   'alpha' : ['CONFIG_ALPHA_DIS'],
1291   'arm' : ['CONFIG_ARM_DIS'],
1292   'avr' : ['CONFIG_AVR_DIS'],
1293   'cris' : ['CONFIG_CRIS_DIS'],
1294   'hexagon' : ['CONFIG_HEXAGON_DIS'],
1295   'hppa' : ['CONFIG_HPPA_DIS'],
1296   'i386' : ['CONFIG_I386_DIS'],
1297   'x86_64' : ['CONFIG_I386_DIS'],
1298   'x32' : ['CONFIG_I386_DIS'],
1299   'm68k' : ['CONFIG_M68K_DIS'],
1300   'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1301   'mips' : ['CONFIG_MIPS_DIS'],
1302   'nios2' : ['CONFIG_NIOS2_DIS'],
1303   'or1k' : ['CONFIG_OPENRISC_DIS'],
1304   'ppc' : ['CONFIG_PPC_DIS'],
1305   'riscv' : ['CONFIG_RISCV_DIS'],
1306   'rx' : ['CONFIG_RX_DIS'],
1307   's390' : ['CONFIG_S390_DIS'],
1308   'sh4' : ['CONFIG_SH4_DIS'],
1309   'sparc' : ['CONFIG_SPARC_DIS'],
1310   'xtensa' : ['CONFIG_XTENSA_DIS'],
1312 if link_language == 'cpp'
1313   disassemblers += {
1314     'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1315     'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1316     'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1317   }
1318 endif
1320 host_kconfig = \
1321   ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1322   ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
1323   ('CONFIG_IVSHMEM' in config_host ? ['CONFIG_IVSHMEM=y'] : []) + \
1324   ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1325   (x11.found() ? ['CONFIG_X11=y'] : []) + \
1326   ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1327   ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1328   ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1329   (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1330   ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1331   ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
1332   (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
1334 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1336 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1337 actual_target_dirs = []
1338 fdt_required = []
1339 foreach target : target_dirs
1340   config_target = { 'TARGET_NAME': target.split('-')[0] }
1341   if target.endswith('linux-user')
1342     if targetos != 'linux'
1343       if default_targets
1344         continue
1345       endif
1346       error('Target @0@ is only available on a Linux host'.format(target))
1347     endif
1348     config_target += { 'CONFIG_LINUX_USER': 'y' }
1349   elif target.endswith('bsd-user')
1350     if 'CONFIG_BSD' not in config_host
1351       if default_targets
1352         continue
1353       endif
1354       error('Target @0@ is only available on a BSD host'.format(target))
1355     endif
1356     config_target += { 'CONFIG_BSD_USER': 'y' }
1357   elif target.endswith('softmmu')
1358     config_target += { 'CONFIG_SOFTMMU': 'y' }
1359   endif
1360   if target.endswith('-user')
1361     config_target += {
1362       'CONFIG_USER_ONLY': 'y',
1363       'CONFIG_QEMU_INTERP_PREFIX':
1364         config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1365     }
1366   endif
1368   accel_kconfig = []
1369   foreach sym: accelerators
1370     if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1371       config_target += { sym: 'y' }
1372       config_all += { sym: 'y' }
1373       if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
1374         config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
1375       elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1376         config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1377       endif
1378       accel_kconfig += [ sym + '=y' ]
1379     endif
1380   endforeach
1381   if accel_kconfig.length() == 0
1382     if default_targets
1383       continue
1384     endif
1385     error('No accelerator available for target @0@'.format(target))
1386   endif
1388   actual_target_dirs += target
1389   config_target += keyval.load('default-configs/targets' / target + '.mak')
1390   config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1392   if 'TARGET_NEED_FDT' in config_target
1393     fdt_required += target
1394   endif
1396   # Add default keys
1397   if 'TARGET_BASE_ARCH' not in config_target
1398     config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1399   endif
1400   if 'TARGET_ABI_DIR' not in config_target
1401     config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1402   endif
1404   foreach k, v: disassemblers
1405     if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1406       foreach sym: v
1407         config_target += { sym: 'y' }
1408         config_all_disas += { sym: 'y' }
1409       endforeach
1410     endif
1411   endforeach
1413   config_target_data = configuration_data()
1414   foreach k, v: config_target
1415     if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1416       # do nothing
1417     elif ignored.contains(k)
1418       # do nothing
1419     elif k == 'TARGET_BASE_ARCH'
1420       # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1421       # not used to select files from sourcesets.
1422       config_target_data.set('TARGET_' + v.to_upper(), 1)
1423     elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1424       config_target_data.set_quoted(k, v)
1425     elif v == 'y'
1426       config_target_data.set(k, 1)
1427     else
1428       config_target_data.set(k, v)
1429     endif
1430   endforeach
1431   config_target_h += {target: configure_file(output: target + '-config-target.h',
1432                                                configuration: config_target_data)}
1434   if target.endswith('-softmmu')
1435     config_devices_mak = target + '-config-devices.mak'
1436     config_devices_mak = configure_file(
1437       input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
1438       output: config_devices_mak,
1439       depfile: config_devices_mak + '.d',
1440       capture: true,
1441       command: [minikconf,
1442                 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1443                 config_devices_mak, '@DEPFILE@', '@INPUT@',
1444                 host_kconfig, accel_kconfig])
1446     config_devices_data = configuration_data()
1447     config_devices = keyval.load(config_devices_mak)
1448     foreach k, v: config_devices
1449       config_devices_data.set(k, 1)
1450     endforeach
1451     config_devices_mak_list += config_devices_mak
1452     config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1453                                                 configuration: config_devices_data)}
1454     config_target += config_devices
1455     config_all_devices += config_devices
1456   endif
1457   config_target_mak += {target: config_target}
1458 endforeach
1459 target_dirs = actual_target_dirs
1461 # This configuration is used to build files that are shared by
1462 # multiple binaries, and then extracted out of the "common"
1463 # static_library target.
1465 # We do not use all_sources()/all_dependencies(), because it would
1466 # build literally all source files, including devices only used by
1467 # targets that are not built for this compilation.  The CONFIG_ALL
1468 # pseudo symbol replaces it.
1470 config_all += config_all_devices
1471 config_all += config_host
1472 config_all += config_all_disas
1473 config_all += {
1474   'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1475   'CONFIG_SOFTMMU': have_system,
1476   'CONFIG_USER_ONLY': have_user,
1477   'CONFIG_ALL': true,
1480 ##############
1481 # Submodules #
1482 ##############
1484 capstone = not_found
1485 capstone_opt = get_option('capstone')
1486 if capstone_opt in ['enabled', 'auto', 'system']
1487   have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1488   capstone = dependency('capstone', version: '>=4.0',
1489                         kwargs: static_kwargs, method: 'pkg-config',
1490                         required: capstone_opt == 'system' or
1491                                   capstone_opt == 'enabled' and not have_internal)
1492   if capstone.found()
1493     capstone_opt = 'system'
1494   elif have_internal
1495     capstone_opt = 'internal'
1496   else
1497     capstone_opt = 'disabled'
1498   endif
1499 endif
1500 if capstone_opt == 'internal'
1501   capstone_data = configuration_data()
1502   capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1504   capstone_files = files(
1505     'capstone/cs.c',
1506     'capstone/MCInst.c',
1507     'capstone/MCInstrDesc.c',
1508     'capstone/MCRegisterInfo.c',
1509     'capstone/SStream.c',
1510     'capstone/utils.c'
1511   )
1513   if 'CONFIG_ARM_DIS' in config_all_disas
1514     capstone_data.set('CAPSTONE_HAS_ARM', '1')
1515     capstone_files += files(
1516       'capstone/arch/ARM/ARMDisassembler.c',
1517       'capstone/arch/ARM/ARMInstPrinter.c',
1518       'capstone/arch/ARM/ARMMapping.c',
1519       'capstone/arch/ARM/ARMModule.c'
1520     )
1521   endif
1523   # FIXME: This config entry currently depends on a c++ compiler.
1524   # Which is needed for building libvixl, but not for capstone.
1525   if 'CONFIG_ARM_A64_DIS' in config_all_disas
1526     capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1527     capstone_files += files(
1528       'capstone/arch/AArch64/AArch64BaseInfo.c',
1529       'capstone/arch/AArch64/AArch64Disassembler.c',
1530       'capstone/arch/AArch64/AArch64InstPrinter.c',
1531       'capstone/arch/AArch64/AArch64Mapping.c',
1532       'capstone/arch/AArch64/AArch64Module.c'
1533     )
1534   endif
1536   if 'CONFIG_PPC_DIS' in config_all_disas
1537     capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1538     capstone_files += files(
1539       'capstone/arch/PowerPC/PPCDisassembler.c',
1540       'capstone/arch/PowerPC/PPCInstPrinter.c',
1541       'capstone/arch/PowerPC/PPCMapping.c',
1542       'capstone/arch/PowerPC/PPCModule.c'
1543     )
1544   endif
1546   if 'CONFIG_S390_DIS' in config_all_disas
1547     capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1548     capstone_files += files(
1549       'capstone/arch/SystemZ/SystemZDisassembler.c',
1550       'capstone/arch/SystemZ/SystemZInstPrinter.c',
1551       'capstone/arch/SystemZ/SystemZMapping.c',
1552       'capstone/arch/SystemZ/SystemZModule.c',
1553       'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1554     )
1555   endif
1557   if 'CONFIG_I386_DIS' in config_all_disas
1558     capstone_data.set('CAPSTONE_HAS_X86', 1)
1559     capstone_files += files(
1560       'capstone/arch/X86/X86Disassembler.c',
1561       'capstone/arch/X86/X86DisassemblerDecoder.c',
1562       'capstone/arch/X86/X86ATTInstPrinter.c',
1563       'capstone/arch/X86/X86IntelInstPrinter.c',
1564       'capstone/arch/X86/X86InstPrinterCommon.c',
1565       'capstone/arch/X86/X86Mapping.c',
1566       'capstone/arch/X86/X86Module.c'
1567     )
1568   endif
1570   configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1572   capstone_cargs = [
1573     # FIXME: There does not seem to be a way to completely replace the c_args
1574     # that come from add_project_arguments() -- we can only add to them.
1575     # So: disable all warnings with a big hammer.
1576     '-Wno-error', '-w',
1578     # Include all configuration defines via a header file, which will wind up
1579     # as a dependency on the object file, and thus changes here will result
1580     # in a rebuild.
1581     '-include', 'capstone-defs.h'
1582   ]
1584   libcapstone = static_library('capstone',
1585                                build_by_default: false,
1586                                sources: capstone_files,
1587                                c_args: capstone_cargs,
1588                                include_directories: 'capstone/include')
1589   capstone = declare_dependency(link_with: libcapstone,
1590                                 include_directories: 'capstone/include/capstone')
1591 endif
1593 slirp = not_found
1594 slirp_opt = 'disabled'
1595 if have_system
1596   slirp_opt = get_option('slirp')
1597   if slirp_opt in ['enabled', 'auto', 'system']
1598     have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1599     slirp = dependency('slirp', kwargs: static_kwargs,
1600                        method: 'pkg-config',
1601                        required: slirp_opt == 'system' or
1602                                  slirp_opt == 'enabled' and not have_internal)
1603     if slirp.found()
1604       slirp_opt = 'system'
1605     elif have_internal
1606       slirp_opt = 'internal'
1607     else
1608       slirp_opt = 'disabled'
1609     endif
1610   endif
1611   if slirp_opt == 'internal'
1612     slirp_deps = []
1613     if targetos == 'windows'
1614       slirp_deps = cc.find_library('iphlpapi')
1615     endif
1616     slirp_conf = configuration_data()
1617     slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1618     slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1619     slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1620     slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1621     slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1622     slirp_files = [
1623       'slirp/src/arp_table.c',
1624       'slirp/src/bootp.c',
1625       'slirp/src/cksum.c',
1626       'slirp/src/dhcpv6.c',
1627       'slirp/src/dnssearch.c',
1628       'slirp/src/if.c',
1629       'slirp/src/ip6_icmp.c',
1630       'slirp/src/ip6_input.c',
1631       'slirp/src/ip6_output.c',
1632       'slirp/src/ip_icmp.c',
1633       'slirp/src/ip_input.c',
1634       'slirp/src/ip_output.c',
1635       'slirp/src/mbuf.c',
1636       'slirp/src/misc.c',
1637       'slirp/src/ncsi.c',
1638       'slirp/src/ndp_table.c',
1639       'slirp/src/sbuf.c',
1640       'slirp/src/slirp.c',
1641       'slirp/src/socket.c',
1642       'slirp/src/state.c',
1643       'slirp/src/stream.c',
1644       'slirp/src/tcp_input.c',
1645       'slirp/src/tcp_output.c',
1646       'slirp/src/tcp_subr.c',
1647       'slirp/src/tcp_timer.c',
1648       'slirp/src/tftp.c',
1649       'slirp/src/udp.c',
1650       'slirp/src/udp6.c',
1651       'slirp/src/util.c',
1652       'slirp/src/version.c',
1653       'slirp/src/vmstate.c',
1654     ]
1656     configure_file(
1657       input : 'slirp/src/libslirp-version.h.in',
1658       output : 'libslirp-version.h',
1659       configuration: slirp_conf)
1661     slirp_inc = include_directories('slirp', 'slirp/src')
1662     libslirp = static_library('slirp',
1663                               build_by_default: false,
1664                               sources: slirp_files,
1665                               c_args: slirp_cargs,
1666                               include_directories: slirp_inc)
1667     slirp = declare_dependency(link_with: libslirp,
1668                                dependencies: slirp_deps,
1669                                include_directories: slirp_inc)
1670   endif
1671 endif
1673 # For CFI, we need to compile slirp as a static library together with qemu.
1674 # This is because we register slirp functions as callbacks for QEMU Timers.
1675 # When using a system-wide shared libslirp, the type information for the
1676 # callback is missing and the timer call produces a false positive with CFI.
1678 # Now that slirp_opt has been defined, check if the selected slirp is compatible
1679 # with control-flow integrity.
1680 if get_option('cfi') and slirp_opt == 'system'
1681   error('Control-Flow Integrity is not compatible with system-wide slirp.' \
1682          + ' Please configure with --enable-slirp=git')
1683 endif
1685 fdt = not_found
1686 fdt_opt = get_option('fdt')
1687 if have_system
1688   if fdt_opt in ['enabled', 'auto', 'system']
1689     have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1690     fdt = cc.find_library('fdt', kwargs: static_kwargs,
1691                           required: fdt_opt == 'system' or
1692                                     fdt_opt == 'enabled' and not have_internal)
1693     if fdt.found() and cc.links('''
1694        #include <libfdt.h>
1695        #include <libfdt_env.h>
1696        int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1697          dependencies: fdt)
1698       fdt_opt = 'system'
1699     elif have_internal
1700       fdt_opt = 'internal'
1701     else
1702       fdt_opt = 'disabled'
1703     endif
1704   endif
1705   if fdt_opt == 'internal'
1706     fdt_files = files(
1707       'dtc/libfdt/fdt.c',
1708       'dtc/libfdt/fdt_ro.c',
1709       'dtc/libfdt/fdt_wip.c',
1710       'dtc/libfdt/fdt_sw.c',
1711       'dtc/libfdt/fdt_rw.c',
1712       'dtc/libfdt/fdt_strerror.c',
1713       'dtc/libfdt/fdt_empty_tree.c',
1714       'dtc/libfdt/fdt_addresses.c',
1715       'dtc/libfdt/fdt_overlay.c',
1716       'dtc/libfdt/fdt_check.c',
1717     )
1719     fdt_inc = include_directories('dtc/libfdt')
1720     libfdt = static_library('fdt',
1721                             build_by_default: false,
1722                             sources: fdt_files,
1723                             include_directories: fdt_inc)
1724     fdt = declare_dependency(link_with: libfdt,
1725                              include_directories: fdt_inc)
1726   endif
1727 endif
1728 if not fdt.found() and fdt_required.length() > 0
1729   error('fdt not available but required by targets ' + ', '.join(fdt_required))
1730 endif
1732 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1733 config_host_data.set('CONFIG_FDT', fdt.found())
1734 config_host_data.set('CONFIG_SLIRP', slirp.found())
1736 #####################
1737 # Generated sources #
1738 #####################
1740 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1742 hxtool = find_program('scripts/hxtool')
1743 shaderinclude = find_program('scripts/shaderinclude.pl')
1744 qapi_gen = find_program('scripts/qapi-gen.py')
1745 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1746                      meson.source_root() / 'scripts/qapi/commands.py',
1747                      meson.source_root() / 'scripts/qapi/common.py',
1748                      meson.source_root() / 'scripts/qapi/error.py',
1749                      meson.source_root() / 'scripts/qapi/events.py',
1750                      meson.source_root() / 'scripts/qapi/expr.py',
1751                      meson.source_root() / 'scripts/qapi/gen.py',
1752                      meson.source_root() / 'scripts/qapi/introspect.py',
1753                      meson.source_root() / 'scripts/qapi/parser.py',
1754                      meson.source_root() / 'scripts/qapi/schema.py',
1755                      meson.source_root() / 'scripts/qapi/source.py',
1756                      meson.source_root() / 'scripts/qapi/types.py',
1757                      meson.source_root() / 'scripts/qapi/visit.py',
1758                      meson.source_root() / 'scripts/qapi/common.py',
1759                      meson.source_root() / 'scripts/qapi-gen.py'
1762 tracetool = [
1763   python, files('scripts/tracetool.py'),
1764    '--backend=' + config_host['TRACE_BACKENDS']
1766 tracetool_depends = files(
1767   'scripts/tracetool/backend/log.py',
1768   'scripts/tracetool/backend/__init__.py',
1769   'scripts/tracetool/backend/dtrace.py',
1770   'scripts/tracetool/backend/ftrace.py',
1771   'scripts/tracetool/backend/simple.py',
1772   'scripts/tracetool/backend/syslog.py',
1773   'scripts/tracetool/backend/ust.py',
1774   'scripts/tracetool/format/tcg_h.py',
1775   'scripts/tracetool/format/ust_events_c.py',
1776   'scripts/tracetool/format/ust_events_h.py',
1777   'scripts/tracetool/format/__init__.py',
1778   'scripts/tracetool/format/d.py',
1779   'scripts/tracetool/format/tcg_helper_c.py',
1780   'scripts/tracetool/format/simpletrace_stap.py',
1781   'scripts/tracetool/format/c.py',
1782   'scripts/tracetool/format/h.py',
1783   'scripts/tracetool/format/tcg_helper_h.py',
1784   'scripts/tracetool/format/log_stap.py',
1785   'scripts/tracetool/format/stap.py',
1786   'scripts/tracetool/format/tcg_helper_wrapper_h.py',
1787   'scripts/tracetool/__init__.py',
1788   'scripts/tracetool/transform.py',
1789   'scripts/tracetool/vcpu.py'
1792 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1793                     meson.current_source_dir(),
1794                     config_host['PKGVERSION'], meson.project_version()]
1795 qemu_version = custom_target('qemu-version.h',
1796                              output: 'qemu-version.h',
1797                              command: qemu_version_cmd,
1798                              capture: true,
1799                              build_by_default: true,
1800                              build_always_stale: true)
1801 genh += qemu_version
1803 hxdep = []
1804 hx_headers = [
1805   ['qemu-options.hx', 'qemu-options.def'],
1806   ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1808 if have_system
1809   hx_headers += [
1810     ['hmp-commands.hx', 'hmp-commands.h'],
1811     ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1812   ]
1813 endif
1814 foreach d : hx_headers
1815   hxdep += custom_target(d[1],
1816                 input: files(d[0]),
1817                 output: d[1],
1818                 capture: true,
1819                 build_by_default: true, # to be removed when added to a target
1820                 command: [hxtool, '-h', '@INPUT0@'])
1821 endforeach
1822 genh += hxdep
1824 ###################
1825 # Collect sources #
1826 ###################
1828 authz_ss = ss.source_set()
1829 blockdev_ss = ss.source_set()
1830 block_ss = ss.source_set()
1831 bsd_user_ss = ss.source_set()
1832 chardev_ss = ss.source_set()
1833 common_ss = ss.source_set()
1834 crypto_ss = ss.source_set()
1835 io_ss = ss.source_set()
1836 linux_user_ss = ss.source_set()
1837 qmp_ss = ss.source_set()
1838 qom_ss = ss.source_set()
1839 softmmu_ss = ss.source_set()
1840 specific_fuzz_ss = ss.source_set()
1841 specific_ss = ss.source_set()
1842 stub_ss = ss.source_set()
1843 trace_ss = ss.source_set()
1844 user_ss = ss.source_set()
1845 util_ss = ss.source_set()
1847 modules = {}
1848 hw_arch = {}
1849 target_arch = {}
1850 target_softmmu_arch = {}
1851 target_user_arch = {}
1853 ###############
1854 # Trace files #
1855 ###############
1857 # TODO: add each directory to the subdirs from its own meson.build, once
1858 # we have those
1859 trace_events_subdirs = [
1860   'crypto',
1861   'qapi',
1862   'qom',
1863   'monitor',
1864   'util',
1866 if have_user
1867   trace_events_subdirs += [ 'linux-user' ]
1868 endif
1869 if have_block
1870   trace_events_subdirs += [
1871     'authz',
1872     'block',
1873     'io',
1874     'nbd',
1875     'scsi',
1876   ]
1877 endif
1878 if have_system
1879   trace_events_subdirs += [
1880     'accel/kvm',
1881     'audio',
1882     'backends',
1883     'backends/tpm',
1884     'chardev',
1885     'ebpf',
1886     'hw/9pfs',
1887     'hw/acpi',
1888     'hw/adc',
1889     'hw/alpha',
1890     'hw/arm',
1891     'hw/audio',
1892     'hw/block',
1893     'hw/block/dataplane',
1894     'hw/char',
1895     'hw/display',
1896     'hw/dma',
1897     'hw/hppa',
1898     'hw/hyperv',
1899     'hw/i2c',
1900     'hw/i386',
1901     'hw/i386/xen',
1902     'hw/ide',
1903     'hw/input',
1904     'hw/intc',
1905     'hw/isa',
1906     'hw/mem',
1907     'hw/mips',
1908     'hw/misc',
1909     'hw/misc/macio',
1910     'hw/net',
1911     'hw/net/can',
1912     'hw/nvme',
1913     'hw/nvram',
1914     'hw/pci',
1915     'hw/pci-host',
1916     'hw/ppc',
1917     'hw/rdma',
1918     'hw/rdma/vmw',
1919     'hw/rtc',
1920     'hw/s390x',
1921     'hw/scsi',
1922     'hw/sd',
1923     'hw/sparc',
1924     'hw/sparc64',
1925     'hw/ssi',
1926     'hw/timer',
1927     'hw/tpm',
1928     'hw/usb',
1929     'hw/vfio',
1930     'hw/virtio',
1931     'hw/watchdog',
1932     'hw/xen',
1933     'hw/gpio',
1934     'migration',
1935     'net',
1936     'softmmu',
1937     'ui',
1938     'hw/remote',
1939   ]
1940 endif
1941 if have_system or have_user
1942   trace_events_subdirs += [
1943     'accel/tcg',
1944     'hw/core',
1945     'target/arm',
1946     'target/hppa',
1947     'target/i386',
1948     'target/i386/kvm',
1949     'target/mips',
1950     'target/ppc',
1951     'target/riscv',
1952     'target/s390x',
1953     'target/sparc',
1954   ]
1955 endif
1957 vhost_user = not_found
1958 if 'CONFIG_VHOST_USER' in config_host
1959   libvhost_user = subproject('libvhost-user')
1960   vhost_user = libvhost_user.get_variable('vhost_user_dep')
1961 endif
1963 subdir('qapi')
1964 subdir('qobject')
1965 subdir('stubs')
1966 subdir('trace')
1967 subdir('util')
1968 subdir('qom')
1969 subdir('authz')
1970 subdir('crypto')
1971 subdir('ui')
1974 if enable_modules
1975   libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1976   modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1977 endif
1979 stub_ss = stub_ss.apply(config_all, strict: false)
1981 util_ss.add_all(trace_ss)
1982 util_ss = util_ss.apply(config_all, strict: false)
1983 libqemuutil = static_library('qemuutil',
1984                              sources: util_ss.sources() + stub_ss.sources() + genh,
1985                              dependencies: [util_ss.dependencies(), libm, glib, socket, malloc, pixman])
1986 qemuutil = declare_dependency(link_with: libqemuutil,
1987                               sources: genh + version_res)
1989 if have_system or have_user
1990   decodetree = generator(find_program('scripts/decodetree.py'),
1991                          output: 'decode-@BASENAME@.c.inc',
1992                          arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1993   subdir('libdecnumber')
1994   subdir('target')
1995 endif
1997 subdir('audio')
1998 subdir('io')
1999 subdir('chardev')
2000 subdir('fsdev')
2001 subdir('dump')
2003 if have_block
2004   block_ss.add(files(
2005     'block.c',
2006     'blockjob.c',
2007     'job.c',
2008     'qemu-io-cmds.c',
2009   ))
2010   block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
2012   subdir('nbd')
2013   subdir('scsi')
2014   subdir('block')
2016   blockdev_ss.add(files(
2017     'blockdev.c',
2018     'blockdev-nbd.c',
2019     'iothread.c',
2020     'job-qmp.c',
2021   ), gnutls)
2023   # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
2024   # os-win32.c does not
2025   blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
2026   softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
2027 endif
2029 common_ss.add(files('cpus-common.c'))
2031 subdir('softmmu')
2033 common_ss.add(capstone)
2034 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
2036 # Work around a gcc bug/misfeature wherein constant propagation looks
2037 # through an alias:
2038 #   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
2039 # to guess that a const variable is always zero.  Without lto, this is
2040 # impossible, as the alias is restricted to page-vary-common.c.  Indeed,
2041 # without lto, not even the alias is required -- we simply use different
2042 # declarations in different compilation units.
2043 pagevary = files('page-vary-common.c')
2044 if get_option('b_lto')
2045   pagevary_flags = ['-fno-lto']
2046   if get_option('cfi')
2047     pagevary_flags += '-fno-sanitize=cfi-icall'
2048   endif
2049   pagevary = static_library('page-vary-common', sources: pagevary,
2050                             c_args: pagevary_flags)
2051   pagevary = declare_dependency(link_with: pagevary)
2052 endif
2053 common_ss.add(pagevary)
2054 specific_ss.add(files('page-vary.c'))
2056 subdir('backends')
2057 subdir('disas')
2058 subdir('migration')
2059 subdir('monitor')
2060 subdir('net')
2061 subdir('replay')
2062 subdir('semihosting')
2063 subdir('hw')
2064 subdir('tcg')
2065 subdir('fpu')
2066 subdir('accel')
2067 subdir('plugins')
2068 subdir('bsd-user')
2069 subdir('linux-user')
2070 subdir('ebpf')
2072 common_ss.add(libbpf)
2074 bsd_user_ss.add(files('gdbstub.c'))
2075 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
2077 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
2078 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
2080 # needed for fuzzing binaries
2081 subdir('tests/qtest/libqos')
2082 subdir('tests/qtest/fuzz')
2084 ########################
2085 # Library dependencies #
2086 ########################
2088 block_mods = []
2089 softmmu_mods = []
2090 foreach d, list : modules
2091   foreach m, module_ss : list
2092     if enable_modules and targetos != 'windows'
2093       module_ss = module_ss.apply(config_all, strict: false)
2094       sl = static_library(d + '-' + m, [genh, module_ss.sources()],
2095                           dependencies: [modulecommon, module_ss.dependencies()], pic: true)
2096       if d == 'block'
2097         block_mods += sl
2098       else
2099         softmmu_mods += sl
2100       endif
2101     else
2102       if d == 'block'
2103         block_ss.add_all(module_ss)
2104       else
2105         softmmu_ss.add_all(module_ss)
2106       endif
2107     endif
2108   endforeach
2109 endforeach
2111 nm = find_program('nm')
2112 undefsym = find_program('scripts/undefsym.py')
2113 block_syms = custom_target('block.syms', output: 'block.syms',
2114                              input: [libqemuutil, block_mods],
2115                              capture: true,
2116                              command: [undefsym, nm, '@INPUT@'])
2117 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
2118                              input: [libqemuutil, softmmu_mods],
2119                              capture: true,
2120                              command: [undefsym, nm, '@INPUT@'])
2122 qom_ss = qom_ss.apply(config_host, strict: false)
2123 libqom = static_library('qom', qom_ss.sources() + genh,
2124                         dependencies: [qom_ss.dependencies()],
2125                         name_suffix: 'fa')
2127 qom = declare_dependency(link_whole: libqom)
2129 authz_ss = authz_ss.apply(config_host, strict: false)
2130 libauthz = static_library('authz', authz_ss.sources() + genh,
2131                           dependencies: [authz_ss.dependencies()],
2132                           name_suffix: 'fa',
2133                           build_by_default: false)
2135 authz = declare_dependency(link_whole: libauthz,
2136                            dependencies: qom)
2138 crypto_ss = crypto_ss.apply(config_host, strict: false)
2139 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2140                            dependencies: [crypto_ss.dependencies()],
2141                            name_suffix: 'fa',
2142                            build_by_default: false)
2144 crypto = declare_dependency(link_whole: libcrypto,
2145                             dependencies: [authz, qom])
2147 io_ss = io_ss.apply(config_host, strict: false)
2148 libio = static_library('io', io_ss.sources() + genh,
2149                        dependencies: [io_ss.dependencies()],
2150                        link_with: libqemuutil,
2151                        name_suffix: 'fa',
2152                        build_by_default: false)
2154 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2156 libmigration = static_library('migration', sources: migration_files + genh,
2157                               name_suffix: 'fa',
2158                               build_by_default: false)
2159 migration = declare_dependency(link_with: libmigration,
2160                                dependencies: [zlib, qom, io])
2161 softmmu_ss.add(migration)
2163 block_ss = block_ss.apply(config_host, strict: false)
2164 libblock = static_library('block', block_ss.sources() + genh,
2165                           dependencies: block_ss.dependencies(),
2166                           link_depends: block_syms,
2167                           name_suffix: 'fa',
2168                           build_by_default: false)
2170 block = declare_dependency(link_whole: [libblock],
2171                            link_args: '@block.syms',
2172                            dependencies: [crypto, io])
2174 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2175 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2176                              dependencies: blockdev_ss.dependencies(),
2177                              name_suffix: 'fa',
2178                              build_by_default: false)
2180 blockdev = declare_dependency(link_whole: [libblockdev],
2181                               dependencies: [block])
2183 qmp_ss = qmp_ss.apply(config_host, strict: false)
2184 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2185                         dependencies: qmp_ss.dependencies(),
2186                         name_suffix: 'fa',
2187                         build_by_default: false)
2189 qmp = declare_dependency(link_whole: [libqmp])
2191 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2192                             name_suffix: 'fa',
2193                             dependencies: [gnutls],
2194                             build_by_default: false)
2196 chardev = declare_dependency(link_whole: libchardev)
2198 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
2199                            name_suffix: 'fa',
2200                            build_by_default: false)
2201 hwcore = declare_dependency(link_whole: libhwcore)
2202 common_ss.add(hwcore)
2204 ###########
2205 # Targets #
2206 ###########
2208 foreach m : block_mods + softmmu_mods
2209   shared_module(m.name(),
2210                 name_prefix: '',
2211                 link_whole: m,
2212                 install: true,
2213                 install_dir: qemu_moddir)
2214 endforeach
2216 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2217 common_ss.add(qom, qemuutil)
2219 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2220 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2222 common_all = common_ss.apply(config_all, strict: false)
2223 common_all = static_library('common',
2224                             build_by_default: false,
2225                             sources: common_all.sources() + genh,
2226                             implicit_include_directories: false,
2227                             dependencies: common_all.dependencies(),
2228                             name_suffix: 'fa')
2230 feature_to_c = find_program('scripts/feature_to_c.sh')
2232 emulators = {}
2233 foreach target : target_dirs
2234   config_target = config_target_mak[target]
2235   target_name = config_target['TARGET_NAME']
2236   arch = config_target['TARGET_BASE_ARCH']
2237   arch_srcs = [config_target_h[target]]
2238   arch_deps = []
2239   c_args = ['-DNEED_CPU_H',
2240             '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2241             '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2242   link_args = emulator_link_args
2244   config_target += config_host
2245   target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2246   if targetos == 'linux'
2247     target_inc += include_directories('linux-headers', is_system: true)
2248   endif
2249   if target.endswith('-softmmu')
2250     qemu_target_name = 'qemu-system-' + target_name
2251     target_type='system'
2252     t = target_softmmu_arch[arch].apply(config_target, strict: false)
2253     arch_srcs += t.sources()
2254     arch_deps += t.dependencies()
2256     hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2257     hw = hw_arch[hw_dir].apply(config_target, strict: false)
2258     arch_srcs += hw.sources()
2259     arch_deps += hw.dependencies()
2261     arch_srcs += config_devices_h[target]
2262     link_args += ['@block.syms', '@qemu.syms']
2263   else
2264     abi = config_target['TARGET_ABI_DIR']
2265     target_type='user'
2266     qemu_target_name = 'qemu-' + target_name
2267     if arch in target_user_arch
2268       t = target_user_arch[arch].apply(config_target, strict: false)
2269       arch_srcs += t.sources()
2270       arch_deps += t.dependencies()
2271     endif
2272     if 'CONFIG_LINUX_USER' in config_target
2273       base_dir = 'linux-user'
2274       target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2275     else
2276       base_dir = 'bsd-user'
2277       target_inc += include_directories('bsd-user/freebsd')
2278     endif
2279     target_inc += include_directories(
2280       base_dir,
2281       base_dir / abi,
2282     )
2283     if 'CONFIG_LINUX_USER' in config_target
2284       dir = base_dir / abi
2285       arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2286       if config_target.has_key('TARGET_SYSTBL_ABI')
2287         arch_srcs += \
2288           syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2289                                              extra_args : config_target['TARGET_SYSTBL_ABI'])
2290       endif
2291     endif
2292   endif
2294   if 'TARGET_XML_FILES' in config_target
2295     gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2296                                 output: target + '-gdbstub-xml.c',
2297                                 input: files(config_target['TARGET_XML_FILES'].split()),
2298                                 command: [feature_to_c, '@INPUT@'],
2299                                 capture: true)
2300     arch_srcs += gdbstub_xml
2301   endif
2303   t = target_arch[arch].apply(config_target, strict: false)
2304   arch_srcs += t.sources()
2305   arch_deps += t.dependencies()
2307   target_common = common_ss.apply(config_target, strict: false)
2308   objects = common_all.extract_objects(target_common.sources())
2309   deps = target_common.dependencies()
2311   target_specific = specific_ss.apply(config_target, strict: false)
2312   arch_srcs += target_specific.sources()
2313   arch_deps += target_specific.dependencies()
2315   lib = static_library('qemu-' + target,
2316                  sources: arch_srcs + genh,
2317                  dependencies: arch_deps,
2318                  objects: objects,
2319                  include_directories: target_inc,
2320                  c_args: c_args,
2321                  build_by_default: false,
2322                  name_suffix: 'fa')
2324   if target.endswith('-softmmu')
2325     execs = [{
2326       'name': 'qemu-system-' + target_name,
2327       'gui': false,
2328       'sources': files('softmmu/main.c'),
2329       'dependencies': []
2330     }]
2331     if targetos == 'windows' and (sdl.found() or gtk.found())
2332       execs += [{
2333         'name': 'qemu-system-' + target_name + 'w',
2334         'gui': true,
2335         'sources': files('softmmu/main.c'),
2336         'dependencies': []
2337       }]
2338     endif
2339     if config_host.has_key('CONFIG_FUZZ')
2340       specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2341       execs += [{
2342         'name': 'qemu-fuzz-' + target_name,
2343         'gui': false,
2344         'sources': specific_fuzz.sources(),
2345         'dependencies': specific_fuzz.dependencies(),
2346       }]
2347     endif
2348   else
2349     execs = [{
2350       'name': 'qemu-' + target_name,
2351       'gui': false,
2352       'sources': [],
2353       'dependencies': []
2354     }]
2355   endif
2356   foreach exe: execs
2357     exe_name = exe['name']
2358     exe_sign = 'CONFIG_HVF' in config_target
2359     if exe_sign
2360       exe_name += '-unsigned'
2361     endif
2363     emulator = executable(exe_name, exe['sources'],
2364                install: true,
2365                c_args: c_args,
2366                dependencies: arch_deps + deps + exe['dependencies'],
2367                objects: lib.extract_all_objects(recursive: true),
2368                link_language: link_language,
2369                link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2370                link_args: link_args,
2371                gui_app: exe['gui'])
2373     if exe_sign
2374       emulators += {exe['name'] : custom_target(exe['name'],
2375                    depends: emulator,
2376                    output: exe['name'],
2377                    command: [
2378                      meson.current_source_dir() / 'scripts/entitlement.sh',
2379                      meson.current_build_dir() / exe_name,
2380                      meson.current_build_dir() / exe['name'],
2381                      meson.current_source_dir() / 'accel/hvf/entitlements.plist'
2382                    ])
2383       }
2385       meson.add_install_script('scripts/entitlement.sh', '--install',
2386                                get_option('bindir') / exe_name,
2387                                get_option('bindir') / exe['name'],
2388                                meson.current_source_dir() / 'accel/hvf/entitlements.plist')
2389     else
2390       emulators += {exe['name']: emulator}
2391     endif
2393     if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2394       foreach stp: [
2395         {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2396         {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2397         {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2398         {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2399       ]
2400         custom_target(exe['name'] + stp['ext'],
2401                       input: trace_events_all,
2402                       output: exe['name'] + stp['ext'],
2403                       install: stp['install'],
2404                       install_dir: get_option('datadir') / 'systemtap/tapset',
2405                       command: [
2406                         tracetool, '--group=all', '--format=' + stp['fmt'],
2407                         '--binary=' + stp['bin'],
2408                         '--target-name=' + target_name,
2409                         '--target-type=' + target_type,
2410                         '--probe-prefix=qemu.' + target_type + '.' + target_name,
2411                         '@INPUT@', '@OUTPUT@'
2412                       ],
2413                       depend_files: tracetool_depends)
2414       endforeach
2415     endif
2416   endforeach
2417 endforeach
2419 # Other build targets
2421 if 'CONFIG_PLUGIN' in config_host
2422   install_headers('include/qemu/qemu-plugin.h')
2423 endif
2425 if 'CONFIG_GUEST_AGENT' in config_host
2426   subdir('qga')
2427 elif get_option('guest_agent_msi').enabled()
2428   error('Guest agent MSI requested, but the guest agent is not being built')
2429 endif
2431 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2432 # when we don't build tools or system
2433 if xkbcommon.found()
2434   # used for the update-keymaps target, so include rules even if !have_tools
2435   qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2436                            dependencies: [qemuutil, xkbcommon], install: have_tools)
2437 endif
2439 if have_tools
2440   qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2441              dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2442   qemu_io = executable('qemu-io', files('qemu-io.c'),
2443              dependencies: [block, qemuutil], install: true)
2444   qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2445                dependencies: [blockdev, qemuutil, gnutls], install: true)
2447   subdir('storage-daemon')
2448   subdir('contrib/rdmacm-mux')
2449   subdir('contrib/elf2dmp')
2451   executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2452              dependencies: qemuutil,
2453              install: true)
2455   if 'CONFIG_VHOST_USER' in config_host
2456     subdir('contrib/vhost-user-blk')
2457     subdir('contrib/vhost-user-gpu')
2458     subdir('contrib/vhost-user-input')
2459     subdir('contrib/vhost-user-scsi')
2460   endif
2462   if targetos == 'linux'
2463     executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2464                dependencies: [qemuutil, libcap_ng],
2465                install: true,
2466                install_dir: get_option('libexecdir'))
2468     executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2469                dependencies: [authz, crypto, io, qom, qemuutil,
2470                               libcap_ng, mpathpersist],
2471                install: true)
2472   endif
2474   if 'CONFIG_IVSHMEM' in config_host
2475     subdir('contrib/ivshmem-client')
2476     subdir('contrib/ivshmem-server')
2477   endif
2478 endif
2480 subdir('scripts')
2481 subdir('tools')
2482 subdir('pc-bios')
2483 subdir('docs')
2484 subdir('tests')
2485 if gtk.found()
2486   subdir('po')
2487 endif
2489 if host_machine.system() == 'windows'
2490   nsis_cmd = [
2491     find_program('scripts/nsis.py'),
2492     '@OUTPUT@',
2493     get_option('prefix'),
2494     meson.current_source_dir(),
2495     host_machine.cpu(),
2496     '--',
2497     '-DDISPLAYVERSION=' + meson.project_version(),
2498   ]
2499   if build_docs
2500     nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2501   endif
2502   if gtk.found()
2503     nsis_cmd += '-DCONFIG_GTK=y'
2504   endif
2506   nsis = custom_target('nsis',
2507                        output: 'qemu-setup-' + meson.project_version() + '.exe',
2508                        input: files('qemu.nsi'),
2509                        build_always_stale: true,
2510                        command: nsis_cmd + ['@INPUT@'])
2511   alias_target('installer', nsis)
2512 endif
2514 #########################
2515 # Configuration summary #
2516 #########################
2518 # Directories
2519 summary_info = {}
2520 summary_info += {'Install prefix':    get_option('prefix')}
2521 summary_info += {'BIOS directory':    qemu_datadir}
2522 summary_info += {'firmware path':     get_option('qemu_firmwarepath')}
2523 summary_info += {'binary directory':  get_option('bindir')}
2524 summary_info += {'library directory': get_option('libdir')}
2525 summary_info += {'module directory':  qemu_moddir}
2526 summary_info += {'libexec directory': get_option('libexecdir')}
2527 summary_info += {'include directory': get_option('includedir')}
2528 summary_info += {'config directory':  get_option('sysconfdir')}
2529 if targetos != 'windows'
2530   summary_info += {'local state directory': get_option('localstatedir')}
2531   summary_info += {'Manual directory':      get_option('mandir')}
2532 else
2533   summary_info += {'local state directory': 'queried at runtime'}
2534 endif
2535 summary_info += {'Doc directory':     get_option('docdir')}
2536 summary_info += {'Build directory':   meson.current_build_dir()}
2537 summary_info += {'Source path':       meson.current_source_dir()}
2538 summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
2539 summary(summary_info, bool_yn: true, section: 'Directories')
2541 # Host binaries
2542 summary_info = {}
2543 summary_info += {'git':               config_host['GIT']}
2544 summary_info += {'make':              config_host['MAKE']}
2545 summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2546 summary_info += {'sphinx-build':      sphinx_build.found()}
2547 if config_host.has_key('HAVE_GDB_BIN')
2548   summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
2549 endif
2550 summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
2551 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
2552   summary_info += {'wixl':            wixl.found() ? wixl.full_path() : false}
2553 endif
2554 if slirp_opt != 'disabled' and 'CONFIG_SLIRP_SMBD' in config_host
2555   summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
2556 endif
2557 summary(summary_info, bool_yn: true, section: 'Host binaries')
2559 # Configurable features
2560 summary_info = {}
2561 summary_info += {'Documentation':     build_docs}
2562 summary_info += {'system-mode emulation': have_system}
2563 summary_info += {'user-mode emulation': have_user}
2564 summary_info += {'block layer':       have_block}
2565 summary_info += {'Install blobs':     get_option('install_blobs')}
2566 summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
2567 if config_host.has_key('CONFIG_MODULES')
2568   summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2569 endif
2570 summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
2571 summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
2572 if have_system
2573   summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
2574 endif
2575 summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
2576 if config_host['TRACE_BACKENDS'].split().contains('simple')
2577   summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2578 endif
2579 summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2580 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2581 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2582 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2583 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2584 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2585 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2586 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2587 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2588 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2589 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2590 summary(summary_info, bool_yn: true, section: 'Configurable features')
2592 # Compilation information
2593 summary_info = {}
2594 summary_info += {'host CPU':          cpu}
2595 summary_info += {'host endianness':   build_machine.endian()}
2596 summary_info += {'C compiler':        ' '.join(meson.get_compiler('c').cmd_array())}
2597 summary_info += {'Host C compiler':   ' '.join(meson.get_compiler('c', native: true).cmd_array())}
2598 if link_language == 'cpp'
2599   summary_info += {'C++ compiler':    ' '.join(meson.get_compiler('cpp').cmd_array())}
2600 else
2601   summary_info += {'C++ compiler':      false}
2602 endif
2603 if targetos == 'darwin'
2604   summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
2605 endif
2606 if targetos == 'windows'
2607   if 'WIN_SDK' in config_host
2608     summary_info += {'Windows SDK':   config_host['WIN_SDK']}
2609   endif
2610 endif
2611 summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
2612 summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
2613                                                + ['-O' + get_option('optimization')]
2614                                                + (get_option('debug') ? ['-g'] : []))}
2615 if link_language == 'cpp'
2616   summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
2617                                                + ['-O' + get_option('optimization')]
2618                                                + (get_option('debug') ? ['-g'] : []))}
2619 endif
2620 link_args = get_option(link_language + '_link_args')
2621 if link_args.length() > 0
2622   summary_info += {'LDFLAGS':         ' '.join(link_args)}
2623 endif
2624 summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
2625 summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
2626 summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
2627 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2628 summary_info += {'PIE':               get_option('b_pie')}
2629 summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
2630 summary_info += {'malloc trim support': has_malloc_trim}
2631 summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
2632 summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
2633 summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
2634 summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
2635 summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2636 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2637 summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
2638 summary_info += {'memory allocator':  get_option('malloc')}
2639 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2640 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2641 summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
2642 summary_info += {'gcov':              get_option('b_coverage')}
2643 summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
2644 summary_info += {'CFI support':       get_option('cfi')}
2645 if get_option('cfi')
2646   summary_info += {'CFI debug support': get_option('cfi_debug')}
2647 endif
2648 summary_info += {'strip binaries':    get_option('strip')}
2649 summary_info += {'sparse':            sparse.found() ? sparse.full_path() : false}
2650 summary_info += {'mingw32 support':   targetos == 'windows'}
2652 # snarf the cross-compilation information for tests
2653 foreach target: target_dirs
2654   tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
2655   if fs.exists(tcg_mak)
2656     config_cross_tcg = keyval.load(tcg_mak)
2657     target = config_cross_tcg['TARGET_NAME']
2658     compiler = ''
2659     if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
2660       summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
2661                                           ' via ' + config_cross_tcg['DOCKER_IMAGE']}
2662     elif 'CROSS_CC_GUEST' in config_cross_tcg
2663       summary_info += {target + ' tests'
2664                                 : config_cross_tcg['CROSS_CC_GUEST'] }
2665     endif
2666    endif
2667 endforeach
2669 summary(summary_info, bool_yn: true, section: 'Compilation')
2671 # Targets and accelerators
2672 summary_info = {}
2673 if have_system
2674   summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
2675   summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
2676   summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
2677   summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
2678   summary_info += {'NVMM support':      config_all.has_key('CONFIG_NVMM')}
2679   summary_info += {'Xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
2680   if config_host.has_key('CONFIG_XEN_BACKEND')
2681     summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2682   endif
2683 endif
2684 summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
2685 if config_all.has_key('CONFIG_TCG')
2686   if get_option('tcg_interpreter')
2687     summary_info += {'TCG backend':   'TCI (TCG with bytecode interpreter, experimental and slow)'}
2688   else
2689     summary_info += {'TCG backend':   'native (@0@)'.format(cpu)}
2690   endif
2691   summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2692 endif
2693 summary_info += {'target list':       ' '.join(target_dirs)}
2694 if have_system
2695   summary_info += {'default devices':   get_option('default_devices')}
2696   summary_info += {'out of process emulation': multiprocess_allowed}
2697 endif
2698 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
2700 # Block layer
2701 summary_info = {}
2702 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2703 summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
2704 if have_block
2705   summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2706   summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2707   summary_info += {'VirtFS support':    have_virtfs}
2708   summary_info += {'build virtiofs daemon': have_virtiofsd}
2709   summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2710   summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2711   summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
2712   summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
2713   summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
2714   summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
2715   summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
2716   summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
2717   summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
2718   summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2719   summary_info += {'FUSE exports':      fuse.found()}
2720 endif
2721 summary(summary_info, bool_yn: true, section: 'Block layer support')
2723 # Crypto
2724 summary_info = {}
2725 summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
2726 summary_info += {'GNUTLS support':    gnutls.found()}
2727 # TODO: add back version
2728 summary_info += {'libgcrypt':         gcrypt.found()}
2729 if gcrypt.found()
2730    summary_info += {'  XTS':             xts != 'private'}
2731 endif
2732 # TODO: add back version
2733 summary_info += {'nettle':            nettle.found()}
2734 if nettle.found()
2735    summary_info += {'  XTS':             xts != 'private'}
2736 endif
2737 summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
2738 summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
2739 summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
2740 summary(summary_info, bool_yn: true, section: 'Crypto')
2742 # Libraries
2743 summary_info = {}
2744 if targetos == 'darwin'
2745   summary_info += {'Cocoa support':   cocoa.found()}
2746 endif
2747 # TODO: add back version
2748 summary_info += {'SDL support':       sdl.found()}
2749 summary_info += {'SDL image support': sdl_image.found()}
2750 # TODO: add back version
2751 summary_info += {'GTK support':       gtk.found()}
2752 summary_info += {'pixman':            pixman.found()}
2753 # TODO: add back version
2754 summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
2755 # TODO: add back version
2756 summary_info += {'slirp support':     slirp_opt == 'disabled' ? false : slirp_opt}
2757 summary_info += {'libtasn1':          tasn1.found()}
2758 summary_info += {'PAM':               pam.found()}
2759 summary_info += {'iconv support':     iconv.found()}
2760 summary_info += {'curses support':    curses.found()}
2761 # TODO: add back version
2762 summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
2763 summary_info += {'curl support':      curl.found()}
2764 summary_info += {'Multipath support': mpathpersist.found()}
2765 summary_info += {'VNC support':       vnc.found()}
2766 if vnc.found()
2767   summary_info += {'VNC SASL support':  sasl.found()}
2768   summary_info += {'VNC JPEG support':  jpeg.found()}
2769   summary_info += {'VNC PNG support':   png.found()}
2770 endif
2771 summary_info += {'brlapi support':    brlapi.found()}
2772 summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
2773 summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
2774 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2775 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2776 summary_info += {'ATTR/XATTR support': libattr.found()}
2777 summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
2778 summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
2779 summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
2780 summary_info += {'libcap-ng support': libcap_ng.found()}
2781 summary_info += {'bpf support': libbpf.found()}
2782 # TODO: add back protocol and server version
2783 summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
2784 summary_info += {'rbd support':       rbd.found()}
2785 summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
2786 summary_info += {'smartcard support': cacard.found()}
2787 summary_info += {'U2F support':       u2f.found()}
2788 summary_info += {'libusb':            libusb.found()}
2789 summary_info += {'usb net redir':     usbredir.found()}
2790 summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
2791 summary_info += {'GBM':               config_host.has_key('CONFIG_GBM')}
2792 summary_info += {'libiscsi support':  libiscsi.found()}
2793 summary_info += {'libnfs support':    libnfs.found()}
2794 if targetos == 'windows'
2795   if config_host.has_key('CONFIG_GUEST_AGENT')
2796     summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
2797     summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2798   endif
2799 endif
2800 summary_info += {'seccomp support':   seccomp.found()}
2801 summary_info += {'GlusterFS support': glusterfs.found()}
2802 summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
2803 summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
2804 summary_info += {'lzo support':       lzo.found()}
2805 summary_info += {'snappy support':    snappy.found()}
2806 summary_info += {'bzip2 support':     libbzip2.found()}
2807 summary_info += {'lzfse support':     liblzfse.found()}
2808 summary_info += {'zstd support':      zstd.found()}
2809 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2810 summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
2811 summary_info += {'capstone':          capstone_opt == 'disabled' ? false : capstone_opt}
2812 summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
2813 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2814 summary_info += {'libudev':           libudev.found()}
2815 summary_info += {'FUSE lseek':        fuse_lseek.found()}
2816 summary(summary_info, bool_yn: true, section: 'Dependencies')
2818 if not supported_cpus.contains(cpu)
2819   message()
2820   warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2821   message()
2822   message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2823   message('The QEMU project intends to remove support for this host CPU in')
2824   message('a future release if nobody volunteers to maintain it and to')
2825   message('provide a build host for our continuous integration setup.')
2826   message('configure has succeeded and you can continue to build, but')
2827   message('if you care about QEMU on this platform you should contact')
2828   message('us upstream at qemu-devel@nongnu.org.')
2829 endif
2831 if not supported_oses.contains(targetos)
2832   message()
2833   warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2834   message()
2835   message('Host OS ' + targetos + 'support is not currently maintained.')
2836   message('The QEMU project intends to remove support for this host OS in')
2837   message('a future release if nobody volunteers to maintain it and to')
2838   message('provide a build host for our continuous integration setup.')
2839   message('configure has succeeded and you can continue to build, but')
2840   message('if you care about QEMU on this platform you should contact')
2841   message('us upstream at qemu-devel@nongnu.org.')
2842 endif