xref: /qemu/meson.build (revision a4d88926)
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('SDL2_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('scripts')
1142subdir('tools')
1143subdir('pc-bios')
1144subdir('tests')
1145subdir('docs')
1146if 'CONFIG_GTK' in config_host
1147  subdir('po')
1148endif
1149
1150if build_docs
1151  makeinfo = find_program('makeinfo', required: build_docs)
1152
1153  docs_inc = [
1154    '-I', meson.current_source_dir(),
1155    '-I', meson.current_build_dir() / 'docs',
1156    '-I', '@OUTDIR@',
1157  ]
1158
1159  version_texi = configure_file(output: 'version.texi',
1160                              input: 'version.texi.in',
1161                              configuration: {'VERSION': meson.project_version(),
1162                                              'qemu_confdir': config_host['qemu_confdir']})
1163
1164  texi = {
1165    'qemu-qmp-ref': ['docs/interop/qemu-qmp-ref.texi', qapi_doc_texi, version_texi],
1166  }
1167  if 'CONFIG_GUEST_AGENT' in config_host
1168    texi += {'qemu-ga-ref': ['docs/interop/qemu-ga-ref.texi', qga_qapi_doc_texi, version_texi]}
1169  endif
1170
1171  if makeinfo.found()
1172    cmd = [
1173      'env', 'LC_ALL=C', makeinfo, '--no-split', '--number-sections', docs_inc,
1174      '@INPUT0@', '-o', '@OUTPUT@',
1175    ]
1176    foreach ext, args: {
1177        'info': [],
1178        'html': ['--no-headers', '--html'],
1179        'txt': ['--no-headers', '--plaintext'],
1180    }
1181      t = []
1182      foreach doc, input: texi
1183        output = doc + '.' + ext
1184        t += custom_target(output,
1185                      input: input,
1186                      output: output,
1187                      install: true,
1188                      install_dir: config_host['qemu_docdir'] / 'interop',
1189                      command: cmd + args)
1190      endforeach
1191      alias_target(ext, t)
1192    endforeach
1193  endif
1194
1195  texi2pdf = find_program('texi2pdf', required: false)
1196
1197  if texi2pdf.found()
1198    pdfs = []
1199    foreach doc, input: texi
1200      output = doc + '.pdf'
1201      pdfs += custom_target(output,
1202                    input: input,
1203                    output: output,
1204                    command: [texi2pdf, '-q', docs_inc, '@INPUT0@', '-o', '@OUTPUT@'],
1205                    build_by_default: false)
1206    endforeach
1207    alias_target('pdf', pdfs)
1208  endif
1209
1210  texi2pod = find_program('scripts/texi2pod.pl')
1211  pod2man = find_program('pod2man', required: build_docs)
1212
1213  if pod2man.found()
1214    foreach doc, input: texi
1215      man = doc + '.7'
1216      pod = custom_target(man + '.pod',
1217                          input: input,
1218                          output: man + '.pod',
1219                          command: [texi2pod,
1220                                    '-DVERSION="' + meson.project_version() + '"',
1221                                    '-DCONFDIR="' + config_host['qemu_confdir'] + '"',
1222                                    '@INPUT0@', '@OUTPUT@'])
1223      man = custom_target(man,
1224                          input: pod,
1225                          output: man,
1226                          capture: true,
1227                          install: true,
1228                          install_dir: config_host['mandir'] / 'man7',
1229                          command: [pod2man, '--utf8', '--section=7', '--center=" "',
1230                                    '--release=" "', '@INPUT@'])
1231    endforeach
1232  endif
1233endif
1234
1235summary_info = {}
1236summary_info += {'Install prefix':    config_host['prefix']}
1237summary_info += {'BIOS directory':    config_host['qemu_datadir']}
1238summary_info += {'firmware path':     config_host['qemu_firmwarepath']}
1239summary_info += {'binary directory':  config_host['bindir']}
1240summary_info += {'library directory': config_host['libdir']}
1241summary_info += {'module directory':  config_host['qemu_moddir']}
1242summary_info += {'libexec directory': config_host['libexecdir']}
1243summary_info += {'include directory': config_host['includedir']}
1244summary_info += {'config directory':  config_host['sysconfdir']}
1245if targetos != 'windows'
1246  summary_info += {'local state directory': config_host['qemu_localstatedir']}
1247  summary_info += {'Manual directory':      config_host['mandir']}
1248else
1249  summary_info += {'local state directory': 'queried at runtime'}
1250endif
1251summary_info += {'Build directory':   meson.current_build_dir()}
1252summary_info += {'Source path':       meson.current_source_dir()}
1253summary_info += {'GIT binary':        config_host['GIT']}
1254summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
1255summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
1256summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
1257if link_language == 'cpp'
1258  summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
1259else
1260  summary_info += {'C++ compiler':      false}
1261endif
1262if targetos == 'darwin'
1263  summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
1264endif
1265summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
1266summary_info += {'CFLAGS':            config_host['CFLAGS']}
1267summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
1268summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
1269summary_info += {'make':              config_host['MAKE']}
1270summary_info += {'install':           config_host['INSTALL']}
1271summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
1272summary_info += {'sphinx-build':      config_host['SPHINX_BUILD']}
1273summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
1274# TODO: add back version
1275summary_info += {'slirp support':     config_host.has_key('CONFIG_SLIRP')}
1276if config_host.has_key('CONFIG_SLIRP')
1277  summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
1278endif
1279summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
1280if config_host.has_key('CONFIG_MODULES')
1281  summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
1282endif
1283summary_info += {'host CPU':          cpu}
1284summary_info += {'host endianness':   build_machine.endian()}
1285summary_info += {'target list':       config_host['TARGET_DIRS']}
1286summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
1287summary_info += {'sparse enabled':    meson.get_compiler('c').cmd_array().contains('cgcc')}
1288summary_info += {'strip binaries':    get_option('strip')}
1289summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
1290summary_info += {'static build':      config_host.has_key('CONFIG_TOOLS')}
1291if targetos == 'darwin'
1292  summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
1293endif
1294# TODO: add back version
1295summary_info += {'SDL support':       sdl.found()}
1296summary_info += {'SDL image support': sdl_image.found()}
1297# TODO: add back version
1298summary_info += {'GTK support':       config_host.has_key('CONFIG_GTK')}
1299summary_info += {'GTK GL support':    config_host.has_key('CONFIG_GTK_GL')}
1300summary_info += {'pixman':            pixman.found()}
1301# TODO: add back version
1302summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
1303summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
1304summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
1305# TODO: add back version
1306summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
1307if config_host.has_key('CONFIG_GCRYPT')
1308   summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
1309   summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1310endif
1311# TODO: add back version
1312summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
1313if config_host.has_key('CONFIG_NETTLE')
1314   summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1315endif
1316summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
1317summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
1318summary_info += {'iconv support':     config_host.has_key('CONFIG_ICONV')}
1319summary_info += {'curses support':    config_host.has_key('CONFIG_CURSES')}
1320# TODO: add back version
1321summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
1322summary_info += {'curl support':      config_host.has_key('CONFIG_CURL')}
1323summary_info += {'mingw32 support':   targetos == 'windows'}
1324summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
1325summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
1326summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
1327summary_info += {'VirtFS support':    config_host.has_key('CONFIG_VIRTFS')}
1328summary_info += {'Multipath support': config_host.has_key('CONFIG_MPATH')}
1329summary_info += {'VNC support':       vnc.found()}
1330if vnc.found()
1331  summary_info += {'VNC SASL support':  sasl.found()}
1332  summary_info += {'VNC JPEG support':  jpeg.found()}
1333  summary_info += {'VNC PNG support':   png.found()}
1334endif
1335summary_info += {'xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
1336if config_host.has_key('CONFIG_XEN_BACKEND')
1337  summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
1338endif
1339summary_info += {'brlapi support':    config_host.has_key('CONFIG_BRLAPI')}
1340summary_info += {'Documentation':     config_host.has_key('BUILD_DOCS')}
1341summary_info += {'PIE':               get_option('b_pie')}
1342summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
1343summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
1344summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
1345summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
1346summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
1347summary_info += {'Install blobs':     config_host.has_key('INSTALL_BLOBS')}
1348# TODO: add back KVM/HAX/HVF/WHPX/TCG
1349#summary_info += {'KVM support':       have_kvm'}
1350#summary_info += {'HAX support':       have_hax'}
1351#summary_info += {'HVF support':       have_hvf'}
1352#summary_info += {'WHPX support':      have_whpx'}
1353#summary_info += {'TCG support':       have_tcg'}
1354#if get_option('tcg')
1355#  summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
1356#  summary_info += {'TCG interpreter':   config_host.has_key('CONFIG_TCG_INTERPRETER')}
1357#endif
1358summary_info += {'malloc trim support': config_host.has_key('CONFIG_MALLOC_TRIM')}
1359summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
1360summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
1361summary_info += {'fdt support':       config_host.has_key('CONFIG_FDT')}
1362summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
1363summary_info += {'preadv support':    config_host.has_key('CONFIG_PREADV')}
1364summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
1365summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
1366summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
1367summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
1368summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
1369summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
1370summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
1371summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
1372summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
1373summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_KERNEL')}
1374summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
1375summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
1376summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
1377if config_host['TRACE_BACKENDS'].split().contains('simple')
1378  summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
1379endif
1380# TODO: add back protocol and server version
1381summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
1382summary_info += {'rbd support':       config_host.has_key('CONFIG_RBD')}
1383summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
1384summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
1385summary_info += {'U2F support':       u2f.found()}
1386summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
1387summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
1388summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
1389summary_info += {'OpenGL dmabufs':    config_host.has_key('CONFIG_OPENGL_DMABUF')}
1390summary_info += {'libiscsi support':  config_host.has_key('CONFIG_LIBISCSI')}
1391summary_info += {'libnfs support':    config_host.has_key('CONFIG_LIBNFS')}
1392summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
1393if targetos == 'windows'
1394  if 'WIN_SDK' in config_host
1395    summary_info += {'Windows SDK':       config_host['WIN_SDK']}
1396  endif
1397  summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
1398  summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
1399  summary_info += {'QGA MSI support':   config_host.has_key('CONFIG_QGA_MSI_ENABLED')}
1400endif
1401summary_info += {'seccomp support':   config_host.has_key('CONFIG_SECCOMP')}
1402summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
1403summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
1404summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
1405summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
1406summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
1407summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
1408summary_info += {'gcov':              get_option('b_coverage')}
1409summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
1410summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
1411summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
1412summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
1413summary_info += {'lzo support':       config_host.has_key('CONFIG_LZO')}
1414summary_info += {'snappy support':    config_host.has_key('CONFIG_SNAPPY')}
1415summary_info += {'bzip2 support':     config_host.has_key('CONFIG_BZIP2')}
1416summary_info += {'lzfse support':     config_host.has_key('CONFIG_LZFSE')}
1417summary_info += {'zstd support':      config_host.has_key('CONFIG_ZSTD')}
1418summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
1419summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
1420summary_info += {'tcmalloc support':  config_host.has_key('CONFIG_TCMALLOC')}
1421summary_info += {'jemalloc support':  config_host.has_key('CONFIG_JEMALLOC')}
1422summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
1423summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
1424summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
1425summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
1426summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
1427summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
1428summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
1429summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
1430summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
1431summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
1432summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
1433summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
1434summary_info += {'capstone':          config_host.has_key('CONFIG_CAPSTONE')}
1435summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
1436summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
1437summary_info += {'libudev':           config_host.has_key('CONFIG_LIBUDEV')}
1438summary_info += {'default devices':   config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
1439summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
1440summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
1441if config_host.has_key('HAVE_GDB_BIN')
1442  summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
1443endif
1444summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
1445summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
1446summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
1447summary(summary_info, bool_yn: true)
1448
1449if not supported_cpus.contains(cpu)
1450  message()
1451  warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
1452  message()
1453  message('CPU host architecture ' + cpu + ' support is not currently maintained.')
1454  message('The QEMU project intends to remove support for this host CPU in')
1455  message('a future release if nobody volunteers to maintain it and to')
1456  message('provide a build host for our continuous integration setup.')
1457  message('configure has succeeded and you can continue to build, but')
1458  message('if you care about QEMU on this platform you should contact')
1459  message('us upstream at qemu-devel@nongnu.org.')
1460endif
1461
1462if not supported_oses.contains(targetos)
1463  message()
1464  warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
1465  message()
1466  message('Host OS ' + targetos + 'support is not currently maintained.')
1467  message('The QEMU project intends to remove support for this host OS in')
1468  message('a future release if nobody volunteers to maintain it and to')
1469  message('provide a build host for our continuous integration setup.')
1470  message('configure has succeeded and you can continue to build, but')
1471  message('if you care about QEMU on this platform you should contact')
1472  message('us upstream at qemu-devel@nongnu.org.')
1473endif
1474