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