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