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