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