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