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