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