xref: /openbmc/qemu/meson.build (revision 04a37d4c)
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/alpha',
1691    'hw/arm',
1692    'hw/audio',
1693    'hw/block',
1694    'hw/block/dataplane',
1695    'hw/char',
1696    'hw/display',
1697    'hw/dma',
1698    'hw/hppa',
1699    'hw/hyperv',
1700    'hw/i2c',
1701    'hw/i386',
1702    'hw/i386/xen',
1703    'hw/ide',
1704    'hw/input',
1705    'hw/intc',
1706    'hw/isa',
1707    'hw/mem',
1708    'hw/mips',
1709    'hw/misc',
1710    'hw/misc/macio',
1711    'hw/net',
1712    'hw/net/can',
1713    'hw/nvram',
1714    'hw/pci',
1715    'hw/pci-host',
1716    'hw/ppc',
1717    'hw/rdma',
1718    'hw/rdma/vmw',
1719    'hw/rtc',
1720    'hw/s390x',
1721    'hw/scsi',
1722    'hw/sd',
1723    'hw/sparc',
1724    'hw/sparc64',
1725    'hw/ssi',
1726    'hw/timer',
1727    'hw/tpm',
1728    'hw/usb',
1729    'hw/vfio',
1730    'hw/virtio',
1731    'hw/watchdog',
1732    'hw/xen',
1733    'hw/gpio',
1734    'migration',
1735    'net',
1736    'softmmu',
1737    'ui',
1738  ]
1739endif
1740trace_events_subdirs += [
1741  'hw/core',
1742  'qapi',
1743  'qom',
1744  'target/arm',
1745  'target/hppa',
1746  'target/i386',
1747  'target/i386/kvm',
1748  'target/mips',
1749  'target/ppc',
1750  'target/riscv',
1751  'target/s390x',
1752  'target/sparc',
1753  'util',
1754]
1755
1756vhost_user = not_found
1757if 'CONFIG_VHOST_USER' in config_host
1758  libvhost_user = subproject('libvhost-user')
1759  vhost_user = libvhost_user.get_variable('vhost_user_dep')
1760endif
1761
1762subdir('qapi')
1763subdir('qobject')
1764subdir('stubs')
1765subdir('trace')
1766subdir('util')
1767subdir('qom')
1768subdir('authz')
1769subdir('crypto')
1770subdir('ui')
1771
1772
1773if enable_modules
1774  libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1775  modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1776endif
1777
1778stub_ss = stub_ss.apply(config_all, strict: false)
1779
1780util_ss.add_all(trace_ss)
1781util_ss = util_ss.apply(config_all, strict: false)
1782libqemuutil = static_library('qemuutil',
1783                             sources: util_ss.sources() + stub_ss.sources() + genh,
1784                             dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1785qemuutil = declare_dependency(link_with: libqemuutil,
1786                              sources: genh + version_res)
1787
1788decodetree = generator(find_program('scripts/decodetree.py'),
1789                       output: 'decode-@BASENAME@.c.inc',
1790                       arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1791
1792subdir('audio')
1793subdir('io')
1794subdir('chardev')
1795subdir('fsdev')
1796subdir('libdecnumber')
1797subdir('target')
1798subdir('dump')
1799
1800block_ss.add(files(
1801  'block.c',
1802  'blockjob.c',
1803  'job.c',
1804  'qemu-io-cmds.c',
1805))
1806block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1807
1808subdir('nbd')
1809subdir('scsi')
1810subdir('block')
1811
1812blockdev_ss.add(files(
1813  'blockdev.c',
1814  'blockdev-nbd.c',
1815  'iothread.c',
1816  'job-qmp.c',
1817))
1818
1819# os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1820# os-win32.c does not
1821blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1822softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1823
1824common_ss.add(files('cpus-common.c'))
1825
1826subdir('softmmu')
1827
1828common_ss.add(capstone)
1829specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
1830specific_ss.add(files('exec-vary.c'))
1831specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1832  'fpu/softfloat.c',
1833  'tcg/optimize.c',
1834  'tcg/tcg-common.c',
1835  'tcg/tcg-op-gvec.c',
1836  'tcg/tcg-op-vec.c',
1837  'tcg/tcg-op.c',
1838  'tcg/tcg.c',
1839))
1840specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1841
1842subdir('backends')
1843subdir('disas')
1844subdir('migration')
1845subdir('monitor')
1846subdir('net')
1847subdir('replay')
1848subdir('hw')
1849subdir('accel')
1850subdir('plugins')
1851subdir('bsd-user')
1852subdir('linux-user')
1853
1854bsd_user_ss.add(files('gdbstub.c'))
1855specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1856
1857linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1858specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1859
1860# needed for fuzzing binaries
1861subdir('tests/qtest/libqos')
1862subdir('tests/qtest/fuzz')
1863
1864########################
1865# Library dependencies #
1866########################
1867
1868block_mods = []
1869softmmu_mods = []
1870foreach d, list : modules
1871  foreach m, module_ss : list
1872    if enable_modules and targetos != 'windows'
1873      module_ss = module_ss.apply(config_all, strict: false)
1874      sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1875                          dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1876      if d == 'block'
1877        block_mods += sl
1878      else
1879        softmmu_mods += sl
1880      endif
1881    else
1882      if d == 'block'
1883        block_ss.add_all(module_ss)
1884      else
1885        softmmu_ss.add_all(module_ss)
1886      endif
1887    endif
1888  endforeach
1889endforeach
1890
1891nm = find_program('nm')
1892undefsym = find_program('scripts/undefsym.py')
1893block_syms = custom_target('block.syms', output: 'block.syms',
1894                             input: [libqemuutil, block_mods],
1895                             capture: true,
1896                             command: [undefsym, nm, '@INPUT@'])
1897qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1898                             input: [libqemuutil, softmmu_mods],
1899                             capture: true,
1900                             command: [undefsym, nm, '@INPUT@'])
1901
1902qom_ss = qom_ss.apply(config_host, strict: false)
1903libqom = static_library('qom', qom_ss.sources() + genh,
1904                        dependencies: [qom_ss.dependencies()],
1905                        name_suffix: 'fa')
1906
1907qom = declare_dependency(link_whole: libqom)
1908
1909authz_ss = authz_ss.apply(config_host, strict: false)
1910libauthz = static_library('authz', authz_ss.sources() + genh,
1911                          dependencies: [authz_ss.dependencies()],
1912                          name_suffix: 'fa',
1913                          build_by_default: false)
1914
1915authz = declare_dependency(link_whole: libauthz,
1916                           dependencies: qom)
1917
1918crypto_ss = crypto_ss.apply(config_host, strict: false)
1919libcrypto = static_library('crypto', crypto_ss.sources() + genh,
1920                           dependencies: [crypto_ss.dependencies()],
1921                           name_suffix: 'fa',
1922                           build_by_default: false)
1923
1924crypto = declare_dependency(link_whole: libcrypto,
1925                            dependencies: [authz, qom])
1926
1927io_ss = io_ss.apply(config_host, strict: false)
1928libio = static_library('io', io_ss.sources() + genh,
1929                       dependencies: [io_ss.dependencies()],
1930                       link_with: libqemuutil,
1931                       name_suffix: 'fa',
1932                       build_by_default: false)
1933
1934io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
1935
1936libmigration = static_library('migration', sources: migration_files + genh,
1937                              name_suffix: 'fa',
1938                              build_by_default: false)
1939migration = declare_dependency(link_with: libmigration,
1940                               dependencies: [zlib, qom, io])
1941softmmu_ss.add(migration)
1942
1943block_ss = block_ss.apply(config_host, strict: false)
1944libblock = static_library('block', block_ss.sources() + genh,
1945                          dependencies: block_ss.dependencies(),
1946                          link_depends: block_syms,
1947                          name_suffix: 'fa',
1948                          build_by_default: false)
1949
1950block = declare_dependency(link_whole: [libblock],
1951                           link_args: '@block.syms',
1952                           dependencies: [crypto, io])
1953
1954blockdev_ss = blockdev_ss.apply(config_host, strict: false)
1955libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
1956                             dependencies: blockdev_ss.dependencies(),
1957                             name_suffix: 'fa',
1958                             build_by_default: false)
1959
1960blockdev = declare_dependency(link_whole: [libblockdev],
1961                              dependencies: [block])
1962
1963qmp_ss = qmp_ss.apply(config_host, strict: false)
1964libqmp = static_library('qmp', qmp_ss.sources() + genh,
1965                        dependencies: qmp_ss.dependencies(),
1966                        name_suffix: 'fa',
1967                        build_by_default: false)
1968
1969qmp = declare_dependency(link_whole: [libqmp])
1970
1971libchardev = static_library('chardev', chardev_ss.sources() + genh,
1972                            name_suffix: 'fa',
1973                            build_by_default: false)
1974
1975chardev = declare_dependency(link_whole: libchardev)
1976
1977libhwcore = static_library('hwcore', sources: hwcore_files + genh,
1978                           name_suffix: 'fa',
1979                           build_by_default: false)
1980hwcore = declare_dependency(link_whole: libhwcore)
1981common_ss.add(hwcore)
1982
1983###########
1984# Targets #
1985###########
1986
1987foreach m : block_mods + softmmu_mods
1988  shared_module(m.name(),
1989                name_prefix: '',
1990                link_whole: m,
1991                install: true,
1992                install_dir: qemu_moddir)
1993endforeach
1994
1995softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
1996common_ss.add(qom, qemuutil)
1997
1998common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
1999common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2000
2001common_all = common_ss.apply(config_all, strict: false)
2002common_all = static_library('common',
2003                            build_by_default: false,
2004                            sources: common_all.sources() + genh,
2005                            dependencies: common_all.dependencies(),
2006                            name_suffix: 'fa')
2007
2008feature_to_c = find_program('scripts/feature_to_c.sh')
2009
2010emulators = {}
2011foreach target : target_dirs
2012  config_target = config_target_mak[target]
2013  target_name = config_target['TARGET_NAME']
2014  arch = config_target['TARGET_BASE_ARCH']
2015  arch_srcs = [config_target_h[target]]
2016  arch_deps = []
2017  c_args = ['-DNEED_CPU_H',
2018            '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2019            '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2020  link_args = emulator_link_args
2021
2022  config_target += config_host
2023  target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2024  if targetos == 'linux'
2025    target_inc += include_directories('linux-headers', is_system: true)
2026  endif
2027  if target.endswith('-softmmu')
2028    qemu_target_name = 'qemu-system-' + target_name
2029    target_type='system'
2030    t = target_softmmu_arch[arch].apply(config_target, strict: false)
2031    arch_srcs += t.sources()
2032    arch_deps += t.dependencies()
2033
2034    hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2035    hw = hw_arch[hw_dir].apply(config_target, strict: false)
2036    arch_srcs += hw.sources()
2037    arch_deps += hw.dependencies()
2038
2039    arch_srcs += config_devices_h[target]
2040    link_args += ['@block.syms', '@qemu.syms']
2041  else
2042    abi = config_target['TARGET_ABI_DIR']
2043    target_type='user'
2044    qemu_target_name = 'qemu-' + target_name
2045    if 'CONFIG_LINUX_USER' in config_target
2046      base_dir = 'linux-user'
2047      target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2048    else
2049      base_dir = 'bsd-user'
2050    endif
2051    target_inc += include_directories(
2052      base_dir,
2053      base_dir / abi,
2054    )
2055    if 'CONFIG_LINUX_USER' in config_target
2056      dir = base_dir / abi
2057      arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2058      if config_target.has_key('TARGET_SYSTBL_ABI')
2059        arch_srcs += \
2060          syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2061                                             extra_args : config_target['TARGET_SYSTBL_ABI'])
2062      endif
2063    endif
2064  endif
2065
2066  if 'TARGET_XML_FILES' in config_target
2067    gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2068                                output: target + '-gdbstub-xml.c',
2069                                input: files(config_target['TARGET_XML_FILES'].split()),
2070                                command: [feature_to_c, '@INPUT@'],
2071                                capture: true)
2072    arch_srcs += gdbstub_xml
2073  endif
2074
2075  t = target_arch[arch].apply(config_target, strict: false)
2076  arch_srcs += t.sources()
2077  arch_deps += t.dependencies()
2078
2079  target_common = common_ss.apply(config_target, strict: false)
2080  objects = common_all.extract_objects(target_common.sources())
2081  deps = target_common.dependencies()
2082
2083  target_specific = specific_ss.apply(config_target, strict: false)
2084  arch_srcs += target_specific.sources()
2085  arch_deps += target_specific.dependencies()
2086
2087  lib = static_library('qemu-' + target,
2088                 sources: arch_srcs + genh,
2089                 dependencies: arch_deps,
2090                 objects: objects,
2091                 include_directories: target_inc,
2092                 c_args: c_args,
2093                 build_by_default: false,
2094                 name_suffix: 'fa')
2095
2096  if target.endswith('-softmmu')
2097    execs = [{
2098      'name': 'qemu-system-' + target_name,
2099      'gui': false,
2100      'sources': files('softmmu/main.c'),
2101      'dependencies': []
2102    }]
2103    if targetos == 'windows' and (sdl.found() or gtk.found())
2104      execs += [{
2105        'name': 'qemu-system-' + target_name + 'w',
2106        'gui': true,
2107        'sources': files('softmmu/main.c'),
2108        'dependencies': []
2109      }]
2110    endif
2111    if config_host.has_key('CONFIG_FUZZ')
2112      specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2113      execs += [{
2114        'name': 'qemu-fuzz-' + target_name,
2115        'gui': false,
2116        'sources': specific_fuzz.sources(),
2117        'dependencies': specific_fuzz.dependencies(),
2118      }]
2119    endif
2120  else
2121    execs = [{
2122      'name': 'qemu-' + target_name,
2123      'gui': false,
2124      'sources': [],
2125      'dependencies': []
2126    }]
2127  endif
2128  foreach exe: execs
2129    emulators += {exe['name']:
2130         executable(exe['name'], exe['sources'],
2131               install: true,
2132               c_args: c_args,
2133               dependencies: arch_deps + deps + exe['dependencies'],
2134               objects: lib.extract_all_objects(recursive: true),
2135               link_language: link_language,
2136               link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2137               link_args: link_args,
2138               gui_app: exe['gui'])
2139    }
2140
2141    if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2142      foreach stp: [
2143        {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2144        {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2145        {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2146        {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2147      ]
2148        custom_target(exe['name'] + stp['ext'],
2149                      input: trace_events_all,
2150                      output: exe['name'] + stp['ext'],
2151                      install: stp['install'],
2152                      install_dir: get_option('datadir') / 'systemtap/tapset',
2153                      command: [
2154                        tracetool, '--group=all', '--format=' + stp['fmt'],
2155                        '--binary=' + stp['bin'],
2156                        '--target-name=' + target_name,
2157                        '--target-type=' + target_type,
2158                        '--probe-prefix=qemu.' + target_type + '.' + target_name,
2159                        '@INPUT@', '@OUTPUT@'
2160                      ])
2161      endforeach
2162    endif
2163  endforeach
2164endforeach
2165
2166# Other build targets
2167
2168if 'CONFIG_PLUGIN' in config_host
2169  install_headers('include/qemu/qemu-plugin.h')
2170endif
2171
2172if 'CONFIG_GUEST_AGENT' in config_host
2173  subdir('qga')
2174endif
2175
2176# Don't build qemu-keymap if xkbcommon is not explicitly enabled
2177# when we don't build tools or system
2178if xkbcommon.found()
2179  # used for the update-keymaps target, so include rules even if !have_tools
2180  qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2181                           dependencies: [qemuutil, xkbcommon], install: have_tools)
2182endif
2183
2184if have_tools
2185  qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2186             dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2187  qemu_io = executable('qemu-io', files('qemu-io.c'),
2188             dependencies: [block, qemuutil], install: true)
2189  qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2190               dependencies: [blockdev, qemuutil], install: true)
2191
2192  subdir('storage-daemon')
2193  subdir('contrib/rdmacm-mux')
2194  subdir('contrib/elf2dmp')
2195
2196  executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2197             dependencies: qemuutil,
2198             install: true)
2199
2200  if 'CONFIG_VHOST_USER' in config_host
2201    subdir('contrib/vhost-user-blk')
2202    subdir('contrib/vhost-user-gpu')
2203    subdir('contrib/vhost-user-input')
2204    subdir('contrib/vhost-user-scsi')
2205  endif
2206
2207  if targetos == 'linux'
2208    executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2209               dependencies: [qemuutil, libcap_ng],
2210               install: true,
2211               install_dir: get_option('libexecdir'))
2212
2213    executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2214               dependencies: [authz, crypto, io, qom, qemuutil,
2215                              libcap_ng, mpathpersist],
2216               install: true)
2217  endif
2218
2219  if 'CONFIG_IVSHMEM' in config_host
2220    subdir('contrib/ivshmem-client')
2221    subdir('contrib/ivshmem-server')
2222  endif
2223endif
2224
2225subdir('scripts')
2226subdir('tools')
2227subdir('pc-bios')
2228subdir('docs')
2229subdir('tests')
2230if 'CONFIG_GTK' in config_host
2231  subdir('po')
2232endif
2233
2234if host_machine.system() == 'windows'
2235  nsis_cmd = [
2236    find_program('scripts/nsis.py'),
2237    '@OUTPUT@',
2238    get_option('prefix'),
2239    meson.current_source_dir(),
2240    host_machine.cpu(),
2241    '--',
2242    '-DDISPLAYVERSION=' + meson.project_version(),
2243  ]
2244  if build_docs
2245    nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2246  endif
2247  if 'CONFIG_GTK' in config_host
2248    nsis_cmd += '-DCONFIG_GTK=y'
2249  endif
2250
2251  nsis = custom_target('nsis',
2252                       output: 'qemu-setup-' + meson.project_version() + '.exe',
2253                       input: files('qemu.nsi'),
2254                       build_always_stale: true,
2255                       command: nsis_cmd + ['@INPUT@'])
2256  alias_target('installer', nsis)
2257endif
2258
2259#########################
2260# Configuration summary #
2261#########################
2262
2263summary_info = {}
2264summary_info += {'Install prefix':    get_option('prefix')}
2265summary_info += {'BIOS directory':    qemu_datadir}
2266summary_info += {'firmware path':     get_option('qemu_firmwarepath')}
2267summary_info += {'binary directory':  get_option('bindir')}
2268summary_info += {'library directory': get_option('libdir')}
2269summary_info += {'module directory':  qemu_moddir}
2270summary_info += {'libexec directory': get_option('libexecdir')}
2271summary_info += {'include directory': get_option('includedir')}
2272summary_info += {'config directory':  get_option('sysconfdir')}
2273if targetos != 'windows'
2274  summary_info += {'local state directory': get_option('localstatedir')}
2275  summary_info += {'Manual directory':      get_option('mandir')}
2276else
2277  summary_info += {'local state directory': 'queried at runtime'}
2278endif
2279summary_info += {'Doc directory':     get_option('docdir')}
2280summary_info += {'Build directory':   meson.current_build_dir()}
2281summary_info += {'Source path':       meson.current_source_dir()}
2282summary_info += {'GIT binary':        config_host['GIT']}
2283summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
2284summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
2285summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
2286if link_language == 'cpp'
2287  summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
2288else
2289  summary_info += {'C++ compiler':      false}
2290endif
2291if targetos == 'darwin'
2292  summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
2293endif
2294summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
2295summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
2296                                               + ['-O' + get_option('optimization')]
2297                                               + (get_option('debug') ? ['-g'] : []))}
2298if link_language == 'cpp'
2299  summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
2300                                               + ['-O' + get_option('optimization')]
2301                                               + (get_option('debug') ? ['-g'] : []))}
2302endif
2303link_args = get_option(link_language + '_link_args')
2304if link_args.length() > 0
2305  summary_info += {'LDFLAGS':         ' '.join(link_args)}
2306endif
2307summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
2308summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
2309summary_info += {'make':              config_host['MAKE']}
2310summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2311summary_info += {'sphinx-build':      sphinx_build.found()}
2312summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
2313# TODO: add back version
2314summary_info += {'slirp support':     slirp_opt == 'disabled' ? false : slirp_opt}
2315if slirp_opt != 'disabled'
2316  summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
2317endif
2318summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
2319if config_host.has_key('CONFIG_MODULES')
2320  summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2321endif
2322summary_info += {'host CPU':          cpu}
2323summary_info += {'host endianness':   build_machine.endian()}
2324summary_info += {'target list':       ' '.join(target_dirs)}
2325summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
2326summary_info += {'sparse enabled':    sparse.found()}
2327summary_info += {'strip binaries':    get_option('strip')}
2328summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
2329summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2330summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
2331if targetos == 'darwin'
2332  summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
2333endif
2334# TODO: add back version
2335summary_info += {'SDL support':       sdl.found()}
2336summary_info += {'SDL image support': sdl_image.found()}
2337# TODO: add back version
2338summary_info += {'GTK support':       config_host.has_key('CONFIG_GTK')}
2339summary_info += {'GTK GL support':    config_host.has_key('CONFIG_GTK_GL')}
2340summary_info += {'pixman':            pixman.found()}
2341# TODO: add back version
2342summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
2343summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
2344summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
2345# TODO: add back version
2346summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
2347if config_host.has_key('CONFIG_GCRYPT')
2348   summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
2349   summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2350endif
2351# TODO: add back version
2352summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
2353if config_host.has_key('CONFIG_NETTLE')
2354   summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2355endif
2356summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
2357summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
2358summary_info += {'iconv support':     iconv.found()}
2359summary_info += {'curses support':    curses.found()}
2360# TODO: add back version
2361summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
2362summary_info += {'curl support':      curl.found()}
2363summary_info += {'mingw32 support':   targetos == 'windows'}
2364summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
2365summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2366summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2367summary_info += {'VirtFS support':    have_virtfs}
2368summary_info += {'build virtiofs daemon': have_virtiofsd}
2369summary_info += {'Multipath support': mpathpersist.found()}
2370summary_info += {'VNC support':       vnc.found()}
2371if vnc.found()
2372  summary_info += {'VNC SASL support':  sasl.found()}
2373  summary_info += {'VNC JPEG support':  jpeg.found()}
2374  summary_info += {'VNC PNG support':   png.found()}
2375endif
2376summary_info += {'xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
2377if config_host.has_key('CONFIG_XEN_BACKEND')
2378  summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2379endif
2380summary_info += {'brlapi support':    brlapi.found()}
2381summary_info += {'Documentation':     build_docs}
2382summary_info += {'PIE':               get_option('b_pie')}
2383summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
2384summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
2385summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2386summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2387summary_info += {'ATTR/XATTR support': libattr.found()}
2388summary_info += {'Install blobs':     get_option('install_blobs')}
2389summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
2390summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
2391summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
2392summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
2393summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
2394if config_all.has_key('CONFIG_TCG')
2395  summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2396  summary_info += {'TCG interpreter':   config_host.has_key('CONFIG_TCG_INTERPRETER')}
2397endif
2398summary_info += {'malloc trim support': has_malloc_trim}
2399summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
2400summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
2401summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
2402summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
2403summary_info += {'preadv support':    config_host.has_key('CONFIG_PREADV')}
2404summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
2405summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
2406summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
2407summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2408summary_info += {'libcap-ng support': libcap_ng.found()}
2409summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2410summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2411summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2412summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2413summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2414summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2415summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2416summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2417summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2418summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
2419if config_host['TRACE_BACKENDS'].split().contains('simple')
2420  summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2421endif
2422# TODO: add back protocol and server version
2423summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
2424summary_info += {'rbd support':       rbd.found()}
2425summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
2426summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2427summary_info += {'U2F support':       u2f.found()}
2428summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
2429summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
2430summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
2431summary_info += {'OpenGL dmabufs':    config_host.has_key('CONFIG_OPENGL_DMABUF')}
2432summary_info += {'libiscsi support':  libiscsi.found()}
2433summary_info += {'libnfs support':    libnfs.found()}
2434summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2435if targetos == 'windows'
2436  if 'WIN_SDK' in config_host
2437    summary_info += {'Windows SDK':       config_host['WIN_SDK']}
2438  endif
2439  summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
2440  summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2441  summary_info += {'QGA MSI support':   config_host.has_key('CONFIG_QGA_MSI')}
2442endif
2443summary_info += {'seccomp support':   seccomp.found()}
2444summary_info += {'CFI support':       get_option('cfi')}
2445summary_info += {'CFI debug support': get_option('cfi_debug')}
2446summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2447summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
2448summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2449summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
2450summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
2451summary_info += {'GlusterFS support': glusterfs.found()}
2452summary_info += {'gcov':              get_option('b_coverage')}
2453summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
2454summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
2455summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2456summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2457summary_info += {'lzo support':       lzo.found()}
2458summary_info += {'snappy support':    snappy.found()}
2459summary_info += {'bzip2 support':     libbzip2.found()}
2460summary_info += {'lzfse support':     liblzfse.found()}
2461summary_info += {'zstd support':      zstd.found()}
2462summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2463summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
2464summary_info += {'memory allocator':  get_option('malloc')}
2465summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2466summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2467summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2468summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
2469summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
2470summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
2471summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
2472summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
2473summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
2474summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
2475summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2476summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
2477summary_info += {'capstone':          capstone_opt == 'disabled' ? false : capstone_opt}
2478summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
2479summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2480summary_info += {'libudev':           libudev.found()}
2481summary_info += {'default devices':   get_option('default_devices')}
2482summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
2483summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
2484if config_host.has_key('HAVE_GDB_BIN')
2485  summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
2486endif
2487summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
2488summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
2489summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
2490summary_info += {'FUSE exports':      fuse.found()}
2491summary_info += {'FUSE lseek':        fuse_lseek.found()}
2492summary(summary_info, bool_yn: true)
2493
2494if not supported_cpus.contains(cpu)
2495  message()
2496  warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2497  message()
2498  message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2499  message('The QEMU project intends to remove support for this host CPU in')
2500  message('a future release if nobody volunteers to maintain it and to')
2501  message('provide a build host for our continuous integration setup.')
2502  message('configure has succeeded and you can continue to build, but')
2503  message('if you care about QEMU on this platform you should contact')
2504  message('us upstream at qemu-devel@nongnu.org.')
2505endif
2506
2507if not supported_oses.contains(targetos)
2508  message()
2509  warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2510  message()
2511  message('Host OS ' + targetos + 'support is not currently maintained.')
2512  message('The QEMU project intends to remove support for this host OS in')
2513  message('a future release if nobody volunteers to maintain it and to')
2514  message('provide a build host for our continuous integration setup.')
2515  message('configure has succeeded and you can continue to build, but')
2516  message('if you care about QEMU on this platform you should contact')
2517  message('us upstream at qemu-devel@nongnu.org.')
2518endif
2519