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