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