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