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