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