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