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