Merge remote-tracking branch 'remotes/kraxel/tags/ui-20210304-pull-request' into...
[qemu.git] / meson.build
blob81d760d6e84f0291f3b7d2ccb0b236335c359298
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 fdt = not_found
1578 fdt_opt = get_option('fdt')
1579 if have_system
1580   if fdt_opt in ['enabled', 'auto', 'system']
1581     have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1582     fdt = cc.find_library('fdt', kwargs: static_kwargs,
1583                           required: fdt_opt == 'system' or
1584                                     fdt_opt == 'enabled' and not have_internal)
1585     if fdt.found() and cc.links('''
1586        #include <libfdt.h>
1587        #include <libfdt_env.h>
1588        int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1589          dependencies: fdt)
1590       fdt_opt = 'system'
1591     elif have_internal
1592       fdt_opt = 'internal'
1593     else
1594       fdt_opt = 'disabled'
1595     endif
1596   endif
1597   if fdt_opt == 'internal'
1598     fdt_files = files(
1599       'dtc/libfdt/fdt.c',
1600       'dtc/libfdt/fdt_ro.c',
1601       'dtc/libfdt/fdt_wip.c',
1602       'dtc/libfdt/fdt_sw.c',
1603       'dtc/libfdt/fdt_rw.c',
1604       'dtc/libfdt/fdt_strerror.c',
1605       'dtc/libfdt/fdt_empty_tree.c',
1606       'dtc/libfdt/fdt_addresses.c',
1607       'dtc/libfdt/fdt_overlay.c',
1608       'dtc/libfdt/fdt_check.c',
1609     )
1611     fdt_inc = include_directories('dtc/libfdt')
1612     libfdt = static_library('fdt',
1613                             build_by_default: false,
1614                             sources: fdt_files,
1615                             include_directories: fdt_inc)
1616     fdt = declare_dependency(link_with: libfdt,
1617                              include_directories: fdt_inc)
1618   endif
1619 endif
1620 if not fdt.found() and fdt_required.length() > 0
1621   error('fdt not available but required by targets ' + ', '.join(fdt_required))
1622 endif
1624 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1625 config_host_data.set('CONFIG_FDT', fdt.found())
1626 config_host_data.set('CONFIG_SLIRP', slirp.found())
1628 #####################
1629 # Generated sources #
1630 #####################
1632 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1634 hxtool = find_program('scripts/hxtool')
1635 shaderinclude = find_program('scripts/shaderinclude.pl')
1636 qapi_gen = find_program('scripts/qapi-gen.py')
1637 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1638                      meson.source_root() / 'scripts/qapi/commands.py',
1639                      meson.source_root() / 'scripts/qapi/common.py',
1640                      meson.source_root() / 'scripts/qapi/error.py',
1641                      meson.source_root() / 'scripts/qapi/events.py',
1642                      meson.source_root() / 'scripts/qapi/expr.py',
1643                      meson.source_root() / 'scripts/qapi/gen.py',
1644                      meson.source_root() / 'scripts/qapi/introspect.py',
1645                      meson.source_root() / 'scripts/qapi/parser.py',
1646                      meson.source_root() / 'scripts/qapi/schema.py',
1647                      meson.source_root() / 'scripts/qapi/source.py',
1648                      meson.source_root() / 'scripts/qapi/types.py',
1649                      meson.source_root() / 'scripts/qapi/visit.py',
1650                      meson.source_root() / 'scripts/qapi/common.py',
1651                      meson.source_root() / 'scripts/qapi-gen.py'
1654 tracetool = [
1655   python, files('scripts/tracetool.py'),
1656    '--backend=' + config_host['TRACE_BACKENDS']
1658 tracetool_depends = files(
1659   'scripts/tracetool/backend/log.py',
1660   'scripts/tracetool/backend/__init__.py',
1661   'scripts/tracetool/backend/dtrace.py',
1662   'scripts/tracetool/backend/ftrace.py',
1663   'scripts/tracetool/backend/simple.py',
1664   'scripts/tracetool/backend/syslog.py',
1665   'scripts/tracetool/backend/ust.py',
1666   'scripts/tracetool/format/tcg_h.py',
1667   'scripts/tracetool/format/ust_events_c.py',
1668   'scripts/tracetool/format/ust_events_h.py',
1669   'scripts/tracetool/format/__init__.py',
1670   'scripts/tracetool/format/d.py',
1671   'scripts/tracetool/format/tcg_helper_c.py',
1672   'scripts/tracetool/format/simpletrace_stap.py',
1673   'scripts/tracetool/format/c.py',
1674   'scripts/tracetool/format/h.py',
1675   'scripts/tracetool/format/tcg_helper_h.py',
1676   'scripts/tracetool/format/log_stap.py',
1677   'scripts/tracetool/format/stap.py',
1678   'scripts/tracetool/format/tcg_helper_wrapper_h.py',
1679   'scripts/tracetool/__init__.py',
1680   'scripts/tracetool/transform.py',
1681   'scripts/tracetool/vcpu.py'
1684 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1685                     meson.current_source_dir(),
1686                     config_host['PKGVERSION'], meson.project_version()]
1687 qemu_version = custom_target('qemu-version.h',
1688                              output: 'qemu-version.h',
1689                              command: qemu_version_cmd,
1690                              capture: true,
1691                              build_by_default: true,
1692                              build_always_stale: true)
1693 genh += qemu_version
1695 hxdep = []
1696 hx_headers = [
1697   ['qemu-options.hx', 'qemu-options.def'],
1698   ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1700 if have_system
1701   hx_headers += [
1702     ['hmp-commands.hx', 'hmp-commands.h'],
1703     ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1704   ]
1705 endif
1706 foreach d : hx_headers
1707   hxdep += custom_target(d[1],
1708                 input: files(d[0]),
1709                 output: d[1],
1710                 capture: true,
1711                 build_by_default: true, # to be removed when added to a target
1712                 command: [hxtool, '-h', '@INPUT0@'])
1713 endforeach
1714 genh += hxdep
1716 ###################
1717 # Collect sources #
1718 ###################
1720 authz_ss = ss.source_set()
1721 blockdev_ss = ss.source_set()
1722 block_ss = ss.source_set()
1723 bsd_user_ss = ss.source_set()
1724 chardev_ss = ss.source_set()
1725 common_ss = ss.source_set()
1726 crypto_ss = ss.source_set()
1727 io_ss = ss.source_set()
1728 linux_user_ss = ss.source_set()
1729 qmp_ss = ss.source_set()
1730 qom_ss = ss.source_set()
1731 softmmu_ss = ss.source_set()
1732 specific_fuzz_ss = ss.source_set()
1733 specific_ss = ss.source_set()
1734 stub_ss = ss.source_set()
1735 trace_ss = ss.source_set()
1736 user_ss = ss.source_set()
1737 util_ss = ss.source_set()
1739 modules = {}
1740 hw_arch = {}
1741 target_arch = {}
1742 target_softmmu_arch = {}
1744 ###############
1745 # Trace files #
1746 ###############
1748 # TODO: add each directory to the subdirs from its own meson.build, once
1749 # we have those
1750 trace_events_subdirs = [
1751   'crypto',
1752   'qapi',
1753   'qom',
1754   'monitor',
1755   'util',
1757 if have_user
1758   trace_events_subdirs += [ 'linux-user' ]
1759 endif
1760 if have_block
1761   trace_events_subdirs += [
1762     'authz',
1763     'block',
1764     'io',
1765     'nbd',
1766     'scsi',
1767   ]
1768 endif
1769 if have_system
1770   trace_events_subdirs += [
1771     'accel/kvm',
1772     'audio',
1773     'backends',
1774     'backends/tpm',
1775     'chardev',
1776     'hw/9pfs',
1777     'hw/acpi',
1778     'hw/adc',
1779     'hw/alpha',
1780     'hw/arm',
1781     'hw/audio',
1782     'hw/block',
1783     'hw/block/dataplane',
1784     'hw/char',
1785     'hw/display',
1786     'hw/dma',
1787     'hw/hppa',
1788     'hw/hyperv',
1789     'hw/i2c',
1790     'hw/i386',
1791     'hw/i386/xen',
1792     'hw/ide',
1793     'hw/input',
1794     'hw/intc',
1795     'hw/isa',
1796     'hw/mem',
1797     'hw/mips',
1798     'hw/misc',
1799     'hw/misc/macio',
1800     'hw/net',
1801     'hw/net/can',
1802     'hw/nvram',
1803     'hw/pci',
1804     'hw/pci-host',
1805     'hw/ppc',
1806     'hw/rdma',
1807     'hw/rdma/vmw',
1808     'hw/rtc',
1809     'hw/s390x',
1810     'hw/scsi',
1811     'hw/sd',
1812     'hw/sparc',
1813     'hw/sparc64',
1814     'hw/ssi',
1815     'hw/timer',
1816     'hw/tpm',
1817     'hw/usb',
1818     'hw/vfio',
1819     'hw/virtio',
1820     'hw/watchdog',
1821     'hw/xen',
1822     'hw/gpio',
1823     'migration',
1824     'net',
1825     'softmmu',
1826     'ui',
1827     'hw/remote',
1828   ]
1829 endif
1830 if have_system or have_user
1831   trace_events_subdirs += [
1832     'accel/tcg',
1833     'hw/core',
1834     'target/arm',
1835     'target/hppa',
1836     'target/i386',
1837     'target/i386/kvm',
1838     'target/mips',
1839     'target/ppc',
1840     'target/riscv',
1841     'target/s390x',
1842     'target/sparc',
1843   ]
1844 endif
1846 vhost_user = not_found
1847 if 'CONFIG_VHOST_USER' in config_host
1848   libvhost_user = subproject('libvhost-user')
1849   vhost_user = libvhost_user.get_variable('vhost_user_dep')
1850 endif
1852 subdir('qapi')
1853 subdir('qobject')
1854 subdir('stubs')
1855 subdir('trace')
1856 subdir('util')
1857 subdir('qom')
1858 subdir('authz')
1859 subdir('crypto')
1860 subdir('ui')
1863 if enable_modules
1864   libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1865   modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1866 endif
1868 stub_ss = stub_ss.apply(config_all, strict: false)
1870 util_ss.add_all(trace_ss)
1871 util_ss = util_ss.apply(config_all, strict: false)
1872 libqemuutil = static_library('qemuutil',
1873                              sources: util_ss.sources() + stub_ss.sources() + genh,
1874                              dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1875 qemuutil = declare_dependency(link_with: libqemuutil,
1876                               sources: genh + version_res)
1878 if have_system or have_user
1879   decodetree = generator(find_program('scripts/decodetree.py'),
1880                          output: 'decode-@BASENAME@.c.inc',
1881                          arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1882   subdir('libdecnumber')
1883   subdir('target')
1884 endif
1886 subdir('audio')
1887 subdir('io')
1888 subdir('chardev')
1889 subdir('fsdev')
1890 subdir('dump')
1892 if have_block
1893   block_ss.add(files(
1894     'block.c',
1895     'blockjob.c',
1896     'job.c',
1897     'qemu-io-cmds.c',
1898   ))
1899   block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1901   subdir('nbd')
1902   subdir('scsi')
1903   subdir('block')
1905   blockdev_ss.add(files(
1906     'blockdev.c',
1907     'blockdev-nbd.c',
1908     'iothread.c',
1909     'job-qmp.c',
1910   ), gnutls)
1912   # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1913   # os-win32.c does not
1914   blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1915   softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1916 endif
1918 common_ss.add(files('cpus-common.c'))
1920 subdir('softmmu')
1922 common_ss.add(capstone)
1923 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
1924 specific_ss.add(files('exec-vary.c'))
1925 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1926   'fpu/softfloat.c',
1927   'tcg/optimize.c',
1928   'tcg/tcg-common.c',
1929   'tcg/tcg-op-gvec.c',
1930   'tcg/tcg-op-vec.c',
1931   'tcg/tcg-op.c',
1932   'tcg/tcg.c',
1934 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1936 subdir('backends')
1937 subdir('disas')
1938 subdir('migration')
1939 subdir('monitor')
1940 subdir('net')
1941 subdir('replay')
1942 subdir('hw')
1943 subdir('accel')
1944 subdir('plugins')
1945 subdir('bsd-user')
1946 subdir('linux-user')
1948 bsd_user_ss.add(files('gdbstub.c'))
1949 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1951 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1952 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1954 # needed for fuzzing binaries
1955 subdir('tests/qtest/libqos')
1956 subdir('tests/qtest/fuzz')
1958 ########################
1959 # Library dependencies #
1960 ########################
1962 block_mods = []
1963 softmmu_mods = []
1964 foreach d, list : modules
1965   foreach m, module_ss : list
1966     if enable_modules and targetos != 'windows'
1967       module_ss = module_ss.apply(config_all, strict: false)
1968       sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1969                           dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1970       if d == 'block'
1971         block_mods += sl
1972       else
1973         softmmu_mods += sl
1974       endif
1975     else
1976       if d == 'block'
1977         block_ss.add_all(module_ss)
1978       else
1979         softmmu_ss.add_all(module_ss)
1980       endif
1981     endif
1982   endforeach
1983 endforeach
1985 nm = find_program('nm')
1986 undefsym = find_program('scripts/undefsym.py')
1987 block_syms = custom_target('block.syms', output: 'block.syms',
1988                              input: [libqemuutil, block_mods],
1989                              capture: true,
1990                              command: [undefsym, nm, '@INPUT@'])
1991 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1992                              input: [libqemuutil, softmmu_mods],
1993                              capture: true,
1994                              command: [undefsym, nm, '@INPUT@'])
1996 qom_ss = qom_ss.apply(config_host, strict: false)
1997 libqom = static_library('qom', qom_ss.sources() + genh,
1998                         dependencies: [qom_ss.dependencies()],
1999                         name_suffix: 'fa')
2001 qom = declare_dependency(link_whole: libqom)
2003 authz_ss = authz_ss.apply(config_host, strict: false)
2004 libauthz = static_library('authz', authz_ss.sources() + genh,
2005                           dependencies: [authz_ss.dependencies()],
2006                           name_suffix: 'fa',
2007                           build_by_default: false)
2009 authz = declare_dependency(link_whole: libauthz,
2010                            dependencies: qom)
2012 crypto_ss = crypto_ss.apply(config_host, strict: false)
2013 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2014                            dependencies: [crypto_ss.dependencies()],
2015                            name_suffix: 'fa',
2016                            build_by_default: false)
2018 crypto = declare_dependency(link_whole: libcrypto,
2019                             dependencies: [authz, qom])
2021 io_ss = io_ss.apply(config_host, strict: false)
2022 libio = static_library('io', io_ss.sources() + genh,
2023                        dependencies: [io_ss.dependencies()],
2024                        link_with: libqemuutil,
2025                        name_suffix: 'fa',
2026                        build_by_default: false)
2028 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2030 libmigration = static_library('migration', sources: migration_files + genh,
2031                               name_suffix: 'fa',
2032                               build_by_default: false)
2033 migration = declare_dependency(link_with: libmigration,
2034                                dependencies: [zlib, qom, io])
2035 softmmu_ss.add(migration)
2037 block_ss = block_ss.apply(config_host, strict: false)
2038 libblock = static_library('block', block_ss.sources() + genh,
2039                           dependencies: block_ss.dependencies(),
2040                           link_depends: block_syms,
2041                           name_suffix: 'fa',
2042                           build_by_default: false)
2044 block = declare_dependency(link_whole: [libblock],
2045                            link_args: '@block.syms',
2046                            dependencies: [crypto, io])
2048 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2049 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2050                              dependencies: blockdev_ss.dependencies(),
2051                              name_suffix: 'fa',
2052                              build_by_default: false)
2054 blockdev = declare_dependency(link_whole: [libblockdev],
2055                               dependencies: [block])
2057 qmp_ss = qmp_ss.apply(config_host, strict: false)
2058 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2059                         dependencies: qmp_ss.dependencies(),
2060                         name_suffix: 'fa',
2061                         build_by_default: false)
2063 qmp = declare_dependency(link_whole: [libqmp])
2065 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2066                             name_suffix: 'fa',
2067                             dependencies: [gnutls],
2068                             build_by_default: false)
2070 chardev = declare_dependency(link_whole: libchardev)
2072 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
2073                            name_suffix: 'fa',
2074                            build_by_default: false)
2075 hwcore = declare_dependency(link_whole: libhwcore)
2076 common_ss.add(hwcore)
2078 ###########
2079 # Targets #
2080 ###########
2082 foreach m : block_mods + softmmu_mods
2083   shared_module(m.name(),
2084                 name_prefix: '',
2085                 link_whole: m,
2086                 install: true,
2087                 install_dir: qemu_moddir)
2088 endforeach
2090 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2091 common_ss.add(qom, qemuutil)
2093 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2094 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2096 common_all = common_ss.apply(config_all, strict: false)
2097 common_all = static_library('common',
2098                             build_by_default: false,
2099                             sources: common_all.sources() + genh,
2100                             dependencies: common_all.dependencies(),
2101                             name_suffix: 'fa')
2103 feature_to_c = find_program('scripts/feature_to_c.sh')
2105 emulators = {}
2106 foreach target : target_dirs
2107   config_target = config_target_mak[target]
2108   target_name = config_target['TARGET_NAME']
2109   arch = config_target['TARGET_BASE_ARCH']
2110   arch_srcs = [config_target_h[target]]
2111   arch_deps = []
2112   c_args = ['-DNEED_CPU_H',
2113             '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2114             '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2115   link_args = emulator_link_args
2117   config_target += config_host
2118   target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2119   if targetos == 'linux'
2120     target_inc += include_directories('linux-headers', is_system: true)
2121   endif
2122   if target.endswith('-softmmu')
2123     qemu_target_name = 'qemu-system-' + target_name
2124     target_type='system'
2125     t = target_softmmu_arch[arch].apply(config_target, strict: false)
2126     arch_srcs += t.sources()
2127     arch_deps += t.dependencies()
2129     hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2130     hw = hw_arch[hw_dir].apply(config_target, strict: false)
2131     arch_srcs += hw.sources()
2132     arch_deps += hw.dependencies()
2134     arch_srcs += config_devices_h[target]
2135     link_args += ['@block.syms', '@qemu.syms']
2136   else
2137     abi = config_target['TARGET_ABI_DIR']
2138     target_type='user'
2139     qemu_target_name = 'qemu-' + target_name
2140     if 'CONFIG_LINUX_USER' in config_target
2141       base_dir = 'linux-user'
2142       target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2143     else
2144       base_dir = 'bsd-user'
2145       target_inc += include_directories('bsd-user/freebsd')
2146     endif
2147     target_inc += include_directories(
2148       base_dir,
2149       base_dir / abi,
2150     )
2151     if 'CONFIG_LINUX_USER' in config_target
2152       dir = base_dir / abi
2153       arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2154       if config_target.has_key('TARGET_SYSTBL_ABI')
2155         arch_srcs += \
2156           syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2157                                              extra_args : config_target['TARGET_SYSTBL_ABI'])
2158       endif
2159     endif
2160   endif
2162   if 'TARGET_XML_FILES' in config_target
2163     gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2164                                 output: target + '-gdbstub-xml.c',
2165                                 input: files(config_target['TARGET_XML_FILES'].split()),
2166                                 command: [feature_to_c, '@INPUT@'],
2167                                 capture: true)
2168     arch_srcs += gdbstub_xml
2169   endif
2171   t = target_arch[arch].apply(config_target, strict: false)
2172   arch_srcs += t.sources()
2173   arch_deps += t.dependencies()
2175   target_common = common_ss.apply(config_target, strict: false)
2176   objects = common_all.extract_objects(target_common.sources())
2177   deps = target_common.dependencies()
2179   target_specific = specific_ss.apply(config_target, strict: false)
2180   arch_srcs += target_specific.sources()
2181   arch_deps += target_specific.dependencies()
2183   lib = static_library('qemu-' + target,
2184                  sources: arch_srcs + genh,
2185                  dependencies: arch_deps,
2186                  objects: objects,
2187                  include_directories: target_inc,
2188                  c_args: c_args,
2189                  build_by_default: false,
2190                  name_suffix: 'fa')
2192   if target.endswith('-softmmu')
2193     execs = [{
2194       'name': 'qemu-system-' + target_name,
2195       'gui': false,
2196       'sources': files('softmmu/main.c'),
2197       'dependencies': []
2198     }]
2199     if targetos == 'windows' and (sdl.found() or gtk.found())
2200       execs += [{
2201         'name': 'qemu-system-' + target_name + 'w',
2202         'gui': true,
2203         'sources': files('softmmu/main.c'),
2204         'dependencies': []
2205       }]
2206     endif
2207     if config_host.has_key('CONFIG_FUZZ')
2208       specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2209       execs += [{
2210         'name': 'qemu-fuzz-' + target_name,
2211         'gui': false,
2212         'sources': specific_fuzz.sources(),
2213         'dependencies': specific_fuzz.dependencies(),
2214       }]
2215     endif
2216   else
2217     execs = [{
2218       'name': 'qemu-' + target_name,
2219       'gui': false,
2220       'sources': [],
2221       'dependencies': []
2222     }]
2223   endif
2224   foreach exe: execs
2225     exe_name = exe['name']
2226     exe_sign = 'CONFIG_HVF' in config_target
2227     if exe_sign
2228       exe_name += '-unsigned'
2229     endif
2231     emulator = executable(exe_name, exe['sources'],
2232                install: true,
2233                c_args: c_args,
2234                dependencies: arch_deps + deps + exe['dependencies'],
2235                objects: lib.extract_all_objects(recursive: true),
2236                link_language: link_language,
2237                link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2238                link_args: link_args,
2239                gui_app: exe['gui'])
2241     if exe_sign
2242       emulators += {exe['name'] : custom_target(exe['name'],
2243                    depends: emulator,
2244                    output: exe['name'],
2245                    command: [
2246                      meson.current_source_dir() / 'scripts/entitlement.sh',
2247                      meson.current_build_dir() / exe_name,
2248                      meson.current_build_dir() / exe['name'],
2249                      meson.current_source_dir() / 'accel/hvf/entitlements.plist'
2250                    ])
2251       }
2253       meson.add_install_script('scripts/entitlement.sh', '--install',
2254                                get_option('bindir') / exe_name,
2255                                get_option('bindir') / exe['name'],
2256                                meson.current_source_dir() / 'accel/hvf/entitlements.plist')
2257     else
2258       emulators += {exe['name']: emulator}
2259     endif
2261     if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2262       foreach stp: [
2263         {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2264         {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2265         {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2266         {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2267       ]
2268         custom_target(exe['name'] + stp['ext'],
2269                       input: trace_events_all,
2270                       output: exe['name'] + stp['ext'],
2271                       install: stp['install'],
2272                       install_dir: get_option('datadir') / 'systemtap/tapset',
2273                       command: [
2274                         tracetool, '--group=all', '--format=' + stp['fmt'],
2275                         '--binary=' + stp['bin'],
2276                         '--target-name=' + target_name,
2277                         '--target-type=' + target_type,
2278                         '--probe-prefix=qemu.' + target_type + '.' + target_name,
2279                         '@INPUT@', '@OUTPUT@'
2280                       ],
2281                       depend_files: tracetool_depends)
2282       endforeach
2283     endif
2284   endforeach
2285 endforeach
2287 # Other build targets
2289 if 'CONFIG_PLUGIN' in config_host
2290   install_headers('include/qemu/qemu-plugin.h')
2291 endif
2293 if 'CONFIG_GUEST_AGENT' in config_host
2294   subdir('qga')
2295 elif get_option('guest_agent_msi').enabled()
2296   error('Guest agent MSI requested, but the guest agent is not being built')
2297 endif
2299 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2300 # when we don't build tools or system
2301 if xkbcommon.found()
2302   # used for the update-keymaps target, so include rules even if !have_tools
2303   qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2304                            dependencies: [qemuutil, xkbcommon], install: have_tools)
2305 endif
2307 if have_tools
2308   qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2309              dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2310   qemu_io = executable('qemu-io', files('qemu-io.c'),
2311              dependencies: [block, qemuutil], install: true)
2312   qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2313                dependencies: [blockdev, qemuutil, gnutls], install: true)
2315   subdir('storage-daemon')
2316   subdir('contrib/rdmacm-mux')
2317   subdir('contrib/elf2dmp')
2319   executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2320              dependencies: qemuutil,
2321              install: true)
2323   if 'CONFIG_VHOST_USER' in config_host
2324     subdir('contrib/vhost-user-blk')
2325     subdir('contrib/vhost-user-gpu')
2326     subdir('contrib/vhost-user-input')
2327     subdir('contrib/vhost-user-scsi')
2328   endif
2330   if targetos == 'linux'
2331     executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2332                dependencies: [qemuutil, libcap_ng],
2333                install: true,
2334                install_dir: get_option('libexecdir'))
2336     executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2337                dependencies: [authz, crypto, io, qom, qemuutil,
2338                               libcap_ng, mpathpersist],
2339                install: true)
2340   endif
2342   if 'CONFIG_IVSHMEM' in config_host
2343     subdir('contrib/ivshmem-client')
2344     subdir('contrib/ivshmem-server')
2345   endif
2346 endif
2348 subdir('scripts')
2349 subdir('tools')
2350 subdir('pc-bios')
2351 subdir('docs')
2352 subdir('tests')
2353 if gtk.found()
2354   subdir('po')
2355 endif
2357 if host_machine.system() == 'windows'
2358   nsis_cmd = [
2359     find_program('scripts/nsis.py'),
2360     '@OUTPUT@',
2361     get_option('prefix'),
2362     meson.current_source_dir(),
2363     host_machine.cpu(),
2364     '--',
2365     '-DDISPLAYVERSION=' + meson.project_version(),
2366   ]
2367   if build_docs
2368     nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2369   endif
2370   if gtk.found()
2371     nsis_cmd += '-DCONFIG_GTK=y'
2372   endif
2374   nsis = custom_target('nsis',
2375                        output: 'qemu-setup-' + meson.project_version() + '.exe',
2376                        input: files('qemu.nsi'),
2377                        build_always_stale: true,
2378                        command: nsis_cmd + ['@INPUT@'])
2379   alias_target('installer', nsis)
2380 endif
2382 #########################
2383 # Configuration summary #
2384 #########################
2386 # Directories
2387 summary_info = {}
2388 summary_info += {'Install prefix':    get_option('prefix')}
2389 summary_info += {'BIOS directory':    qemu_datadir}
2390 summary_info += {'firmware path':     get_option('qemu_firmwarepath')}
2391 summary_info += {'binary directory':  get_option('bindir')}
2392 summary_info += {'library directory': get_option('libdir')}
2393 summary_info += {'module directory':  qemu_moddir}
2394 summary_info += {'libexec directory': get_option('libexecdir')}
2395 summary_info += {'include directory': get_option('includedir')}
2396 summary_info += {'config directory':  get_option('sysconfdir')}
2397 if targetos != 'windows'
2398   summary_info += {'local state directory': get_option('localstatedir')}
2399   summary_info += {'Manual directory':      get_option('mandir')}
2400 else
2401   summary_info += {'local state directory': 'queried at runtime'}
2402 endif
2403 summary_info += {'Doc directory':     get_option('docdir')}
2404 summary_info += {'Build directory':   meson.current_build_dir()}
2405 summary_info += {'Source path':       meson.current_source_dir()}
2406 summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
2407 summary(summary_info, bool_yn: true, section: 'Directories')
2409 # Host binaries
2410 summary_info = {}
2411 summary_info += {'git':               config_host['GIT']}
2412 summary_info += {'make':              config_host['MAKE']}
2413 summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2414 summary_info += {'sphinx-build':      sphinx_build.found()}
2415 if config_host.has_key('HAVE_GDB_BIN')
2416   summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
2417 endif
2418 summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
2419 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
2420   summary_info += {'wixl':            wixl.found() ? wixl.full_path() : false}
2421 endif
2422 if slirp_opt != 'disabled'
2423   summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
2424 endif
2425 summary(summary_info, bool_yn: true, section: 'Host binaries')
2427 # Configurable features
2428 summary_info = {}
2429 summary_info += {'Documentation':     build_docs}
2430 summary_info += {'system-mode emulation': have_system}
2431 summary_info += {'user-mode emulation': have_user}
2432 summary_info += {'block layer':       have_block}
2433 summary_info += {'Install blobs':     get_option('install_blobs')}
2434 summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
2435 if config_host.has_key('CONFIG_MODULES')
2436   summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2437 endif
2438 summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
2439 summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
2440 if have_system
2441   summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
2442 endif
2443 summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
2444 if config_host['TRACE_BACKENDS'].split().contains('simple')
2445   summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2446 endif
2447 summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2448 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2449 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2450 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2451 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2452 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2453 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2454 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2455 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2456 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2457 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2458 summary(summary_info, bool_yn: true, section: 'Configurable features')
2460 # Compilation information
2461 summary_info = {}
2462 summary_info += {'host CPU':          cpu}
2463 summary_info += {'host endianness':   build_machine.endian()}
2464 summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
2465 summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
2466 if link_language == 'cpp'
2467   summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
2468 else
2469   summary_info += {'C++ compiler':      false}
2470 endif
2471 if targetos == 'darwin'
2472   summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
2473 endif
2474 if targetos == 'windows'
2475   if 'WIN_SDK' in config_host
2476     summary_info += {'Windows SDK':   config_host['WIN_SDK']}
2477   endif
2478 endif
2479 summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
2480 summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
2481                                                + ['-O' + get_option('optimization')]
2482                                                + (get_option('debug') ? ['-g'] : []))}
2483 if link_language == 'cpp'
2484   summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
2485                                                + ['-O' + get_option('optimization')]
2486                                                + (get_option('debug') ? ['-g'] : []))}
2487 endif
2488 link_args = get_option(link_language + '_link_args')
2489 if link_args.length() > 0
2490   summary_info += {'LDFLAGS':         ' '.join(link_args)}
2491 endif
2492 summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
2493 summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
2494 summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
2495 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2496 summary_info += {'PIE':               get_option('b_pie')}
2497 summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
2498 summary_info += {'malloc trim support': has_malloc_trim}
2499 summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
2500 summary_info += {'preadv support':    config_host_data.get('CONFIG_PREADV')}
2501 summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
2502 summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
2503 summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
2504 summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2505 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2506 summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
2507 summary_info += {'memory allocator':  get_option('malloc')}
2508 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2509 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2510 summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
2511 summary_info += {'gcov':              get_option('b_coverage')}
2512 summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
2513 summary_info += {'CFI support':       get_option('cfi')}
2514 if get_option('cfi')
2515   summary_info += {'CFI debug support': get_option('cfi_debug')}
2516 endif
2517 summary_info += {'strip binaries':    get_option('strip')}
2518 summary_info += {'sparse':            sparse.found() ? sparse.full_path() : false}
2519 summary_info += {'mingw32 support':   targetos == 'windows'}
2521 # snarf the cross-compilation information for tests
2522 foreach target: target_dirs
2523   tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
2524   if fs.exists(tcg_mak)
2525     config_cross_tcg = keyval.load(tcg_mak)
2526     target = config_cross_tcg['TARGET_NAME']
2527     compiler = ''
2528     if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
2529       summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
2530                                           ' via ' + config_cross_tcg['DOCKER_IMAGE']}
2531     elif 'CROSS_CC_GUEST' in config_cross_tcg
2532       summary_info += {target + ' tests'
2533                                 : config_cross_tcg['CROSS_CC_GUEST'] }
2534     endif
2535    endif
2536 endforeach
2538 summary(summary_info, bool_yn: true, section: 'Compilation')
2540 # Targets and accelerators
2541 summary_info = {}
2542 if have_system
2543   summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
2544   summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
2545   summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
2546   summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
2547   summary_info += {'Xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
2548   if config_host.has_key('CONFIG_XEN_BACKEND')
2549     summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2550   endif
2551 endif
2552 summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
2553 if config_all.has_key('CONFIG_TCG')
2554   if get_option('tcg_interpreter')
2555     summary_info += {'TCG backend':   'TCI (TCG with bytecode interpreter, experimental and slow)'}
2556   else
2557     summary_info += {'TCG backend':   'native (@0@)'.format(cpu)}
2558   endif
2559   summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2560 endif
2561 summary_info += {'target list':       ' '.join(target_dirs)}
2562 if have_system
2563   summary_info += {'default devices':   get_option('default_devices')}
2564   summary_info += {'out of process emulation': multiprocess_allowed}
2565 endif
2566 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
2568 # Block layer
2569 summary_info = {}
2570 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2571 summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
2572 if have_block
2573   summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2574   summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2575   summary_info += {'VirtFS support':    have_virtfs}
2576   summary_info += {'build virtiofs daemon': have_virtiofsd}
2577   summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2578   summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2579   summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
2580   summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
2581   summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
2582   summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
2583   summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
2584   summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
2585   summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
2586   summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2587   summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
2588   summary_info += {'FUSE exports':      fuse.found()}
2589 endif
2590 summary(summary_info, bool_yn: true, section: 'Block layer support')
2592 # Crypto
2593 summary_info = {}
2594 summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
2595 summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
2596 # TODO: add back version
2597 summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
2598 if config_host.has_key('CONFIG_GCRYPT')
2599    summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
2600    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2601 endif
2602 # TODO: add back version
2603 summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
2604 if config_host.has_key('CONFIG_NETTLE')
2605    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2606 endif
2607 summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
2608 summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
2609 summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
2610 summary(summary_info, bool_yn: true, section: 'Crypto')
2612 # Libraries
2613 summary_info = {}
2614 if targetos == 'darwin'
2615   summary_info += {'Cocoa support':   cocoa.found()}
2616 endif
2617 # TODO: add back version
2618 summary_info += {'SDL support':       sdl.found()}
2619 summary_info += {'SDL image support': sdl_image.found()}
2620 # TODO: add back version
2621 summary_info += {'GTK support':       gtk.found()}
2622 summary_info += {'pixman':            pixman.found()}
2623 # TODO: add back version
2624 summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
2625 # TODO: add back version
2626 summary_info += {'slirp support':     slirp_opt == 'disabled' ? false : slirp_opt}
2627 summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
2628 summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
2629 summary_info += {'iconv support':     iconv.found()}
2630 summary_info += {'curses support':    curses.found()}
2631 # TODO: add back version
2632 summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
2633 summary_info += {'curl support':      curl.found()}
2634 summary_info += {'Multipath support': mpathpersist.found()}
2635 summary_info += {'VNC support':       vnc.found()}
2636 if vnc.found()
2637   summary_info += {'VNC SASL support':  sasl.found()}
2638   summary_info += {'VNC JPEG support':  jpeg.found()}
2639   summary_info += {'VNC PNG support':   png.found()}
2640 endif
2641 summary_info += {'brlapi support':    brlapi.found()}
2642 summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
2643 summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
2644 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2645 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2646 summary_info += {'ATTR/XATTR support': libattr.found()}
2647 summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
2648 summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
2649 summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
2650 summary_info += {'libcap-ng support': libcap_ng.found()}
2651 # TODO: add back protocol and server version
2652 summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
2653 summary_info += {'rbd support':       rbd.found()}
2654 summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
2655 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2656 summary_info += {'U2F support':       u2f.found()}
2657 summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
2658 summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
2659 summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
2660 summary_info += {'GBM':               config_host.has_key('CONFIG_GBM')}
2661 summary_info += {'libiscsi support':  libiscsi.found()}
2662 summary_info += {'libnfs support':    libnfs.found()}
2663 if targetos == 'windows'
2664   if config_host.has_key('CONFIG_GUEST_AGENT')
2665     summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
2666     summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2667   endif
2668 endif
2669 summary_info += {'seccomp support':   seccomp.found()}
2670 summary_info += {'GlusterFS support': glusterfs.found()}
2671 summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
2672 summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
2673 summary_info += {'lzo support':       lzo.found()}
2674 summary_info += {'snappy support':    snappy.found()}
2675 summary_info += {'bzip2 support':     libbzip2.found()}
2676 summary_info += {'lzfse support':     liblzfse.found()}
2677 summary_info += {'zstd support':      zstd.found()}
2678 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2679 summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
2680 summary_info += {'capstone':          capstone_opt == 'disabled' ? false : capstone_opt}
2681 summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
2682 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2683 summary_info += {'libudev':           libudev.found()}
2684 summary_info += {'FUSE lseek':        fuse_lseek.found()}
2685 summary(summary_info, bool_yn: true, section: 'Dependencies')
2687 if not supported_cpus.contains(cpu)
2688   message()
2689   warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2690   message()
2691   message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2692   message('The QEMU project intends to remove support for this host CPU in')
2693   message('a future release if nobody volunteers to maintain it and to')
2694   message('provide a build host for our continuous integration setup.')
2695   message('configure has succeeded and you can continue to build, but')
2696   message('if you care about QEMU on this platform you should contact')
2697   message('us upstream at qemu-devel@nongnu.org.')
2698 endif
2700 if not supported_oses.contains(targetos)
2701   message()
2702   warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2703   message()
2704   message('Host OS ' + targetos + 'support is not currently maintained.')
2705   message('The QEMU project intends to remove support for this host OS 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