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