qapi/qom: Add ObjectOptions for secret*, deprecate 'loaded'
[qemu/kevin.git] / meson.build
blob5c85a15364d9c35ee3618796dd5b3d9fa0b96e3e
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('tcg/tci.c'))
1948 subdir('backends')
1949 subdir('disas')
1950 subdir('migration')
1951 subdir('monitor')
1952 subdir('net')
1953 subdir('replay')
1954 subdir('semihosting')
1955 subdir('hw')
1956 subdir('accel')
1957 subdir('plugins')
1958 subdir('bsd-user')
1959 subdir('linux-user')
1961 bsd_user_ss.add(files('gdbstub.c'))
1962 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1964 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1965 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1967 # needed for fuzzing binaries
1968 subdir('tests/qtest/libqos')
1969 subdir('tests/qtest/fuzz')
1971 ########################
1972 # Library dependencies #
1973 ########################
1975 block_mods = []
1976 softmmu_mods = []
1977 foreach d, list : modules
1978   foreach m, module_ss : list
1979     if enable_modules and targetos != 'windows'
1980       module_ss = module_ss.apply(config_all, strict: false)
1981       sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1982                           dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1983       if d == 'block'
1984         block_mods += sl
1985       else
1986         softmmu_mods += sl
1987       endif
1988     else
1989       if d == 'block'
1990         block_ss.add_all(module_ss)
1991       else
1992         softmmu_ss.add_all(module_ss)
1993       endif
1994     endif
1995   endforeach
1996 endforeach
1998 nm = find_program('nm')
1999 undefsym = find_program('scripts/undefsym.py')
2000 block_syms = custom_target('block.syms', output: 'block.syms',
2001                              input: [libqemuutil, block_mods],
2002                              capture: true,
2003                              command: [undefsym, nm, '@INPUT@'])
2004 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
2005                              input: [libqemuutil, softmmu_mods],
2006                              capture: true,
2007                              command: [undefsym, nm, '@INPUT@'])
2009 qom_ss = qom_ss.apply(config_host, strict: false)
2010 libqom = static_library('qom', qom_ss.sources() + genh,
2011                         dependencies: [qom_ss.dependencies()],
2012                         name_suffix: 'fa')
2014 qom = declare_dependency(link_whole: libqom)
2016 authz_ss = authz_ss.apply(config_host, strict: false)
2017 libauthz = static_library('authz', authz_ss.sources() + genh,
2018                           dependencies: [authz_ss.dependencies()],
2019                           name_suffix: 'fa',
2020                           build_by_default: false)
2022 authz = declare_dependency(link_whole: libauthz,
2023                            dependencies: qom)
2025 crypto_ss = crypto_ss.apply(config_host, strict: false)
2026 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2027                            dependencies: [crypto_ss.dependencies()],
2028                            name_suffix: 'fa',
2029                            build_by_default: false)
2031 crypto = declare_dependency(link_whole: libcrypto,
2032                             dependencies: [authz, qom])
2034 io_ss = io_ss.apply(config_host, strict: false)
2035 libio = static_library('io', io_ss.sources() + genh,
2036                        dependencies: [io_ss.dependencies()],
2037                        link_with: libqemuutil,
2038                        name_suffix: 'fa',
2039                        build_by_default: false)
2041 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2043 libmigration = static_library('migration', sources: migration_files + genh,
2044                               name_suffix: 'fa',
2045                               build_by_default: false)
2046 migration = declare_dependency(link_with: libmigration,
2047                                dependencies: [zlib, qom, io])
2048 softmmu_ss.add(migration)
2050 block_ss = block_ss.apply(config_host, strict: false)
2051 libblock = static_library('block', block_ss.sources() + genh,
2052                           dependencies: block_ss.dependencies(),
2053                           link_depends: block_syms,
2054                           name_suffix: 'fa',
2055                           build_by_default: false)
2057 block = declare_dependency(link_whole: [libblock],
2058                            link_args: '@block.syms',
2059                            dependencies: [crypto, io])
2061 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2062 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2063                              dependencies: blockdev_ss.dependencies(),
2064                              name_suffix: 'fa',
2065                              build_by_default: false)
2067 blockdev = declare_dependency(link_whole: [libblockdev],
2068                               dependencies: [block])
2070 qmp_ss = qmp_ss.apply(config_host, strict: false)
2071 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2072                         dependencies: qmp_ss.dependencies(),
2073                         name_suffix: 'fa',
2074                         build_by_default: false)
2076 qmp = declare_dependency(link_whole: [libqmp])
2078 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2079                             name_suffix: 'fa',
2080                             dependencies: [gnutls],
2081                             build_by_default: false)
2083 chardev = declare_dependency(link_whole: libchardev)
2085 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
2086                            name_suffix: 'fa',
2087                            build_by_default: false)
2088 hwcore = declare_dependency(link_whole: libhwcore)
2089 common_ss.add(hwcore)
2091 ###########
2092 # Targets #
2093 ###########
2095 foreach m : block_mods + softmmu_mods
2096   shared_module(m.name(),
2097                 name_prefix: '',
2098                 link_whole: m,
2099                 install: true,
2100                 install_dir: qemu_moddir)
2101 endforeach
2103 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2104 common_ss.add(qom, qemuutil)
2106 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2107 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2109 common_all = common_ss.apply(config_all, strict: false)
2110 common_all = static_library('common',
2111                             build_by_default: false,
2112                             sources: common_all.sources() + genh,
2113                             dependencies: common_all.dependencies(),
2114                             name_suffix: 'fa')
2116 feature_to_c = find_program('scripts/feature_to_c.sh')
2118 emulators = {}
2119 foreach target : target_dirs
2120   config_target = config_target_mak[target]
2121   target_name = config_target['TARGET_NAME']
2122   arch = config_target['TARGET_BASE_ARCH']
2123   arch_srcs = [config_target_h[target]]
2124   arch_deps = []
2125   c_args = ['-DNEED_CPU_H',
2126             '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2127             '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2128   link_args = emulator_link_args
2130   config_target += config_host
2131   target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2132   if targetos == 'linux'
2133     target_inc += include_directories('linux-headers', is_system: true)
2134   endif
2135   if target.endswith('-softmmu')
2136     qemu_target_name = 'qemu-system-' + target_name
2137     target_type='system'
2138     t = target_softmmu_arch[arch].apply(config_target, strict: false)
2139     arch_srcs += t.sources()
2140     arch_deps += t.dependencies()
2142     hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2143     hw = hw_arch[hw_dir].apply(config_target, strict: false)
2144     arch_srcs += hw.sources()
2145     arch_deps += hw.dependencies()
2147     arch_srcs += config_devices_h[target]
2148     link_args += ['@block.syms', '@qemu.syms']
2149   else
2150     abi = config_target['TARGET_ABI_DIR']
2151     target_type='user'
2152     qemu_target_name = 'qemu-' + target_name
2153     if 'CONFIG_LINUX_USER' in config_target
2154       base_dir = 'linux-user'
2155       target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2156     else
2157       base_dir = 'bsd-user'
2158       target_inc += include_directories('bsd-user/freebsd')
2159     endif
2160     target_inc += include_directories(
2161       base_dir,
2162       base_dir / abi,
2163     )
2164     if 'CONFIG_LINUX_USER' in config_target
2165       dir = base_dir / abi
2166       arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2167       if config_target.has_key('TARGET_SYSTBL_ABI')
2168         arch_srcs += \
2169           syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2170                                              extra_args : config_target['TARGET_SYSTBL_ABI'])
2171       endif
2172     endif
2173   endif
2175   if 'TARGET_XML_FILES' in config_target
2176     gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2177                                 output: target + '-gdbstub-xml.c',
2178                                 input: files(config_target['TARGET_XML_FILES'].split()),
2179                                 command: [feature_to_c, '@INPUT@'],
2180                                 capture: true)
2181     arch_srcs += gdbstub_xml
2182   endif
2184   t = target_arch[arch].apply(config_target, strict: false)
2185   arch_srcs += t.sources()
2186   arch_deps += t.dependencies()
2188   target_common = common_ss.apply(config_target, strict: false)
2189   objects = common_all.extract_objects(target_common.sources())
2190   deps = target_common.dependencies()
2192   target_specific = specific_ss.apply(config_target, strict: false)
2193   arch_srcs += target_specific.sources()
2194   arch_deps += target_specific.dependencies()
2196   lib = static_library('qemu-' + target,
2197                  sources: arch_srcs + genh,
2198                  dependencies: arch_deps,
2199                  objects: objects,
2200                  include_directories: target_inc,
2201                  c_args: c_args,
2202                  build_by_default: false,
2203                  name_suffix: 'fa')
2205   if target.endswith('-softmmu')
2206     execs = [{
2207       'name': 'qemu-system-' + target_name,
2208       'gui': false,
2209       'sources': files('softmmu/main.c'),
2210       'dependencies': []
2211     }]
2212     if targetos == 'windows' and (sdl.found() or gtk.found())
2213       execs += [{
2214         'name': 'qemu-system-' + target_name + 'w',
2215         'gui': true,
2216         'sources': files('softmmu/main.c'),
2217         'dependencies': []
2218       }]
2219     endif
2220     if config_host.has_key('CONFIG_FUZZ')
2221       specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2222       execs += [{
2223         'name': 'qemu-fuzz-' + target_name,
2224         'gui': false,
2225         'sources': specific_fuzz.sources(),
2226         'dependencies': specific_fuzz.dependencies(),
2227       }]
2228     endif
2229   else
2230     execs = [{
2231       'name': 'qemu-' + target_name,
2232       'gui': false,
2233       'sources': [],
2234       'dependencies': []
2235     }]
2236   endif
2237   foreach exe: execs
2238     exe_name = exe['name']
2239     exe_sign = 'CONFIG_HVF' in config_target
2240     if exe_sign
2241       exe_name += '-unsigned'
2242     endif
2244     emulator = executable(exe_name, exe['sources'],
2245                install: true,
2246                c_args: c_args,
2247                dependencies: arch_deps + deps + exe['dependencies'],
2248                objects: lib.extract_all_objects(recursive: true),
2249                link_language: link_language,
2250                link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2251                link_args: link_args,
2252                gui_app: exe['gui'])
2254     if exe_sign
2255       emulators += {exe['name'] : custom_target(exe['name'],
2256                    depends: emulator,
2257                    output: exe['name'],
2258                    command: [
2259                      meson.current_source_dir() / 'scripts/entitlement.sh',
2260                      meson.current_build_dir() / exe_name,
2261                      meson.current_build_dir() / exe['name'],
2262                      meson.current_source_dir() / 'accel/hvf/entitlements.plist'
2263                    ])
2264       }
2266       meson.add_install_script('scripts/entitlement.sh', '--install',
2267                                get_option('bindir') / exe_name,
2268                                get_option('bindir') / exe['name'],
2269                                meson.current_source_dir() / 'accel/hvf/entitlements.plist')
2270     else
2271       emulators += {exe['name']: emulator}
2272     endif
2274     if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2275       foreach stp: [
2276         {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2277         {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2278         {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2279         {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2280       ]
2281         custom_target(exe['name'] + stp['ext'],
2282                       input: trace_events_all,
2283                       output: exe['name'] + stp['ext'],
2284                       install: stp['install'],
2285                       install_dir: get_option('datadir') / 'systemtap/tapset',
2286                       command: [
2287                         tracetool, '--group=all', '--format=' + stp['fmt'],
2288                         '--binary=' + stp['bin'],
2289                         '--target-name=' + target_name,
2290                         '--target-type=' + target_type,
2291                         '--probe-prefix=qemu.' + target_type + '.' + target_name,
2292                         '@INPUT@', '@OUTPUT@'
2293                       ],
2294                       depend_files: tracetool_depends)
2295       endforeach
2296     endif
2297   endforeach
2298 endforeach
2300 # Other build targets
2302 if 'CONFIG_PLUGIN' in config_host
2303   install_headers('include/qemu/qemu-plugin.h')
2304 endif
2306 if 'CONFIG_GUEST_AGENT' in config_host
2307   subdir('qga')
2308 elif get_option('guest_agent_msi').enabled()
2309   error('Guest agent MSI requested, but the guest agent is not being built')
2310 endif
2312 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2313 # when we don't build tools or system
2314 if xkbcommon.found()
2315   # used for the update-keymaps target, so include rules even if !have_tools
2316   qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2317                            dependencies: [qemuutil, xkbcommon], install: have_tools)
2318 endif
2320 if have_tools
2321   qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2322              dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2323   qemu_io = executable('qemu-io', files('qemu-io.c'),
2324              dependencies: [block, qemuutil], install: true)
2325   qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2326                dependencies: [blockdev, qemuutil, gnutls], install: true)
2328   subdir('storage-daemon')
2329   subdir('contrib/rdmacm-mux')
2330   subdir('contrib/elf2dmp')
2332   executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2333              dependencies: qemuutil,
2334              install: true)
2336   if 'CONFIG_VHOST_USER' in config_host
2337     subdir('contrib/vhost-user-blk')
2338     subdir('contrib/vhost-user-gpu')
2339     subdir('contrib/vhost-user-input')
2340     subdir('contrib/vhost-user-scsi')
2341   endif
2343   if targetos == 'linux'
2344     executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2345                dependencies: [qemuutil, libcap_ng],
2346                install: true,
2347                install_dir: get_option('libexecdir'))
2349     executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2350                dependencies: [authz, crypto, io, qom, qemuutil,
2351                               libcap_ng, mpathpersist],
2352                install: true)
2353   endif
2355   if 'CONFIG_IVSHMEM' in config_host
2356     subdir('contrib/ivshmem-client')
2357     subdir('contrib/ivshmem-server')
2358   endif
2359 endif
2361 subdir('scripts')
2362 subdir('tools')
2363 subdir('pc-bios')
2364 subdir('docs')
2365 subdir('tests')
2366 if gtk.found()
2367   subdir('po')
2368 endif
2370 if host_machine.system() == 'windows'
2371   nsis_cmd = [
2372     find_program('scripts/nsis.py'),
2373     '@OUTPUT@',
2374     get_option('prefix'),
2375     meson.current_source_dir(),
2376     host_machine.cpu(),
2377     '--',
2378     '-DDISPLAYVERSION=' + meson.project_version(),
2379   ]
2380   if build_docs
2381     nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2382   endif
2383   if gtk.found()
2384     nsis_cmd += '-DCONFIG_GTK=y'
2385   endif
2387   nsis = custom_target('nsis',
2388                        output: 'qemu-setup-' + meson.project_version() + '.exe',
2389                        input: files('qemu.nsi'),
2390                        build_always_stale: true,
2391                        command: nsis_cmd + ['@INPUT@'])
2392   alias_target('installer', nsis)
2393 endif
2395 #########################
2396 # Configuration summary #
2397 #########################
2399 # Directories
2400 summary_info = {}
2401 summary_info += {'Install prefix':    get_option('prefix')}
2402 summary_info += {'BIOS directory':    qemu_datadir}
2403 summary_info += {'firmware path':     get_option('qemu_firmwarepath')}
2404 summary_info += {'binary directory':  get_option('bindir')}
2405 summary_info += {'library directory': get_option('libdir')}
2406 summary_info += {'module directory':  qemu_moddir}
2407 summary_info += {'libexec directory': get_option('libexecdir')}
2408 summary_info += {'include directory': get_option('includedir')}
2409 summary_info += {'config directory':  get_option('sysconfdir')}
2410 if targetos != 'windows'
2411   summary_info += {'local state directory': get_option('localstatedir')}
2412   summary_info += {'Manual directory':      get_option('mandir')}
2413 else
2414   summary_info += {'local state directory': 'queried at runtime'}
2415 endif
2416 summary_info += {'Doc directory':     get_option('docdir')}
2417 summary_info += {'Build directory':   meson.current_build_dir()}
2418 summary_info += {'Source path':       meson.current_source_dir()}
2419 summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
2420 summary(summary_info, bool_yn: true, section: 'Directories')
2422 # Host binaries
2423 summary_info = {}
2424 summary_info += {'git':               config_host['GIT']}
2425 summary_info += {'make':              config_host['MAKE']}
2426 summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2427 summary_info += {'sphinx-build':      sphinx_build.found()}
2428 if config_host.has_key('HAVE_GDB_BIN')
2429   summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
2430 endif
2431 summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
2432 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
2433   summary_info += {'wixl':            wixl.found() ? wixl.full_path() : false}
2434 endif
2435 if slirp_opt != 'disabled'
2436   summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
2437 endif
2438 summary(summary_info, bool_yn: true, section: 'Host binaries')
2440 # Configurable features
2441 summary_info = {}
2442 summary_info += {'Documentation':     build_docs}
2443 summary_info += {'system-mode emulation': have_system}
2444 summary_info += {'user-mode emulation': have_user}
2445 summary_info += {'block layer':       have_block}
2446 summary_info += {'Install blobs':     get_option('install_blobs')}
2447 summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
2448 if config_host.has_key('CONFIG_MODULES')
2449   summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2450 endif
2451 summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
2452 summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
2453 if have_system
2454   summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
2455 endif
2456 summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
2457 if config_host['TRACE_BACKENDS'].split().contains('simple')
2458   summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2459 endif
2460 summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2461 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2462 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2463 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2464 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2465 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2466 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2467 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2468 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2469 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2470 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2471 summary(summary_info, bool_yn: true, section: 'Configurable features')
2473 # Compilation information
2474 summary_info = {}
2475 summary_info += {'host CPU':          cpu}
2476 summary_info += {'host endianness':   build_machine.endian()}
2477 summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
2478 summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
2479 if link_language == 'cpp'
2480   summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
2481 else
2482   summary_info += {'C++ compiler':      false}
2483 endif
2484 if targetos == 'darwin'
2485   summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
2486 endif
2487 if targetos == 'windows'
2488   if 'WIN_SDK' in config_host
2489     summary_info += {'Windows SDK':   config_host['WIN_SDK']}
2490   endif
2491 endif
2492 summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
2493 summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
2494                                                + ['-O' + get_option('optimization')]
2495                                                + (get_option('debug') ? ['-g'] : []))}
2496 if link_language == 'cpp'
2497   summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
2498                                                + ['-O' + get_option('optimization')]
2499                                                + (get_option('debug') ? ['-g'] : []))}
2500 endif
2501 link_args = get_option(link_language + '_link_args')
2502 if link_args.length() > 0
2503   summary_info += {'LDFLAGS':         ' '.join(link_args)}
2504 endif
2505 summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
2506 summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
2507 summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
2508 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2509 summary_info += {'PIE':               get_option('b_pie')}
2510 summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
2511 summary_info += {'malloc trim support': has_malloc_trim}
2512 summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
2513 summary_info += {'preadv support':    config_host_data.get('CONFIG_PREADV')}
2514 summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
2515 summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
2516 summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
2517 summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2518 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2519 summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
2520 summary_info += {'memory allocator':  get_option('malloc')}
2521 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2522 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2523 summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
2524 summary_info += {'gcov':              get_option('b_coverage')}
2525 summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
2526 summary_info += {'CFI support':       get_option('cfi')}
2527 if get_option('cfi')
2528   summary_info += {'CFI debug support': get_option('cfi_debug')}
2529 endif
2530 summary_info += {'strip binaries':    get_option('strip')}
2531 summary_info += {'sparse':            sparse.found() ? sparse.full_path() : false}
2532 summary_info += {'mingw32 support':   targetos == 'windows'}
2534 # snarf the cross-compilation information for tests
2535 foreach target: target_dirs
2536   tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
2537   if fs.exists(tcg_mak)
2538     config_cross_tcg = keyval.load(tcg_mak)
2539     target = config_cross_tcg['TARGET_NAME']
2540     compiler = ''
2541     if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
2542       summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
2543                                           ' via ' + config_cross_tcg['DOCKER_IMAGE']}
2544     elif 'CROSS_CC_GUEST' in config_cross_tcg
2545       summary_info += {target + ' tests'
2546                                 : config_cross_tcg['CROSS_CC_GUEST'] }
2547     endif
2548    endif
2549 endforeach
2551 summary(summary_info, bool_yn: true, section: 'Compilation')
2553 # Targets and accelerators
2554 summary_info = {}
2555 if have_system
2556   summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
2557   summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
2558   summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
2559   summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
2560   summary_info += {'Xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
2561   if config_host.has_key('CONFIG_XEN_BACKEND')
2562     summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2563   endif
2564 endif
2565 summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
2566 if config_all.has_key('CONFIG_TCG')
2567   if get_option('tcg_interpreter')
2568     summary_info += {'TCG backend':   'TCI (TCG with bytecode interpreter, experimental and slow)'}
2569   else
2570     summary_info += {'TCG backend':   'native (@0@)'.format(cpu)}
2571   endif
2572   summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2573 endif
2574 summary_info += {'target list':       ' '.join(target_dirs)}
2575 if have_system
2576   summary_info += {'default devices':   get_option('default_devices')}
2577   summary_info += {'out of process emulation': multiprocess_allowed}
2578 endif
2579 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
2581 # Block layer
2582 summary_info = {}
2583 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2584 summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
2585 if have_block
2586   summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2587   summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2588   summary_info += {'VirtFS support':    have_virtfs}
2589   summary_info += {'build virtiofs daemon': have_virtiofsd}
2590   summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2591   summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2592   summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
2593   summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
2594   summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
2595   summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
2596   summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
2597   summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
2598   summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
2599   summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2600   summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
2601   summary_info += {'FUSE exports':      fuse.found()}
2602 endif
2603 summary(summary_info, bool_yn: true, section: 'Block layer support')
2605 # Crypto
2606 summary_info = {}
2607 summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
2608 summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
2609 # TODO: add back version
2610 summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
2611 if config_host.has_key('CONFIG_GCRYPT')
2612    summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
2613    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2614 endif
2615 # TODO: add back version
2616 summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
2617 if config_host.has_key('CONFIG_NETTLE')
2618    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2619 endif
2620 summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
2621 summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
2622 summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
2623 summary(summary_info, bool_yn: true, section: 'Crypto')
2625 # Libraries
2626 summary_info = {}
2627 if targetos == 'darwin'
2628   summary_info += {'Cocoa support':   cocoa.found()}
2629 endif
2630 # TODO: add back version
2631 summary_info += {'SDL support':       sdl.found()}
2632 summary_info += {'SDL image support': sdl_image.found()}
2633 # TODO: add back version
2634 summary_info += {'GTK support':       gtk.found()}
2635 summary_info += {'pixman':            pixman.found()}
2636 # TODO: add back version
2637 summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
2638 # TODO: add back version
2639 summary_info += {'slirp support':     slirp_opt == 'disabled' ? false : slirp_opt}
2640 summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
2641 summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
2642 summary_info += {'iconv support':     iconv.found()}
2643 summary_info += {'curses support':    curses.found()}
2644 # TODO: add back version
2645 summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
2646 summary_info += {'curl support':      curl.found()}
2647 summary_info += {'Multipath support': mpathpersist.found()}
2648 summary_info += {'VNC support':       vnc.found()}
2649 if vnc.found()
2650   summary_info += {'VNC SASL support':  sasl.found()}
2651   summary_info += {'VNC JPEG support':  jpeg.found()}
2652   summary_info += {'VNC PNG support':   png.found()}
2653 endif
2654 summary_info += {'brlapi support':    brlapi.found()}
2655 summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
2656 summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
2657 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2658 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2659 summary_info += {'ATTR/XATTR support': libattr.found()}
2660 summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
2661 summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
2662 summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
2663 summary_info += {'libcap-ng support': libcap_ng.found()}
2664 # TODO: add back protocol and server version
2665 summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
2666 summary_info += {'rbd support':       rbd.found()}
2667 summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
2668 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2669 summary_info += {'U2F support':       u2f.found()}
2670 summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
2671 summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
2672 summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
2673 summary_info += {'GBM':               config_host.has_key('CONFIG_GBM')}
2674 summary_info += {'libiscsi support':  libiscsi.found()}
2675 summary_info += {'libnfs support':    libnfs.found()}
2676 if targetos == 'windows'
2677   if config_host.has_key('CONFIG_GUEST_AGENT')
2678     summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
2679     summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2680   endif
2681 endif
2682 summary_info += {'seccomp support':   seccomp.found()}
2683 summary_info += {'GlusterFS support': glusterfs.found()}
2684 summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
2685 summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
2686 summary_info += {'lzo support':       lzo.found()}
2687 summary_info += {'snappy support':    snappy.found()}
2688 summary_info += {'bzip2 support':     libbzip2.found()}
2689 summary_info += {'lzfse support':     liblzfse.found()}
2690 summary_info += {'zstd support':      zstd.found()}
2691 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2692 summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
2693 summary_info += {'capstone':          capstone_opt == 'disabled' ? false : capstone_opt}
2694 summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
2695 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2696 summary_info += {'libudev':           libudev.found()}
2697 summary_info += {'FUSE lseek':        fuse_lseek.found()}
2698 summary(summary_info, bool_yn: true, section: 'Dependencies')
2700 if not supported_cpus.contains(cpu)
2701   message()
2702   warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2703   message()
2704   message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2705   message('The QEMU project intends to remove support for this host CPU in')
2706   message('a future release if nobody volunteers to maintain it and to')
2707   message('provide a build host for our continuous integration setup.')
2708   message('configure has succeeded and you can continue to build, but')
2709   message('if you care about QEMU on this platform you should contact')
2710   message('us upstream at qemu-devel@nongnu.org.')
2711 endif
2713 if not supported_oses.contains(targetos)
2714   message()
2715   warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2716   message()
2717   message('Host OS ' + targetos + 'support is not currently maintained.')
2718   message('The QEMU project intends to remove support for this host OS in')
2719   message('a future release if nobody volunteers to maintain it and to')
2720   message('provide a build host for our continuous integration setup.')
2721   message('configure has succeeded and you can continue to build, but')
2722   message('if you care about QEMU on this platform you should contact')
2723   message('us upstream at qemu-devel@nongnu.org.')
2724 endif