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