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