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