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