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