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