xref: /openbmc/qemu/meson.build (revision 9db70dac85446d7cb86669c39d1f4278f033337e)
1project('qemu', ['c'], meson_version: '>=0.55.0',
2        default_options: ['warning_level=1', 'c_std=gnu99', 'cpp_std=gnu++11',
3                          'b_lundef=false','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')
13
14sh = find_program('sh')
15cc = meson.get_compiler('c')
16config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
17config_all_disas = keyval.load(meson.current_build_dir() / 'config-all-disas.mak')
18enable_modules = 'CONFIG_MODULES' in config_host
19enable_static = 'CONFIG_STATIC' in config_host
20build_docs = 'BUILD_DOCS' in config_host
21config_host_data = configuration_data()
22genh = []
23
24target_dirs = config_host['TARGET_DIRS'].split()
25have_user = false
26have_system = false
27foreach target : target_dirs
28  have_user = have_user or target.endswith('-user')
29  have_system = have_system or target.endswith('-softmmu')
30endforeach
31have_tools = 'CONFIG_TOOLS' in config_host
32have_block = have_system or have_tools
33
34add_project_arguments(config_host['QEMU_CFLAGS'].split(),
35                      native: false, language: ['c', 'objc'])
36add_project_arguments(config_host['QEMU_CXXFLAGS'].split(),
37                      native: false, language: 'cpp')
38add_project_link_arguments(config_host['QEMU_LDFLAGS'].split(),
39                           native: false, language: ['c', 'cpp', 'objc'])
40add_project_arguments(config_host['QEMU_INCLUDES'].split(),
41                      language: ['c', 'cpp', 'objc'])
42
43python = import('python').find_installation()
44
45link_language = meson.get_external_property('link_language', 'cpp')
46if link_language == 'cpp'
47  add_languages('cpp', required: true, native: false)
48endif
49if host_machine.system() == 'darwin'
50  add_languages('objc', required: false, native: false)
51endif
52
53if 'SPARSE_CFLAGS' in config_host
54  run_target('sparse',
55             command: [find_program('scripts/check_sparse.py'),
56                       config_host['SPARSE_CFLAGS'].split(),
57                       'compile_commands.json'])
58endif
59
60configure_file(input: files('scripts/ninjatool.py'),
61               output: 'ninjatool',
62               configuration: config_host)
63
64supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
65supported_cpus = ['ppc', 'ppc64', 's390x', 'sparc64', 'riscv32', 'riscv64', 'x86', 'x86_64',
66  'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
67
68cpu = host_machine.cpu_family()
69targetos = host_machine.system()
70
71m = cc.find_library('m', required: false)
72util = cc.find_library('util', required: false)
73winmm = []
74socket = []
75version_res = []
76coref = []
77iokit = []
78cocoa = []
79hvf = []
80if targetos == 'windows'
81  socket = cc.find_library('ws2_32')
82  winmm = cc.find_library('winmm')
83
84  win = import('windows')
85  version_res = win.compile_resources('version.rc',
86                                      depend_files: files('pc-bios/qemu-nsis.ico'),
87                                      include_directories: include_directories('.'))
88elif targetos == 'darwin'
89  coref = dependency('appleframeworks', modules: 'CoreFoundation')
90  iokit = dependency('appleframeworks', modules: 'IOKit')
91  cocoa = dependency('appleframeworks', modules: 'Cocoa')
92  hvf = dependency('appleframeworks', modules: 'Hypervisor')
93elif targetos == 'sunos'
94  socket = [cc.find_library('socket'),
95            cc.find_library('nsl'),
96            cc.find_library('resolv')]
97elif targetos == 'haiku'
98  socket = [cc.find_library('posix_error_mapper'),
99            cc.find_library('network'),
100            cc.find_library('bsd')]
101endif
102glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
103                          link_args: config_host['GLIB_LIBS'].split())
104gio = not_found
105if 'CONFIG_GIO' in config_host
106  gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
107                           link_args: config_host['GIO_LIBS'].split())
108endif
109lttng = not_found
110if 'CONFIG_TRACE_UST' in config_host
111  lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
112endif
113urcubp = not_found
114if 'CONFIG_TRACE_UST' in config_host
115  urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
116endif
117nettle = not_found
118if 'CONFIG_NETTLE' in config_host
119  nettle = declare_dependency(compile_args: config_host['NETTLE_CFLAGS'].split(),
120                              link_args: config_host['NETTLE_LIBS'].split())
121endif
122gnutls = not_found
123if 'CONFIG_GNUTLS' in config_host
124  gnutls = declare_dependency(compile_args: config_host['GNUTLS_CFLAGS'].split(),
125                              link_args: config_host['GNUTLS_LIBS'].split())
126endif
127pixman = not_found
128if have_system or have_tools
129  pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
130                      static: enable_static)
131endif
132pam = not_found
133if 'CONFIG_AUTH_PAM' in config_host
134  pam = cc.find_library('pam')
135endif
136libaio = cc.find_library('aio', required: false)
137zlib = not_found
138if 'CONFIG_ZLIB' in config_host
139  zlib = declare_dependency(compile_args: config_host['ZLIB_CFLAGS'].split(),
140                            link_args: config_host['ZLIB_LIBS'].split())
141endif
142linux_io_uring = not_found
143if 'CONFIG_LINUX_IO_URING' in config_host
144  linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
145                                      link_args: config_host['LINUX_IO_URING_LIBS'].split())
146endif
147libxml2 = not_found
148if 'CONFIG_LIBXML2' in config_host
149  libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
150                               link_args: config_host['LIBXML2_LIBS'].split())
151endif
152libnfs = not_found
153if 'CONFIG_LIBNFS' in config_host
154  libnfs = declare_dependency(link_args: config_host['LIBNFS_LIBS'].split())
155endif
156libattr = not_found
157if 'CONFIG_ATTR' in config_host
158  libattr = declare_dependency(link_args: config_host['LIBATTR_LIBS'].split())
159endif
160seccomp = not_found
161if 'CONFIG_SECCOMP' in config_host
162  seccomp = declare_dependency(compile_args: config_host['SECCOMP_CFLAGS'].split(),
163                               link_args: config_host['SECCOMP_LIBS'].split())
164endif
165libcap_ng = not_found
166if 'CONFIG_LIBCAP_NG' in config_host
167  libcap_ng = declare_dependency(link_args: config_host['LIBCAP_NG_LIBS'].split())
168endif
169if get_option('xkbcommon').auto() and not have_system and not have_tools
170  xkbcommon = not_found
171else
172  xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
173                         static: enable_static)
174endif
175slirp = not_found
176if config_host.has_key('CONFIG_SLIRP')
177  slirp = declare_dependency(compile_args: config_host['SLIRP_CFLAGS'].split(),
178                             link_args: config_host['SLIRP_LIBS'].split())
179endif
180vde = not_found
181if config_host.has_key('CONFIG_VDE')
182  vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
183endif
184pulse = not_found
185if 'CONFIG_LIBPULSE' in config_host
186  pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
187                             link_args: config_host['PULSE_LIBS'].split())
188endif
189alsa = not_found
190if 'CONFIG_ALSA' in config_host
191  alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
192                            link_args: config_host['ALSA_LIBS'].split())
193endif
194jack = not_found
195if 'CONFIG_LIBJACK' in config_host
196  jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
197endif
198spice = not_found
199if 'CONFIG_SPICE' in config_host
200  spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
201                             link_args: config_host['SPICE_LIBS'].split())
202endif
203rt = cc.find_library('rt', required: false)
204libmpathpersist = not_found
205if config_host.has_key('CONFIG_MPATH')
206  libmpathpersist = cc.find_library('mpathpersist')
207endif
208libiscsi = not_found
209if 'CONFIG_LIBISCSI' in config_host
210  libiscsi = declare_dependency(compile_args: config_host['LIBISCSI_CFLAGS'].split(),
211                                link_args: config_host['LIBISCSI_LIBS'].split())
212endif
213zstd = not_found
214if 'CONFIG_ZSTD' in config_host
215  zstd = declare_dependency(compile_args: config_host['ZSTD_CFLAGS'].split(),
216                            link_args: config_host['ZSTD_LIBS'].split())
217endif
218gbm = not_found
219if 'CONFIG_GBM' in config_host
220  gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
221                           link_args: config_host['GBM_LIBS'].split())
222endif
223virgl = not_found
224if 'CONFIG_VIRGL' in config_host
225  virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
226                             link_args: config_host['VIRGL_LIBS'].split())
227endif
228curl = not_found
229if 'CONFIG_CURL' in config_host
230  curl = declare_dependency(compile_args: config_host['CURL_CFLAGS'].split(),
231                            link_args: config_host['CURL_LIBS'].split())
232endif
233libudev = not_found
234if 'CONFIG_LIBUDEV' in config_host
235  libudev = declare_dependency(link_args: config_host['LIBUDEV_LIBS'].split())
236endif
237brlapi = not_found
238if 'CONFIG_BRLAPI' in config_host
239  brlapi = declare_dependency(link_args: config_host['BRLAPI_LIBS'].split())
240endif
241
242sdl = not_found
243if have_system
244  sdl = dependency('sdl2', required: get_option('sdl'), static: enable_static)
245  sdl_image = not_found
246endif
247if sdl.found()
248  # work around 2.0.8 bug
249  sdl = declare_dependency(compile_args: '-Wno-undef',
250                           dependencies: sdl)
251  sdl_image = dependency('sdl-image', required: get_option('sdl_image'),
252                         static: enable_static)
253else
254  if get_option('sdl_image').enabled()
255    error('sdl-image required, but SDL was @0@',
256          get_option('sdl').disabled() ? 'disabled' : 'not found')
257  endif
258  sdl_image = not_found
259endif
260
261rbd = not_found
262if 'CONFIG_RBD' in config_host
263  rbd = declare_dependency(link_args: config_host['RBD_LIBS'].split())
264endif
265glusterfs = not_found
266if 'CONFIG_GLUSTERFS' in config_host
267  glusterfs = declare_dependency(compile_args: config_host['GLUSTERFS_CFLAGS'].split(),
268                                 link_args: config_host['GLUSTERFS_LIBS'].split())
269endif
270libssh = not_found
271if 'CONFIG_LIBSSH' in config_host
272  libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
273                              link_args: config_host['LIBSSH_LIBS'].split())
274endif
275libbzip2 = not_found
276if 'CONFIG_BZIP2' in config_host
277  libbzip2 = declare_dependency(link_args: config_host['BZIP2_LIBS'].split())
278endif
279liblzfse = not_found
280if 'CONFIG_LZFSE' in config_host
281  liblzfse = declare_dependency(link_args: config_host['LZFSE_LIBS'].split())
282endif
283oss = not_found
284if 'CONFIG_AUDIO_OSS' in config_host
285  oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
286endif
287dsound = not_found
288if 'CONFIG_AUDIO_DSOUND' in config_host
289  dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
290endif
291coreaudio = not_found
292if 'CONFIG_AUDIO_COREAUDIO' in config_host
293  coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
294endif
295opengl = not_found
296if 'CONFIG_OPENGL' in config_host
297  opengl = declare_dependency(link_args: config_host['OPENGL_LIBS'].split())
298else
299endif
300gtk = not_found
301if 'CONFIG_GTK' in config_host
302  gtk = declare_dependency(compile_args: config_host['GTK_CFLAGS'].split(),
303                              link_args: config_host['GTK_LIBS'].split())
304endif
305vte = not_found
306if 'CONFIG_VTE' in config_host
307  vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
308                           link_args: config_host['VTE_LIBS'].split())
309endif
310x11 = not_found
311if 'CONFIG_X11' in config_host
312  x11 = declare_dependency(compile_args: config_host['X11_CFLAGS'].split(),
313                           link_args: config_host['X11_LIBS'].split())
314endif
315curses = not_found
316if 'CONFIG_CURSES' in config_host
317  curses = declare_dependency(compile_args: config_host['CURSES_CFLAGS'].split(),
318                              link_args: config_host['CURSES_LIBS'].split())
319endif
320iconv = not_found
321if 'CONFIG_ICONV' in config_host
322  iconv = declare_dependency(compile_args: config_host['ICONV_CFLAGS'].split(),
323                             link_args: config_host['ICONV_LIBS'].split())
324endif
325gio = not_found
326if 'CONFIG_GIO' in config_host
327  gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
328                           link_args: config_host['GIO_LIBS'].split())
329endif
330vnc = not_found
331png = not_found
332jpeg = not_found
333sasl = not_found
334if get_option('vnc').enabled()
335  vnc = declare_dependency() # dummy dependency
336  png = dependency('libpng', required: get_option('vnc_png'),
337                   static: enable_static)
338  jpeg = cc.find_library('jpeg', has_headers: ['jpeglib.h'],
339                         required: get_option('vnc_jpeg'),
340                         static: enable_static)
341  sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
342                         required: get_option('vnc_sasl'),
343                         static: enable_static)
344  if sasl.found()
345    sasl = declare_dependency(dependencies: sasl,
346                              compile_args: '-DSTRUCT_IOVEC_DEFINED')
347  endif
348endif
349fdt = not_found
350if 'CONFIG_FDT' in config_host
351  fdt = declare_dependency(compile_args: config_host['FDT_CFLAGS'].split(),
352                           link_args: config_host['FDT_LIBS'].split())
353endif
354snappy = not_found
355if 'CONFIG_SNAPPY' in config_host
356  snappy = declare_dependency(link_args: config_host['SNAPPY_LIBS'].split())
357endif
358lzo = not_found
359if 'CONFIG_LZO' in config_host
360  lzo = declare_dependency(link_args: config_host['LZO_LIBS'].split())
361endif
362rdma = not_found
363if 'CONFIG_RDMA' in config_host
364  rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
365endif
366numa = not_found
367if 'CONFIG_NUMA' in config_host
368  numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
369endif
370xen = not_found
371if 'CONFIG_XEN_BACKEND' in config_host
372  xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
373                           link_args: config_host['XEN_LIBS'].split())
374endif
375cacard = not_found
376if 'CONFIG_SMARTCARD' in config_host
377  cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
378                              link_args: config_host['SMARTCARD_LIBS'].split())
379endif
380u2f = not_found
381if have_system
382  u2f = dependency('u2f-emu', required: get_option('u2f'),
383                   method: 'pkg-config',
384                   static: enable_static)
385endif
386usbredir = not_found
387if 'CONFIG_USB_REDIR' in config_host
388  usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
389                                link_args: config_host['USB_REDIR_LIBS'].split())
390endif
391libusb = not_found
392if 'CONFIG_USB_LIBUSB' in config_host
393  libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
394                              link_args: config_host['LIBUSB_LIBS'].split())
395endif
396capstone = not_found
397if 'CONFIG_CAPSTONE' in config_host
398  capstone = declare_dependency(compile_args: config_host['CAPSTONE_CFLAGS'].split(),
399                                link_args: config_host['CAPSTONE_LIBS'].split())
400endif
401libpmem = not_found
402if 'CONFIG_LIBPMEM' in config_host
403  libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
404                               link_args: config_host['LIBPMEM_LIBS'].split())
405endif
406libdaxctl = not_found
407if 'CONFIG_LIBDAXCTL' in config_host
408  libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
409endif
410
411# Create config-host.h
412
413config_host_data.set('CONFIG_SDL', sdl.found())
414config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
415config_host_data.set('CONFIG_VNC', vnc.found())
416config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
417config_host_data.set('CONFIG_VNC_PNG', png.found())
418config_host_data.set('CONFIG_VNC_SASL', sasl.found())
419config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
420config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
421config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
422config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
423config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
424
425arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
426strings = ['HOST_DSOSUF', 'CONFIG_IASL', 'qemu_confdir', 'qemu_datadir',
427           'qemu_moddir', 'qemu_localstatedir', 'qemu_helperdir', 'qemu_localedir',
428           'qemu_icondir', 'qemu_desktopdir', 'qemu_firmwarepath']
429foreach k, v: config_host
430  if arrays.contains(k)
431    if v != ''
432      v = '"' + '", "'.join(v.split()) + '", '
433    endif
434    config_host_data.set(k, v)
435  elif k == 'ARCH'
436    config_host_data.set('HOST_' + v.to_upper(), 1)
437  elif strings.contains(k)
438    if not k.startswith('CONFIG_')
439      k = 'CONFIG_' + k.to_upper()
440    endif
441    config_host_data.set_quoted(k, v)
442  elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
443    config_host_data.set(k, v == 'y' ? 1 : v)
444  endif
445endforeach
446genh += configure_file(output: 'config-host.h', configuration: config_host_data)
447
448minikconf = find_program('scripts/minikconf.py')
449config_devices_mak_list = []
450config_devices_h = {}
451config_target_h = {}
452config_target_mak = {}
453kconfig_external_symbols = [
454  'CONFIG_KVM',
455  'CONFIG_XEN',
456  'CONFIG_TPM',
457  'CONFIG_SPICE',
458  'CONFIG_IVSHMEM',
459  'CONFIG_OPENGL',
460  'CONFIG_X11',
461  'CONFIG_VHOST_USER',
462  'CONFIG_VHOST_KERNEL',
463  'CONFIG_VIRTFS',
464  'CONFIG_LINUX',
465  'CONFIG_PVRDMA',
466]
467ignored = ['TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_DIRS']
468foreach target : target_dirs
469  config_target = keyval.load(meson.current_build_dir() / target / 'config-target.mak')
470
471  config_target_data = configuration_data()
472  foreach k, v: config_target
473    if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
474      # do nothing
475    elif ignored.contains(k)
476      # do nothing
477    elif k == 'TARGET_BASE_ARCH'
478      config_target_data.set('TARGET_' + v.to_upper(), 1)
479    elif k == 'TARGET_NAME'
480      config_target_data.set_quoted(k, v)
481    elif v == 'y'
482      config_target_data.set(k, 1)
483    else
484      config_target_data.set(k, v)
485    endif
486  endforeach
487  config_target_h += {target: configure_file(output: target + '-config-target.h',
488                                               configuration: config_target_data)}
489
490  if target.endswith('-softmmu')
491    base_kconfig = []
492    foreach sym : kconfig_external_symbols
493      if sym in config_target or sym in config_host
494        base_kconfig += '@0@=y'.format(sym)
495      endif
496    endforeach
497
498    config_devices_mak = target + '-config-devices.mak'
499    config_devices_mak = configure_file(
500      input: ['default-configs' / target + '.mak', 'Kconfig'],
501      output: config_devices_mak,
502      depfile: config_devices_mak + '.d',
503      capture: true,
504      command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'],
505                config_devices_mak, '@DEPFILE@', '@INPUT@',
506                base_kconfig])
507
508    config_devices_data = configuration_data()
509    config_devices = keyval.load(config_devices_mak)
510    foreach k, v: config_devices
511      config_devices_data.set(k, 1)
512    endforeach
513    config_devices_mak_list += config_devices_mak
514    config_devices_h += {target: configure_file(output: target + '-config-devices.h',
515                                                configuration: config_devices_data)}
516    config_target += config_devices
517  endif
518  config_target_mak += {target: config_target}
519endforeach
520
521grepy = find_program('scripts/grepy.sh')
522# This configuration is used to build files that are shared by
523# multiple binaries, and then extracted out of the "common"
524# static_library target.
525#
526# We do not use all_sources()/all_dependencies(), because it would
527# build literally all source files, including devices only used by
528# targets that are not built for this compilation.  The CONFIG_ALL
529# pseudo symbol replaces it.
530
531if have_system
532  config_all_devices_mak = configure_file(
533    output: 'config-all-devices.mak',
534    input: config_devices_mak_list,
535    capture: true,
536    command: [grepy, '@INPUT@'],
537  )
538  config_all_devices = keyval.load(config_all_devices_mak)
539else
540  config_all_devices = {}
541endif
542config_all = config_all_devices
543config_all += config_host
544config_all += config_all_disas
545config_all += {
546  'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
547  'CONFIG_SOFTMMU': have_system,
548  'CONFIG_USER_ONLY': have_user,
549  'CONFIG_ALL': true,
550}
551
552# Generators
553
554hxtool = find_program('scripts/hxtool')
555shaderinclude = find_program('scripts/shaderinclude.pl')
556qapi_gen = find_program('scripts/qapi-gen.py')
557qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
558                     meson.source_root() / 'scripts/qapi/commands.py',
559                     meson.source_root() / 'scripts/qapi/common.py',
560                     meson.source_root() / 'scripts/qapi/doc.py',
561                     meson.source_root() / 'scripts/qapi/error.py',
562                     meson.source_root() / 'scripts/qapi/events.py',
563                     meson.source_root() / 'scripts/qapi/expr.py',
564                     meson.source_root() / 'scripts/qapi/gen.py',
565                     meson.source_root() / 'scripts/qapi/introspect.py',
566                     meson.source_root() / 'scripts/qapi/parser.py',
567                     meson.source_root() / 'scripts/qapi/schema.py',
568                     meson.source_root() / 'scripts/qapi/source.py',
569                     meson.source_root() / 'scripts/qapi/types.py',
570                     meson.source_root() / 'scripts/qapi/visit.py',
571                     meson.source_root() / 'scripts/qapi/common.py',
572                     meson.source_root() / 'scripts/qapi/doc.py',
573                     meson.source_root() / 'scripts/qapi-gen.py'
574]
575
576tracetool = [
577  python, files('scripts/tracetool.py'),
578   '--backend=' + config_host['TRACE_BACKENDS']
579]
580
581qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
582                    meson.current_source_dir(),
583                    config_host['PKGVERSION'], meson.project_version()]
584qemu_version = custom_target('qemu-version.h',
585                             output: 'qemu-version.h',
586                             command: qemu_version_cmd,
587                             capture: true,
588                             build_by_default: true,
589                             build_always_stale: true)
590genh += qemu_version
591
592hxdep = []
593hx_headers = [
594  ['qemu-options.hx', 'qemu-options.def'],
595  ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
596]
597if have_system
598  hx_headers += [
599    ['hmp-commands.hx', 'hmp-commands.h'],
600    ['hmp-commands-info.hx', 'hmp-commands-info.h'],
601  ]
602endif
603foreach d : hx_headers
604  hxdep += custom_target(d[1],
605                input: files(d[0]),
606                output: d[1],
607                capture: true,
608                build_by_default: true, # to be removed when added to a target
609                command: [hxtool, '-h', '@INPUT0@'])
610endforeach
611genh += hxdep
612
613# Collect sourcesets.
614
615util_ss = ss.source_set()
616stub_ss = ss.source_set()
617trace_ss = ss.source_set()
618block_ss = ss.source_set()
619blockdev_ss = ss.source_set()
620qmp_ss = ss.source_set()
621common_ss = ss.source_set()
622softmmu_ss = ss.source_set()
623user_ss = ss.source_set()
624bsd_user_ss = ss.source_set()
625linux_user_ss = ss.source_set()
626specific_ss = ss.source_set()
627specific_fuzz_ss = ss.source_set()
628
629modules = {}
630hw_arch = {}
631target_arch = {}
632target_softmmu_arch = {}
633
634###############
635# Trace files #
636###############
637
638# TODO: add each directory to the subdirs from its own meson.build, once
639# we have those
640trace_events_subdirs = [
641  'accel/kvm',
642  'accel/tcg',
643  'crypto',
644  'monitor',
645]
646if have_user
647  trace_events_subdirs += [ 'linux-user' ]
648endif
649if have_block
650  trace_events_subdirs += [
651    'authz',
652    'block',
653    'io',
654    'nbd',
655    'scsi',
656  ]
657endif
658if have_system
659  trace_events_subdirs += [
660    'audio',
661    'backends',
662    'backends/tpm',
663    'chardev',
664    'hw/9pfs',
665    'hw/acpi',
666    'hw/alpha',
667    'hw/arm',
668    'hw/audio',
669    'hw/block',
670    'hw/block/dataplane',
671    'hw/char',
672    'hw/display',
673    'hw/dma',
674    'hw/hppa',
675    'hw/hyperv',
676    'hw/i2c',
677    'hw/i386',
678    'hw/i386/xen',
679    'hw/ide',
680    'hw/input',
681    'hw/intc',
682    'hw/isa',
683    'hw/mem',
684    'hw/mips',
685    'hw/misc',
686    'hw/misc/macio',
687    'hw/net',
688    'hw/nvram',
689    'hw/pci',
690    'hw/pci-host',
691    'hw/ppc',
692    'hw/rdma',
693    'hw/rdma/vmw',
694    'hw/rtc',
695    'hw/s390x',
696    'hw/scsi',
697    'hw/sd',
698    'hw/sparc',
699    'hw/sparc64',
700    'hw/ssi',
701    'hw/timer',
702    'hw/tpm',
703    'hw/usb',
704    'hw/vfio',
705    'hw/virtio',
706    'hw/watchdog',
707    'hw/xen',
708    'hw/gpio',
709    'hw/riscv',
710    'migration',
711    'net',
712    'ui',
713  ]
714endif
715trace_events_subdirs += [
716  'hw/core',
717  'qapi',
718  'qom',
719  'target/arm',
720  'target/hppa',
721  'target/i386',
722  'target/mips',
723  'target/ppc',
724  'target/riscv',
725  'target/s390x',
726  'target/sparc',
727  'util',
728]
729
730subdir('qapi')
731subdir('qobject')
732subdir('stubs')
733subdir('trace')
734subdir('util')
735subdir('qom')
736subdir('authz')
737subdir('crypto')
738subdir('ui')
739
740
741if enable_modules
742  libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
743  modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
744endif
745
746# Build targets from sourcesets
747
748stub_ss = stub_ss.apply(config_all, strict: false)
749
750util_ss.add_all(trace_ss)
751util_ss = util_ss.apply(config_all, strict: false)
752libqemuutil = static_library('qemuutil',
753                             sources: util_ss.sources() + stub_ss.sources() + genh,
754                             dependencies: [util_ss.dependencies(), m, glib, socket])
755qemuutil = declare_dependency(link_with: libqemuutil,
756                              sources: genh + version_res)
757
758decodetree = generator(find_program('scripts/decodetree.py'),
759                       output: 'decode-@BASENAME@.c.inc',
760                       arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
761
762subdir('audio')
763subdir('io')
764subdir('chardev')
765subdir('fsdev')
766subdir('libdecnumber')
767subdir('target')
768subdir('dump')
769
770block_ss.add(files(
771  'block.c',
772  'blockjob.c',
773  'job.c',
774  'qemu-io-cmds.c',
775))
776block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
777
778subdir('nbd')
779subdir('scsi')
780subdir('block')
781
782blockdev_ss.add(files(
783  'blockdev.c',
784  'blockdev-nbd.c',
785  'iothread.c',
786  'job-qmp.c',
787))
788
789# os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
790# os-win32.c does not
791blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
792softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
793
794softmmu_ss.add_all(blockdev_ss)
795softmmu_ss.add(files(
796  'bootdevice.c',
797  'dma-helpers.c',
798  'qdev-monitor.c',
799), sdl)
800
801softmmu_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c'))
802softmmu_ss.add(when: 'CONFIG_SECCOMP', if_true: [files('qemu-seccomp.c'), seccomp])
803softmmu_ss.add(when: ['CONFIG_FDT', fdt],  if_true: [files('device_tree.c')])
804
805common_ss.add(files('cpus-common.c'))
806
807subdir('softmmu')
808
809specific_ss.add(files('disas.c', 'exec.c', 'gdbstub.c'), capstone, libpmem, libdaxctl)
810specific_ss.add(files('exec-vary.c'))
811specific_ss.add(when: 'CONFIG_TCG', if_true: files(
812  'fpu/softfloat.c',
813  'tcg/optimize.c',
814  'tcg/tcg-common.c',
815  'tcg/tcg-op-gvec.c',
816  'tcg/tcg-op-vec.c',
817  'tcg/tcg-op.c',
818  'tcg/tcg.c',
819))
820specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
821
822subdir('backends')
823subdir('disas')
824subdir('migration')
825subdir('monitor')
826subdir('net')
827subdir('replay')
828subdir('hw')
829subdir('accel')
830subdir('plugins')
831subdir('bsd-user')
832subdir('linux-user')
833
834bsd_user_ss.add(files('gdbstub.c'))
835specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
836
837linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
838specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
839
840# needed for fuzzing binaries
841subdir('tests/qtest/libqos')
842subdir('tests/qtest/fuzz')
843
844block_mods = []
845softmmu_mods = []
846foreach d, list : modules
847  foreach m, module_ss : list
848    if enable_modules and targetos != 'windows'
849      module_ss = module_ss.apply(config_host, strict: false)
850      sl = static_library(d + '-' + m, [genh, module_ss.sources()],
851                          dependencies: [modulecommon, module_ss.dependencies()], pic: true)
852      if d == 'block'
853        block_mods += sl
854      else
855        softmmu_mods += sl
856      endif
857    else
858      if d == 'block'
859        block_ss.add_all(module_ss)
860      else
861        softmmu_ss.add_all(module_ss)
862      endif
863    endif
864  endforeach
865endforeach
866
867nm = find_program('nm')
868undefsym = find_program('scripts/undefsym.sh')
869block_syms = custom_target('block.syms', output: 'block.syms',
870                             input: [libqemuutil, block_mods],
871                             capture: true,
872                             command: [undefsym, nm, '@INPUT@'])
873qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
874                             input: [libqemuutil, softmmu_mods],
875                             capture: true,
876                             command: [undefsym, nm, '@INPUT@'])
877
878block_ss = block_ss.apply(config_host, strict: false)
879libblock = static_library('block', block_ss.sources() + genh,
880                          dependencies: block_ss.dependencies(),
881                          link_depends: block_syms,
882                          name_suffix: 'fa',
883                          build_by_default: false)
884
885block = declare_dependency(link_whole: [libblock],
886                           link_args: '@block.syms',
887                           dependencies: [crypto, io])
888
889qmp_ss = qmp_ss.apply(config_host, strict: false)
890libqmp = static_library('qmp', qmp_ss.sources() + genh,
891                        dependencies: qmp_ss.dependencies(),
892                        name_suffix: 'fa',
893                        build_by_default: false)
894
895qmp = declare_dependency(link_whole: [libqmp])
896
897foreach m : block_mods + softmmu_mods
898  shared_module(m.name(),
899                name_prefix: '',
900                link_whole: m,
901                install: true,
902                install_dir: config_host['qemu_moddir'])
903endforeach
904
905softmmu_ss.add(authz, block, chardev, crypto, io, qmp)
906common_ss.add(qom, qemuutil)
907
908common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
909common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
910
911common_all = common_ss.apply(config_all, strict: false)
912common_all = static_library('common',
913                            build_by_default: false,
914                            sources: common_all.sources() + genh,
915                            dependencies: common_all.dependencies(),
916                            name_suffix: 'fa')
917
918feature_to_c = find_program('scripts/feature_to_c.sh')
919
920emulators = []
921foreach target : target_dirs
922  config_target = config_target_mak[target]
923  target_name = config_target['TARGET_NAME']
924  arch = config_target['TARGET_BASE_ARCH']
925  arch_srcs = [config_target_h[target]]
926  arch_deps = []
927  c_args = ['-DNEED_CPU_H',
928            '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
929            '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
930  link_args = []
931
932  config_target += config_host
933  target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
934  if targetos == 'linux'
935    target_inc += include_directories('linux-headers', is_system: true)
936  endif
937  if target.endswith('-softmmu')
938    qemu_target_name = 'qemu-system-' + target_name
939    target_type='system'
940    t = target_softmmu_arch[arch].apply(config_target, strict: false)
941    arch_srcs += t.sources()
942    arch_deps += t.dependencies()
943
944    hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
945    hw = hw_arch[hw_dir].apply(config_target, strict: false)
946    arch_srcs += hw.sources()
947    arch_deps += hw.dependencies()
948
949    arch_srcs += config_devices_h[target]
950    link_args += ['@block.syms', '@qemu.syms']
951  else
952    abi = config_target['TARGET_ABI_DIR']
953    target_type='user'
954    qemu_target_name = 'qemu-' + target_name
955    if 'CONFIG_LINUX_USER' in config_target
956      base_dir = 'linux-user'
957      target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
958    else
959      base_dir = 'bsd-user'
960    endif
961    target_inc += include_directories(
962      base_dir,
963      base_dir / abi,
964    )
965    if 'CONFIG_LINUX_USER' in config_target
966      dir = base_dir / abi
967      arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
968      if config_target.has_key('TARGET_SYSTBL_ABI')
969        arch_srcs += \
970          syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
971                                             extra_args : config_target['TARGET_SYSTBL_ABI'])
972      endif
973    endif
974  endif
975
976  if 'TARGET_XML_FILES' in config_target
977    gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
978                                output: target + '-gdbstub-xml.c',
979                                input: files(config_target['TARGET_XML_FILES'].split()),
980                                command: [feature_to_c, '@INPUT@'],
981                                capture: true)
982    arch_srcs += gdbstub_xml
983  endif
984
985  t = target_arch[arch].apply(config_target, strict: false)
986  arch_srcs += t.sources()
987  arch_deps += t.dependencies()
988
989  target_common = common_ss.apply(config_target, strict: false)
990  objects = common_all.extract_objects(target_common.sources())
991  deps = target_common.dependencies()
992
993  target_specific = specific_ss.apply(config_target, strict: false)
994  arch_srcs += target_specific.sources()
995  arch_deps += target_specific.dependencies()
996
997  lib = static_library('qemu-' + target,
998                 sources: arch_srcs + genh,
999                 dependencies: arch_deps,
1000                 objects: objects,
1001                 include_directories: target_inc,
1002                 c_args: c_args,
1003                 build_by_default: false,
1004                 name_suffix: 'fa')
1005
1006  if target.endswith('-softmmu')
1007    execs = [{
1008      'name': 'qemu-system-' + target_name,
1009      'gui': false,
1010      'sources': files('softmmu/main.c'),
1011      'dependencies': []
1012    }]
1013    if targetos == 'windows' and (sdl.found() or gtk.found())
1014      execs += [{
1015        'name': 'qemu-system-' + target_name + 'w',
1016        'gui': true,
1017        'sources': files('softmmu/main.c'),
1018        'dependencies': []
1019      }]
1020    endif
1021    if config_host.has_key('CONFIG_FUZZ')
1022      specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
1023      execs += [{
1024        'name': 'qemu-fuzz-' + target_name,
1025        'gui': false,
1026        'sources': specific_fuzz.sources(),
1027        'dependencies': specific_fuzz.dependencies(),
1028        'link_depends': [files('tests/qtest/fuzz/fork_fuzz.ld')],
1029      }]
1030    endif
1031  else
1032    execs = [{
1033      'name': 'qemu-' + target_name,
1034      'gui': false,
1035      'sources': [],
1036      'dependencies': []
1037    }]
1038  endif
1039  foreach exe: execs
1040    emulators += executable(exe['name'], exe['sources'],
1041               install: true,
1042               c_args: c_args,
1043               dependencies: arch_deps + deps + exe['dependencies'],
1044               objects: lib.extract_all_objects(recursive: true),
1045               link_language: link_language,
1046               link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
1047               link_args: link_args,
1048               gui_app: exe['gui'])
1049
1050    if 'CONFIG_TRACE_SYSTEMTAP' in config_host
1051      foreach stp: [
1052        {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
1053        {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
1054        {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
1055        {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
1056      ]
1057        custom_target(exe['name'] + stp['ext'],
1058                      input: trace_events_all,
1059                      output: exe['name'] + stp['ext'],
1060                      capture: true,
1061                      install: stp['install'],
1062                      install_dir: config_host['qemu_datadir'] / '../systemtap/tapset',
1063                      command: [
1064                        tracetool, '--group=all', '--format=' + stp['fmt'],
1065                        '--binary=' + stp['bin'],
1066                        '--target-name=' + target_name,
1067                        '--target-type=' + target_type,
1068                        '--probe-prefix=qemu.' + target_type + '.' + target_name,
1069                        '@INPUT@',
1070                      ])
1071      endforeach
1072    endif
1073  endforeach
1074endforeach
1075
1076# Other build targets
1077
1078if 'CONFIG_PLUGIN' in config_host
1079  install_headers('include/qemu/qemu-plugin.h')
1080endif
1081
1082if 'CONFIG_GUEST_AGENT' in config_host
1083  subdir('qga')
1084endif
1085
1086# Don't build qemu-keymap if xkbcommon is not explicitly enabled
1087# when we don't build tools or system
1088if xkbcommon.found()
1089  # used for the update-keymaps target, so include rules even if !have_tools
1090  qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
1091                           dependencies: [qemuutil, xkbcommon], install: have_tools)
1092endif
1093
1094qemu_block_tools = []
1095if have_tools
1096  qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
1097             dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
1098  qemu_io = executable('qemu-io', files('qemu-io.c'),
1099             dependencies: [block, qemuutil], install: true)
1100  qemu_block_tools += [qemu_img, qemu_io]
1101  if targetos != 'windows'
1102    qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
1103               dependencies: [block, qemuutil], install: true)
1104    qemu_block_tools += [qemu_nbd]
1105  endif
1106
1107  subdir('storage-daemon')
1108  subdir('contrib/rdmacm-mux')
1109  subdir('contrib/elf2dmp')
1110
1111  executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
1112             dependencies: qemuutil,
1113             install: true)
1114
1115  if 'CONFIG_VHOST_USER' in config_host
1116    subdir('contrib/libvhost-user')
1117    subdir('contrib/vhost-user-blk')
1118    subdir('contrib/vhost-user-gpu')
1119    subdir('contrib/vhost-user-input')
1120    subdir('contrib/vhost-user-scsi')
1121  endif
1122
1123  if targetos == 'linux'
1124    executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
1125               dependencies: [qemuutil, libcap_ng],
1126               install: true,
1127               install_dir: get_option('libexecdir'))
1128
1129    executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
1130               dependencies: [authz, crypto, io, qom, qemuutil,
1131                              libcap_ng, libudev, libmpathpersist],
1132               install: true)
1133  endif
1134
1135  if 'CONFIG_IVSHMEM' in config_host
1136    subdir('contrib/ivshmem-client')
1137    subdir('contrib/ivshmem-server')
1138  endif
1139endif
1140
1141subdir('tools')
1142subdir('pc-bios')
1143subdir('tests')
1144subdir('docs')
1145if 'CONFIG_GTK' in config_host
1146  subdir('po')
1147endif
1148
1149if build_docs
1150  makeinfo = find_program('makeinfo', required: build_docs)
1151
1152  docs_inc = [
1153    '-I', meson.current_source_dir(),
1154    '-I', meson.current_build_dir() / 'docs',
1155    '-I', '@OUTDIR@',
1156  ]
1157
1158  version_texi = configure_file(output: 'version.texi',
1159                              input: 'version.texi.in',
1160                              configuration: {'VERSION': meson.project_version(),
1161                                              'qemu_confdir': config_host['qemu_confdir']})
1162
1163  texi = {
1164    'qemu-qmp-ref': ['docs/interop/qemu-qmp-ref.texi', qapi_doc_texi, version_texi],
1165  }
1166  if 'CONFIG_GUEST_AGENT' in config_host
1167    texi += {'qemu-ga-ref': ['docs/interop/qemu-ga-ref.texi', qga_qapi_doc_texi, version_texi]}
1168  endif
1169
1170  if makeinfo.found()
1171    cmd = [
1172      'env', 'LC_ALL=C', makeinfo, '--no-split', '--number-sections', docs_inc,
1173      '@INPUT0@', '-o', '@OUTPUT@',
1174    ]
1175    foreach ext, args: {
1176        'info': [],
1177        'html': ['--no-headers', '--html'],
1178        'txt': ['--no-headers', '--plaintext'],
1179    }
1180      t = []
1181      foreach doc, input: texi
1182        output = doc + '.' + ext
1183        t += custom_target(output,
1184                      input: input,
1185                      output: output,
1186                      install: true,
1187                      install_dir: config_host['qemu_docdir'] / 'interop',
1188                      command: cmd + args)
1189      endforeach
1190      alias_target(ext, t)
1191    endforeach
1192  endif
1193
1194  texi2pdf = find_program('texi2pdf', required: false)
1195
1196  if texi2pdf.found()
1197    pdfs = []
1198    foreach doc, input: texi
1199      output = doc + '.pdf'
1200      pdfs += custom_target(output,
1201                    input: input,
1202                    output: output,
1203                    command: [texi2pdf, '-q', docs_inc, '@INPUT0@', '-o', '@OUTPUT@'],
1204                    build_by_default: false)
1205    endforeach
1206    alias_target('pdf', pdfs)
1207  endif
1208
1209  texi2pod = find_program('scripts/texi2pod.pl')
1210  pod2man = find_program('pod2man', required: build_docs)
1211
1212  if pod2man.found()
1213    foreach doc, input: texi
1214      man = doc + '.7'
1215      pod = custom_target(man + '.pod',
1216                          input: input,
1217                          output: man + '.pod',
1218                          command: [texi2pod,
1219                                    '-DVERSION="' + meson.project_version() + '"',
1220                                    '-DCONFDIR="' + config_host['qemu_confdir'] + '"',
1221                                    '@INPUT0@', '@OUTPUT@'])
1222      man = custom_target(man,
1223                          input: pod,
1224                          output: man,
1225                          capture: true,
1226                          install: true,
1227                          install_dir: config_host['mandir'] / 'man7',
1228                          command: [pod2man, '--utf8', '--section=7', '--center=" "',
1229                                    '--release=" "', '@INPUT@'])
1230    endforeach
1231  endif
1232endif
1233
1234summary_info = {}
1235summary_info += {'Install prefix':    config_host['prefix']}
1236summary_info += {'BIOS directory':    config_host['qemu_datadir']}
1237summary_info += {'firmware path':     config_host['qemu_firmwarepath']}
1238summary_info += {'binary directory':  config_host['bindir']}
1239summary_info += {'library directory': config_host['libdir']}
1240summary_info += {'module directory':  config_host['qemu_moddir']}
1241summary_info += {'libexec directory': config_host['libexecdir']}
1242summary_info += {'include directory': config_host['includedir']}
1243summary_info += {'config directory':  config_host['sysconfdir']}
1244if targetos != 'windows'
1245  summary_info += {'local state directory': config_host['qemu_localstatedir']}
1246  summary_info += {'Manual directory':      config_host['mandir']}
1247else
1248  summary_info += {'local state directory': 'queried at runtime'}
1249endif
1250summary_info += {'Build directory':   meson.current_build_dir()}
1251summary_info += {'Source path':       meson.current_source_dir()}
1252summary_info += {'GIT binary':        config_host['GIT']}
1253summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
1254summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
1255summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
1256if link_language == 'cpp'
1257  summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
1258else
1259  summary_info += {'C++ compiler':      false}
1260endif
1261if targetos == 'darwin'
1262  summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
1263endif
1264summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
1265summary_info += {'CFLAGS':            config_host['CFLAGS']}
1266summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
1267summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
1268summary_info += {'make':              config_host['MAKE']}
1269summary_info += {'install':           config_host['INSTALL']}
1270summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
1271summary_info += {'sphinx-build':      config_host['SPHINX_BUILD']}
1272summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
1273# TODO: add back version
1274summary_info += {'slirp support':     config_host.has_key('CONFIG_SLIRP')}
1275if config_host.has_key('CONFIG_SLIRP')
1276  summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
1277endif
1278summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
1279if config_host.has_key('CONFIG_MODULES')
1280  summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
1281endif
1282summary_info += {'host CPU':          cpu}
1283summary_info += {'host endianness':   build_machine.endian()}
1284summary_info += {'target list':       config_host['TARGET_DIRS']}
1285summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
1286summary_info += {'sparse enabled':    meson.get_compiler('c').cmd_array().contains('cgcc')}
1287summary_info += {'strip binaries':    get_option('strip')}
1288summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
1289summary_info += {'static build':      config_host.has_key('CONFIG_TOOLS')}
1290if targetos == 'darwin'
1291  summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
1292endif
1293# TODO: add back version
1294summary_info += {'SDL support':       sdl.found()}
1295summary_info += {'SDL image support': sdl_image.found()}
1296# TODO: add back version
1297summary_info += {'GTK support':       config_host.has_key('CONFIG_GTK')}
1298summary_info += {'GTK GL support':    config_host.has_key('CONFIG_GTK_GL')}
1299summary_info += {'pixman':            pixman.found()}
1300# TODO: add back version
1301summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
1302summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
1303summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
1304# TODO: add back version
1305summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
1306if config_host.has_key('CONFIG_GCRYPT')
1307   summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
1308   summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1309endif
1310# TODO: add back version
1311summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
1312if config_host.has_key('CONFIG_NETTLE')
1313   summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1314endif
1315summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
1316summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
1317summary_info += {'iconv support':     config_host.has_key('CONFIG_ICONV')}
1318summary_info += {'curses support':    config_host.has_key('CONFIG_CURSES')}
1319# TODO: add back version
1320summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
1321summary_info += {'curl support':      config_host.has_key('CONFIG_CURL')}
1322summary_info += {'mingw32 support':   targetos == 'windows'}
1323summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
1324summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
1325summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
1326summary_info += {'VirtFS support':    config_host.has_key('CONFIG_VIRTFS')}
1327summary_info += {'Multipath support': config_host.has_key('CONFIG_MPATH')}
1328summary_info += {'VNC support':       vnc.found()}
1329if vnc.found()
1330  summary_info += {'VNC SASL support':  sasl.found()}
1331  summary_info += {'VNC JPEG support':  jpeg.found()}
1332  summary_info += {'VNC PNG support':   png.found()}
1333endif
1334summary_info += {'xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
1335if config_host.has_key('CONFIG_XEN_BACKEND')
1336  summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
1337endif
1338summary_info += {'brlapi support':    config_host.has_key('CONFIG_BRLAPI')}
1339summary_info += {'Documentation':     config_host.has_key('BUILD_DOCS')}
1340summary_info += {'PIE':               get_option('b_pie')}
1341summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
1342summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
1343summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
1344summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
1345summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
1346summary_info += {'Install blobs':     config_host.has_key('INSTALL_BLOBS')}
1347# TODO: add back KVM/HAX/HVF/WHPX/TCG
1348#summary_info += {'KVM support':       have_kvm'}
1349#summary_info += {'HAX support':       have_hax'}
1350#summary_info += {'HVF support':       have_hvf'}
1351#summary_info += {'WHPX support':      have_whpx'}
1352#summary_info += {'TCG support':       have_tcg'}
1353#if get_option('tcg')
1354#  summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
1355#  summary_info += {'TCG interpreter':   config_host.has_key('CONFIG_TCG_INTERPRETER')}
1356#endif
1357summary_info += {'malloc trim support': config_host.has_key('CONFIG_MALLOC_TRIM')}
1358summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
1359summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
1360summary_info += {'fdt support':       config_host.has_key('CONFIG_FDT')}
1361summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
1362summary_info += {'preadv support':    config_host.has_key('CONFIG_PREADV')}
1363summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
1364summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
1365summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
1366summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
1367summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
1368summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
1369summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
1370summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
1371summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
1372summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_KERNEL')}
1373summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
1374summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
1375summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
1376if config_host['TRACE_BACKENDS'].split().contains('simple')
1377  summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
1378endif
1379# TODO: add back protocol and server version
1380summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
1381summary_info += {'rbd support':       config_host.has_key('CONFIG_RBD')}
1382summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
1383summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
1384summary_info += {'U2F support':       u2f.found()}
1385summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
1386summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
1387summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
1388summary_info += {'OpenGL dmabufs':    config_host.has_key('CONFIG_OPENGL_DMABUF')}
1389summary_info += {'libiscsi support':  config_host.has_key('CONFIG_LIBISCSI')}
1390summary_info += {'libnfs support':    config_host.has_key('CONFIG_LIBNFS')}
1391summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
1392if targetos == 'windows'
1393  if 'WIN_SDK' in config_host
1394    summary_info += {'Windows SDK':       config_host['WIN_SDK']}
1395  endif
1396  summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
1397  summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
1398  summary_info += {'QGA MSI support':   config_host.has_key('CONFIG_QGA_MSI_ENABLED')}
1399endif
1400summary_info += {'seccomp support':   config_host.has_key('CONFIG_SECCOMP')}
1401summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
1402summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
1403summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
1404summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
1405summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
1406summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
1407summary_info += {'gcov':              get_option('b_coverage')}
1408summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
1409summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
1410summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
1411summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
1412summary_info += {'lzo support':       config_host.has_key('CONFIG_LZO')}
1413summary_info += {'snappy support':    config_host.has_key('CONFIG_SNAPPY')}
1414summary_info += {'bzip2 support':     config_host.has_key('CONFIG_BZIP2')}
1415summary_info += {'lzfse support':     config_host.has_key('CONFIG_LZFSE')}
1416summary_info += {'zstd support':      config_host.has_key('CONFIG_ZSTD')}
1417summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
1418summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
1419summary_info += {'tcmalloc support':  config_host.has_key('CONFIG_TCMALLOC')}
1420summary_info += {'jemalloc support':  config_host.has_key('CONFIG_JEMALLOC')}
1421summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
1422summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
1423summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
1424summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
1425summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
1426summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
1427summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
1428summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
1429summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
1430summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
1431summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
1432summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
1433summary_info += {'capstone':          config_host.has_key('CONFIG_CAPSTONE')}
1434summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
1435summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
1436summary_info += {'libudev':           config_host.has_key('CONFIG_LIBUDEV')}
1437summary_info += {'default devices':   config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
1438summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
1439summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
1440if config_host.has_key('HAVE_GDB_BIN')
1441  summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
1442endif
1443summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
1444summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
1445summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
1446summary(summary_info, bool_yn: true)
1447
1448if not supported_cpus.contains(cpu)
1449  message()
1450  warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
1451  message()
1452  message('CPU host architecture ' + cpu + ' support is not currently maintained.')
1453  message('The QEMU project intends to remove support for this host CPU in')
1454  message('a future release if nobody volunteers to maintain it and to')
1455  message('provide a build host for our continuous integration setup.')
1456  message('configure has succeeded and you can continue to build, but')
1457  message('if you care about QEMU on this platform you should contact')
1458  message('us upstream at qemu-devel@nongnu.org.')
1459endif
1460
1461if not supported_oses.contains(targetos)
1462  message()
1463  warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
1464  message()
1465  message('Host OS ' + targetos + 'support is not currently maintained.')
1466  message('The QEMU project intends to remove support for this host OS in')
1467  message('a future release if nobody volunteers to maintain it and to')
1468  message('provide a build host for our continuous integration setup.')
1469  message('configure has succeeded and you can continue to build, but')
1470  message('if you care about QEMU on this platform you should contact')
1471  message('us upstream at qemu-devel@nongnu.org.')
1472endif
1473