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