xref: /openbmc/qemu/meson.build (revision 660f79309303d696531ffb394719dfab3e0c42c0)
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')
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
413tasn1 = not_found
414if 'CONFIG_TASN1' in config_host
415  tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(),
416                             link_args: config_host['TASN1_LIBS'].split())
417endif
418keyutils = dependency('libkeyutils', required: false,
419                      method: 'pkg-config', static: enable_static)
420
421has_gettid = cc.has_function('gettid')
422
423# Create config-host.h
424
425config_host_data.set('CONFIG_SDL', sdl.found())
426config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
427config_host_data.set('CONFIG_VNC', vnc.found())
428config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
429config_host_data.set('CONFIG_VNC_PNG', png.found())
430config_host_data.set('CONFIG_VNC_SASL', sasl.found())
431config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
432config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
433config_host_data.set('CONFIG_GETTID', has_gettid)
434config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
435config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
436config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
437config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
438
439arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
440strings = ['HOST_DSOSUF', 'CONFIG_IASL', 'qemu_confdir', 'qemu_datadir',
441           'qemu_moddir', 'qemu_localstatedir', 'qemu_helperdir', 'qemu_localedir',
442           'qemu_icondir', 'qemu_desktopdir', 'qemu_firmwarepath']
443foreach k, v: config_host
444  if arrays.contains(k)
445    if v != ''
446      v = '"' + '", "'.join(v.split()) + '", '
447    endif
448    config_host_data.set(k, v)
449  elif k == 'ARCH'
450    config_host_data.set('HOST_' + v.to_upper(), 1)
451  elif strings.contains(k)
452    if not k.startswith('CONFIG_')
453      k = 'CONFIG_' + k.to_upper()
454    endif
455    config_host_data.set_quoted(k, v)
456  elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
457    config_host_data.set(k, v == 'y' ? 1 : v)
458  endif
459endforeach
460genh += configure_file(output: 'config-host.h', configuration: config_host_data)
461
462minikconf = find_program('scripts/minikconf.py')
463config_all_devices = {}
464config_devices_mak_list = []
465config_devices_h = {}
466config_target_h = {}
467config_target_mak = {}
468kconfig_external_symbols = [
469  'CONFIG_KVM',
470  'CONFIG_XEN',
471  'CONFIG_TPM',
472  'CONFIG_SPICE',
473  'CONFIG_IVSHMEM',
474  'CONFIG_OPENGL',
475  'CONFIG_X11',
476  'CONFIG_VHOST_USER',
477  'CONFIG_VHOST_KERNEL',
478  'CONFIG_VIRTFS',
479  'CONFIG_LINUX',
480  'CONFIG_PVRDMA',
481]
482ignored = ['TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_DIRS']
483foreach target : target_dirs
484  config_target = keyval.load(meson.current_build_dir() / target / 'config-target.mak')
485
486  config_target_data = configuration_data()
487  foreach k, v: config_target
488    if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
489      # do nothing
490    elif ignored.contains(k)
491      # do nothing
492    elif k == 'TARGET_BASE_ARCH'
493      config_target_data.set('TARGET_' + v.to_upper(), 1)
494    elif k == 'TARGET_NAME'
495      config_target_data.set_quoted(k, v)
496    elif v == 'y'
497      config_target_data.set(k, 1)
498    else
499      config_target_data.set(k, v)
500    endif
501  endforeach
502  config_target_h += {target: configure_file(output: target + '-config-target.h',
503                                               configuration: config_target_data)}
504
505  if target.endswith('-softmmu')
506    base_kconfig = []
507    foreach sym : kconfig_external_symbols
508      if sym in config_target or sym in config_host
509        base_kconfig += '@0@=y'.format(sym)
510      endif
511    endforeach
512
513    config_devices_mak = target + '-config-devices.mak'
514    config_devices_mak = configure_file(
515      input: ['default-configs' / target + '.mak', 'Kconfig'],
516      output: config_devices_mak,
517      depfile: config_devices_mak + '.d',
518      capture: true,
519      command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'],
520                config_devices_mak, '@DEPFILE@', '@INPUT@',
521                base_kconfig])
522
523    config_devices_data = configuration_data()
524    config_devices = keyval.load(config_devices_mak)
525    foreach k, v: config_devices
526      config_devices_data.set(k, 1)
527    endforeach
528    config_devices_mak_list += config_devices_mak
529    config_devices_h += {target: configure_file(output: target + '-config-devices.h',
530                                                configuration: config_devices_data)}
531    config_target += config_devices
532    config_all_devices += config_devices
533  endif
534  config_target_mak += {target: config_target}
535endforeach
536
537# This configuration is used to build files that are shared by
538# multiple binaries, and then extracted out of the "common"
539# static_library target.
540#
541# We do not use all_sources()/all_dependencies(), because it would
542# build literally all source files, including devices only used by
543# targets that are not built for this compilation.  The CONFIG_ALL
544# pseudo symbol replaces it.
545
546config_all = config_all_devices
547config_all += config_host
548config_all += config_all_disas
549config_all += {
550  'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
551  'CONFIG_SOFTMMU': have_system,
552  'CONFIG_USER_ONLY': have_user,
553  'CONFIG_ALL': true,
554}
555
556# Generators
557
558hxtool = find_program('scripts/hxtool')
559shaderinclude = find_program('scripts/shaderinclude.pl')
560qapi_gen = find_program('scripts/qapi-gen.py')
561qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
562                     meson.source_root() / 'scripts/qapi/commands.py',
563                     meson.source_root() / 'scripts/qapi/common.py',
564                     meson.source_root() / 'scripts/qapi/doc.py',
565                     meson.source_root() / 'scripts/qapi/error.py',
566                     meson.source_root() / 'scripts/qapi/events.py',
567                     meson.source_root() / 'scripts/qapi/expr.py',
568                     meson.source_root() / 'scripts/qapi/gen.py',
569                     meson.source_root() / 'scripts/qapi/introspect.py',
570                     meson.source_root() / 'scripts/qapi/parser.py',
571                     meson.source_root() / 'scripts/qapi/schema.py',
572                     meson.source_root() / 'scripts/qapi/source.py',
573                     meson.source_root() / 'scripts/qapi/types.py',
574                     meson.source_root() / 'scripts/qapi/visit.py',
575                     meson.source_root() / 'scripts/qapi/common.py',
576                     meson.source_root() / 'scripts/qapi/doc.py',
577                     meson.source_root() / 'scripts/qapi-gen.py'
578]
579
580tracetool = [
581  python, files('scripts/tracetool.py'),
582   '--backend=' + config_host['TRACE_BACKENDS']
583]
584
585qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
586                    meson.current_source_dir(),
587                    config_host['PKGVERSION'], meson.project_version()]
588qemu_version = custom_target('qemu-version.h',
589                             output: 'qemu-version.h',
590                             command: qemu_version_cmd,
591                             capture: true,
592                             build_by_default: true,
593                             build_always_stale: true)
594genh += qemu_version
595
596hxdep = []
597hx_headers = [
598  ['qemu-options.hx', 'qemu-options.def'],
599  ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
600]
601if have_system
602  hx_headers += [
603    ['hmp-commands.hx', 'hmp-commands.h'],
604    ['hmp-commands-info.hx', 'hmp-commands-info.h'],
605  ]
606endif
607foreach d : hx_headers
608  hxdep += custom_target(d[1],
609                input: files(d[0]),
610                output: d[1],
611                capture: true,
612                build_by_default: true, # to be removed when added to a target
613                command: [hxtool, '-h', '@INPUT0@'])
614endforeach
615genh += hxdep
616
617# Collect sourcesets.
618
619util_ss = ss.source_set()
620stub_ss = ss.source_set()
621trace_ss = ss.source_set()
622block_ss = ss.source_set()
623blockdev_ss = ss.source_set()
624qmp_ss = ss.source_set()
625common_ss = ss.source_set()
626softmmu_ss = ss.source_set()
627user_ss = ss.source_set()
628bsd_user_ss = ss.source_set()
629linux_user_ss = ss.source_set()
630specific_ss = ss.source_set()
631specific_fuzz_ss = ss.source_set()
632
633modules = {}
634hw_arch = {}
635target_arch = {}
636target_softmmu_arch = {}
637
638###############
639# Trace files #
640###############
641
642# TODO: add each directory to the subdirs from its own meson.build, once
643# we have those
644trace_events_subdirs = [
645  'accel/kvm',
646  'accel/tcg',
647  'crypto',
648  'monitor',
649]
650if have_user
651  trace_events_subdirs += [ 'linux-user' ]
652endif
653if have_block
654  trace_events_subdirs += [
655    'authz',
656    'block',
657    'io',
658    'nbd',
659    'scsi',
660  ]
661endif
662if have_system
663  trace_events_subdirs += [
664    'audio',
665    'backends',
666    'backends/tpm',
667    'chardev',
668    'hw/9pfs',
669    'hw/acpi',
670    'hw/alpha',
671    'hw/arm',
672    'hw/audio',
673    'hw/block',
674    'hw/block/dataplane',
675    'hw/char',
676    'hw/display',
677    'hw/dma',
678    'hw/hppa',
679    'hw/hyperv',
680    'hw/i2c',
681    'hw/i386',
682    'hw/i386/xen',
683    'hw/ide',
684    'hw/input',
685    'hw/intc',
686    'hw/isa',
687    'hw/mem',
688    'hw/mips',
689    'hw/misc',
690    'hw/misc/macio',
691    'hw/net',
692    'hw/nvram',
693    'hw/pci',
694    'hw/pci-host',
695    'hw/ppc',
696    'hw/rdma',
697    'hw/rdma/vmw',
698    'hw/rtc',
699    'hw/s390x',
700    'hw/scsi',
701    'hw/sd',
702    'hw/sparc',
703    'hw/sparc64',
704    'hw/ssi',
705    'hw/timer',
706    'hw/tpm',
707    'hw/usb',
708    'hw/vfio',
709    'hw/virtio',
710    'hw/watchdog',
711    'hw/xen',
712    'hw/gpio',
713    'hw/riscv',
714    'migration',
715    'net',
716    'ui',
717  ]
718endif
719trace_events_subdirs += [
720  'hw/core',
721  'qapi',
722  'qom',
723  'target/arm',
724  'target/hppa',
725  'target/i386',
726  'target/mips',
727  'target/ppc',
728  'target/riscv',
729  'target/s390x',
730  'target/sparc',
731  'util',
732]
733
734subdir('qapi')
735subdir('qobject')
736subdir('stubs')
737subdir('trace')
738subdir('util')
739subdir('qom')
740subdir('authz')
741subdir('crypto')
742subdir('ui')
743
744
745if enable_modules
746  libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
747  modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
748endif
749
750# Build targets from sourcesets
751
752stub_ss = stub_ss.apply(config_all, strict: false)
753
754util_ss.add_all(trace_ss)
755util_ss = util_ss.apply(config_all, strict: false)
756libqemuutil = static_library('qemuutil',
757                             sources: util_ss.sources() + stub_ss.sources() + genh,
758                             dependencies: [util_ss.dependencies(), m, glib, socket])
759qemuutil = declare_dependency(link_with: libqemuutil,
760                              sources: genh + version_res)
761
762decodetree = generator(find_program('scripts/decodetree.py'),
763                       output: 'decode-@BASENAME@.c.inc',
764                       arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
765
766subdir('audio')
767subdir('io')
768subdir('chardev')
769subdir('fsdev')
770subdir('libdecnumber')
771subdir('target')
772subdir('dump')
773
774block_ss.add(files(
775  'block.c',
776  'blockjob.c',
777  'job.c',
778  'qemu-io-cmds.c',
779))
780block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
781
782subdir('nbd')
783subdir('scsi')
784subdir('block')
785
786blockdev_ss.add(files(
787  'blockdev.c',
788  'blockdev-nbd.c',
789  'iothread.c',
790  'job-qmp.c',
791))
792
793# os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
794# os-win32.c does not
795blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
796softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
797
798softmmu_ss.add_all(blockdev_ss)
799softmmu_ss.add(files(
800  'bootdevice.c',
801  'dma-helpers.c',
802  'qdev-monitor.c',
803), sdl)
804
805softmmu_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c'))
806softmmu_ss.add(when: 'CONFIG_SECCOMP', if_true: [files('qemu-seccomp.c'), seccomp])
807softmmu_ss.add(when: ['CONFIG_FDT', fdt],  if_true: [files('device_tree.c')])
808
809common_ss.add(files('cpus-common.c'))
810
811subdir('softmmu')
812
813specific_ss.add(files('disas.c', 'exec.c', 'gdbstub.c'), capstone, libpmem, libdaxctl)
814specific_ss.add(files('exec-vary.c'))
815specific_ss.add(when: 'CONFIG_TCG', if_true: files(
816  'fpu/softfloat.c',
817  'tcg/optimize.c',
818  'tcg/tcg-common.c',
819  'tcg/tcg-op-gvec.c',
820  'tcg/tcg-op-vec.c',
821  'tcg/tcg-op.c',
822  'tcg/tcg.c',
823))
824specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
825
826subdir('backends')
827subdir('disas')
828subdir('migration')
829subdir('monitor')
830subdir('net')
831subdir('replay')
832subdir('hw')
833subdir('accel')
834subdir('plugins')
835subdir('bsd-user')
836subdir('linux-user')
837
838bsd_user_ss.add(files('gdbstub.c'))
839specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
840
841linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
842specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
843
844# needed for fuzzing binaries
845subdir('tests/qtest/libqos')
846subdir('tests/qtest/fuzz')
847
848block_mods = []
849softmmu_mods = []
850foreach d, list : modules
851  foreach m, module_ss : list
852    if enable_modules and targetos != 'windows'
853      module_ss = module_ss.apply(config_host, strict: false)
854      sl = static_library(d + '-' + m, [genh, module_ss.sources()],
855                          dependencies: [modulecommon, module_ss.dependencies()], pic: true)
856      if d == 'block'
857        block_mods += sl
858      else
859        softmmu_mods += sl
860      endif
861    else
862      if d == 'block'
863        block_ss.add_all(module_ss)
864      else
865        softmmu_ss.add_all(module_ss)
866      endif
867    endif
868  endforeach
869endforeach
870
871nm = find_program('nm')
872undefsym = find_program('scripts/undefsym.sh')
873block_syms = custom_target('block.syms', output: 'block.syms',
874                             input: [libqemuutil, block_mods],
875                             capture: true,
876                             command: [undefsym, nm, '@INPUT@'])
877qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
878                             input: [libqemuutil, softmmu_mods],
879                             capture: true,
880                             command: [undefsym, nm, '@INPUT@'])
881
882block_ss = block_ss.apply(config_host, strict: false)
883libblock = static_library('block', block_ss.sources() + genh,
884                          dependencies: block_ss.dependencies(),
885                          link_depends: block_syms,
886                          name_suffix: 'fa',
887                          build_by_default: false)
888
889block = declare_dependency(link_whole: [libblock],
890                           link_args: '@block.syms',
891                           dependencies: [crypto, io])
892
893qmp_ss = qmp_ss.apply(config_host, strict: false)
894libqmp = static_library('qmp', qmp_ss.sources() + genh,
895                        dependencies: qmp_ss.dependencies(),
896                        name_suffix: 'fa',
897                        build_by_default: false)
898
899qmp = declare_dependency(link_whole: [libqmp])
900
901foreach m : block_mods + softmmu_mods
902  shared_module(m.name(),
903                name_prefix: '',
904                link_whole: m,
905                install: true,
906                install_dir: config_host['qemu_moddir'])
907endforeach
908
909softmmu_ss.add(authz, block, chardev, crypto, io, qmp)
910common_ss.add(qom, qemuutil)
911
912common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
913common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
914
915common_all = common_ss.apply(config_all, strict: false)
916common_all = static_library('common',
917                            build_by_default: false,
918                            sources: common_all.sources() + genh,
919                            dependencies: common_all.dependencies(),
920                            name_suffix: 'fa')
921
922feature_to_c = find_program('scripts/feature_to_c.sh')
923
924emulators = []
925foreach target : target_dirs
926  config_target = config_target_mak[target]
927  target_name = config_target['TARGET_NAME']
928  arch = config_target['TARGET_BASE_ARCH']
929  arch_srcs = [config_target_h[target]]
930  arch_deps = []
931  c_args = ['-DNEED_CPU_H',
932            '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
933            '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
934  link_args = []
935
936  config_target += config_host
937  target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
938  if targetos == 'linux'
939    target_inc += include_directories('linux-headers', is_system: true)
940  endif
941  if target.endswith('-softmmu')
942    qemu_target_name = 'qemu-system-' + target_name
943    target_type='system'
944    t = target_softmmu_arch[arch].apply(config_target, strict: false)
945    arch_srcs += t.sources()
946    arch_deps += t.dependencies()
947
948    hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
949    hw = hw_arch[hw_dir].apply(config_target, strict: false)
950    arch_srcs += hw.sources()
951    arch_deps += hw.dependencies()
952
953    arch_srcs += config_devices_h[target]
954    link_args += ['@block.syms', '@qemu.syms']
955  else
956    abi = config_target['TARGET_ABI_DIR']
957    target_type='user'
958    qemu_target_name = 'qemu-' + target_name
959    if 'CONFIG_LINUX_USER' in config_target
960      base_dir = 'linux-user'
961      target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
962    else
963      base_dir = 'bsd-user'
964    endif
965    target_inc += include_directories(
966      base_dir,
967      base_dir / abi,
968    )
969    if 'CONFIG_LINUX_USER' in config_target
970      dir = base_dir / abi
971      arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
972      if config_target.has_key('TARGET_SYSTBL_ABI')
973        arch_srcs += \
974          syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
975                                             extra_args : config_target['TARGET_SYSTBL_ABI'])
976      endif
977    endif
978  endif
979
980  if 'TARGET_XML_FILES' in config_target
981    gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
982                                output: target + '-gdbstub-xml.c',
983                                input: files(config_target['TARGET_XML_FILES'].split()),
984                                command: [feature_to_c, '@INPUT@'],
985                                capture: true)
986    arch_srcs += gdbstub_xml
987  endif
988
989  t = target_arch[arch].apply(config_target, strict: false)
990  arch_srcs += t.sources()
991  arch_deps += t.dependencies()
992
993  target_common = common_ss.apply(config_target, strict: false)
994  objects = common_all.extract_objects(target_common.sources())
995  deps = target_common.dependencies()
996
997  target_specific = specific_ss.apply(config_target, strict: false)
998  arch_srcs += target_specific.sources()
999  arch_deps += target_specific.dependencies()
1000
1001  lib = static_library('qemu-' + target,
1002                 sources: arch_srcs + genh,
1003                 dependencies: arch_deps,
1004                 objects: objects,
1005                 include_directories: target_inc,
1006                 c_args: c_args,
1007                 build_by_default: false,
1008                 name_suffix: 'fa')
1009
1010  if target.endswith('-softmmu')
1011    execs = [{
1012      'name': 'qemu-system-' + target_name,
1013      'gui': false,
1014      'sources': files('softmmu/main.c'),
1015      'dependencies': []
1016    }]
1017    if targetos == 'windows' and (sdl.found() or gtk.found())
1018      execs += [{
1019        'name': 'qemu-system-' + target_name + 'w',
1020        'gui': true,
1021        'sources': files('softmmu/main.c'),
1022        'dependencies': []
1023      }]
1024    endif
1025    if config_host.has_key('CONFIG_FUZZ')
1026      specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
1027      execs += [{
1028        'name': 'qemu-fuzz-' + target_name,
1029        'gui': false,
1030        'sources': specific_fuzz.sources(),
1031        'dependencies': specific_fuzz.dependencies(),
1032        'link_depends': [files('tests/qtest/fuzz/fork_fuzz.ld')],
1033      }]
1034    endif
1035  else
1036    execs = [{
1037      'name': 'qemu-' + target_name,
1038      'gui': false,
1039      'sources': [],
1040      'dependencies': []
1041    }]
1042  endif
1043  foreach exe: execs
1044    emulators += executable(exe['name'], exe['sources'],
1045               install: true,
1046               c_args: c_args,
1047               dependencies: arch_deps + deps + exe['dependencies'],
1048               objects: lib.extract_all_objects(recursive: true),
1049               link_language: link_language,
1050               link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
1051               link_args: link_args,
1052               gui_app: exe['gui'])
1053
1054    if 'CONFIG_TRACE_SYSTEMTAP' in config_host
1055      foreach stp: [
1056        {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
1057        {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
1058        {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
1059        {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
1060      ]
1061        custom_target(exe['name'] + stp['ext'],
1062                      input: trace_events_all,
1063                      output: exe['name'] + stp['ext'],
1064                      capture: true,
1065                      install: stp['install'],
1066                      install_dir: qemu_datadir / '../systemtap/tapset',
1067                      command: [
1068                        tracetool, '--group=all', '--format=' + stp['fmt'],
1069                        '--binary=' + stp['bin'],
1070                        '--target-name=' + target_name,
1071                        '--target-type=' + target_type,
1072                        '--probe-prefix=qemu.' + target_type + '.' + target_name,
1073                        '@INPUT@',
1074                      ])
1075      endforeach
1076    endif
1077  endforeach
1078endforeach
1079
1080# Other build targets
1081
1082if 'CONFIG_PLUGIN' in config_host
1083  install_headers('include/qemu/qemu-plugin.h')
1084endif
1085
1086if 'CONFIG_GUEST_AGENT' in config_host
1087  subdir('qga')
1088endif
1089
1090# Don't build qemu-keymap if xkbcommon is not explicitly enabled
1091# when we don't build tools or system
1092if xkbcommon.found()
1093  # used for the update-keymaps target, so include rules even if !have_tools
1094  qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
1095                           dependencies: [qemuutil, xkbcommon], install: have_tools)
1096endif
1097
1098qemu_block_tools = []
1099if have_tools
1100  qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
1101             dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
1102  qemu_io = executable('qemu-io', files('qemu-io.c'),
1103             dependencies: [block, qemuutil], install: true)
1104  qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
1105               dependencies: [block, qemuutil], install: true)
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