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