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