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