xref: /openbmc/qemu/meson.build (revision 55567891)
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
303vde = not_found
304if config_host.has_key('CONFIG_VDE')
305  vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
306endif
307pulse = not_found
308if 'CONFIG_LIBPULSE' in config_host
309  pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
310                             link_args: config_host['PULSE_LIBS'].split())
311endif
312alsa = not_found
313if 'CONFIG_ALSA' in config_host
314  alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
315                            link_args: config_host['ALSA_LIBS'].split())
316endif
317jack = not_found
318if 'CONFIG_LIBJACK' in config_host
319  jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
320endif
321spice = not_found
322if 'CONFIG_SPICE' in config_host
323  spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
324                             link_args: config_host['SPICE_LIBS'].split())
325endif
326rt = cc.find_library('rt', required: false)
327libdl = not_found
328if 'CONFIG_PLUGIN' in config_host
329  libdl = cc.find_library('dl', required: true)
330endif
331libiscsi = not_found
332if 'CONFIG_LIBISCSI' in config_host
333  libiscsi = declare_dependency(compile_args: config_host['LIBISCSI_CFLAGS'].split(),
334                                link_args: config_host['LIBISCSI_LIBS'].split())
335endif
336zstd = not_found
337if 'CONFIG_ZSTD' in config_host
338  zstd = declare_dependency(compile_args: config_host['ZSTD_CFLAGS'].split(),
339                            link_args: config_host['ZSTD_LIBS'].split())
340endif
341gbm = not_found
342if 'CONFIG_GBM' in config_host
343  gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
344                           link_args: config_host['GBM_LIBS'].split())
345endif
346virgl = not_found
347if 'CONFIG_VIRGL' in config_host
348  virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
349                             link_args: config_host['VIRGL_LIBS'].split())
350endif
351curl = not_found
352if 'CONFIG_CURL' in config_host
353  curl = declare_dependency(compile_args: config_host['CURL_CFLAGS'].split(),
354                            link_args: config_host['CURL_LIBS'].split())
355endif
356libudev = not_found
357if targetos == 'linux' and (have_system or have_tools)
358  libudev = dependency('libudev',
359                       required: get_option('mpath').enabled(),
360                       static: enable_static)
361endif
362
363mpathpersist = not_found
364mpathpersist_new_api = false
365if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
366  mpath_test_source_new = '''
367    #include <libudev.h>
368    #include <mpath_persist.h>
369    unsigned mpath_mx_alloc_len = 1024;
370    int logsink;
371    static struct config *multipath_conf;
372    extern struct udev *udev;
373    extern struct config *get_multipath_config(void);
374    extern void put_multipath_config(struct config *conf);
375    struct udev *udev;
376    struct config *get_multipath_config(void) { return multipath_conf; }
377    void put_multipath_config(struct config *conf) { }
378    int main(void) {
379        udev = udev_new();
380        multipath_conf = mpath_lib_init();
381        return 0;
382    }'''
383  mpath_test_source_old = '''
384      #include <libudev.h>
385      #include <mpath_persist.h>
386      unsigned mpath_mx_alloc_len = 1024;
387      int logsink;
388      int main(void) {
389          struct udev *udev = udev_new();
390          mpath_lib_init(udev);
391          return 0;
392      }'''
393  mpathlibs = [libudev]
394  if enable_static
395    mpathlibs += cc.find_library('devmapper',
396                                   required: get_option('mpath'),
397                                   static: enable_static)
398  endif
399  mpathlibs += cc.find_library('multipath',
400                               required: get_option('mpath'),
401                               static: enable_static)
402  mpathlibs += cc.find_library('mpathpersist',
403                               required: get_option('mpath'),
404                               static: enable_static)
405  foreach lib: mpathlibs
406    if not lib.found()
407      mpathlibs = []
408      break
409    endif
410  endforeach
411  if mpathlibs.length() > 0
412    if cc.links(mpath_test_source_new, dependencies: mpathlibs)
413      mpathpersist = declare_dependency(dependencies: mpathlibs)
414      mpathpersist_new_api = true
415    elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
416      mpathpersist = declare_dependency(dependencies: mpathlibs)
417    else
418      if get_option('mpath').enabled()
419        error('Cannot detect libmpathpersist API')
420      else
421        warning('Cannot detect libmpathpersist API, disabling')
422      endif
423    endif
424  endif
425endif
426
427brlapi = not_found
428if 'CONFIG_BRLAPI' in config_host
429  brlapi = declare_dependency(link_args: config_host['BRLAPI_LIBS'].split())
430endif
431
432sdl = not_found
433if have_system
434  sdl = dependency('sdl2', required: get_option('sdl'), static: enable_static)
435  sdl_image = not_found
436endif
437if sdl.found()
438  # work around 2.0.8 bug
439  sdl = declare_dependency(compile_args: '-Wno-undef',
440                           dependencies: sdl)
441  sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
442                         method: 'pkg-config', static: enable_static)
443else
444  if get_option('sdl_image').enabled()
445    error('sdl-image required, but SDL was @0@'.format(
446          get_option('sdl').disabled() ? 'disabled' : 'not found'))
447  endif
448  sdl_image = not_found
449endif
450
451rbd = not_found
452if 'CONFIG_RBD' in config_host
453  rbd = declare_dependency(link_args: config_host['RBD_LIBS'].split())
454endif
455glusterfs = not_found
456if 'CONFIG_GLUSTERFS' in config_host
457  glusterfs = declare_dependency(compile_args: config_host['GLUSTERFS_CFLAGS'].split(),
458                                 link_args: config_host['GLUSTERFS_LIBS'].split())
459endif
460libssh = not_found
461if 'CONFIG_LIBSSH' in config_host
462  libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
463                              link_args: config_host['LIBSSH_LIBS'].split())
464endif
465libbzip2 = not_found
466if 'CONFIG_BZIP2' in config_host
467  libbzip2 = declare_dependency(link_args: config_host['BZIP2_LIBS'].split())
468endif
469liblzfse = not_found
470if 'CONFIG_LZFSE' in config_host
471  liblzfse = declare_dependency(link_args: config_host['LZFSE_LIBS'].split())
472endif
473oss = not_found
474if 'CONFIG_AUDIO_OSS' in config_host
475  oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
476endif
477dsound = not_found
478if 'CONFIG_AUDIO_DSOUND' in config_host
479  dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
480endif
481coreaudio = not_found
482if 'CONFIG_AUDIO_COREAUDIO' in config_host
483  coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
484endif
485opengl = not_found
486if 'CONFIG_OPENGL' in config_host
487  opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
488                              link_args: config_host['OPENGL_LIBS'].split())
489endif
490gtk = not_found
491if 'CONFIG_GTK' in config_host
492  gtk = declare_dependency(compile_args: config_host['GTK_CFLAGS'].split(),
493                              link_args: config_host['GTK_LIBS'].split())
494endif
495vte = not_found
496if 'CONFIG_VTE' in config_host
497  vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
498                           link_args: config_host['VTE_LIBS'].split())
499endif
500x11 = not_found
501if 'CONFIG_X11' in config_host
502  x11 = declare_dependency(compile_args: config_host['X11_CFLAGS'].split(),
503                           link_args: config_host['X11_LIBS'].split())
504endif
505curses = not_found
506if 'CONFIG_CURSES' in config_host
507  curses = declare_dependency(compile_args: config_host['CURSES_CFLAGS'].split(),
508                              link_args: config_host['CURSES_LIBS'].split())
509endif
510iconv = not_found
511if 'CONFIG_ICONV' in config_host
512  iconv = declare_dependency(compile_args: config_host['ICONV_CFLAGS'].split(),
513                             link_args: config_host['ICONV_LIBS'].split())
514endif
515vnc = not_found
516png = not_found
517jpeg = not_found
518sasl = not_found
519if get_option('vnc').enabled()
520  vnc = declare_dependency() # dummy dependency
521  png = dependency('libpng', required: get_option('vnc_png'),
522                   method: 'pkg-config', static: enable_static)
523  jpeg = cc.find_library('jpeg', has_headers: ['jpeglib.h'],
524                         required: get_option('vnc_jpeg'),
525                         static: enable_static)
526  sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
527                         required: get_option('vnc_sasl'),
528                         static: enable_static)
529  if sasl.found()
530    sasl = declare_dependency(dependencies: sasl,
531                              compile_args: '-DSTRUCT_IOVEC_DEFINED')
532  endif
533endif
534snappy = not_found
535if 'CONFIG_SNAPPY' in config_host
536  snappy = declare_dependency(link_args: config_host['SNAPPY_LIBS'].split())
537endif
538lzo = not_found
539if 'CONFIG_LZO' in config_host
540  lzo = declare_dependency(link_args: config_host['LZO_LIBS'].split())
541endif
542rdma = not_found
543if 'CONFIG_RDMA' in config_host
544  rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
545endif
546numa = not_found
547if 'CONFIG_NUMA' in config_host
548  numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
549endif
550xen = not_found
551if 'CONFIG_XEN_BACKEND' in config_host
552  xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
553                           link_args: config_host['XEN_LIBS'].split())
554endif
555cacard = not_found
556if 'CONFIG_SMARTCARD' in config_host
557  cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
558                              link_args: config_host['SMARTCARD_LIBS'].split())
559endif
560u2f = not_found
561if have_system
562  u2f = dependency('u2f-emu', required: get_option('u2f'),
563                   method: 'pkg-config',
564                   static: enable_static)
565endif
566usbredir = not_found
567if 'CONFIG_USB_REDIR' in config_host
568  usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
569                                link_args: config_host['USB_REDIR_LIBS'].split())
570endif
571libusb = not_found
572if 'CONFIG_USB_LIBUSB' in config_host
573  libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
574                              link_args: config_host['LIBUSB_LIBS'].split())
575endif
576libpmem = not_found
577if 'CONFIG_LIBPMEM' in config_host
578  libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
579                               link_args: config_host['LIBPMEM_LIBS'].split())
580endif
581libdaxctl = not_found
582if 'CONFIG_LIBDAXCTL' in config_host
583  libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
584endif
585tasn1 = not_found
586if 'CONFIG_TASN1' in config_host
587  tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(),
588                             link_args: config_host['TASN1_LIBS'].split())
589endif
590keyutils = dependency('libkeyutils', required: false,
591                      method: 'pkg-config', static: enable_static)
592
593has_gettid = cc.has_function('gettid')
594
595# Malloc tests
596
597malloc = []
598if get_option('malloc') == 'system'
599  has_malloc_trim = \
600    not get_option('malloc_trim').disabled() and \
601    cc.links('''#include <malloc.h>
602                int main(void) { malloc_trim(0); return 0; }''')
603else
604  has_malloc_trim = false
605  malloc = cc.find_library(get_option('malloc'), required: true)
606endif
607if not has_malloc_trim and get_option('malloc_trim').enabled()
608  if get_option('malloc') == 'system'
609    error('malloc_trim not available on this platform.')
610  else
611    error('malloc_trim not available with non-libc memory allocator')
612  endif
613endif
614
615# Create config-host.h
616
617config_host_data.set('CONFIG_COCOA', cocoa.found())
618config_host_data.set('CONFIG_LIBUDEV', libudev.found())
619config_host_data.set('CONFIG_MPATH', mpathpersist.found())
620config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
621config_host_data.set('CONFIG_SDL', sdl.found())
622config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
623config_host_data.set('CONFIG_VNC', vnc.found())
624config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
625config_host_data.set('CONFIG_VNC_PNG', png.found())
626config_host_data.set('CONFIG_VNC_SASL', sasl.found())
627config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
628config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
629config_host_data.set('CONFIG_GETTID', has_gettid)
630config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
631config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
632config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
633config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
634config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
635
636ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
637arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
638strings = ['HOST_DSOSUF', 'CONFIG_IASL', 'bindir', 'prefix', 'qemu_confdir', 'qemu_datadir',
639           'qemu_moddir', 'qemu_localstatedir', 'qemu_helperdir', 'qemu_localedir',
640           'qemu_icondir', 'qemu_desktopdir', 'qemu_firmwarepath', 'sysconfdir']
641foreach k, v: config_host
642  if ignored.contains(k)
643    # do nothing
644  elif arrays.contains(k)
645    if v != ''
646      v = '"' + '", "'.join(v.split()) + '", '
647    endif
648    config_host_data.set(k, v)
649  elif k == 'ARCH'
650    config_host_data.set('HOST_' + v.to_upper(), 1)
651  elif strings.contains(k)
652    if not k.startswith('CONFIG_')
653      k = 'CONFIG_' + k.to_upper()
654    endif
655    config_host_data.set_quoted(k, v)
656  elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
657    config_host_data.set(k, v == 'y' ? 1 : v)
658  endif
659endforeach
660
661minikconf = find_program('scripts/minikconf.py')
662config_all = {}
663config_all_devices = {}
664config_all_disas = {}
665config_devices_mak_list = []
666config_devices_h = {}
667config_target_h = {}
668config_target_mak = {}
669
670disassemblers = {
671  'alpha' : ['CONFIG_ALPHA_DIS'],
672  'arm' : ['CONFIG_ARM_DIS'],
673  'avr' : ['CONFIG_AVR_DIS'],
674  'cris' : ['CONFIG_CRIS_DIS'],
675  'hppa' : ['CONFIG_HPPA_DIS'],
676  'i386' : ['CONFIG_I386_DIS'],
677  'x86_64' : ['CONFIG_I386_DIS'],
678  'x32' : ['CONFIG_I386_DIS'],
679  'lm32' : ['CONFIG_LM32_DIS'],
680  'm68k' : ['CONFIG_M68K_DIS'],
681  'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
682  'mips' : ['CONFIG_MIPS_DIS'],
683  'moxie' : ['CONFIG_MOXIE_DIS'],
684  'nios2' : ['CONFIG_NIOS2_DIS'],
685  'or1k' : ['CONFIG_OPENRISC_DIS'],
686  'ppc' : ['CONFIG_PPC_DIS'],
687  'riscv' : ['CONFIG_RISCV_DIS'],
688  'rx' : ['CONFIG_RX_DIS'],
689  's390' : ['CONFIG_S390_DIS'],
690  'sh4' : ['CONFIG_SH4_DIS'],
691  'sparc' : ['CONFIG_SPARC_DIS'],
692  'xtensa' : ['CONFIG_XTENSA_DIS'],
693}
694if link_language == 'cpp'
695  disassemblers += {
696    'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
697    'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
698    'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
699  }
700endif
701
702kconfig_external_symbols = [
703  'CONFIG_KVM',
704  'CONFIG_XEN',
705  'CONFIG_TPM',
706  'CONFIG_SPICE',
707  'CONFIG_IVSHMEM',
708  'CONFIG_OPENGL',
709  'CONFIG_X11',
710  'CONFIG_VHOST_USER',
711  'CONFIG_VHOST_VDPA',
712  'CONFIG_VHOST_KERNEL',
713  'CONFIG_VIRTFS',
714  'CONFIG_LINUX',
715  'CONFIG_PVRDMA',
716]
717ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
718
719default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
720actual_target_dirs = []
721fdt_required = []
722foreach target : target_dirs
723  config_target = { 'TARGET_NAME': target.split('-')[0] }
724  if target.endswith('linux-user')
725    if targetos != 'linux'
726      if default_targets
727        continue
728      endif
729      error('Target @0@ is only available on a Linux host'.format(target))
730    endif
731    config_target += { 'CONFIG_LINUX_USER': 'y' }
732  elif target.endswith('bsd-user')
733    if 'CONFIG_BSD' not in config_host
734      if default_targets
735        continue
736      endif
737      error('Target @0@ is only available on a BSD host'.format(target))
738    endif
739    config_target += { 'CONFIG_BSD_USER': 'y' }
740  elif target.endswith('softmmu')
741    config_target += { 'CONFIG_SOFTMMU': 'y' }
742  endif
743  if target.endswith('-user')
744    config_target += {
745      'CONFIG_USER_ONLY': 'y',
746      'CONFIG_QEMU_INTERP_PREFIX':
747        config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
748    }
749  endif
750
751  have_accel = false
752  foreach sym: accelerators
753    if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
754      config_target += { sym: 'y' }
755      config_all += { sym: 'y' }
756      if sym == 'CONFIG_XEN' and have_xen_pci_passthrough
757        config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
758      endif
759      have_accel = true
760    endif
761  endforeach
762  if not have_accel
763    if default_targets
764      continue
765    endif
766    error('No accelerator available for target @0@'.format(target))
767  endif
768
769  actual_target_dirs += target
770  config_target += keyval.load('default-configs/targets' / target + '.mak')
771  config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
772
773  if 'TARGET_NEED_FDT' in config_target
774    fdt_required += target
775  endif
776
777  # Add default keys
778  if 'TARGET_BASE_ARCH' not in config_target
779    config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
780  endif
781  if 'TARGET_ABI_DIR' not in config_target
782    config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
783  endif
784
785  foreach k, v: disassemblers
786    if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
787      foreach sym: v
788        config_target += { sym: 'y' }
789        config_all_disas += { sym: 'y' }
790      endforeach
791    endif
792  endforeach
793
794  config_target_data = configuration_data()
795  foreach k, v: config_target
796    if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
797      # do nothing
798    elif ignored.contains(k)
799      # do nothing
800    elif k == 'TARGET_BASE_ARCH'
801      # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
802      # not used to select files from sourcesets.
803      config_target_data.set('TARGET_' + v.to_upper(), 1)
804    elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
805      config_target_data.set_quoted(k, v)
806    elif v == 'y'
807      config_target_data.set(k, 1)
808    else
809      config_target_data.set(k, v)
810    endif
811  endforeach
812  config_target_h += {target: configure_file(output: target + '-config-target.h',
813                                               configuration: config_target_data)}
814
815  if target.endswith('-softmmu')
816    base_kconfig = []
817    foreach sym : kconfig_external_symbols
818      if sym in config_target or sym in config_host
819        base_kconfig += '@0@=y'.format(sym)
820      endif
821    endforeach
822
823    config_devices_mak = target + '-config-devices.mak'
824    config_devices_mak = configure_file(
825      input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
826      output: config_devices_mak,
827      depfile: config_devices_mak + '.d',
828      capture: true,
829      command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'],
830                config_devices_mak, '@DEPFILE@', '@INPUT@',
831                base_kconfig])
832
833    config_devices_data = configuration_data()
834    config_devices = keyval.load(config_devices_mak)
835    foreach k, v: config_devices
836      config_devices_data.set(k, 1)
837    endforeach
838    config_devices_mak_list += config_devices_mak
839    config_devices_h += {target: configure_file(output: target + '-config-devices.h',
840                                                configuration: config_devices_data)}
841    config_target += config_devices
842    config_all_devices += config_devices
843  endif
844  config_target_mak += {target: config_target}
845endforeach
846target_dirs = actual_target_dirs
847
848# This configuration is used to build files that are shared by
849# multiple binaries, and then extracted out of the "common"
850# static_library target.
851#
852# We do not use all_sources()/all_dependencies(), because it would
853# build literally all source files, including devices only used by
854# targets that are not built for this compilation.  The CONFIG_ALL
855# pseudo symbol replaces it.
856
857config_all += config_all_devices
858config_all += config_host
859config_all += config_all_disas
860config_all += {
861  'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
862  'CONFIG_SOFTMMU': have_system,
863  'CONFIG_USER_ONLY': have_user,
864  'CONFIG_ALL': true,
865}
866
867# Submodules
868
869capstone = not_found
870capstone_opt = get_option('capstone')
871if capstone_opt in ['enabled', 'auto', 'system']
872  have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
873  capstone = dependency('capstone', version: '>=4.0',
874                        static: enable_static, method: 'pkg-config',
875                        required: capstone_opt == 'system' or
876                                  capstone_opt == 'enabled' and not have_internal)
877  if capstone.found()
878    capstone_opt = 'system'
879  elif have_internal
880    capstone_opt = 'internal'
881  else
882    capstone_opt = 'disabled'
883  endif
884endif
885if capstone_opt == 'internal'
886  capstone_data = configuration_data()
887  capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
888
889  capstone_files = files(
890    'capstone/cs.c',
891    'capstone/MCInst.c',
892    'capstone/MCInstrDesc.c',
893    'capstone/MCRegisterInfo.c',
894    'capstone/SStream.c',
895    'capstone/utils.c'
896  )
897
898  if 'CONFIG_ARM_DIS' in config_all_disas
899    capstone_data.set('CAPSTONE_HAS_ARM', '1')
900    capstone_files += files(
901      'capstone/arch/ARM/ARMDisassembler.c',
902      'capstone/arch/ARM/ARMInstPrinter.c',
903      'capstone/arch/ARM/ARMMapping.c',
904      'capstone/arch/ARM/ARMModule.c'
905    )
906  endif
907
908  # FIXME: This config entry currently depends on a c++ compiler.
909  # Which is needed for building libvixl, but not for capstone.
910  if 'CONFIG_ARM_A64_DIS' in config_all_disas
911    capstone_data.set('CAPSTONE_HAS_ARM64', '1')
912    capstone_files += files(
913      'capstone/arch/AArch64/AArch64BaseInfo.c',
914      'capstone/arch/AArch64/AArch64Disassembler.c',
915      'capstone/arch/AArch64/AArch64InstPrinter.c',
916      'capstone/arch/AArch64/AArch64Mapping.c',
917      'capstone/arch/AArch64/AArch64Module.c'
918    )
919  endif
920
921  if 'CONFIG_PPC_DIS' in config_all_disas
922    capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
923    capstone_files += files(
924      'capstone/arch/PowerPC/PPCDisassembler.c',
925      'capstone/arch/PowerPC/PPCInstPrinter.c',
926      'capstone/arch/PowerPC/PPCMapping.c',
927      'capstone/arch/PowerPC/PPCModule.c'
928    )
929  endif
930
931  if 'CONFIG_S390_DIS' in config_all_disas
932    capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
933    capstone_files += files(
934      'capstone/arch/SystemZ/SystemZDisassembler.c',
935      'capstone/arch/SystemZ/SystemZInstPrinter.c',
936      'capstone/arch/SystemZ/SystemZMapping.c',
937      'capstone/arch/SystemZ/SystemZModule.c',
938      'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
939    )
940  endif
941
942  if 'CONFIG_I386_DIS' in config_all_disas
943    capstone_data.set('CAPSTONE_HAS_X86', 1)
944    capstone_files += files(
945      'capstone/arch/X86/X86Disassembler.c',
946      'capstone/arch/X86/X86DisassemblerDecoder.c',
947      'capstone/arch/X86/X86ATTInstPrinter.c',
948      'capstone/arch/X86/X86IntelInstPrinter.c',
949      'capstone/arch/X86/X86InstPrinterCommon.c',
950      'capstone/arch/X86/X86Mapping.c',
951      'capstone/arch/X86/X86Module.c'
952    )
953  endif
954
955  configure_file(output: 'capstone-defs.h', configuration: capstone_data)
956
957  capstone_cargs = [
958    # FIXME: There does not seem to be a way to completely replace the c_args
959    # that come from add_project_arguments() -- we can only add to them.
960    # So: disable all warnings with a big hammer.
961    '-Wno-error', '-w',
962
963    # Include all configuration defines via a header file, which will wind up
964    # as a dependency on the object file, and thus changes here will result
965    # in a rebuild.
966    '-include', 'capstone-defs.h'
967  ]
968
969  libcapstone = static_library('capstone',
970                               sources: capstone_files,
971                               c_args: capstone_cargs,
972                               include_directories: 'capstone/include')
973  capstone = declare_dependency(link_with: libcapstone,
974                                include_directories: 'capstone/include/capstone')
975endif
976
977slirp = not_found
978slirp_opt = 'disabled'
979if have_system
980  slirp_opt = get_option('slirp')
981  if slirp_opt in ['enabled', 'auto', 'system']
982    have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
983    slirp = dependency('slirp', static: enable_static,
984                       method: 'pkg-config',
985                       required: slirp_opt == 'system' or
986                                 slirp_opt == 'enabled' and not have_internal)
987    if slirp.found()
988      slirp_opt = 'system'
989    elif have_internal
990      slirp_opt = 'internal'
991    else
992      slirp_opt = 'disabled'
993    endif
994  endif
995  if slirp_opt == 'internal'
996    slirp_deps = []
997    if targetos == 'windows'
998      slirp_deps = cc.find_library('iphlpapi')
999    endif
1000    slirp_conf = configuration_data()
1001    slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1002    slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1003    slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1004    slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1005    slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1006    slirp_files = [
1007      'slirp/src/arp_table.c',
1008      'slirp/src/bootp.c',
1009      'slirp/src/cksum.c',
1010      'slirp/src/dhcpv6.c',
1011      'slirp/src/dnssearch.c',
1012      'slirp/src/if.c',
1013      'slirp/src/ip6_icmp.c',
1014      'slirp/src/ip6_input.c',
1015      'slirp/src/ip6_output.c',
1016      'slirp/src/ip_icmp.c',
1017      'slirp/src/ip_input.c',
1018      'slirp/src/ip_output.c',
1019      'slirp/src/mbuf.c',
1020      'slirp/src/misc.c',
1021      'slirp/src/ncsi.c',
1022      'slirp/src/ndp_table.c',
1023      'slirp/src/sbuf.c',
1024      'slirp/src/slirp.c',
1025      'slirp/src/socket.c',
1026      'slirp/src/state.c',
1027      'slirp/src/stream.c',
1028      'slirp/src/tcp_input.c',
1029      'slirp/src/tcp_output.c',
1030      'slirp/src/tcp_subr.c',
1031      'slirp/src/tcp_timer.c',
1032      'slirp/src/tftp.c',
1033      'slirp/src/udp.c',
1034      'slirp/src/udp6.c',
1035      'slirp/src/util.c',
1036      'slirp/src/version.c',
1037      'slirp/src/vmstate.c',
1038    ]
1039
1040    configure_file(
1041      input : 'slirp/src/libslirp-version.h.in',
1042      output : 'libslirp-version.h',
1043      configuration: slirp_conf)
1044
1045    slirp_inc = include_directories('slirp', 'slirp/src')
1046    libslirp = static_library('slirp',
1047                              sources: slirp_files,
1048                              c_args: slirp_cargs,
1049                              include_directories: slirp_inc)
1050    slirp = declare_dependency(link_with: libslirp,
1051                               dependencies: slirp_deps,
1052                               include_directories: slirp_inc)
1053  endif
1054endif
1055
1056fdt = not_found
1057fdt_opt = get_option('fdt')
1058if have_system
1059  if fdt_opt in ['enabled', 'auto', 'system']
1060    have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1061    fdt = cc.find_library('fdt', static: enable_static,
1062                          required: fdt_opt == 'system' or
1063                                    fdt_opt == 'enabled' and not have_internal)
1064    if fdt.found() and cc.links('''
1065       #include <libfdt.h>
1066       #include <libfdt_env.h>
1067       int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1068         dependencies: fdt)
1069      fdt_opt = 'system'
1070    elif have_internal
1071      fdt_opt = 'internal'
1072    else
1073      fdt_opt = 'disabled'
1074    endif
1075  endif
1076  if fdt_opt == 'internal'
1077    fdt_files = files(
1078      'dtc/libfdt/fdt.c',
1079      'dtc/libfdt/fdt_ro.c',
1080      'dtc/libfdt/fdt_wip.c',
1081      'dtc/libfdt/fdt_sw.c',
1082      'dtc/libfdt/fdt_rw.c',
1083      'dtc/libfdt/fdt_strerror.c',
1084      'dtc/libfdt/fdt_empty_tree.c',
1085      'dtc/libfdt/fdt_addresses.c',
1086      'dtc/libfdt/fdt_overlay.c',
1087      'dtc/libfdt/fdt_check.c',
1088    )
1089
1090    fdt_inc = include_directories('dtc/libfdt')
1091    libfdt = static_library('fdt',
1092                            sources: fdt_files,
1093                            include_directories: fdt_inc)
1094    fdt = declare_dependency(link_with: libfdt,
1095                             include_directories: fdt_inc)
1096  endif
1097endif
1098if not fdt.found() and fdt_required.length() > 0
1099  error('fdt not available but required by targets ' + ', '.join(fdt_required))
1100endif
1101
1102config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1103config_host_data.set('CONFIG_FDT', fdt.found())
1104config_host_data.set('CONFIG_SLIRP', slirp.found())
1105
1106genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1107
1108# Generators
1109
1110hxtool = find_program('scripts/hxtool')
1111shaderinclude = find_program('scripts/shaderinclude.pl')
1112qapi_gen = find_program('scripts/qapi-gen.py')
1113qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1114                     meson.source_root() / 'scripts/qapi/commands.py',
1115                     meson.source_root() / 'scripts/qapi/common.py',
1116                     meson.source_root() / 'scripts/qapi/error.py',
1117                     meson.source_root() / 'scripts/qapi/events.py',
1118                     meson.source_root() / 'scripts/qapi/expr.py',
1119                     meson.source_root() / 'scripts/qapi/gen.py',
1120                     meson.source_root() / 'scripts/qapi/introspect.py',
1121                     meson.source_root() / 'scripts/qapi/parser.py',
1122                     meson.source_root() / 'scripts/qapi/schema.py',
1123                     meson.source_root() / 'scripts/qapi/source.py',
1124                     meson.source_root() / 'scripts/qapi/types.py',
1125                     meson.source_root() / 'scripts/qapi/visit.py',
1126                     meson.source_root() / 'scripts/qapi/common.py',
1127                     meson.source_root() / 'scripts/qapi-gen.py'
1128]
1129
1130tracetool = [
1131  python, files('scripts/tracetool.py'),
1132   '--backend=' + config_host['TRACE_BACKENDS']
1133]
1134
1135qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1136                    meson.current_source_dir(),
1137                    config_host['PKGVERSION'], meson.project_version()]
1138qemu_version = custom_target('qemu-version.h',
1139                             output: 'qemu-version.h',
1140                             command: qemu_version_cmd,
1141                             capture: true,
1142                             build_by_default: true,
1143                             build_always_stale: true)
1144genh += qemu_version
1145
1146hxdep = []
1147hx_headers = [
1148  ['qemu-options.hx', 'qemu-options.def'],
1149  ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1150]
1151if have_system
1152  hx_headers += [
1153    ['hmp-commands.hx', 'hmp-commands.h'],
1154    ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1155  ]
1156endif
1157foreach d : hx_headers
1158  hxdep += custom_target(d[1],
1159                input: files(d[0]),
1160                output: d[1],
1161                capture: true,
1162                build_by_default: true, # to be removed when added to a target
1163                command: [hxtool, '-h', '@INPUT0@'])
1164endforeach
1165genh += hxdep
1166
1167SPHINX_ARGS = [config_host['SPHINX_BUILD'],
1168               '-Dversion=' + meson.project_version(),
1169               '-Drelease=' + config_host['PKGVERSION']]
1170
1171if get_option('werror')
1172  SPHINX_ARGS += [ '-W' ]
1173endif
1174
1175sphinx_extn_depends = [ meson.source_root() / 'docs/sphinx/depfile.py',
1176                        meson.source_root() / 'docs/sphinx/hxtool.py',
1177                        meson.source_root() / 'docs/sphinx/kerneldoc.py',
1178                        meson.source_root() / 'docs/sphinx/kernellog.py',
1179                        meson.source_root() / 'docs/sphinx/qapidoc.py',
1180                        meson.source_root() / 'docs/sphinx/qmp_lexer.py',
1181                        qapi_gen_depends ]
1182
1183# Collect sourcesets.
1184
1185authz_ss = ss.source_set()
1186blockdev_ss = ss.source_set()
1187block_ss = ss.source_set()
1188bsd_user_ss = ss.source_set()
1189chardev_ss = ss.source_set()
1190common_ss = ss.source_set()
1191crypto_ss = ss.source_set()
1192io_ss = ss.source_set()
1193linux_user_ss = ss.source_set()
1194qmp_ss = ss.source_set()
1195softmmu_ss = ss.source_set()
1196specific_fuzz_ss = ss.source_set()
1197specific_ss = ss.source_set()
1198stub_ss = ss.source_set()
1199trace_ss = ss.source_set()
1200user_ss = ss.source_set()
1201util_ss = ss.source_set()
1202
1203modules = {}
1204hw_arch = {}
1205target_arch = {}
1206target_softmmu_arch = {}
1207
1208###############
1209# Trace files #
1210###############
1211
1212# TODO: add each directory to the subdirs from its own meson.build, once
1213# we have those
1214trace_events_subdirs = [
1215  'accel/kvm',
1216  'accel/tcg',
1217  'crypto',
1218  'monitor',
1219]
1220if have_user
1221  trace_events_subdirs += [ 'linux-user' ]
1222endif
1223if have_block
1224  trace_events_subdirs += [
1225    'authz',
1226    'block',
1227    'io',
1228    'nbd',
1229    'scsi',
1230  ]
1231endif
1232if have_system
1233  trace_events_subdirs += [
1234    'audio',
1235    'backends',
1236    'backends/tpm',
1237    'chardev',
1238    'hw/9pfs',
1239    'hw/acpi',
1240    'hw/alpha',
1241    'hw/arm',
1242    'hw/audio',
1243    'hw/block',
1244    'hw/block/dataplane',
1245    'hw/char',
1246    'hw/display',
1247    'hw/dma',
1248    'hw/hppa',
1249    'hw/hyperv',
1250    'hw/i2c',
1251    'hw/i386',
1252    'hw/i386/xen',
1253    'hw/ide',
1254    'hw/input',
1255    'hw/intc',
1256    'hw/isa',
1257    'hw/mem',
1258    'hw/mips',
1259    'hw/misc',
1260    'hw/misc/macio',
1261    'hw/net',
1262    'hw/nvram',
1263    'hw/pci',
1264    'hw/pci-host',
1265    'hw/ppc',
1266    'hw/rdma',
1267    'hw/rdma/vmw',
1268    'hw/rtc',
1269    'hw/s390x',
1270    'hw/scsi',
1271    'hw/sd',
1272    'hw/sparc',
1273    'hw/sparc64',
1274    'hw/ssi',
1275    'hw/timer',
1276    'hw/tpm',
1277    'hw/usb',
1278    'hw/vfio',
1279    'hw/virtio',
1280    'hw/watchdog',
1281    'hw/xen',
1282    'hw/gpio',
1283    'migration',
1284    'net',
1285    'softmmu',
1286    'ui',
1287  ]
1288endif
1289trace_events_subdirs += [
1290  'hw/core',
1291  'qapi',
1292  'qom',
1293  'target/arm',
1294  'target/hppa',
1295  'target/i386',
1296  'target/mips',
1297  'target/ppc',
1298  'target/riscv',
1299  'target/s390x',
1300  'target/sparc',
1301  'util',
1302]
1303
1304subdir('qapi')
1305subdir('qobject')
1306subdir('stubs')
1307subdir('trace')
1308subdir('util')
1309subdir('qom')
1310subdir('authz')
1311subdir('crypto')
1312subdir('ui')
1313
1314
1315if enable_modules
1316  libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1317  modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1318endif
1319
1320# Build targets from sourcesets
1321
1322stub_ss = stub_ss.apply(config_all, strict: false)
1323
1324util_ss.add_all(trace_ss)
1325util_ss = util_ss.apply(config_all, strict: false)
1326libqemuutil = static_library('qemuutil',
1327                             sources: util_ss.sources() + stub_ss.sources() + genh,
1328                             dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1329qemuutil = declare_dependency(link_with: libqemuutil,
1330                              sources: genh + version_res)
1331
1332decodetree = generator(find_program('scripts/decodetree.py'),
1333                       output: 'decode-@BASENAME@.c.inc',
1334                       arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1335
1336subdir('audio')
1337subdir('io')
1338subdir('chardev')
1339subdir('fsdev')
1340subdir('libdecnumber')
1341subdir('target')
1342subdir('dump')
1343
1344block_ss.add(files(
1345  'block.c',
1346  'blockdev-nbd.c',
1347  'blockjob.c',
1348  'job.c',
1349  'qemu-io-cmds.c',
1350))
1351block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1352
1353subdir('nbd')
1354subdir('scsi')
1355subdir('block')
1356
1357blockdev_ss.add(files(
1358  'blockdev.c',
1359  'iothread.c',
1360  'job-qmp.c',
1361))
1362
1363# os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1364# os-win32.c does not
1365blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1366softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1367
1368softmmu_ss.add_all(blockdev_ss)
1369softmmu_ss.add(files(
1370  'bootdevice.c',
1371  'dma-helpers.c',
1372  'qdev-monitor.c',
1373), sdl)
1374
1375softmmu_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c'))
1376softmmu_ss.add(when: 'CONFIG_SECCOMP', if_true: [files('qemu-seccomp.c'), seccomp])
1377softmmu_ss.add(when: fdt, if_true: files('device_tree.c'))
1378
1379common_ss.add(files('cpus-common.c'))
1380
1381subdir('softmmu')
1382
1383common_ss.add(capstone)
1384specific_ss.add(files('disas.c', 'exec.c', 'gdbstub.c'), capstone, libpmem, libdaxctl)
1385specific_ss.add(files('exec-vary.c'))
1386specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1387  'fpu/softfloat.c',
1388  'tcg/optimize.c',
1389  'tcg/tcg-common.c',
1390  'tcg/tcg-op-gvec.c',
1391  'tcg/tcg-op-vec.c',
1392  'tcg/tcg-op.c',
1393  'tcg/tcg.c',
1394))
1395specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1396
1397subdir('backends')
1398subdir('disas')
1399subdir('migration')
1400subdir('monitor')
1401subdir('net')
1402subdir('replay')
1403subdir('hw')
1404subdir('accel')
1405subdir('plugins')
1406subdir('bsd-user')
1407subdir('linux-user')
1408
1409bsd_user_ss.add(files('gdbstub.c'))
1410specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1411
1412linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1413specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1414
1415# needed for fuzzing binaries
1416subdir('tests/qtest/libqos')
1417subdir('tests/qtest/fuzz')
1418
1419block_mods = []
1420softmmu_mods = []
1421foreach d, list : modules
1422  foreach m, module_ss : list
1423    if enable_modules and targetos != 'windows'
1424      module_ss = module_ss.apply(config_all, strict: false)
1425      sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1426                          dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1427      if d == 'block'
1428        block_mods += sl
1429      else
1430        softmmu_mods += sl
1431      endif
1432    else
1433      if d == 'block'
1434        block_ss.add_all(module_ss)
1435      else
1436        softmmu_ss.add_all(module_ss)
1437      endif
1438    endif
1439  endforeach
1440endforeach
1441
1442nm = find_program('nm')
1443undefsym = find_program('scripts/undefsym.py')
1444block_syms = custom_target('block.syms', output: 'block.syms',
1445                             input: [libqemuutil, block_mods],
1446                             capture: true,
1447                             command: [undefsym, nm, '@INPUT@'])
1448qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1449                             input: [libqemuutil, softmmu_mods],
1450                             capture: true,
1451                             command: [undefsym, nm, '@INPUT@'])
1452
1453########################
1454# Library dependencies #
1455########################
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