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