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