xref: /openbmc/qemu/meson.build (revision 740b1759)
1project('qemu', ['c'], meson_version: '>=0.55.0',
2        default_options: ['warning_level=1', 'c_std=gnu99', 'cpp_std=gnu++11',
3                          'b_colorout=auto'],
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
20build_docs = 'BUILD_DOCS' in config_host
21
22if get_option('qemu_suffix').startswith('/')
23  error('qemu_suffix cannot start with a /')
24endif
25
26qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
27qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
28config_host_data = configuration_data()
29genh = []
30
31target_dirs = config_host['TARGET_DIRS'].split()
32have_user = false
33have_system = false
34foreach target : target_dirs
35  have_user = have_user or target.endswith('-user')
36  have_system = have_system or target.endswith('-softmmu')
37endforeach
38have_tools = 'CONFIG_TOOLS' in config_host
39have_block = have_system or have_tools
40
41python = import('python').find_installation()
42
43supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
44supported_cpus = ['ppc', 'ppc64', 's390x', 'sparc64', 'riscv32', 'riscv64', 'x86', 'x86_64',
45  'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
46
47cpu = host_machine.cpu_family()
48targetos = host_machine.system()
49
50configure_file(input: files('scripts/ninjatool.py'),
51               output: 'ninjatool',
52               configuration: config_host)
53
54if cpu in ['x86', 'x86_64']
55  kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
56elif cpu == 'aarch64'
57  kvm_targets = ['aarch64-softmmu']
58elif cpu == 's390x'
59  kvm_targets = ['s390x-softmmu']
60elif cpu in ['ppc', 'ppc64']
61  kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
62else
63  kvm_targets = []
64endif
65
66accelerator_targets = { 'CONFIG_KVM': kvm_targets }
67if cpu in ['x86', 'x86_64']
68  accelerator_targets += {
69    'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
70    'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
71    'CONFIG_HVF': ['x86_64-softmmu'],
72    'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
73  }
74endif
75
76##################
77# Compiler flags #
78##################
79
80# Specify linker-script with add_project_link_arguments so that it is not placed
81# within a linker --start-group/--end-group pair
82if 'CONFIG_FUZZ' in config_host
83   add_project_link_arguments(['-Wl,-T,',
84                               (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
85                              native: false, language: ['c', 'cpp', 'objc'])
86endif
87
88add_project_arguments(config_host['QEMU_CFLAGS'].split(),
89                      native: false, language: ['c', 'objc'])
90add_project_arguments(config_host['QEMU_CXXFLAGS'].split(),
91                      native: false, language: 'cpp')
92add_project_link_arguments(config_host['QEMU_LDFLAGS'].split(),
93                           native: false, language: ['c', 'cpp', 'objc'])
94add_project_arguments(config_host['QEMU_INCLUDES'].split(),
95                      language: ['c', 'cpp', 'objc'])
96
97
98link_language = meson.get_external_property('link_language', 'cpp')
99if link_language == 'cpp'
100  add_languages('cpp', required: true, native: false)
101endif
102if host_machine.system() == 'darwin'
103  add_languages('objc', required: false, native: false)
104endif
105
106sparse = find_program('cgcc', required: get_option('sparse'))
107if sparse.found()
108  run_target('sparse',
109             command: [find_program('scripts/check_sparse.py'),
110                       'compile_commands.json', sparse.full_path(), '-Wbitwise',
111                       '-Wno-transparent-union', '-Wno-old-initializer',
112                       '-Wno-non-pointer-null'])
113endif
114
115###########################################
116# Target-specific checks and dependencies #
117###########################################
118
119if targetos != 'linux' and get_option('mpath').enabled()
120  error('Multipath is supported only on Linux')
121endif
122
123m = cc.find_library('m', required: false)
124util = cc.find_library('util', required: false)
125winmm = []
126socket = []
127version_res = []
128coref = []
129iokit = []
130emulator_link_args = []
131cocoa = not_found
132hvf = not_found
133if targetos == 'windows'
134  socket = cc.find_library('ws2_32')
135  winmm = cc.find_library('winmm')
136
137  win = import('windows')
138  version_res = win.compile_resources('version.rc',
139                                      depend_files: files('pc-bios/qemu-nsis.ico'),
140                                      include_directories: include_directories('.'))
141elif targetos == 'darwin'
142  coref = dependency('appleframeworks', modules: 'CoreFoundation')
143  iokit = dependency('appleframeworks', modules: 'IOKit')
144  cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
145elif targetos == 'sunos'
146  socket = [cc.find_library('socket'),
147            cc.find_library('nsl'),
148            cc.find_library('resolv')]
149elif targetos == 'haiku'
150  socket = [cc.find_library('posix_error_mapper'),
151            cc.find_library('network'),
152            cc.find_library('bsd')]
153elif targetos == 'openbsd'
154  if not get_option('tcg').disabled() and target_dirs.length() > 0
155    # Disable OpenBSD W^X if available
156    emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
157  endif
158endif
159
160accelerators = []
161if not get_option('kvm').disabled() and targetos == 'linux'
162  accelerators += 'CONFIG_KVM'
163endif
164if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
165  accelerators += 'CONFIG_XEN'
166  have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
167else
168  have_xen_pci_passthrough = false
169endif
170if not get_option('whpx').disabled() and targetos == 'windows'
171  if get_option('whpx').enabled() and cpu != 'x86_64'
172    error('WHPX requires 64-bit host')
173  elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
174       cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
175    accelerators += 'CONFIG_WHPX'
176  endif
177endif
178if not get_option('hvf').disabled()
179  hvf = dependency('appleframeworks', modules: 'Hypervisor',
180                   required: get_option('hvf'))
181  if hvf.found()
182    accelerators += 'CONFIG_HVF'
183  endif
184endif
185if not get_option('hax').disabled()
186  if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
187    accelerators += 'CONFIG_HAX'
188  endif
189endif
190if not get_option('tcg').disabled()
191  if cpu not in supported_cpus
192    if 'CONFIG_TCG_INTERPRETER' in config_host
193      warning('Unsupported CPU @0@, will use TCG with TCI (experimental)'.format(cpu))
194    else
195      error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
196    endif
197  endif
198  accelerators += 'CONFIG_TCG'
199  config_host += { 'CONFIG_TCG': 'y' }
200endif
201
202if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
203  error('KVM not available on this platform')
204endif
205if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
206  error('HVF not available on this platform')
207endif
208if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
209  error('WHPX not available on this platform')
210endif
211if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
212  if 'CONFIG_XEN' in accelerators
213    error('Xen PCI passthrough not available on this platform')
214  else
215    error('Xen PCI passthrough requested but Xen not enabled')
216  endif
217endif
218if not cocoa.found() and get_option('cocoa').enabled()
219  error('Cocoa not available on this platform')
220endif
221
222################
223# Dependencies #
224################
225
226# The path to glib.h is added to all compilation commands.  This was
227# grandfathered in from the QEMU Makefiles.
228add_project_arguments(config_host['GLIB_CFLAGS'].split(),
229                      native: false, language: ['c', 'cpp', 'objc'])
230glib = declare_dependency(link_args: config_host['GLIB_LIBS'].split())
231gio = not_found
232if 'CONFIG_GIO' in config_host
233  gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
234                           link_args: config_host['GIO_LIBS'].split())
235endif
236lttng = not_found
237if 'CONFIG_TRACE_UST' in config_host
238  lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
239endif
240urcubp = not_found
241if 'CONFIG_TRACE_UST' in config_host
242  urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
243endif
244gcrypt = not_found
245if 'CONFIG_GCRYPT' in config_host
246  gcrypt = declare_dependency(compile_args: config_host['GCRYPT_CFLAGS'].split(),
247                              link_args: config_host['GCRYPT_LIBS'].split())
248endif
249nettle = not_found
250if 'CONFIG_NETTLE' in config_host
251  nettle = declare_dependency(compile_args: config_host['NETTLE_CFLAGS'].split(),
252                              link_args: config_host['NETTLE_LIBS'].split())
253endif
254gnutls = not_found
255if 'CONFIG_GNUTLS' in config_host
256  gnutls = declare_dependency(compile_args: config_host['GNUTLS_CFLAGS'].split(),
257                              link_args: config_host['GNUTLS_LIBS'].split())
258endif
259pixman = not_found
260if have_system or have_tools
261  pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
262                      method: 'pkg-config', static: enable_static)
263endif
264pam = not_found
265if 'CONFIG_AUTH_PAM' in config_host
266  pam = cc.find_library('pam')
267endif
268libaio = cc.find_library('aio', required: false)
269zlib = dependency('zlib', required: true, static: enable_static)
270linux_io_uring = not_found
271if 'CONFIG_LINUX_IO_URING' in config_host
272  linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
273                                      link_args: config_host['LINUX_IO_URING_LIBS'].split())
274endif
275libxml2 = not_found
276if 'CONFIG_LIBXML2' in config_host
277  libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
278                               link_args: config_host['LIBXML2_LIBS'].split())
279endif
280libnfs = not_found
281if 'CONFIG_LIBNFS' in config_host
282  libnfs = declare_dependency(link_args: config_host['LIBNFS_LIBS'].split())
283endif
284libattr = not_found
285if 'CONFIG_ATTR' in config_host
286  libattr = declare_dependency(link_args: config_host['LIBATTR_LIBS'].split())
287endif
288seccomp = not_found
289if 'CONFIG_SECCOMP' in config_host
290  seccomp = declare_dependency(compile_args: config_host['SECCOMP_CFLAGS'].split(),
291                               link_args: config_host['SECCOMP_LIBS'].split())
292endif
293libcap_ng = not_found
294if 'CONFIG_LIBCAP_NG' in config_host
295  libcap_ng = declare_dependency(link_args: config_host['LIBCAP_NG_LIBS'].split())
296endif
297if get_option('xkbcommon').auto() and not have_system and not have_tools
298  xkbcommon = not_found
299else
300  xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
301                         method: 'pkg-config', static: enable_static)
302endif
303slirp = not_found
304if config_host.has_key('CONFIG_SLIRP')
305  slirp = declare_dependency(compile_args: config_host['SLIRP_CFLAGS'].split(),
306                             link_args: config_host['SLIRP_LIBS'].split())
307endif
308vde = not_found
309if config_host.has_key('CONFIG_VDE')
310  vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
311endif
312pulse = not_found
313if 'CONFIG_LIBPULSE' in config_host
314  pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
315                             link_args: config_host['PULSE_LIBS'].split())
316endif
317alsa = not_found
318if 'CONFIG_ALSA' in config_host
319  alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
320                            link_args: config_host['ALSA_LIBS'].split())
321endif
322jack = not_found
323if 'CONFIG_LIBJACK' in config_host
324  jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
325endif
326spice = not_found
327if 'CONFIG_SPICE' in config_host
328  spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
329                             link_args: config_host['SPICE_LIBS'].split())
330endif
331rt = cc.find_library('rt', required: false)
332libdl = not_found
333if 'CONFIG_PLUGIN' in config_host
334  libdl = cc.find_library('dl', required: true)
335endif
336libiscsi = not_found
337if 'CONFIG_LIBISCSI' in config_host
338  libiscsi = declare_dependency(compile_args: config_host['LIBISCSI_CFLAGS'].split(),
339                                link_args: config_host['LIBISCSI_LIBS'].split())
340endif
341zstd = not_found
342if 'CONFIG_ZSTD' in config_host
343  zstd = declare_dependency(compile_args: config_host['ZSTD_CFLAGS'].split(),
344                            link_args: config_host['ZSTD_LIBS'].split())
345endif
346gbm = not_found
347if 'CONFIG_GBM' in config_host
348  gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
349                           link_args: config_host['GBM_LIBS'].split())
350endif
351virgl = not_found
352if 'CONFIG_VIRGL' in config_host
353  virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
354                             link_args: config_host['VIRGL_LIBS'].split())
355endif
356curl = not_found
357if 'CONFIG_CURL' in config_host
358  curl = declare_dependency(compile_args: config_host['CURL_CFLAGS'].split(),
359                            link_args: config_host['CURL_LIBS'].split())
360endif
361libudev = not_found
362if targetos == 'linux' and (have_system or have_tools)
363  libudev = dependency('libudev',
364                       required: get_option('mpath').enabled(),
365                       static: enable_static)
366endif
367
368mpathpersist = not_found
369mpathpersist_new_api = false
370if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
371  mpath_test_source_new = '''
372    #include <libudev.h>
373    #include <mpath_persist.h>
374    unsigned mpath_mx_alloc_len = 1024;
375    int logsink;
376    static struct config *multipath_conf;
377    extern struct udev *udev;
378    extern struct config *get_multipath_config(void);
379    extern void put_multipath_config(struct config *conf);
380    struct udev *udev;
381    struct config *get_multipath_config(void) { return multipath_conf; }
382    void put_multipath_config(struct config *conf) { }
383    int main(void) {
384        udev = udev_new();
385        multipath_conf = mpath_lib_init();
386        return 0;
387    }'''
388  mpath_test_source_old = '''
389      #include <libudev.h>
390      #include <mpath_persist.h>
391      unsigned mpath_mx_alloc_len = 1024;
392      int logsink;
393      int main(void) {
394          struct udev *udev = udev_new();
395          mpath_lib_init(udev);
396          return 0;
397      }'''
398  mpathlibs = [libudev]
399  if enable_static
400    mpathlibs += cc.find_library('devmapper',
401                                   required: get_option('mpath'),
402                                   static: enable_static)
403  endif
404  mpathlibs += cc.find_library('multipath',
405                               required: get_option('mpath'),
406                               static: enable_static)
407  mpathlibs += cc.find_library('mpathpersist',
408                               required: get_option('mpath'),
409                               static: enable_static)
410  foreach lib: mpathlibs
411    if not lib.found()
412      mpathlibs = []
413      break
414    endif
415  endforeach
416  if mpathlibs.length() > 0
417    if cc.links(mpath_test_source_new, dependencies: mpathlibs)
418      mpathpersist = declare_dependency(dependencies: mpathlibs)
419      mpathpersist_new_api = true
420    elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
421      mpathpersist = declare_dependency(dependencies: mpathlibs)
422    else
423      if get_option('mpath').enabled()
424        error('Cannot detect libmpathpersist API')
425      else
426        warning('Cannot detect libmpathpersist API, disabling')
427      endif
428    endif
429  endif
430endif
431
432brlapi = not_found
433if 'CONFIG_BRLAPI' in config_host
434  brlapi = declare_dependency(link_args: config_host['BRLAPI_LIBS'].split())
435endif
436
437sdl = not_found
438if have_system
439  sdl = dependency('sdl2', required: get_option('sdl'), static: enable_static)
440  sdl_image = not_found
441endif
442if sdl.found()
443  # work around 2.0.8 bug
444  sdl = declare_dependency(compile_args: '-Wno-undef',
445                           dependencies: sdl)
446  sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
447                         method: 'pkg-config', static: enable_static)
448else
449  if get_option('sdl_image').enabled()
450    error('sdl-image required, but SDL was @0@'.format(
451          get_option('sdl').disabled() ? 'disabled' : 'not found'))
452  endif
453  sdl_image = not_found
454endif
455
456rbd = not_found
457if 'CONFIG_RBD' in config_host
458  rbd = declare_dependency(link_args: config_host['RBD_LIBS'].split())
459endif
460glusterfs = not_found
461if 'CONFIG_GLUSTERFS' in config_host
462  glusterfs = declare_dependency(compile_args: config_host['GLUSTERFS_CFLAGS'].split(),
463                                 link_args: config_host['GLUSTERFS_LIBS'].split())
464endif
465libssh = not_found
466if 'CONFIG_LIBSSH' in config_host
467  libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
468                              link_args: config_host['LIBSSH_LIBS'].split())
469endif
470libbzip2 = not_found
471if 'CONFIG_BZIP2' in config_host
472  libbzip2 = declare_dependency(link_args: config_host['BZIP2_LIBS'].split())
473endif
474liblzfse = not_found
475if 'CONFIG_LZFSE' in config_host
476  liblzfse = declare_dependency(link_args: config_host['LZFSE_LIBS'].split())
477endif
478oss = not_found
479if 'CONFIG_AUDIO_OSS' in config_host
480  oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
481endif
482dsound = not_found
483if 'CONFIG_AUDIO_DSOUND' in config_host
484  dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
485endif
486coreaudio = not_found
487if 'CONFIG_AUDIO_COREAUDIO' in config_host
488  coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
489endif
490opengl = not_found
491if 'CONFIG_OPENGL' in config_host
492  opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
493                              link_args: config_host['OPENGL_LIBS'].split())
494endif
495gtk = not_found
496if 'CONFIG_GTK' in config_host
497  gtk = declare_dependency(compile_args: config_host['GTK_CFLAGS'].split(),
498                              link_args: config_host['GTK_LIBS'].split())
499endif
500vte = not_found
501if 'CONFIG_VTE' in config_host
502  vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
503                           link_args: config_host['VTE_LIBS'].split())
504endif
505x11 = not_found
506if 'CONFIG_X11' in config_host
507  x11 = declare_dependency(compile_args: config_host['X11_CFLAGS'].split(),
508                           link_args: config_host['X11_LIBS'].split())
509endif
510curses = not_found
511if 'CONFIG_CURSES' in config_host
512  curses = declare_dependency(compile_args: config_host['CURSES_CFLAGS'].split(),
513                              link_args: config_host['CURSES_LIBS'].split())
514endif
515iconv = not_found
516if 'CONFIG_ICONV' in config_host
517  iconv = declare_dependency(compile_args: config_host['ICONV_CFLAGS'].split(),
518                             link_args: config_host['ICONV_LIBS'].split())
519endif
520vnc = not_found
521png = not_found
522jpeg = not_found
523sasl = not_found
524if get_option('vnc').enabled()
525  vnc = declare_dependency() # dummy dependency
526  png = dependency('libpng', required: get_option('vnc_png'),
527                   method: 'pkg-config', static: enable_static)
528  jpeg = cc.find_library('jpeg', has_headers: ['jpeglib.h'],
529                         required: get_option('vnc_jpeg'),
530                         static: enable_static)
531  sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
532                         required: get_option('vnc_sasl'),
533                         static: enable_static)
534  if sasl.found()
535    sasl = declare_dependency(dependencies: sasl,
536                              compile_args: '-DSTRUCT_IOVEC_DEFINED')
537  endif
538endif
539fdt = not_found
540if 'CONFIG_FDT' in config_host
541  fdt = declare_dependency(compile_args: config_host['FDT_CFLAGS'].split(),
542                           link_args: config_host['FDT_LIBS'].split())
543endif
544snappy = not_found
545if 'CONFIG_SNAPPY' in config_host
546  snappy = declare_dependency(link_args: config_host['SNAPPY_LIBS'].split())
547endif
548lzo = not_found
549if 'CONFIG_LZO' in config_host
550  lzo = declare_dependency(link_args: config_host['LZO_LIBS'].split())
551endif
552rdma = not_found
553if 'CONFIG_RDMA' in config_host
554  rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
555endif
556numa = not_found
557if 'CONFIG_NUMA' in config_host
558  numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
559endif
560xen = not_found
561if 'CONFIG_XEN_BACKEND' in config_host
562  xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
563                           link_args: config_host['XEN_LIBS'].split())
564endif
565cacard = not_found
566if 'CONFIG_SMARTCARD' in config_host
567  cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
568                              link_args: config_host['SMARTCARD_LIBS'].split())
569endif
570u2f = not_found
571if have_system
572  u2f = dependency('u2f-emu', required: get_option('u2f'),
573                   method: 'pkg-config',
574                   static: enable_static)
575endif
576usbredir = not_found
577if 'CONFIG_USB_REDIR' in config_host
578  usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
579                                link_args: config_host['USB_REDIR_LIBS'].split())
580endif
581libusb = not_found
582if 'CONFIG_USB_LIBUSB' in config_host
583  libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
584                              link_args: config_host['LIBUSB_LIBS'].split())
585endif
586libpmem = not_found
587if 'CONFIG_LIBPMEM' in config_host
588  libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
589                               link_args: config_host['LIBPMEM_LIBS'].split())
590endif
591libdaxctl = not_found
592if 'CONFIG_LIBDAXCTL' in config_host
593  libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
594endif
595tasn1 = not_found
596if 'CONFIG_TASN1' in config_host
597  tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(),
598                             link_args: config_host['TASN1_LIBS'].split())
599endif
600keyutils = dependency('libkeyutils', required: false,
601                      method: 'pkg-config', static: enable_static)
602
603has_gettid = cc.has_function('gettid')
604
605# Malloc tests
606
607malloc = []
608if get_option('malloc') == 'system'
609  has_malloc_trim = \
610    not get_option('malloc_trim').disabled() and \
611    cc.links('''#include <malloc.h>
612                int main(void) { malloc_trim(0); return 0; }''')
613else
614  has_malloc_trim = false
615  malloc = cc.find_library(get_option('malloc'), required: true)
616endif
617if not has_malloc_trim and get_option('malloc_trim').enabled()
618  if get_option('malloc') == 'system'
619    error('malloc_trim not available on this platform.')
620  else
621    error('malloc_trim not available with non-libc memory allocator')
622  endif
623endif
624
625# Create config-host.h
626
627config_host_data.set('CONFIG_COCOA', cocoa.found())
628config_host_data.set('CONFIG_LIBUDEV', libudev.found())
629config_host_data.set('CONFIG_MPATH', mpathpersist.found())
630config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
631config_host_data.set('CONFIG_SDL', sdl.found())
632config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
633config_host_data.set('CONFIG_VNC', vnc.found())
634config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
635config_host_data.set('CONFIG_VNC_PNG', png.found())
636config_host_data.set('CONFIG_VNC_SASL', sasl.found())
637config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
638config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
639config_host_data.set('CONFIG_GETTID', has_gettid)
640config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
641config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
642config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
643config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
644config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
645
646ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
647arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
648strings = ['HOST_DSOSUF', 'CONFIG_IASL', 'bindir', 'prefix', 'qemu_confdir', 'qemu_datadir',
649           'qemu_moddir', 'qemu_localstatedir', 'qemu_helperdir', 'qemu_localedir',
650           'qemu_icondir', 'qemu_desktopdir', 'qemu_firmwarepath', 'sysconfdir']
651foreach k, v: config_host
652  if ignored.contains(k)
653    # do nothing
654  elif arrays.contains(k)
655    if v != ''
656      v = '"' + '", "'.join(v.split()) + '", '
657    endif
658    config_host_data.set(k, v)
659  elif k == 'ARCH'
660    config_host_data.set('HOST_' + v.to_upper(), 1)
661  elif strings.contains(k)
662    if not k.startswith('CONFIG_')
663      k = 'CONFIG_' + k.to_upper()
664    endif
665    config_host_data.set_quoted(k, v)
666  elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
667    config_host_data.set(k, v == 'y' ? 1 : v)
668  endif
669endforeach
670
671minikconf = find_program('scripts/minikconf.py')
672config_all = {}
673config_all_devices = {}
674config_all_disas = {}
675config_devices_mak_list = []
676config_devices_h = {}
677config_target_h = {}
678config_target_mak = {}
679
680disassemblers = {
681  'alpha' : ['CONFIG_ALPHA_DIS'],
682  'arm' : ['CONFIG_ARM_DIS'],
683  'avr' : ['CONFIG_AVR_DIS'],
684  'cris' : ['CONFIG_CRIS_DIS'],
685  'hppa' : ['CONFIG_HPPA_DIS'],
686  'i386' : ['CONFIG_I386_DIS'],
687  'x86_64' : ['CONFIG_I386_DIS'],
688  'x32' : ['CONFIG_I386_DIS'],
689  'lm32' : ['CONFIG_LM32_DIS'],
690  'm68k' : ['CONFIG_M68K_DIS'],
691  'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
692  'mips' : ['CONFIG_MIPS_DIS'],
693  'moxie' : ['CONFIG_MOXIE_DIS'],
694  'nios2' : ['CONFIG_NIOS2_DIS'],
695  'or1k' : ['CONFIG_OPENRISC_DIS'],
696  'ppc' : ['CONFIG_PPC_DIS'],
697  'riscv' : ['CONFIG_RISCV_DIS'],
698  'rx' : ['CONFIG_RX_DIS'],
699  's390' : ['CONFIG_S390_DIS'],
700  'sh4' : ['CONFIG_SH4_DIS'],
701  'sparc' : ['CONFIG_SPARC_DIS'],
702  'xtensa' : ['CONFIG_XTENSA_DIS'],
703}
704if link_language == 'cpp'
705  disassemblers += {
706    'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
707    'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
708    'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
709  }
710endif
711
712kconfig_external_symbols = [
713  'CONFIG_KVM',
714  'CONFIG_XEN',
715  'CONFIG_TPM',
716  'CONFIG_SPICE',
717  'CONFIG_IVSHMEM',
718  'CONFIG_OPENGL',
719  'CONFIG_X11',
720  'CONFIG_VHOST_USER',
721  'CONFIG_VHOST_VDPA',
722  'CONFIG_VHOST_KERNEL',
723  'CONFIG_VIRTFS',
724  'CONFIG_LINUX',
725  'CONFIG_PVRDMA',
726]
727ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
728
729default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
730actual_target_dirs = []
731foreach target : target_dirs
732  config_target = { 'TARGET_NAME': target.split('-')[0] }
733  if target.endswith('linux-user')
734    if targetos != 'linux'
735      if default_targets
736        continue
737      endif
738      error('Target @0@ is only available on a Linux host'.format(target))
739    endif
740    config_target += { 'CONFIG_LINUX_USER': 'y' }
741  elif target.endswith('bsd-user')
742    if 'CONFIG_BSD' not in config_host
743      if default_targets
744        continue
745      endif
746      error('Target @0@ is only available on a BSD host'.format(target))
747    endif
748    config_target += { 'CONFIG_BSD_USER': 'y' }
749  elif target.endswith('softmmu')
750    config_target += { 'CONFIG_SOFTMMU': 'y' }
751  endif
752  if target.endswith('-user')
753    config_target += {
754      'CONFIG_USER_ONLY': 'y',
755      'CONFIG_QEMU_INTERP_PREFIX':
756        config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
757    }
758  endif
759
760  have_accel = false
761  foreach sym: accelerators
762    if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
763      config_target += { sym: 'y' }
764      config_all += { sym: 'y' }
765      if sym == 'CONFIG_XEN' and have_xen_pci_passthrough
766        config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
767      endif
768      have_accel = true
769    endif
770  endforeach
771  if not have_accel
772    if default_targets
773      continue
774    endif
775    error('No accelerator available for target @0@'.format(target))
776  endif
777
778  actual_target_dirs += target
779  config_target += keyval.load('default-configs/targets' / target + '.mak')
780  config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
781
782  # Add default keys
783  if 'TARGET_BASE_ARCH' not in config_target
784    config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
785  endif
786  if 'TARGET_ABI_DIR' not in config_target
787    config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
788  endif
789
790  foreach k, v: disassemblers
791    if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
792      foreach sym: v
793        config_target += { sym: 'y' }
794        config_all_disas += { sym: 'y' }
795      endforeach
796    endif
797  endforeach
798
799  config_target_data = configuration_data()
800  foreach k, v: config_target
801    if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
802      # do nothing
803    elif ignored.contains(k)
804      # do nothing
805    elif k == 'TARGET_BASE_ARCH'
806      # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
807      # not used to select files from sourcesets.
808      config_target_data.set('TARGET_' + v.to_upper(), 1)
809    elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
810      config_target_data.set_quoted(k, v)
811    elif v == 'y'
812      config_target_data.set(k, 1)
813    else
814      config_target_data.set(k, v)
815    endif
816  endforeach
817  config_target_h += {target: configure_file(output: target + '-config-target.h',
818                                               configuration: config_target_data)}
819
820  if target.endswith('-softmmu')
821    base_kconfig = []
822    foreach sym : kconfig_external_symbols
823      if sym in config_target or sym in config_host
824        base_kconfig += '@0@=y'.format(sym)
825      endif
826    endforeach
827
828    config_devices_mak = target + '-config-devices.mak'
829    config_devices_mak = configure_file(
830      input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
831      output: config_devices_mak,
832      depfile: config_devices_mak + '.d',
833      capture: true,
834      command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'],
835                config_devices_mak, '@DEPFILE@', '@INPUT@',
836                base_kconfig])
837
838    config_devices_data = configuration_data()
839    config_devices = keyval.load(config_devices_mak)
840    foreach k, v: config_devices
841      config_devices_data.set(k, 1)
842    endforeach
843    config_devices_mak_list += config_devices_mak
844    config_devices_h += {target: configure_file(output: target + '-config-devices.h',
845                                                configuration: config_devices_data)}
846    config_target += config_devices
847    config_all_devices += config_devices
848  endif
849  config_target_mak += {target: config_target}
850endforeach
851target_dirs = actual_target_dirs
852
853# This configuration is used to build files that are shared by
854# multiple binaries, and then extracted out of the "common"
855# static_library target.
856#
857# We do not use all_sources()/all_dependencies(), because it would
858# build literally all source files, including devices only used by
859# targets that are not built for this compilation.  The CONFIG_ALL
860# pseudo symbol replaces it.
861
862config_all += config_all_devices
863config_all += config_host
864config_all += config_all_disas
865config_all += {
866  'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
867  'CONFIG_SOFTMMU': have_system,
868  'CONFIG_USER_ONLY': have_user,
869  'CONFIG_ALL': true,
870}
871
872# Submodules
873
874capstone = not_found
875capstone_opt = get_option('capstone')
876if capstone_opt in ['enabled', 'auto', 'system']
877  have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
878  capstone = dependency('capstone', version: '>=4.0',
879                        static: enable_static, method: 'pkg-config',
880                        required: capstone_opt == 'system' or
881                                  capstone_opt == 'enabled' and not have_internal)
882  if capstone.found()
883    capstone_opt = 'system'
884  elif have_internal
885    capstone_opt = 'internal'
886  else
887    capstone_opt = 'disabled'
888  endif
889endif
890if capstone_opt == 'internal'
891  capstone_data = configuration_data()
892  capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
893
894  capstone_files = files(
895    'capstone/cs.c',
896    'capstone/MCInst.c',
897    'capstone/MCInstrDesc.c',
898    'capstone/MCRegisterInfo.c',
899    'capstone/SStream.c',
900    'capstone/utils.c'
901  )
902
903  if 'CONFIG_ARM_DIS' in config_all_disas
904    capstone_data.set('CAPSTONE_HAS_ARM', '1')
905    capstone_files += files(
906      'capstone/arch/ARM/ARMDisassembler.c',
907      'capstone/arch/ARM/ARMInstPrinter.c',
908      'capstone/arch/ARM/ARMMapping.c',
909      'capstone/arch/ARM/ARMModule.c'
910    )
911  endif
912
913  # FIXME: This config entry currently depends on a c++ compiler.
914  # Which is needed for building libvixl, but not for capstone.
915  if 'CONFIG_ARM_A64_DIS' in config_all_disas
916    capstone_data.set('CAPSTONE_HAS_ARM64', '1')
917    capstone_files += files(
918      'capstone/arch/AArch64/AArch64BaseInfo.c',
919      'capstone/arch/AArch64/AArch64Disassembler.c',
920      'capstone/arch/AArch64/AArch64InstPrinter.c',
921      'capstone/arch/AArch64/AArch64Mapping.c',
922      'capstone/arch/AArch64/AArch64Module.c'
923    )
924  endif
925
926  if 'CONFIG_PPC_DIS' in config_all_disas
927    capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
928    capstone_files += files(
929      'capstone/arch/PowerPC/PPCDisassembler.c',
930      'capstone/arch/PowerPC/PPCInstPrinter.c',
931      'capstone/arch/PowerPC/PPCMapping.c',
932      'capstone/arch/PowerPC/PPCModule.c'
933    )
934  endif
935
936  if 'CONFIG_S390_DIS' in config_all_disas
937    capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
938    capstone_files += files(
939      'capstone/arch/SystemZ/SystemZDisassembler.c',
940      'capstone/arch/SystemZ/SystemZInstPrinter.c',
941      'capstone/arch/SystemZ/SystemZMapping.c',
942      'capstone/arch/SystemZ/SystemZModule.c',
943      'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
944    )
945  endif
946
947  if 'CONFIG_I386_DIS' in config_all_disas
948    capstone_data.set('CAPSTONE_HAS_X86', 1)
949    capstone_files += files(
950      'capstone/arch/X86/X86Disassembler.c',
951      'capstone/arch/X86/X86DisassemblerDecoder.c',
952      'capstone/arch/X86/X86ATTInstPrinter.c',
953      'capstone/arch/X86/X86IntelInstPrinter.c',
954      'capstone/arch/X86/X86InstPrinterCommon.c',
955      'capstone/arch/X86/X86Mapping.c',
956      'capstone/arch/X86/X86Module.c'
957    )
958  endif
959
960  configure_file(output: 'capstone-defs.h', configuration: capstone_data)
961
962  capstone_cargs = [
963    # FIXME: There does not seem to be a way to completely replace the c_args
964    # that come from add_project_arguments() -- we can only add to them.
965    # So: disable all warnings with a big hammer.
966    '-Wno-error', '-w',
967
968    # Include all configuration defines via a header file, which will wind up
969    # as a dependency on the object file, and thus changes here will result
970    # in a rebuild.
971    '-include', 'capstone-defs.h'
972  ]
973
974  libcapstone = static_library('capstone',
975                               sources: capstone_files,
976                               c_args: capstone_cargs,
977                               include_directories: 'capstone/include')
978  capstone = declare_dependency(link_with: libcapstone,
979                                include_directories: 'capstone/include/capstone')
980endif
981config_host_data.set('CONFIG_CAPSTONE', capstone.found())
982
983genh += configure_file(output: 'config-host.h', configuration: config_host_data)
984
985# Generators
986
987hxtool = find_program('scripts/hxtool')
988shaderinclude = find_program('scripts/shaderinclude.pl')
989qapi_gen = find_program('scripts/qapi-gen.py')
990qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
991                     meson.source_root() / 'scripts/qapi/commands.py',
992                     meson.source_root() / 'scripts/qapi/common.py',
993                     meson.source_root() / 'scripts/qapi/error.py',
994                     meson.source_root() / 'scripts/qapi/events.py',
995                     meson.source_root() / 'scripts/qapi/expr.py',
996                     meson.source_root() / 'scripts/qapi/gen.py',
997                     meson.source_root() / 'scripts/qapi/introspect.py',
998                     meson.source_root() / 'scripts/qapi/parser.py',
999                     meson.source_root() / 'scripts/qapi/schema.py',
1000                     meson.source_root() / 'scripts/qapi/source.py',
1001                     meson.source_root() / 'scripts/qapi/types.py',
1002                     meson.source_root() / 'scripts/qapi/visit.py',
1003                     meson.source_root() / 'scripts/qapi/common.py',
1004                     meson.source_root() / 'scripts/qapi-gen.py'
1005]
1006
1007tracetool = [
1008  python, files('scripts/tracetool.py'),
1009   '--backend=' + config_host['TRACE_BACKENDS']
1010]
1011
1012qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1013                    meson.current_source_dir(),
1014                    config_host['PKGVERSION'], meson.project_version()]
1015qemu_version = custom_target('qemu-version.h',
1016                             output: 'qemu-version.h',
1017                             command: qemu_version_cmd,
1018                             capture: true,
1019                             build_by_default: true,
1020                             build_always_stale: true)
1021genh += qemu_version
1022
1023hxdep = []
1024hx_headers = [
1025  ['qemu-options.hx', 'qemu-options.def'],
1026  ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1027]
1028if have_system
1029  hx_headers += [
1030    ['hmp-commands.hx', 'hmp-commands.h'],
1031    ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1032  ]
1033endif
1034foreach d : hx_headers
1035  hxdep += custom_target(d[1],
1036                input: files(d[0]),
1037                output: d[1],
1038                capture: true,
1039                build_by_default: true, # to be removed when added to a target
1040                command: [hxtool, '-h', '@INPUT0@'])
1041endforeach
1042genh += hxdep
1043
1044SPHINX_ARGS = [config_host['SPHINX_BUILD'],
1045               '-Dversion=' + meson.project_version(),
1046               '-Drelease=' + config_host['PKGVERSION']]
1047
1048if get_option('werror')
1049  SPHINX_ARGS += [ '-W' ]
1050endif
1051
1052sphinx_extn_depends = [ meson.source_root() / 'docs/sphinx/depfile.py',
1053                        meson.source_root() / 'docs/sphinx/hxtool.py',
1054                        meson.source_root() / 'docs/sphinx/kerneldoc.py',
1055                        meson.source_root() / 'docs/sphinx/kernellog.py',
1056                        meson.source_root() / 'docs/sphinx/qapidoc.py',
1057                        meson.source_root() / 'docs/sphinx/qmp_lexer.py',
1058                        qapi_gen_depends ]
1059
1060# Collect sourcesets.
1061
1062util_ss = ss.source_set()
1063stub_ss = ss.source_set()
1064trace_ss = ss.source_set()
1065block_ss = ss.source_set()
1066blockdev_ss = ss.source_set()
1067qmp_ss = ss.source_set()
1068common_ss = ss.source_set()
1069softmmu_ss = ss.source_set()
1070user_ss = ss.source_set()
1071bsd_user_ss = ss.source_set()
1072linux_user_ss = ss.source_set()
1073specific_ss = ss.source_set()
1074specific_fuzz_ss = ss.source_set()
1075
1076modules = {}
1077hw_arch = {}
1078target_arch = {}
1079target_softmmu_arch = {}
1080
1081###############
1082# Trace files #
1083###############
1084
1085# TODO: add each directory to the subdirs from its own meson.build, once
1086# we have those
1087trace_events_subdirs = [
1088  'accel/kvm',
1089  'accel/tcg',
1090  'crypto',
1091  'monitor',
1092]
1093if have_user
1094  trace_events_subdirs += [ 'linux-user' ]
1095endif
1096if have_block
1097  trace_events_subdirs += [
1098    'authz',
1099    'block',
1100    'io',
1101    'nbd',
1102    'scsi',
1103  ]
1104endif
1105if have_system
1106  trace_events_subdirs += [
1107    'audio',
1108    'backends',
1109    'backends/tpm',
1110    'chardev',
1111    'hw/9pfs',
1112    'hw/acpi',
1113    'hw/alpha',
1114    'hw/arm',
1115    'hw/audio',
1116    'hw/block',
1117    'hw/block/dataplane',
1118    'hw/char',
1119    'hw/display',
1120    'hw/dma',
1121    'hw/hppa',
1122    'hw/hyperv',
1123    'hw/i2c',
1124    'hw/i386',
1125    'hw/i386/xen',
1126    'hw/ide',
1127    'hw/input',
1128    'hw/intc',
1129    'hw/isa',
1130    'hw/mem',
1131    'hw/mips',
1132    'hw/misc',
1133    'hw/misc/macio',
1134    'hw/net',
1135    'hw/nvram',
1136    'hw/pci',
1137    'hw/pci-host',
1138    'hw/ppc',
1139    'hw/rdma',
1140    'hw/rdma/vmw',
1141    'hw/rtc',
1142    'hw/s390x',
1143    'hw/scsi',
1144    'hw/sd',
1145    'hw/sparc',
1146    'hw/sparc64',
1147    'hw/ssi',
1148    'hw/timer',
1149    'hw/tpm',
1150    'hw/usb',
1151    'hw/vfio',
1152    'hw/virtio',
1153    'hw/watchdog',
1154    'hw/xen',
1155    'hw/gpio',
1156    'migration',
1157    'net',
1158    'softmmu',
1159    'ui',
1160  ]
1161endif
1162trace_events_subdirs += [
1163  'hw/core',
1164  'qapi',
1165  'qom',
1166  'target/arm',
1167  'target/hppa',
1168  'target/i386',
1169  'target/mips',
1170  'target/ppc',
1171  'target/riscv',
1172  'target/s390x',
1173  'target/sparc',
1174  'util',
1175]
1176
1177subdir('qapi')
1178subdir('qobject')
1179subdir('stubs')
1180subdir('trace')
1181subdir('util')
1182subdir('qom')
1183subdir('authz')
1184subdir('crypto')
1185subdir('ui')
1186
1187
1188if enable_modules
1189  libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1190  modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1191endif
1192
1193# Build targets from sourcesets
1194
1195stub_ss = stub_ss.apply(config_all, strict: false)
1196
1197util_ss.add_all(trace_ss)
1198util_ss = util_ss.apply(config_all, strict: false)
1199libqemuutil = static_library('qemuutil',
1200                             sources: util_ss.sources() + stub_ss.sources() + genh,
1201                             dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1202qemuutil = declare_dependency(link_with: libqemuutil,
1203                              sources: genh + version_res)
1204
1205decodetree = generator(find_program('scripts/decodetree.py'),
1206                       output: 'decode-@BASENAME@.c.inc',
1207                       arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1208
1209subdir('audio')
1210subdir('io')
1211subdir('chardev')
1212subdir('fsdev')
1213subdir('libdecnumber')
1214subdir('target')
1215subdir('dump')
1216
1217block_ss.add(files(
1218  'block.c',
1219  'blockdev-nbd.c',
1220  'blockjob.c',
1221  'job.c',
1222  'qemu-io-cmds.c',
1223))
1224block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1225
1226subdir('nbd')
1227subdir('scsi')
1228subdir('block')
1229
1230blockdev_ss.add(files(
1231  'blockdev.c',
1232  'iothread.c',
1233  'job-qmp.c',
1234))
1235
1236# os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1237# os-win32.c does not
1238blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1239softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1240
1241softmmu_ss.add_all(blockdev_ss)
1242softmmu_ss.add(files(
1243  'bootdevice.c',
1244  'dma-helpers.c',
1245  'qdev-monitor.c',
1246), sdl)
1247
1248softmmu_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c'))
1249softmmu_ss.add(when: 'CONFIG_SECCOMP', if_true: [files('qemu-seccomp.c'), seccomp])
1250softmmu_ss.add(when: ['CONFIG_FDT', fdt],  if_true: [files('device_tree.c')])
1251
1252common_ss.add(files('cpus-common.c'))
1253
1254subdir('softmmu')
1255
1256common_ss.add(capstone)
1257specific_ss.add(files('disas.c', 'exec.c', 'gdbstub.c'), capstone, libpmem, libdaxctl)
1258specific_ss.add(files('exec-vary.c'))
1259specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1260  'fpu/softfloat.c',
1261  'tcg/optimize.c',
1262  'tcg/tcg-common.c',
1263  'tcg/tcg-op-gvec.c',
1264  'tcg/tcg-op-vec.c',
1265  'tcg/tcg-op.c',
1266  'tcg/tcg.c',
1267))
1268specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1269
1270subdir('backends')
1271subdir('disas')
1272subdir('migration')
1273subdir('monitor')
1274subdir('net')
1275subdir('replay')
1276subdir('hw')
1277subdir('accel')
1278subdir('plugins')
1279subdir('bsd-user')
1280subdir('linux-user')
1281
1282bsd_user_ss.add(files('gdbstub.c'))
1283specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1284
1285linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1286specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1287
1288# needed for fuzzing binaries
1289subdir('tests/qtest/libqos')
1290subdir('tests/qtest/fuzz')
1291
1292block_mods = []
1293softmmu_mods = []
1294foreach d, list : modules
1295  foreach m, module_ss : list
1296    if enable_modules and targetos != 'windows'
1297      module_ss = module_ss.apply(config_all, strict: false)
1298      sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1299                          dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1300      if d == 'block'
1301        block_mods += sl
1302      else
1303        softmmu_mods += sl
1304      endif
1305    else
1306      if d == 'block'
1307        block_ss.add_all(module_ss)
1308      else
1309        softmmu_ss.add_all(module_ss)
1310      endif
1311    endif
1312  endforeach
1313endforeach
1314
1315nm = find_program('nm')
1316undefsym = find_program('scripts/undefsym.py')
1317block_syms = custom_target('block.syms', output: 'block.syms',
1318                             input: [libqemuutil, block_mods],
1319                             capture: true,
1320                             command: [undefsym, nm, '@INPUT@'])
1321qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1322                             input: [libqemuutil, softmmu_mods],
1323                             capture: true,
1324                             command: [undefsym, nm, '@INPUT@'])
1325
1326block_ss = block_ss.apply(config_host, strict: false)
1327libblock = static_library('block', block_ss.sources() + genh,
1328                          dependencies: block_ss.dependencies(),
1329                          link_depends: block_syms,
1330                          name_suffix: 'fa',
1331                          build_by_default: false)
1332
1333block = declare_dependency(link_whole: [libblock],
1334                           link_args: '@block.syms',
1335                           dependencies: [crypto, io])
1336
1337qmp_ss = qmp_ss.apply(config_host, strict: false)
1338libqmp = static_library('qmp', qmp_ss.sources() + genh,
1339                        dependencies: qmp_ss.dependencies(),
1340                        name_suffix: 'fa',
1341                        build_by_default: false)
1342
1343qmp = declare_dependency(link_whole: [libqmp])
1344
1345foreach m : block_mods + softmmu_mods
1346  shared_module(m.name(),
1347                name_prefix: '',
1348                link_whole: m,
1349                install: true,
1350                install_dir: config_host['qemu_moddir'])
1351endforeach
1352
1353softmmu_ss.add(authz, block, chardev, crypto, io, qmp)
1354common_ss.add(qom, qemuutil)
1355
1356common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
1357common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
1358
1359common_all = common_ss.apply(config_all, strict: false)
1360common_all = static_library('common',
1361                            build_by_default: false,
1362                            sources: common_all.sources() + genh,
1363                            dependencies: common_all.dependencies(),
1364                            name_suffix: 'fa')
1365
1366feature_to_c = find_program('scripts/feature_to_c.sh')
1367
1368emulators = {}
1369foreach target : target_dirs
1370  config_target = config_target_mak[target]
1371  target_name = config_target['TARGET_NAME']
1372  arch = config_target['TARGET_BASE_ARCH']
1373  arch_srcs = [config_target_h[target]]
1374  arch_deps = []
1375  c_args = ['-DNEED_CPU_H',
1376            '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
1377            '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
1378  link_args = emulator_link_args
1379
1380  config_target += config_host
1381  target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
1382  if targetos == 'linux'
1383    target_inc += include_directories('linux-headers', is_system: true)
1384  endif
1385  if target.endswith('-softmmu')
1386    qemu_target_name = 'qemu-system-' + target_name
1387    target_type='system'
1388    t = target_softmmu_arch[arch].apply(config_target, strict: false)
1389    arch_srcs += t.sources()
1390    arch_deps += t.dependencies()
1391
1392    hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
1393    hw = hw_arch[hw_dir].apply(config_target, strict: false)
1394    arch_srcs += hw.sources()
1395    arch_deps += hw.dependencies()
1396
1397    arch_srcs += config_devices_h[target]
1398    link_args += ['@block.syms', '@qemu.syms']
1399  else
1400    abi = config_target['TARGET_ABI_DIR']
1401    target_type='user'
1402    qemu_target_name = 'qemu-' + target_name
1403    if 'CONFIG_LINUX_USER' in config_target
1404      base_dir = 'linux-user'
1405      target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
1406    else
1407      base_dir = 'bsd-user'
1408    endif
1409    target_inc += include_directories(
1410      base_dir,
1411      base_dir / abi,
1412    )
1413    if 'CONFIG_LINUX_USER' in config_target
1414      dir = base_dir / abi
1415      arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
1416      if config_target.has_key('TARGET_SYSTBL_ABI')
1417        arch_srcs += \
1418          syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
1419                                             extra_args : config_target['TARGET_SYSTBL_ABI'])
1420      endif
1421    endif
1422  endif
1423
1424  if 'TARGET_XML_FILES' in config_target
1425    gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
1426                                output: target + '-gdbstub-xml.c',
1427                                input: files(config_target['TARGET_XML_FILES'].split()),
1428                                command: [feature_to_c, '@INPUT@'],
1429                                capture: true)
1430    arch_srcs += gdbstub_xml
1431  endif
1432
1433  t = target_arch[arch].apply(config_target, strict: false)
1434  arch_srcs += t.sources()
1435  arch_deps += t.dependencies()
1436
1437  target_common = common_ss.apply(config_target, strict: false)
1438  objects = common_all.extract_objects(target_common.sources())
1439  deps = target_common.dependencies()
1440
1441  target_specific = specific_ss.apply(config_target, strict: false)
1442  arch_srcs += target_specific.sources()
1443  arch_deps += target_specific.dependencies()
1444
1445  lib = static_library('qemu-' + target,
1446                 sources: arch_srcs + genh,
1447                 dependencies: arch_deps,
1448                 objects: objects,
1449                 include_directories: target_inc,
1450                 c_args: c_args,
1451                 build_by_default: false,
1452                 name_suffix: 'fa')
1453
1454  if target.endswith('-softmmu')
1455    execs = [{
1456      'name': 'qemu-system-' + target_name,
1457      'gui': false,
1458      'sources': files('softmmu/main.c'),
1459      'dependencies': []
1460    }]
1461    if targetos == 'windows' and (sdl.found() or gtk.found())
1462      execs += [{
1463        'name': 'qemu-system-' + target_name + 'w',
1464        'gui': true,
1465        'sources': files('softmmu/main.c'),
1466        'dependencies': []
1467      }]
1468    endif
1469    if config_host.has_key('CONFIG_FUZZ')
1470      specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
1471      execs += [{
1472        'name': 'qemu-fuzz-' + target_name,
1473        'gui': false,
1474        'sources': specific_fuzz.sources(),
1475        'dependencies': specific_fuzz.dependencies(),
1476      }]
1477    endif
1478  else
1479    execs = [{
1480      'name': 'qemu-' + target_name,
1481      'gui': false,
1482      'sources': [],
1483      'dependencies': []
1484    }]
1485  endif
1486  foreach exe: execs
1487    emulators += {exe['name']:
1488         executable(exe['name'], exe['sources'],
1489               install: true,
1490               c_args: c_args,
1491               dependencies: arch_deps + deps + exe['dependencies'],
1492               objects: lib.extract_all_objects(recursive: true),
1493               link_language: link_language,
1494               link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
1495               link_args: link_args,
1496               gui_app: exe['gui'])
1497    }
1498
1499    if 'CONFIG_TRACE_SYSTEMTAP' in config_host
1500      foreach stp: [
1501        {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
1502        {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
1503        {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
1504        {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
1505      ]
1506        custom_target(exe['name'] + stp['ext'],
1507                      input: trace_events_all,
1508                      output: exe['name'] + stp['ext'],
1509                      capture: true,
1510                      install: stp['install'],
1511                      install_dir: qemu_datadir / '../systemtap/tapset',
1512                      command: [
1513                        tracetool, '--group=all', '--format=' + stp['fmt'],
1514                        '--binary=' + stp['bin'],
1515                        '--target-name=' + target_name,
1516                        '--target-type=' + target_type,
1517                        '--probe-prefix=qemu.' + target_type + '.' + target_name,
1518                        '@INPUT@',
1519                      ])
1520      endforeach
1521    endif
1522  endforeach
1523endforeach
1524
1525# Other build targets
1526
1527if 'CONFIG_PLUGIN' in config_host
1528  install_headers('include/qemu/qemu-plugin.h')
1529endif
1530
1531if 'CONFIG_GUEST_AGENT' in config_host
1532  subdir('qga')
1533endif
1534
1535# Don't build qemu-keymap if xkbcommon is not explicitly enabled
1536# when we don't build tools or system
1537if xkbcommon.found()
1538  # used for the update-keymaps target, so include rules even if !have_tools
1539  qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
1540                           dependencies: [qemuutil, xkbcommon], install: have_tools)
1541endif
1542
1543if have_tools
1544  qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
1545             dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
1546  qemu_io = executable('qemu-io', files('qemu-io.c'),
1547             dependencies: [block, qemuutil], install: true)
1548  qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
1549               dependencies: [block, qemuutil], install: true)
1550
1551  subdir('storage-daemon')
1552  subdir('contrib/rdmacm-mux')
1553  subdir('contrib/elf2dmp')
1554
1555  executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
1556             dependencies: qemuutil,
1557             install: true)
1558
1559  if 'CONFIG_VHOST_USER' in config_host
1560    subdir('contrib/libvhost-user')
1561    subdir('contrib/vhost-user-blk')
1562    subdir('contrib/vhost-user-gpu')
1563    subdir('contrib/vhost-user-input')
1564    subdir('contrib/vhost-user-scsi')
1565  endif
1566
1567  if targetos == 'linux'
1568    executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
1569               dependencies: [qemuutil, libcap_ng],
1570               install: true,
1571               install_dir: get_option('libexecdir'))
1572
1573    executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
1574               dependencies: [authz, crypto, io, qom, qemuutil,
1575                              libcap_ng, mpathpersist],
1576               install: true)
1577  endif
1578
1579  if 'CONFIG_IVSHMEM' in config_host
1580    subdir('contrib/ivshmem-client')
1581    subdir('contrib/ivshmem-server')
1582  endif
1583endif
1584
1585subdir('scripts')
1586subdir('tools')
1587subdir('pc-bios')
1588subdir('tests')
1589subdir('docs')
1590if 'CONFIG_GTK' in config_host
1591  subdir('po')
1592endif
1593
1594if host_machine.system() == 'windows'
1595  nsis_cmd = [
1596    find_program('scripts/nsis.py'),
1597    '@OUTPUT@',
1598    get_option('prefix'),
1599    meson.current_source_dir(),
1600    host_machine.cpu_family(),
1601    '--',
1602    '-DDISPLAYVERSION=' + meson.project_version(),
1603  ]
1604  if build_docs
1605    nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
1606  endif
1607  if 'CONFIG_GTK' in config_host
1608    nsis_cmd += '-DCONFIG_GTK=y'
1609  endif
1610
1611  nsis = custom_target('nsis',
1612                       output: 'qemu-setup-' + meson.project_version() + '.exe',
1613                       input: files('qemu.nsi'),
1614                       build_always_stale: true,
1615                       command: nsis_cmd + ['@INPUT@'])
1616  alias_target('installer', nsis)
1617endif
1618
1619summary_info = {}
1620summary_info += {'Install prefix':    config_host['prefix']}
1621summary_info += {'BIOS directory':    config_host['qemu_datadir']}
1622summary_info += {'firmware path':     config_host['qemu_firmwarepath']}
1623summary_info += {'binary directory':  config_host['bindir']}
1624summary_info += {'library directory': config_host['libdir']}
1625summary_info += {'module directory':  config_host['qemu_moddir']}
1626summary_info += {'libexec directory': config_host['libexecdir']}
1627summary_info += {'include directory': config_host['includedir']}
1628summary_info += {'config directory':  config_host['sysconfdir']}
1629if targetos != 'windows'
1630  summary_info += {'local state directory': config_host['qemu_localstatedir']}
1631  summary_info += {'Manual directory':      get_option('mandir')}
1632else
1633  summary_info += {'local state directory': 'queried at runtime'}
1634endif
1635summary_info += {'Doc directory':     get_option('docdir')}
1636summary_info += {'Build directory':   meson.current_build_dir()}
1637summary_info += {'Source path':       meson.current_source_dir()}
1638summary_info += {'GIT binary':        config_host['GIT']}
1639summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
1640summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
1641summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
1642if link_language == 'cpp'
1643  summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
1644else
1645  summary_info += {'C++ compiler':      false}
1646endif
1647if targetos == 'darwin'
1648  summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
1649endif
1650summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
1651summary_info += {'CFLAGS':            config_host['CFLAGS']}
1652summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
1653summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
1654summary_info += {'make':              config_host['MAKE']}
1655summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
1656summary_info += {'sphinx-build':      config_host['SPHINX_BUILD']}
1657summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
1658# TODO: add back version
1659summary_info += {'slirp support':     config_host.has_key('CONFIG_SLIRP')}
1660if config_host.has_key('CONFIG_SLIRP')
1661  summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
1662endif
1663summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
1664if config_host.has_key('CONFIG_MODULES')
1665  summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
1666endif
1667summary_info += {'host CPU':          cpu}
1668summary_info += {'host endianness':   build_machine.endian()}
1669summary_info += {'target list':       ' '.join(target_dirs)}
1670summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
1671summary_info += {'sparse enabled':    sparse.found()}
1672summary_info += {'strip binaries':    get_option('strip')}
1673summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
1674summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
1675if targetos == 'darwin'
1676  summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
1677endif
1678# TODO: add back version
1679summary_info += {'SDL support':       sdl.found()}
1680summary_info += {'SDL image support': sdl_image.found()}
1681# TODO: add back version
1682summary_info += {'GTK support':       config_host.has_key('CONFIG_GTK')}
1683summary_info += {'GTK GL support':    config_host.has_key('CONFIG_GTK_GL')}
1684summary_info += {'pixman':            pixman.found()}
1685# TODO: add back version
1686summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
1687summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
1688summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
1689# TODO: add back version
1690summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
1691if config_host.has_key('CONFIG_GCRYPT')
1692   summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
1693   summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1694endif
1695# TODO: add back version
1696summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
1697if config_host.has_key('CONFIG_NETTLE')
1698   summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1699endif
1700summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
1701summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
1702summary_info += {'iconv support':     config_host.has_key('CONFIG_ICONV')}
1703summary_info += {'curses support':    config_host.has_key('CONFIG_CURSES')}
1704# TODO: add back version
1705summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
1706summary_info += {'curl support':      config_host.has_key('CONFIG_CURL')}
1707summary_info += {'mingw32 support':   targetos == 'windows'}
1708summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
1709summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
1710summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
1711summary_info += {'VirtFS support':    config_host.has_key('CONFIG_VIRTFS')}
1712summary_info += {'Multipath support': mpathpersist.found()}
1713summary_info += {'VNC support':       vnc.found()}
1714if vnc.found()
1715  summary_info += {'VNC SASL support':  sasl.found()}
1716  summary_info += {'VNC JPEG support':  jpeg.found()}
1717  summary_info += {'VNC PNG support':   png.found()}
1718endif
1719summary_info += {'xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
1720if config_host.has_key('CONFIG_XEN_BACKEND')
1721  summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
1722endif
1723summary_info += {'brlapi support':    config_host.has_key('CONFIG_BRLAPI')}
1724summary_info += {'Documentation':     config_host.has_key('BUILD_DOCS')}
1725summary_info += {'PIE':               get_option('b_pie')}
1726summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
1727summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
1728summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
1729summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
1730summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
1731summary_info += {'Install blobs':     config_host.has_key('INSTALL_BLOBS')}
1732summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
1733summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
1734summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
1735summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
1736summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
1737if config_all.has_key('CONFIG_TCG')
1738  summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
1739  summary_info += {'TCG interpreter':   config_host.has_key('CONFIG_TCG_INTERPRETER')}
1740endif
1741summary_info += {'malloc trim support': has_malloc_trim}
1742summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
1743summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
1744summary_info += {'fdt support':       config_host.has_key('CONFIG_FDT')}
1745summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
1746summary_info += {'preadv support':    config_host.has_key('CONFIG_PREADV')}
1747summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
1748summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
1749summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
1750summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
1751summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
1752summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
1753summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
1754summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
1755summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
1756summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_KERNEL')}
1757summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
1758summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
1759summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
1760if config_host['TRACE_BACKENDS'].split().contains('simple')
1761  summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
1762endif
1763# TODO: add back protocol and server version
1764summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
1765summary_info += {'rbd support':       config_host.has_key('CONFIG_RBD')}
1766summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
1767summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
1768summary_info += {'U2F support':       u2f.found()}
1769summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
1770summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
1771summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
1772summary_info += {'OpenGL dmabufs':    config_host.has_key('CONFIG_OPENGL_DMABUF')}
1773summary_info += {'libiscsi support':  config_host.has_key('CONFIG_LIBISCSI')}
1774summary_info += {'libnfs support':    config_host.has_key('CONFIG_LIBNFS')}
1775summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
1776if targetos == 'windows'
1777  if 'WIN_SDK' in config_host
1778    summary_info += {'Windows SDK':       config_host['WIN_SDK']}
1779  endif
1780  summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
1781  summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
1782  summary_info += {'QGA MSI support':   config_host.has_key('CONFIG_QGA_MSI')}
1783endif
1784summary_info += {'seccomp support':   config_host.has_key('CONFIG_SECCOMP')}
1785summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
1786summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
1787summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
1788summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
1789summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
1790summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
1791summary_info += {'gcov':              get_option('b_coverage')}
1792summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
1793summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
1794summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
1795summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
1796summary_info += {'lzo support':       config_host.has_key('CONFIG_LZO')}
1797summary_info += {'snappy support':    config_host.has_key('CONFIG_SNAPPY')}
1798summary_info += {'bzip2 support':     config_host.has_key('CONFIG_BZIP2')}
1799summary_info += {'lzfse support':     config_host.has_key('CONFIG_LZFSE')}
1800summary_info += {'zstd support':      config_host.has_key('CONFIG_ZSTD')}
1801summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
1802summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
1803summary_info += {'memory allocator':  get_option('malloc')}
1804summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
1805summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
1806summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
1807summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
1808summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
1809summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
1810summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
1811summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
1812summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
1813summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
1814summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
1815summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
1816summary_info += {'capstone':          capstone_opt == 'disabled' ? false : capstone_opt}
1817summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
1818summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
1819summary_info += {'libudev':           libudev.found()}
1820summary_info += {'default devices':   config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
1821summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
1822summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
1823if config_host.has_key('HAVE_GDB_BIN')
1824  summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
1825endif
1826summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
1827summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
1828summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
1829summary(summary_info, bool_yn: true)
1830
1831if not supported_cpus.contains(cpu)
1832  message()
1833  warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
1834  message()
1835  message('CPU host architecture ' + cpu + ' support is not currently maintained.')
1836  message('The QEMU project intends to remove support for this host CPU in')
1837  message('a future release if nobody volunteers to maintain it and to')
1838  message('provide a build host for our continuous integration setup.')
1839  message('configure has succeeded and you can continue to build, but')
1840  message('if you care about QEMU on this platform you should contact')
1841  message('us upstream at qemu-devel@nongnu.org.')
1842endif
1843
1844if not supported_oses.contains(targetos)
1845  message()
1846  warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
1847  message()
1848  message('Host OS ' + targetos + 'support is not currently maintained.')
1849  message('The QEMU project intends to remove support for this host OS in')
1850  message('a future release if nobody volunteers to maintain it and to')
1851  message('provide a build host for our continuous integration setup.')
1852  message('configure has succeeded and you can continue to build, but')
1853  message('if you care about QEMU on this platform you should contact')
1854  message('us upstream at qemu-devel@nongnu.org.')
1855endif
1856