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