xref: /openbmc/qemu/meson.build (revision 9921e3d3)
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 = not_found
156if 'CONFIG_XKBCOMMON' in config_host
157  xkbcommon = declare_dependency(compile_args: config_host['XKBCOMMON_CFLAGS'].split(),
158                                 link_args: config_host['XKBCOMMON_LIBS'].split())
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('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
393config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
394config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
395config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
396
397arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
398strings = ['HOST_DSOSUF', 'CONFIG_IASL', 'qemu_confdir', 'qemu_datadir',
399           'qemu_moddir', 'qemu_localstatedir', 'qemu_helperdir', 'qemu_localedir',
400           'qemu_icondir', 'qemu_desktopdir', 'qemu_firmwarepath']
401foreach k, v: config_host
402  if arrays.contains(k)
403    if v != ''
404      v = '"' + '", "'.join(v.split()) + '", '
405    endif
406    config_host_data.set(k, v)
407  elif k == 'ARCH'
408    config_host_data.set('HOST_' + v.to_upper(), 1)
409  elif strings.contains(k)
410    if not k.startswith('CONFIG_')
411      k = 'CONFIG_' + k.to_upper()
412    endif
413    config_host_data.set_quoted(k, v)
414  elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
415    config_host_data.set(k, v == 'y' ? 1 : v)
416  endif
417endforeach
418genh += configure_file(output: 'config-host.h', configuration: config_host_data)
419
420minikconf = find_program('scripts/minikconf.py')
421target_dirs = config_host['TARGET_DIRS'].split()
422have_user = false
423have_system = false
424config_devices_mak_list = []
425config_devices_h = {}
426config_target_h = {}
427config_target_mak = {}
428kconfig_external_symbols = [
429  'CONFIG_KVM',
430  'CONFIG_XEN',
431  'CONFIG_TPM',
432  'CONFIG_SPICE',
433  'CONFIG_IVSHMEM',
434  'CONFIG_OPENGL',
435  'CONFIG_X11',
436  'CONFIG_VHOST_USER',
437  'CONFIG_VHOST_KERNEL',
438  'CONFIG_VIRTFS',
439  'CONFIG_LINUX',
440  'CONFIG_PVRDMA',
441]
442ignored = ['TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_DIRS']
443foreach target : target_dirs
444  have_user = have_user or target.endswith('-user')
445  config_target = keyval.load(meson.current_build_dir() / target / 'config-target.mak')
446
447  config_target_data = configuration_data()
448  foreach k, v: config_target
449    if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
450      # do nothing
451    elif ignored.contains(k)
452      # do nothing
453    elif k == 'TARGET_BASE_ARCH'
454      config_target_data.set('TARGET_' + v.to_upper(), 1)
455    elif k == 'TARGET_NAME'
456      config_target_data.set_quoted(k, v)
457    elif v == 'y'
458      config_target_data.set(k, 1)
459    else
460      config_target_data.set(k, v)
461    endif
462  endforeach
463  config_target_h += {target: configure_file(output: target + '-config-target.h',
464                                               configuration: config_target_data)}
465
466  if target.endswith('-softmmu')
467    have_system = true
468
469    base_kconfig = []
470    foreach sym : kconfig_external_symbols
471      if sym in config_target or sym in config_host
472        base_kconfig += '@0@=y'.format(sym)
473      endif
474    endforeach
475
476    config_devices_mak = target + '-config-devices.mak'
477    config_devices_mak = configure_file(
478      input: ['default-configs' / target + '.mak', 'Kconfig'],
479      output: config_devices_mak,
480      depfile: config_devices_mak + '.d',
481      capture: true,
482      command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'],
483                config_devices_mak, '@DEPFILE@', '@INPUT@',
484                base_kconfig])
485
486    config_devices_data = configuration_data()
487    config_devices = keyval.load(config_devices_mak)
488    foreach k, v: config_devices
489      config_devices_data.set(k, 1)
490    endforeach
491    config_devices_mak_list += config_devices_mak
492    config_devices_h += {target: configure_file(output: target + '-config-devices.h',
493                                                configuration: config_devices_data)}
494    config_target += config_devices
495  endif
496  config_target_mak += {target: config_target}
497endforeach
498have_tools = 'CONFIG_TOOLS' in config_host
499have_block = have_system or have_tools
500
501grepy = find_program('scripts/grepy.sh')
502# This configuration is used to build files that are shared by
503# multiple binaries, and then extracted out of the "common"
504# static_library target.
505#
506# We do not use all_sources()/all_dependencies(), because it would
507# build literally all source files, including devices only used by
508# targets that are not built for this compilation.  The CONFIG_ALL
509# pseudo symbol replaces it.
510
511if have_system
512  config_all_devices_mak = configure_file(
513    output: 'config-all-devices.mak',
514    input: config_devices_mak_list,
515    capture: true,
516    command: [grepy, '@INPUT@'],
517  )
518  config_all_devices = keyval.load(config_all_devices_mak)
519else
520  config_all_devices = {}
521endif
522config_all = config_all_devices
523config_all += config_host
524config_all += config_all_disas
525config_all += {
526  'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
527  'CONFIG_SOFTMMU': have_system,
528  'CONFIG_USER_ONLY': have_user,
529  'CONFIG_ALL': true,
530}
531
532# Generators
533
534hxtool = find_program('scripts/hxtool')
535shaderinclude = find_program('scripts/shaderinclude.pl')
536qapi_gen = find_program('scripts/qapi-gen.py')
537qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
538                     meson.source_root() / 'scripts/qapi/commands.py',
539                     meson.source_root() / 'scripts/qapi/common.py',
540                     meson.source_root() / 'scripts/qapi/doc.py',
541                     meson.source_root() / 'scripts/qapi/error.py',
542                     meson.source_root() / 'scripts/qapi/events.py',
543                     meson.source_root() / 'scripts/qapi/expr.py',
544                     meson.source_root() / 'scripts/qapi/gen.py',
545                     meson.source_root() / 'scripts/qapi/introspect.py',
546                     meson.source_root() / 'scripts/qapi/parser.py',
547                     meson.source_root() / 'scripts/qapi/schema.py',
548                     meson.source_root() / 'scripts/qapi/source.py',
549                     meson.source_root() / 'scripts/qapi/types.py',
550                     meson.source_root() / 'scripts/qapi/visit.py',
551                     meson.source_root() / 'scripts/qapi/common.py',
552                     meson.source_root() / 'scripts/qapi/doc.py',
553                     meson.source_root() / 'scripts/qapi-gen.py'
554]
555
556tracetool = [
557  python, files('scripts/tracetool.py'),
558   '--backend=' + config_host['TRACE_BACKENDS']
559]
560
561qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
562                    meson.current_source_dir(),
563                    config_host['PKGVERSION'], meson.project_version()]
564qemu_version = custom_target('qemu-version.h',
565                             output: 'qemu-version.h',
566                             command: qemu_version_cmd,
567                             capture: true,
568                             build_by_default: true,
569                             build_always_stale: true)
570genh += qemu_version
571
572hxdep = []
573hx_headers = [
574  ['qemu-options.hx', 'qemu-options.def'],
575  ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
576]
577if have_system
578  hx_headers += [
579    ['hmp-commands.hx', 'hmp-commands.h'],
580    ['hmp-commands-info.hx', 'hmp-commands-info.h'],
581  ]
582endif
583foreach d : hx_headers
584  hxdep += custom_target(d[1],
585                input: files(d[0]),
586                output: d[1],
587                capture: true,
588                build_by_default: true, # to be removed when added to a target
589                command: [hxtool, '-h', '@INPUT0@'])
590endforeach
591genh += hxdep
592
593# Collect sourcesets.
594
595util_ss = ss.source_set()
596stub_ss = ss.source_set()
597trace_ss = ss.source_set()
598block_ss = ss.source_set()
599blockdev_ss = ss.source_set()
600qmp_ss = ss.source_set()
601common_ss = ss.source_set()
602softmmu_ss = ss.source_set()
603user_ss = ss.source_set()
604bsd_user_ss = ss.source_set()
605linux_user_ss = ss.source_set()
606specific_ss = ss.source_set()
607specific_fuzz_ss = ss.source_set()
608
609modules = {}
610hw_arch = {}
611target_arch = {}
612target_softmmu_arch = {}
613
614###############
615# Trace files #
616###############
617
618# TODO: add each directory to the subdirs from its own meson.build, once
619# we have those
620trace_events_subdirs = [
621  'accel/kvm',
622  'accel/tcg',
623  'crypto',
624  'monitor',
625]
626if have_user
627  trace_events_subdirs += [ 'linux-user' ]
628endif
629if have_block
630  trace_events_subdirs += [
631    'authz',
632    'block',
633    'io',
634    'nbd',
635    'scsi',
636  ]
637endif
638if have_system
639  trace_events_subdirs += [
640    'audio',
641    'backends',
642    'backends/tpm',
643    'chardev',
644    'hw/9pfs',
645    'hw/acpi',
646    'hw/alpha',
647    'hw/arm',
648    'hw/audio',
649    'hw/block',
650    'hw/block/dataplane',
651    'hw/char',
652    'hw/display',
653    'hw/dma',
654    'hw/hppa',
655    'hw/hyperv',
656    'hw/i2c',
657    'hw/i386',
658    'hw/i386/xen',
659    'hw/ide',
660    'hw/input',
661    'hw/intc',
662    'hw/isa',
663    'hw/mem',
664    'hw/mips',
665    'hw/misc',
666    'hw/misc/macio',
667    'hw/net',
668    'hw/nvram',
669    'hw/pci',
670    'hw/pci-host',
671    'hw/ppc',
672    'hw/rdma',
673    'hw/rdma/vmw',
674    'hw/rtc',
675    'hw/s390x',
676    'hw/scsi',
677    'hw/sd',
678    'hw/sparc',
679    'hw/sparc64',
680    'hw/ssi',
681    'hw/timer',
682    'hw/tpm',
683    'hw/usb',
684    'hw/vfio',
685    'hw/virtio',
686    'hw/watchdog',
687    'hw/xen',
688    'hw/gpio',
689    'hw/riscv',
690    'migration',
691    'net',
692    'ui',
693  ]
694endif
695trace_events_subdirs += [
696  'hw/core',
697  'qapi',
698  'qom',
699  'target/arm',
700  'target/hppa',
701  'target/i386',
702  'target/mips',
703  'target/ppc',
704  'target/riscv',
705  'target/s390x',
706  'target/sparc',
707  'util',
708]
709
710subdir('qapi')
711subdir('qobject')
712subdir('stubs')
713subdir('trace')
714subdir('util')
715subdir('qom')
716subdir('authz')
717subdir('crypto')
718subdir('ui')
719
720
721if enable_modules
722  libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
723  modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
724endif
725
726# Build targets from sourcesets
727
728stub_ss = stub_ss.apply(config_all, strict: false)
729
730util_ss.add_all(trace_ss)
731util_ss = util_ss.apply(config_all, strict: false)
732libqemuutil = static_library('qemuutil',
733                             sources: util_ss.sources() + stub_ss.sources() + genh,
734                             dependencies: [util_ss.dependencies(), m, glib, socket])
735qemuutil = declare_dependency(link_with: libqemuutil,
736                              sources: genh + version_res)
737
738decodetree = generator(find_program('scripts/decodetree.py'),
739                       output: 'decode-@BASENAME@.c.inc',
740                       arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
741
742subdir('audio')
743subdir('io')
744subdir('chardev')
745subdir('fsdev')
746subdir('libdecnumber')
747subdir('target')
748subdir('dump')
749
750block_ss.add(files(
751  'block.c',
752  'blockjob.c',
753  'job.c',
754  'qemu-io-cmds.c',
755))
756block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
757
758subdir('nbd')
759subdir('scsi')
760subdir('block')
761
762blockdev_ss.add(files(
763  'blockdev.c',
764  'blockdev-nbd.c',
765  'iothread.c',
766  'job-qmp.c',
767))
768
769# os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
770# os-win32.c does not
771blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
772softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
773
774softmmu_ss.add_all(blockdev_ss)
775softmmu_ss.add(files(
776  'bootdevice.c',
777  'dma-helpers.c',
778  'qdev-monitor.c',
779), sdl)
780
781softmmu_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c'))
782softmmu_ss.add(when: 'CONFIG_SECCOMP', if_true: [files('qemu-seccomp.c'), seccomp])
783softmmu_ss.add(when: ['CONFIG_FDT', fdt],  if_true: [files('device_tree.c')])
784
785common_ss.add(files('cpus-common.c'))
786
787subdir('softmmu')
788
789specific_ss.add(files('disas.c', 'exec.c', 'gdbstub.c'), capstone, libpmem)
790specific_ss.add(files('exec-vary.c'))
791specific_ss.add(when: 'CONFIG_TCG', if_true: files(
792  'fpu/softfloat.c',
793  'tcg/optimize.c',
794  'tcg/tcg-common.c',
795  'tcg/tcg-op-gvec.c',
796  'tcg/tcg-op-vec.c',
797  'tcg/tcg-op.c',
798  'tcg/tcg.c',
799))
800specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
801
802subdir('backends')
803subdir('disas')
804subdir('migration')
805subdir('monitor')
806subdir('net')
807subdir('replay')
808subdir('hw')
809subdir('accel')
810subdir('plugins')
811subdir('bsd-user')
812subdir('linux-user')
813
814bsd_user_ss.add(files('gdbstub.c'))
815specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
816
817linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
818specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
819
820# needed for fuzzing binaries
821subdir('tests/qtest/libqos')
822subdir('tests/qtest/fuzz')
823
824block_mods = []
825softmmu_mods = []
826foreach d, list : modules
827  foreach m, module_ss : list
828    if enable_modules and targetos != 'windows'
829      module_ss = module_ss.apply(config_host, strict: false)
830      sl = static_library(d + '-' + m, [genh, module_ss.sources()],
831                          dependencies: [modulecommon, module_ss.dependencies()], pic: true)
832      if d == 'block'
833        block_mods += sl
834      else
835        softmmu_mods += sl
836      endif
837    else
838      if d == 'block'
839        block_ss.add_all(module_ss)
840      else
841        softmmu_ss.add_all(module_ss)
842      endif
843    endif
844  endforeach
845endforeach
846
847nm = find_program('nm')
848undefsym = find_program('scripts/undefsym.sh')
849block_syms = custom_target('block.syms', output: 'block.syms',
850                             input: [libqemuutil, block_mods],
851                             capture: true,
852                             command: [undefsym, nm, '@INPUT@'])
853qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
854                             input: [libqemuutil, softmmu_mods],
855                             capture: true,
856                             command: [undefsym, nm, '@INPUT@'])
857
858block_ss = block_ss.apply(config_host, strict: false)
859libblock = static_library('block', block_ss.sources() + genh,
860                          dependencies: block_ss.dependencies(),
861                          link_depends: block_syms,
862                          name_suffix: 'fa',
863                          build_by_default: false)
864
865block = declare_dependency(link_whole: [libblock],
866                           link_args: '@block.syms',
867                           dependencies: [crypto, io])
868
869qmp_ss = qmp_ss.apply(config_host, strict: false)
870libqmp = static_library('qmp', qmp_ss.sources() + genh,
871                        dependencies: qmp_ss.dependencies(),
872                        name_suffix: 'fa',
873                        build_by_default: false)
874
875qmp = declare_dependency(link_whole: [libqmp])
876
877foreach m : block_mods + softmmu_mods
878  shared_module(m.name(),
879                name_prefix: '',
880                link_whole: m,
881                install: true,
882                install_dir: config_host['qemu_moddir'])
883endforeach
884
885softmmu_ss.add(authz, block, chardev, crypto, io, qmp)
886common_ss.add(qom, qemuutil)
887
888common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
889common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
890
891common_all = common_ss.apply(config_all, strict: false)
892common_all = static_library('common',
893                            build_by_default: false,
894                            sources: common_all.sources() + genh,
895                            dependencies: common_all.dependencies(),
896                            name_suffix: 'fa')
897
898feature_to_c = find_program('scripts/feature_to_c.sh')
899
900emulators = []
901foreach target : target_dirs
902  config_target = config_target_mak[target]
903  target_name = config_target['TARGET_NAME']
904  arch = config_target['TARGET_BASE_ARCH']
905  arch_srcs = [config_target_h[target]]
906  arch_deps = []
907  c_args = ['-DNEED_CPU_H',
908            '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
909            '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
910  link_args = []
911
912  config_target += config_host
913  target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
914  if targetos == 'linux'
915    target_inc += include_directories('linux-headers', is_system: true)
916  endif
917  if target.endswith('-softmmu')
918    qemu_target_name = 'qemu-system-' + target_name
919    target_type='system'
920    t = target_softmmu_arch[arch].apply(config_target, strict: false)
921    arch_srcs += t.sources()
922    arch_deps += t.dependencies()
923
924    hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
925    hw = hw_arch[hw_dir].apply(config_target, strict: false)
926    arch_srcs += hw.sources()
927    arch_deps += hw.dependencies()
928
929    arch_srcs += config_devices_h[target]
930    link_args += ['@block.syms', '@qemu.syms']
931  else
932    abi = config_target['TARGET_ABI_DIR']
933    target_type='user'
934    qemu_target_name = 'qemu-' + target_name
935    if 'CONFIG_LINUX_USER' in config_target
936      base_dir = 'linux-user'
937      target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
938    else
939      base_dir = 'bsd-user'
940    endif
941    target_inc += include_directories(
942      base_dir,
943      base_dir / abi,
944    )
945    if 'CONFIG_LINUX_USER' in config_target
946      dir = base_dir / abi
947      arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
948      if config_target.has_key('TARGET_SYSTBL_ABI')
949        arch_srcs += \
950          syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
951                                             extra_args : config_target['TARGET_SYSTBL_ABI'])
952      endif
953    endif
954  endif
955
956  if 'TARGET_XML_FILES' in config_target
957    gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
958                                output: target + '-gdbstub-xml.c',
959                                input: files(config_target['TARGET_XML_FILES'].split()),
960                                command: [feature_to_c, '@INPUT@'],
961                                capture: true)
962    arch_srcs += gdbstub_xml
963  endif
964
965  t = target_arch[arch].apply(config_target, strict: false)
966  arch_srcs += t.sources()
967  arch_deps += t.dependencies()
968
969  target_common = common_ss.apply(config_target, strict: false)
970  objects = common_all.extract_objects(target_common.sources())
971  deps = target_common.dependencies()
972
973  target_specific = specific_ss.apply(config_target, strict: false)
974  arch_srcs += target_specific.sources()
975  arch_deps += target_specific.dependencies()
976
977  lib = static_library('qemu-' + target,
978                 sources: arch_srcs + genh,
979                 objects: objects,
980                 include_directories: target_inc,
981                 c_args: c_args,
982                 build_by_default: false,
983                 name_suffix: 'fa')
984
985  if target.endswith('-softmmu')
986    execs = [{
987      'name': 'qemu-system-' + target_name,
988      'gui': false,
989      'sources': files('softmmu/main.c'),
990      'dependencies': []
991    }]
992    if targetos == 'windows' and (sdl.found() or gtk.found())
993      execs += [{
994        'name': 'qemu-system-' + target_name + 'w',
995        'gui': true,
996        'sources': files('softmmu/main.c'),
997        'dependencies': []
998      }]
999    endif
1000    if config_host.has_key('CONFIG_FUZZ')
1001      specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
1002      execs += [{
1003        'name': 'qemu-fuzz-' + target_name,
1004        'gui': false,
1005        'sources': specific_fuzz.sources(),
1006        'dependencies': specific_fuzz.dependencies(),
1007        'link_depends': [files('tests/qtest/fuzz/fork_fuzz.ld')],
1008      }]
1009    endif
1010  else
1011    execs = [{
1012      'name': 'qemu-' + target_name,
1013      'gui': false,
1014      'sources': [],
1015      'dependencies': []
1016    }]
1017  endif
1018  foreach exe: execs
1019    emulators += executable(exe['name'], exe['sources'],
1020               install: true,
1021               c_args: c_args,
1022               dependencies: arch_deps + deps + exe['dependencies'],
1023               objects: lib.extract_all_objects(recursive: true),
1024               link_language: link_language,
1025               link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
1026               link_args: link_args,
1027               gui_app: exe['gui'])
1028
1029    if 'CONFIG_TRACE_SYSTEMTAP' in config_host
1030      foreach stp: [
1031        {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe_name, 'install': false},
1032        {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe_name, 'install': true},
1033        {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
1034        {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
1035      ]
1036        custom_target(exe_name + stp['ext'],
1037                      input: trace_events_all,
1038                      output: exe_name + stp['ext'],
1039                      capture: true,
1040                      install: stp['install'],
1041                      install_dir: config_host['qemu_datadir'] / '../systemtap/tapset',
1042                      command: [
1043                        tracetool, '--group=all', '--format=' + stp['fmt'],
1044                        '--binary=' + stp['bin'],
1045                        '--target-name=' + target_name,
1046                        '--target-type=' + target_type,
1047                        '--probe-prefix=qemu.' + target_type + '.' + target_name,
1048                        '@INPUT@',
1049                      ])
1050      endforeach
1051    endif
1052  endforeach
1053endforeach
1054
1055# Other build targets
1056
1057if 'CONFIG_PLUGIN' in config_host
1058  install_headers('include/qemu/qemu-plugin.h')
1059endif
1060
1061if 'CONFIG_GUEST_AGENT' in config_host
1062  subdir('qga')
1063endif
1064
1065if have_tools
1066  qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
1067             dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
1068  qemu_io = executable('qemu-io', files('qemu-io.c'),
1069             dependencies: [block, qemuutil], install: true)
1070  qemu_block_tools = [qemu_img, qemu_io]
1071  if targetos == 'linux' or targetos == 'sunos' or targetos.endswith('bsd')
1072    qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
1073               dependencies: [block, qemuutil], install: true)
1074    qemu_block_tools += [qemu_nbd]
1075  endif
1076
1077  subdir('storage-daemon')
1078  subdir('contrib/rdmacm-mux')
1079  subdir('contrib/elf2dmp')
1080
1081  if 'CONFIG_XKBCOMMON' in config_host
1082    executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c'),
1083               dependencies: [qemuutil, xkbcommon], install: true)
1084  endif
1085
1086  executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
1087             dependencies: qemuutil,
1088             install: true)
1089
1090  if 'CONFIG_VHOST_USER' in config_host
1091    subdir('contrib/libvhost-user')
1092    subdir('contrib/vhost-user-blk')
1093    if 'CONFIG_LINUX' in config_host
1094      subdir('contrib/vhost-user-gpu')
1095    endif
1096    subdir('contrib/vhost-user-input')
1097    subdir('contrib/vhost-user-scsi')
1098  endif
1099
1100  if targetos == 'linux'
1101    executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
1102               dependencies: [qemuutil, libcap_ng],
1103               install: true,
1104               install_dir: get_option('libexecdir'))
1105
1106    executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
1107               dependencies: [authz, crypto, io, qom, qemuutil,
1108                              libcap_ng, libudev, libmpathpersist],
1109               install: true)
1110  endif
1111
1112  if 'CONFIG_IVSHMEM' in config_host
1113    subdir('contrib/ivshmem-client')
1114    subdir('contrib/ivshmem-server')
1115  endif
1116endif
1117
1118subdir('tools')
1119subdir('pc-bios')
1120subdir('tests')
1121subdir('docs')
1122if 'CONFIG_GTK' in config_host
1123  subdir('po')
1124endif
1125
1126if build_docs
1127  makeinfo = find_program('makeinfo', required: build_docs)
1128
1129  docs_inc = [
1130    '-I', meson.current_source_dir(),
1131    '-I', meson.current_build_dir() / 'docs',
1132    '-I', '@OUTDIR@',
1133  ]
1134
1135  version_texi = configure_file(output: 'version.texi',
1136                              input: 'version.texi.in',
1137                              configuration: {'VERSION': meson.project_version(),
1138                                              'qemu_confdir': config_host['qemu_confdir']})
1139
1140  texi = {
1141    'qemu-qmp-ref': ['docs/interop/qemu-qmp-ref.texi', qapi_doc_texi, version_texi],
1142  }
1143  if 'CONFIG_GUEST_AGENT' in config_host
1144    texi += {'qemu-ga-ref': ['docs/interop/qemu-ga-ref.texi', qga_qapi_doc_texi, version_texi]}
1145  endif
1146
1147  if makeinfo.found()
1148    cmd = [
1149      'env', 'LC_ALL=C', makeinfo, '--no-split', '--number-sections', docs_inc,
1150      '@INPUT0@', '-o', '@OUTPUT@',
1151    ]
1152    foreach ext, args: {
1153        'info': [],
1154        'html': ['--no-headers', '--html'],
1155        'txt': ['--no-headers', '--plaintext'],
1156    }
1157      t = []
1158      foreach doc, input: texi
1159        output = doc + '.' + ext
1160        t += custom_target(output,
1161                      input: input,
1162                      output: output,
1163                      install: true,
1164                      install_dir: config_host['qemu_docdir'] / 'interop',
1165                      command: cmd + args)
1166      endforeach
1167      alias_target(ext, t)
1168    endforeach
1169  endif
1170
1171  texi2pdf = find_program('texi2pdf', required: false)
1172
1173  if texi2pdf.found()
1174    pdfs = []
1175    foreach doc, input: texi
1176      output = doc + '.pdf'
1177      pdfs += custom_target(output,
1178                    input: input,
1179                    output: output,
1180                    command: [texi2pdf, '-q', docs_inc, '@INPUT0@', '-o', '@OUTPUT@'],
1181                    build_by_default: false)
1182    endforeach
1183    alias_target('pdf', pdfs)
1184  endif
1185
1186  texi2pod = find_program('scripts/texi2pod.pl')
1187  pod2man = find_program('pod2man', required: build_docs)
1188
1189  if pod2man.found()
1190    foreach doc, input: texi
1191      man = doc + '.7'
1192      pod = custom_target(man + '.pod',
1193                          input: input,
1194                          output: man + '.pod',
1195                          command: [texi2pod,
1196                                    '-DVERSION="' + meson.project_version() + '"',
1197                                    '-DCONFDIR="' + config_host['qemu_confdir'] + '"',
1198                                    '@INPUT0@', '@OUTPUT@'])
1199      man = custom_target(man,
1200                          input: pod,
1201                          output: man,
1202                          capture: true,
1203                          install: true,
1204                          install_dir: config_host['mandir'] / 'man7',
1205                          command: [pod2man, '--utf8', '--section=7', '--center=" "',
1206                                    '--release=" "', '@INPUT@'])
1207    endforeach
1208  endif
1209endif
1210
1211summary_info = {}
1212summary_info += {'Install prefix':    config_host['prefix']}
1213summary_info += {'BIOS directory':    config_host['qemu_datadir']}
1214summary_info += {'firmware path':     config_host['qemu_firmwarepath']}
1215summary_info += {'binary directory':  config_host['bindir']}
1216summary_info += {'library directory': config_host['libdir']}
1217summary_info += {'module directory':  config_host['qemu_moddir']}
1218summary_info += {'libexec directory': config_host['libexecdir']}
1219summary_info += {'include directory': config_host['includedir']}
1220summary_info += {'config directory':  config_host['sysconfdir']}
1221if targetos != 'windows'
1222  summary_info += {'local state directory': config_host['qemu_localstatedir']}
1223  summary_info += {'Manual directory':      config_host['mandir']}
1224else
1225  summary_info += {'local state directory': 'queried at runtime'}
1226endif
1227summary_info += {'Build directory':   meson.current_build_dir()}
1228summary_info += {'Source path':       meson.current_source_dir()}
1229summary_info += {'GIT binary':        config_host['GIT']}
1230summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
1231summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
1232summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
1233if link_language == 'cpp'
1234  summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
1235else
1236  summary_info += {'C++ compiler':      false}
1237endif
1238if targetos == 'darwin'
1239  summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
1240endif
1241summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
1242summary_info += {'CFLAGS':            config_host['CFLAGS']}
1243summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
1244summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
1245summary_info += {'make':              config_host['MAKE']}
1246summary_info += {'install':           config_host['INSTALL']}
1247summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
1248summary_info += {'sphinx-build':      config_host['SPHINX_BUILD']}
1249summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
1250# TODO: add back version
1251summary_info += {'slirp support':     config_host.has_key('CONFIG_SLIRP')}
1252if config_host.has_key('CONFIG_SLIRP')
1253  summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
1254endif
1255summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
1256if config_host.has_key('CONFIG_MODULES')
1257  summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
1258endif
1259summary_info += {'host CPU':          cpu}
1260summary_info += {'host endianness':   build_machine.endian()}
1261summary_info += {'target list':       config_host['TARGET_DIRS']}
1262summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
1263summary_info += {'sparse enabled':    meson.get_compiler('c').cmd_array().contains('cgcc')}
1264summary_info += {'strip binaries':    get_option('strip')}
1265summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
1266summary_info += {'static build':      config_host.has_key('CONFIG_TOOLS')}
1267if targetos == 'darwin'
1268  summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
1269endif
1270# TODO: add back version
1271summary_info += {'SDL support':       sdl.found()}
1272summary_info += {'SDL image support': sdl_image.found()}
1273# TODO: add back version
1274summary_info += {'GTK support':       config_host.has_key('CONFIG_GTK')}
1275summary_info += {'GTK GL support':    config_host.has_key('CONFIG_GTK_GL')}
1276# TODO: add back version
1277summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
1278summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
1279summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
1280# TODO: add back version
1281summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
1282if config_host.has_key('CONFIG_GCRYPT')
1283   summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
1284   summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1285endif
1286# TODO: add back version
1287summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
1288if config_host.has_key('CONFIG_NETTLE')
1289   summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1290endif
1291summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
1292summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
1293summary_info += {'iconv support':     config_host.has_key('CONFIG_ICONV')}
1294summary_info += {'curses support':    config_host.has_key('CONFIG_CURSES')}
1295# TODO: add back version
1296summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
1297summary_info += {'curl support':      config_host.has_key('CONFIG_CURL')}
1298summary_info += {'mingw32 support':   targetos == 'windows'}
1299summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
1300summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
1301summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
1302summary_info += {'VirtFS support':    config_host.has_key('CONFIG_VIRTFS')}
1303summary_info += {'Multipath support': config_host.has_key('CONFIG_MPATH')}
1304summary_info += {'VNC support':       vnc.found()}
1305if vnc.found()
1306  summary_info += {'VNC SASL support':  sasl.found()}
1307  summary_info += {'VNC JPEG support':  jpeg.found()}
1308  summary_info += {'VNC PNG support':   png.found()}
1309endif
1310summary_info += {'xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
1311if config_host.has_key('CONFIG_XEN_BACKEND')
1312  summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
1313endif
1314summary_info += {'brlapi support':    config_host.has_key('CONFIG_BRLAPI')}
1315summary_info += {'Documentation':     config_host.has_key('BUILD_DOCS')}
1316summary_info += {'PIE':               get_option('b_pie')}
1317summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
1318summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
1319summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
1320summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
1321summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
1322summary_info += {'Install blobs':     config_host.has_key('INSTALL_BLOBS')}
1323# TODO: add back KVM/HAX/HVF/WHPX/TCG
1324#summary_info += {'KVM support':       have_kvm'}
1325#summary_info += {'HAX support':       have_hax'}
1326#summary_info += {'HVF support':       have_hvf'}
1327#summary_info += {'WHPX support':      have_whpx'}
1328#summary_info += {'TCG support':       have_tcg'}
1329#if get_option('tcg')
1330#  summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
1331#  summary_info += {'TCG interpreter':   config_host.has_key('CONFIG_TCG_INTERPRETER')}
1332#endif
1333summary_info += {'malloc trim support': config_host.has_key('CONFIG_MALLOC_TRIM')}
1334summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
1335summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
1336summary_info += {'fdt support':       config_host.has_key('CONFIG_FDT')}
1337summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
1338summary_info += {'preadv support':    config_host.has_key('CONFIG_PREADV')}
1339summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
1340summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
1341summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
1342summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
1343summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
1344summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
1345summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
1346summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
1347summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
1348summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_KERNEL')}
1349summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
1350summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
1351summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
1352if config_host['TRACE_BACKENDS'].split().contains('simple')
1353  summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
1354endif
1355# TODO: add back protocol and server version
1356summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
1357summary_info += {'rbd support':       config_host.has_key('CONFIG_RBD')}
1358summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
1359summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
1360summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
1361summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
1362summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
1363summary_info += {'OpenGL dmabufs':    config_host.has_key('CONFIG_OPENGL_DMABUF')}
1364summary_info += {'libiscsi support':  config_host.has_key('CONFIG_LIBISCSI')}
1365summary_info += {'libnfs support':    config_host.has_key('CONFIG_LIBNFS')}
1366summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
1367if targetos == 'windows'
1368  if 'WIN_SDK' in config_host
1369    summary_info += {'Windows SDK':       config_host['WIN_SDK']}
1370  endif
1371  summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
1372  summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
1373  summary_info += {'QGA MSI support':   config_host.has_key('CONFIG_QGA_MSI_ENABLED')}
1374endif
1375summary_info += {'seccomp support':   config_host.has_key('CONFIG_SECCOMP')}
1376summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
1377summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
1378summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
1379summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
1380summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
1381summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
1382summary_info += {'gcov':              get_option('b_coverage')}
1383summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
1384summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
1385summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
1386summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
1387summary_info += {'lzo support':       config_host.has_key('CONFIG_LZO')}
1388summary_info += {'snappy support':    config_host.has_key('CONFIG_SNAPPY')}
1389summary_info += {'bzip2 support':     config_host.has_key('CONFIG_BZIP2')}
1390summary_info += {'lzfse support':     config_host.has_key('CONFIG_LZFSE')}
1391summary_info += {'zstd support':      config_host.has_key('CONFIG_ZSTD')}
1392summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
1393summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
1394summary_info += {'tcmalloc support':  config_host.has_key('CONFIG_TCMALLOC')}
1395summary_info += {'jemalloc support':  config_host.has_key('CONFIG_JEMALLOC')}
1396summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
1397summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
1398summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
1399summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
1400summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
1401summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
1402summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
1403summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
1404summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
1405summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
1406summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
1407summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
1408summary_info += {'capstone':          config_host.has_key('CONFIG_CAPSTONE')}
1409summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
1410summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
1411summary_info += {'libudev':           config_host.has_key('CONFIG_LIBUDEV')}
1412summary_info += {'default devices':   config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
1413summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
1414summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
1415if config_host.has_key('HAVE_GDB_BIN')
1416  summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
1417endif
1418summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
1419summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
1420summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
1421summary(summary_info, bool_yn: true)
1422
1423if not supported_cpus.contains(cpu)
1424  message()
1425  warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
1426  message()
1427  message('CPU host architecture ' + cpu + ' support is not currently maintained.')
1428  message('The QEMU project intends to remove support for this host CPU in')
1429  message('a future release if nobody volunteers to maintain it and to')
1430  message('provide a build host for our continuous integration setup.')
1431  message('configure has succeeded and you can continue to build, but')
1432  message('if you care about QEMU on this platform you should contact')
1433  message('us upstream at qemu-devel@nongnu.org.')
1434endif
1435
1436if not supported_oses.contains(targetos)
1437  message()
1438  warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
1439  message()
1440  message('Host OS ' + targetos + 'support is not currently maintained.')
1441  message('The QEMU project intends to remove support for this host OS in')
1442  message('a future release if nobody volunteers to maintain it and to')
1443  message('provide a build host for our continuous integration setup.')
1444  message('configure has succeeded and you can continue to build, but')
1445  message('if you care about QEMU on this platform you should contact')
1446  message('us upstream at qemu-devel@nongnu.org.')
1447endif
1448