xref: /openbmc/qemu/meson.build (revision b39847a5)
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
1185util_ss = ss.source_set()
1186stub_ss = ss.source_set()
1187trace_ss = ss.source_set()
1188block_ss = ss.source_set()
1189blockdev_ss = ss.source_set()
1190qmp_ss = ss.source_set()
1191common_ss = ss.source_set()
1192softmmu_ss = ss.source_set()
1193user_ss = ss.source_set()
1194bsd_user_ss = ss.source_set()
1195linux_user_ss = ss.source_set()
1196specific_ss = ss.source_set()
1197specific_fuzz_ss = ss.source_set()
1198
1199modules = {}
1200hw_arch = {}
1201target_arch = {}
1202target_softmmu_arch = {}
1203
1204###############
1205# Trace files #
1206###############
1207
1208# TODO: add each directory to the subdirs from its own meson.build, once
1209# we have those
1210trace_events_subdirs = [
1211  'accel/kvm',
1212  'accel/tcg',
1213  'crypto',
1214  'monitor',
1215]
1216if have_user
1217  trace_events_subdirs += [ 'linux-user' ]
1218endif
1219if have_block
1220  trace_events_subdirs += [
1221    'authz',
1222    'block',
1223    'io',
1224    'nbd',
1225    'scsi',
1226  ]
1227endif
1228if have_system
1229  trace_events_subdirs += [
1230    'audio',
1231    'backends',
1232    'backends/tpm',
1233    'chardev',
1234    'hw/9pfs',
1235    'hw/acpi',
1236    'hw/alpha',
1237    'hw/arm',
1238    'hw/audio',
1239    'hw/block',
1240    'hw/block/dataplane',
1241    'hw/char',
1242    'hw/display',
1243    'hw/dma',
1244    'hw/hppa',
1245    'hw/hyperv',
1246    'hw/i2c',
1247    'hw/i386',
1248    'hw/i386/xen',
1249    'hw/ide',
1250    'hw/input',
1251    'hw/intc',
1252    'hw/isa',
1253    'hw/mem',
1254    'hw/mips',
1255    'hw/misc',
1256    'hw/misc/macio',
1257    'hw/net',
1258    'hw/nvram',
1259    'hw/pci',
1260    'hw/pci-host',
1261    'hw/ppc',
1262    'hw/rdma',
1263    'hw/rdma/vmw',
1264    'hw/rtc',
1265    'hw/s390x',
1266    'hw/scsi',
1267    'hw/sd',
1268    'hw/sparc',
1269    'hw/sparc64',
1270    'hw/ssi',
1271    'hw/timer',
1272    'hw/tpm',
1273    'hw/usb',
1274    'hw/vfio',
1275    'hw/virtio',
1276    'hw/watchdog',
1277    'hw/xen',
1278    'hw/gpio',
1279    'migration',
1280    'net',
1281    'softmmu',
1282    'ui',
1283  ]
1284endif
1285trace_events_subdirs += [
1286  'hw/core',
1287  'qapi',
1288  'qom',
1289  'target/arm',
1290  'target/hppa',
1291  'target/i386',
1292  'target/mips',
1293  'target/ppc',
1294  'target/riscv',
1295  'target/s390x',
1296  'target/sparc',
1297  'util',
1298]
1299
1300subdir('qapi')
1301subdir('qobject')
1302subdir('stubs')
1303subdir('trace')
1304subdir('util')
1305subdir('qom')
1306subdir('authz')
1307subdir('crypto')
1308subdir('ui')
1309
1310
1311if enable_modules
1312  libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1313  modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1314endif
1315
1316# Build targets from sourcesets
1317
1318stub_ss = stub_ss.apply(config_all, strict: false)
1319
1320util_ss.add_all(trace_ss)
1321util_ss = util_ss.apply(config_all, strict: false)
1322libqemuutil = static_library('qemuutil',
1323                             sources: util_ss.sources() + stub_ss.sources() + genh,
1324                             dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1325qemuutil = declare_dependency(link_with: libqemuutil,
1326                              sources: genh + version_res)
1327
1328decodetree = generator(find_program('scripts/decodetree.py'),
1329                       output: 'decode-@BASENAME@.c.inc',
1330                       arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1331
1332subdir('audio')
1333subdir('io')
1334subdir('chardev')
1335subdir('fsdev')
1336subdir('libdecnumber')
1337subdir('target')
1338subdir('dump')
1339
1340block_ss.add(files(
1341  'block.c',
1342  'blockdev-nbd.c',
1343  'blockjob.c',
1344  'job.c',
1345  'qemu-io-cmds.c',
1346))
1347block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1348
1349subdir('nbd')
1350subdir('scsi')
1351subdir('block')
1352
1353blockdev_ss.add(files(
1354  'blockdev.c',
1355  'iothread.c',
1356  'job-qmp.c',
1357))
1358
1359# os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1360# os-win32.c does not
1361blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1362softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1363
1364softmmu_ss.add_all(blockdev_ss)
1365softmmu_ss.add(files(
1366  'bootdevice.c',
1367  'dma-helpers.c',
1368  'qdev-monitor.c',
1369), sdl)
1370
1371softmmu_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c'))
1372softmmu_ss.add(when: 'CONFIG_SECCOMP', if_true: [files('qemu-seccomp.c'), seccomp])
1373softmmu_ss.add(when: fdt, if_true: files('device_tree.c'))
1374
1375common_ss.add(files('cpus-common.c'))
1376
1377subdir('softmmu')
1378
1379common_ss.add(capstone)
1380specific_ss.add(files('disas.c', 'exec.c', 'gdbstub.c'), capstone, libpmem, libdaxctl)
1381specific_ss.add(files('exec-vary.c'))
1382specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1383  'fpu/softfloat.c',
1384  'tcg/optimize.c',
1385  'tcg/tcg-common.c',
1386  'tcg/tcg-op-gvec.c',
1387  'tcg/tcg-op-vec.c',
1388  'tcg/tcg-op.c',
1389  'tcg/tcg.c',
1390))
1391specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1392
1393subdir('backends')
1394subdir('disas')
1395subdir('migration')
1396subdir('monitor')
1397subdir('net')
1398subdir('replay')
1399subdir('hw')
1400subdir('accel')
1401subdir('plugins')
1402subdir('bsd-user')
1403subdir('linux-user')
1404
1405bsd_user_ss.add(files('gdbstub.c'))
1406specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1407
1408linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1409specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1410
1411# needed for fuzzing binaries
1412subdir('tests/qtest/libqos')
1413subdir('tests/qtest/fuzz')
1414
1415block_mods = []
1416softmmu_mods = []
1417foreach d, list : modules
1418  foreach m, module_ss : list
1419    if enable_modules and targetos != 'windows'
1420      module_ss = module_ss.apply(config_all, strict: false)
1421      sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1422                          dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1423      if d == 'block'
1424        block_mods += sl
1425      else
1426        softmmu_mods += sl
1427      endif
1428    else
1429      if d == 'block'
1430        block_ss.add_all(module_ss)
1431      else
1432        softmmu_ss.add_all(module_ss)
1433      endif
1434    endif
1435  endforeach
1436endforeach
1437
1438nm = find_program('nm')
1439undefsym = find_program('scripts/undefsym.py')
1440block_syms = custom_target('block.syms', output: 'block.syms',
1441                             input: [libqemuutil, block_mods],
1442                             capture: true,
1443                             command: [undefsym, nm, '@INPUT@'])
1444qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1445                             input: [libqemuutil, softmmu_mods],
1446                             capture: true,
1447                             command: [undefsym, nm, '@INPUT@'])
1448
1449block_ss = block_ss.apply(config_host, strict: false)
1450libblock = static_library('block', block_ss.sources() + genh,
1451                          dependencies: block_ss.dependencies(),
1452                          link_depends: block_syms,
1453                          name_suffix: 'fa',
1454                          build_by_default: false)
1455
1456block = declare_dependency(link_whole: [libblock],
1457                           link_args: '@block.syms',
1458                           dependencies: [crypto, io])
1459
1460qmp_ss = qmp_ss.apply(config_host, strict: false)
1461libqmp = static_library('qmp', qmp_ss.sources() + genh,
1462                        dependencies: qmp_ss.dependencies(),
1463                        name_suffix: 'fa',
1464                        build_by_default: false)
1465
1466qmp = declare_dependency(link_whole: [libqmp])
1467
1468foreach m : block_mods + softmmu_mods
1469  shared_module(m.name(),
1470                name_prefix: '',
1471                link_whole: m,
1472                install: true,
1473                install_dir: config_host['qemu_moddir'])
1474endforeach
1475
1476softmmu_ss.add(authz, block, chardev, crypto, io, qmp)
1477common_ss.add(qom, qemuutil)
1478
1479common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
1480common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
1481
1482common_all = common_ss.apply(config_all, strict: false)
1483common_all = static_library('common',
1484                            build_by_default: false,
1485                            sources: common_all.sources() + genh,
1486                            dependencies: common_all.dependencies(),
1487                            name_suffix: 'fa')
1488
1489feature_to_c = find_program('scripts/feature_to_c.sh')
1490
1491emulators = {}
1492foreach target : target_dirs
1493  config_target = config_target_mak[target]
1494  target_name = config_target['TARGET_NAME']
1495  arch = config_target['TARGET_BASE_ARCH']
1496  arch_srcs = [config_target_h[target]]
1497  arch_deps = []
1498  c_args = ['-DNEED_CPU_H',
1499            '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
1500            '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
1501  link_args = emulator_link_args
1502
1503  config_target += config_host
1504  target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
1505  if targetos == 'linux'
1506    target_inc += include_directories('linux-headers', is_system: true)
1507  endif
1508  if target.endswith('-softmmu')
1509    qemu_target_name = 'qemu-system-' + target_name
1510    target_type='system'
1511    t = target_softmmu_arch[arch].apply(config_target, strict: false)
1512    arch_srcs += t.sources()
1513    arch_deps += t.dependencies()
1514
1515    hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
1516    hw = hw_arch[hw_dir].apply(config_target, strict: false)
1517    arch_srcs += hw.sources()
1518    arch_deps += hw.dependencies()
1519
1520    arch_srcs += config_devices_h[target]
1521    link_args += ['@block.syms', '@qemu.syms']
1522  else
1523    abi = config_target['TARGET_ABI_DIR']
1524    target_type='user'
1525    qemu_target_name = 'qemu-' + target_name
1526    if 'CONFIG_LINUX_USER' in config_target
1527      base_dir = 'linux-user'
1528      target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
1529    else
1530      base_dir = 'bsd-user'
1531    endif
1532    target_inc += include_directories(
1533      base_dir,
1534      base_dir / abi,
1535    )
1536    if 'CONFIG_LINUX_USER' in config_target
1537      dir = base_dir / abi
1538      arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
1539      if config_target.has_key('TARGET_SYSTBL_ABI')
1540        arch_srcs += \
1541          syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
1542                                             extra_args : config_target['TARGET_SYSTBL_ABI'])
1543      endif
1544    endif
1545  endif
1546
1547  if 'TARGET_XML_FILES' in config_target
1548    gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
1549                                output: target + '-gdbstub-xml.c',
1550                                input: files(config_target['TARGET_XML_FILES'].split()),
1551                                command: [feature_to_c, '@INPUT@'],
1552                                capture: true)
1553    arch_srcs += gdbstub_xml
1554  endif
1555
1556  t = target_arch[arch].apply(config_target, strict: false)
1557  arch_srcs += t.sources()
1558  arch_deps += t.dependencies()
1559
1560  target_common = common_ss.apply(config_target, strict: false)
1561  objects = common_all.extract_objects(target_common.sources())
1562  deps = target_common.dependencies()
1563
1564  target_specific = specific_ss.apply(config_target, strict: false)
1565  arch_srcs += target_specific.sources()
1566  arch_deps += target_specific.dependencies()
1567
1568  lib = static_library('qemu-' + target,
1569                 sources: arch_srcs + genh,
1570                 dependencies: arch_deps,
1571                 objects: objects,
1572                 include_directories: target_inc,
1573                 c_args: c_args,
1574                 build_by_default: false,
1575                 name_suffix: 'fa')
1576
1577  if target.endswith('-softmmu')
1578    execs = [{
1579      'name': 'qemu-system-' + target_name,
1580      'gui': false,
1581      'sources': files('softmmu/main.c'),
1582      'dependencies': []
1583    }]
1584    if targetos == 'windows' and (sdl.found() or gtk.found())
1585      execs += [{
1586        'name': 'qemu-system-' + target_name + 'w',
1587        'gui': true,
1588        'sources': files('softmmu/main.c'),
1589        'dependencies': []
1590      }]
1591    endif
1592    if config_host.has_key('CONFIG_FUZZ')
1593      specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
1594      execs += [{
1595        'name': 'qemu-fuzz-' + target_name,
1596        'gui': false,
1597        'sources': specific_fuzz.sources(),
1598        'dependencies': specific_fuzz.dependencies(),
1599      }]
1600    endif
1601  else
1602    execs = [{
1603      'name': 'qemu-' + target_name,
1604      'gui': false,
1605      'sources': [],
1606      'dependencies': []
1607    }]
1608  endif
1609  foreach exe: execs
1610    emulators += {exe['name']:
1611         executable(exe['name'], exe['sources'],
1612               install: true,
1613               c_args: c_args,
1614               dependencies: arch_deps + deps + exe['dependencies'],
1615               objects: lib.extract_all_objects(recursive: true),
1616               link_language: link_language,
1617               link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
1618               link_args: link_args,
1619               gui_app: exe['gui'])
1620    }
1621
1622    if 'CONFIG_TRACE_SYSTEMTAP' in config_host
1623      foreach stp: [
1624        {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
1625        {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
1626        {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
1627        {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
1628      ]
1629        custom_target(exe['name'] + stp['ext'],
1630                      input: trace_events_all,
1631                      output: exe['name'] + stp['ext'],
1632                      capture: true,
1633                      install: stp['install'],
1634                      install_dir: qemu_datadir / '../systemtap/tapset',
1635                      command: [
1636                        tracetool, '--group=all', '--format=' + stp['fmt'],
1637                        '--binary=' + stp['bin'],
1638                        '--target-name=' + target_name,
1639                        '--target-type=' + target_type,
1640                        '--probe-prefix=qemu.' + target_type + '.' + target_name,
1641                        '@INPUT@',
1642                      ])
1643      endforeach
1644    endif
1645  endforeach
1646endforeach
1647
1648# Other build targets
1649
1650if 'CONFIG_PLUGIN' in config_host
1651  install_headers('include/qemu/qemu-plugin.h')
1652endif
1653
1654if 'CONFIG_GUEST_AGENT' in config_host
1655  subdir('qga')
1656endif
1657
1658# Don't build qemu-keymap if xkbcommon is not explicitly enabled
1659# when we don't build tools or system
1660if xkbcommon.found()
1661  # used for the update-keymaps target, so include rules even if !have_tools
1662  qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
1663                           dependencies: [qemuutil, xkbcommon], install: have_tools)
1664endif
1665
1666if have_tools
1667  qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
1668             dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
1669  qemu_io = executable('qemu-io', files('qemu-io.c'),
1670             dependencies: [block, qemuutil], install: true)
1671  qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
1672               dependencies: [block, qemuutil], install: true)
1673
1674  subdir('storage-daemon')
1675  subdir('contrib/rdmacm-mux')
1676  subdir('contrib/elf2dmp')
1677
1678  executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
1679             dependencies: qemuutil,
1680             install: true)
1681
1682  if 'CONFIG_VHOST_USER' in config_host
1683    subdir('contrib/libvhost-user')
1684    subdir('contrib/vhost-user-blk')
1685    subdir('contrib/vhost-user-gpu')
1686    subdir('contrib/vhost-user-input')
1687    subdir('contrib/vhost-user-scsi')
1688  endif
1689
1690  if targetos == 'linux'
1691    executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
1692               dependencies: [qemuutil, libcap_ng],
1693               install: true,
1694               install_dir: get_option('libexecdir'))
1695
1696    executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
1697               dependencies: [authz, crypto, io, qom, qemuutil,
1698                              libcap_ng, mpathpersist],
1699               install: true)
1700  endif
1701
1702  if 'CONFIG_IVSHMEM' in config_host
1703    subdir('contrib/ivshmem-client')
1704    subdir('contrib/ivshmem-server')
1705  endif
1706endif
1707
1708subdir('scripts')
1709subdir('tools')
1710subdir('pc-bios')
1711subdir('tests')
1712subdir('docs')
1713if 'CONFIG_GTK' in config_host
1714  subdir('po')
1715endif
1716
1717if host_machine.system() == 'windows'
1718  nsis_cmd = [
1719    find_program('scripts/nsis.py'),
1720    '@OUTPUT@',
1721    get_option('prefix'),
1722    meson.current_source_dir(),
1723    host_machine.cpu_family(),
1724    '--',
1725    '-DDISPLAYVERSION=' + meson.project_version(),
1726  ]
1727  if build_docs
1728    nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
1729  endif
1730  if 'CONFIG_GTK' in config_host
1731    nsis_cmd += '-DCONFIG_GTK=y'
1732  endif
1733
1734  nsis = custom_target('nsis',
1735                       output: 'qemu-setup-' + meson.project_version() + '.exe',
1736                       input: files('qemu.nsi'),
1737                       build_always_stale: true,
1738                       command: nsis_cmd + ['@INPUT@'])
1739  alias_target('installer', nsis)
1740endif
1741
1742summary_info = {}
1743summary_info += {'Install prefix':    config_host['prefix']}
1744summary_info += {'BIOS directory':    config_host['qemu_datadir']}
1745summary_info += {'firmware path':     config_host['qemu_firmwarepath']}
1746summary_info += {'binary directory':  config_host['bindir']}
1747summary_info += {'library directory': config_host['libdir']}
1748summary_info += {'module directory':  config_host['qemu_moddir']}
1749summary_info += {'libexec directory': config_host['libexecdir']}
1750summary_info += {'include directory': config_host['includedir']}
1751summary_info += {'config directory':  config_host['sysconfdir']}
1752if targetos != 'windows'
1753  summary_info += {'local state directory': config_host['qemu_localstatedir']}
1754  summary_info += {'Manual directory':      get_option('mandir')}
1755else
1756  summary_info += {'local state directory': 'queried at runtime'}
1757endif
1758summary_info += {'Doc directory':     get_option('docdir')}
1759summary_info += {'Build directory':   meson.current_build_dir()}
1760summary_info += {'Source path':       meson.current_source_dir()}
1761summary_info += {'GIT binary':        config_host['GIT']}
1762summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
1763summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
1764summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
1765if link_language == 'cpp'
1766  summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
1767else
1768  summary_info += {'C++ compiler':      false}
1769endif
1770if targetos == 'darwin'
1771  summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
1772endif
1773summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
1774summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
1775                                               + ['-O' + get_option('optimization')]
1776                                               + (get_option('debug') ? ['-g'] : []))}
1777if link_language == 'cpp'
1778  summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
1779                                               + ['-O' + get_option('optimization')]
1780                                               + (get_option('debug') ? ['-g'] : []))}
1781endif
1782link_args = get_option(link_language + '_link_args')
1783if link_args.length() > 0
1784  summary_info += {'LDFLAGS':         ' '.join(link_args)}
1785endif
1786summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
1787summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
1788summary_info += {'make':              config_host['MAKE']}
1789summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
1790summary_info += {'sphinx-build':      config_host['SPHINX_BUILD']}
1791summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
1792# TODO: add back version
1793summary_info += {'slirp support':     slirp_opt == 'disabled' ? false : slirp_opt}
1794if slirp_opt != 'disabled'
1795  summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
1796endif
1797summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
1798if config_host.has_key('CONFIG_MODULES')
1799  summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
1800endif
1801summary_info += {'host CPU':          cpu}
1802summary_info += {'host endianness':   build_machine.endian()}
1803summary_info += {'target list':       ' '.join(target_dirs)}
1804summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
1805summary_info += {'sparse enabled':    sparse.found()}
1806summary_info += {'strip binaries':    get_option('strip')}
1807summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
1808summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
1809if targetos == 'darwin'
1810  summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
1811endif
1812# TODO: add back version
1813summary_info += {'SDL support':       sdl.found()}
1814summary_info += {'SDL image support': sdl_image.found()}
1815# TODO: add back version
1816summary_info += {'GTK support':       config_host.has_key('CONFIG_GTK')}
1817summary_info += {'GTK GL support':    config_host.has_key('CONFIG_GTK_GL')}
1818summary_info += {'pixman':            pixman.found()}
1819# TODO: add back version
1820summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
1821summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
1822summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
1823# TODO: add back version
1824summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
1825if config_host.has_key('CONFIG_GCRYPT')
1826   summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
1827   summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1828endif
1829# TODO: add back version
1830summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
1831if config_host.has_key('CONFIG_NETTLE')
1832   summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1833endif
1834summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
1835summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
1836summary_info += {'iconv support':     config_host.has_key('CONFIG_ICONV')}
1837summary_info += {'curses support':    config_host.has_key('CONFIG_CURSES')}
1838# TODO: add back version
1839summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
1840summary_info += {'curl support':      config_host.has_key('CONFIG_CURL')}
1841summary_info += {'mingw32 support':   targetos == 'windows'}
1842summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
1843summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
1844summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
1845summary_info += {'VirtFS support':    config_host.has_key('CONFIG_VIRTFS')}
1846summary_info += {'Multipath support': mpathpersist.found()}
1847summary_info += {'VNC support':       vnc.found()}
1848if vnc.found()
1849  summary_info += {'VNC SASL support':  sasl.found()}
1850  summary_info += {'VNC JPEG support':  jpeg.found()}
1851  summary_info += {'VNC PNG support':   png.found()}
1852endif
1853summary_info += {'xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
1854if config_host.has_key('CONFIG_XEN_BACKEND')
1855  summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
1856endif
1857summary_info += {'brlapi support':    config_host.has_key('CONFIG_BRLAPI')}
1858summary_info += {'Documentation':     config_host.has_key('BUILD_DOCS')}
1859summary_info += {'PIE':               get_option('b_pie')}
1860summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
1861summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
1862summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
1863summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
1864summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
1865summary_info += {'Install blobs':     config_host.has_key('INSTALL_BLOBS')}
1866summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
1867summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
1868summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
1869summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
1870summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
1871if config_all.has_key('CONFIG_TCG')
1872  summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
1873  summary_info += {'TCG interpreter':   config_host.has_key('CONFIG_TCG_INTERPRETER')}
1874endif
1875summary_info += {'malloc trim support': has_malloc_trim}
1876summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
1877summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
1878summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
1879summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
1880summary_info += {'preadv support':    config_host.has_key('CONFIG_PREADV')}
1881summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
1882summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
1883summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
1884summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
1885summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
1886summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
1887summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
1888summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
1889summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
1890summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_KERNEL')}
1891summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
1892summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
1893summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
1894if config_host['TRACE_BACKENDS'].split().contains('simple')
1895  summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
1896endif
1897# TODO: add back protocol and server version
1898summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
1899summary_info += {'rbd support':       config_host.has_key('CONFIG_RBD')}
1900summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
1901summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
1902summary_info += {'U2F support':       u2f.found()}
1903summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
1904summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
1905summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
1906summary_info += {'OpenGL dmabufs':    config_host.has_key('CONFIG_OPENGL_DMABUF')}
1907summary_info += {'libiscsi support':  config_host.has_key('CONFIG_LIBISCSI')}
1908summary_info += {'libnfs support':    config_host.has_key('CONFIG_LIBNFS')}
1909summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
1910if targetos == 'windows'
1911  if 'WIN_SDK' in config_host
1912    summary_info += {'Windows SDK':       config_host['WIN_SDK']}
1913  endif
1914  summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
1915  summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
1916  summary_info += {'QGA MSI support':   config_host.has_key('CONFIG_QGA_MSI')}
1917endif
1918summary_info += {'seccomp support':   config_host.has_key('CONFIG_SECCOMP')}
1919summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
1920summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
1921summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
1922summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
1923summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
1924summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
1925summary_info += {'gcov':              get_option('b_coverage')}
1926summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
1927summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
1928summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
1929summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
1930summary_info += {'lzo support':       config_host.has_key('CONFIG_LZO')}
1931summary_info += {'snappy support':    config_host.has_key('CONFIG_SNAPPY')}
1932summary_info += {'bzip2 support':     config_host.has_key('CONFIG_BZIP2')}
1933summary_info += {'lzfse support':     config_host.has_key('CONFIG_LZFSE')}
1934summary_info += {'zstd support':      config_host.has_key('CONFIG_ZSTD')}
1935summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
1936summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
1937summary_info += {'memory allocator':  get_option('malloc')}
1938summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
1939summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
1940summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
1941summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
1942summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
1943summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
1944summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
1945summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
1946summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
1947summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
1948summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
1949summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
1950summary_info += {'capstone':          capstone_opt == 'disabled' ? false : capstone_opt}
1951summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
1952summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
1953summary_info += {'libudev':           libudev.found()}
1954summary_info += {'default devices':   config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
1955summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
1956summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
1957if config_host.has_key('HAVE_GDB_BIN')
1958  summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
1959endif
1960summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
1961summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
1962summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
1963summary(summary_info, bool_yn: true)
1964
1965if not supported_cpus.contains(cpu)
1966  message()
1967  warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
1968  message()
1969  message('CPU host architecture ' + cpu + ' support is not currently maintained.')
1970  message('The QEMU project intends to remove support for this host CPU in')
1971  message('a future release if nobody volunteers to maintain it and to')
1972  message('provide a build host for our continuous integration setup.')
1973  message('configure has succeeded and you can continue to build, but')
1974  message('if you care about QEMU on this platform you should contact')
1975  message('us upstream at qemu-devel@nongnu.org.')
1976endif
1977
1978if not supported_oses.contains(targetos)
1979  message()
1980  warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
1981  message()
1982  message('Host OS ' + targetos + 'support is not currently maintained.')
1983  message('The QEMU project intends to remove support for this host OS in')
1984  message('a future release if nobody volunteers to maintain it and to')
1985  message('provide a build host for our continuous integration setup.')
1986  message('configure has succeeded and you can continue to build, but')
1987  message('if you care about QEMU on this platform you should contact')
1988  message('us upstream at qemu-devel@nongnu.org.')
1989endif
1990