virtiofsd: Used glib "shared" thread pool
[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_KERNEL',
525   'CONFIG_VIRTFS',
526   'CONFIG_LINUX',
527   'CONFIG_PVRDMA',
528 ]
529 ignored = ['TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_DIRS']
530
531 foreach target : target_dirs
532   config_target = keyval.load(meson.current_build_dir() / target / 'config-target.mak')
533
534   foreach k, v: disassemblers
535     if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
536       foreach sym: v
537         config_target += { sym: 'y' }
538         config_all_disas += { sym: 'y' }
539       endforeach
540     endif
541   endforeach
542
543   config_target_data = configuration_data()
544   foreach k, v: config_target
545     if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
546       # do nothing
547     elif ignored.contains(k)
548       # do nothing
549     elif k == 'TARGET_BASE_ARCH'
550       config_target_data.set('TARGET_' + v.to_upper(), 1)
551     elif k == 'TARGET_NAME'
552       config_target_data.set_quoted(k, v)
553     elif v == 'y'
554       config_target_data.set(k, 1)
555     else
556       config_target_data.set(k, v)
557     endif
558   endforeach
559   config_target_h += {target: configure_file(output: target + '-config-target.h',
560                                                configuration: config_target_data)}
561
562   if target.endswith('-softmmu')
563     base_kconfig = []
564     foreach sym : kconfig_external_symbols
565       if sym in config_target or sym in config_host
566         base_kconfig += '@0@=y'.format(sym)
567       endif
568     endforeach
569
570     config_devices_mak = target + '-config-devices.mak'
571     config_devices_mak = configure_file(
572       input: ['default-configs' / target + '.mak', 'Kconfig'],
573       output: config_devices_mak,
574       depfile: config_devices_mak + '.d',
575       capture: true,
576       command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'],
577                 config_devices_mak, '@DEPFILE@', '@INPUT@',
578                 base_kconfig])
579
580     config_devices_data = configuration_data()
581     config_devices = keyval.load(config_devices_mak)
582     foreach k, v: config_devices
583       config_devices_data.set(k, 1)
584     endforeach
585     config_devices_mak_list += config_devices_mak
586     config_devices_h += {target: configure_file(output: target + '-config-devices.h',
587                                                 configuration: config_devices_data)}
588     config_target += config_devices
589     config_all_devices += config_devices
590   endif
591   config_target_mak += {target: config_target}
592 endforeach
593
594 # This configuration is used to build files that are shared by
595 # multiple binaries, and then extracted out of the "common"
596 # static_library target.
597 #
598 # We do not use all_sources()/all_dependencies(), because it would
599 # build literally all source files, including devices only used by
600 # targets that are not built for this compilation.  The CONFIG_ALL
601 # pseudo symbol replaces it.
602
603 config_all = config_all_devices
604 config_all += config_host
605 config_all += config_all_disas
606 config_all += {
607   'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
608   'CONFIG_SOFTMMU': have_system,
609   'CONFIG_USER_ONLY': have_user,
610   'CONFIG_ALL': true,
611 }
612
613 # Generators
614
615 hxtool = find_program('scripts/hxtool')
616 shaderinclude = find_program('scripts/shaderinclude.pl')
617 qapi_gen = find_program('scripts/qapi-gen.py')
618 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
619                      meson.source_root() / 'scripts/qapi/commands.py',
620                      meson.source_root() / 'scripts/qapi/common.py',
621                      meson.source_root() / 'scripts/qapi/doc.py',
622                      meson.source_root() / 'scripts/qapi/error.py',
623                      meson.source_root() / 'scripts/qapi/events.py',
624                      meson.source_root() / 'scripts/qapi/expr.py',
625                      meson.source_root() / 'scripts/qapi/gen.py',
626                      meson.source_root() / 'scripts/qapi/introspect.py',
627                      meson.source_root() / 'scripts/qapi/parser.py',
628                      meson.source_root() / 'scripts/qapi/schema.py',
629                      meson.source_root() / 'scripts/qapi/source.py',
630                      meson.source_root() / 'scripts/qapi/types.py',
631                      meson.source_root() / 'scripts/qapi/visit.py',
632                      meson.source_root() / 'scripts/qapi/common.py',
633                      meson.source_root() / 'scripts/qapi/doc.py',
634                      meson.source_root() / 'scripts/qapi-gen.py'
635 ]
636
637 tracetool = [
638   python, files('scripts/tracetool.py'),
639    '--backend=' + config_host['TRACE_BACKENDS']
640 ]
641
642 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
643                     meson.current_source_dir(),
644                     config_host['PKGVERSION'], meson.project_version()]
645 qemu_version = custom_target('qemu-version.h',
646                              output: 'qemu-version.h',
647                              command: qemu_version_cmd,
648                              capture: true,
649                              build_by_default: true,
650                              build_always_stale: true)
651 genh += qemu_version
652
653 hxdep = []
654 hx_headers = [
655   ['qemu-options.hx', 'qemu-options.def'],
656   ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
657 ]
658 if have_system
659   hx_headers += [
660     ['hmp-commands.hx', 'hmp-commands.h'],
661     ['hmp-commands-info.hx', 'hmp-commands-info.h'],
662   ]
663 endif
664 foreach d : hx_headers
665   hxdep += custom_target(d[1],
666                 input: files(d[0]),
667                 output: d[1],
668                 capture: true,
669                 build_by_default: true, # to be removed when added to a target
670                 command: [hxtool, '-h', '@INPUT0@'])
671 endforeach
672 genh += hxdep
673
674 # Collect sourcesets.
675
676 util_ss = ss.source_set()
677 stub_ss = ss.source_set()
678 trace_ss = ss.source_set()
679 block_ss = ss.source_set()
680 blockdev_ss = ss.source_set()
681 qmp_ss = ss.source_set()
682 common_ss = ss.source_set()
683 softmmu_ss = ss.source_set()
684 user_ss = ss.source_set()
685 bsd_user_ss = ss.source_set()
686 linux_user_ss = ss.source_set()
687 specific_ss = ss.source_set()
688 specific_fuzz_ss = ss.source_set()
689
690 modules = {}
691 hw_arch = {}
692 target_arch = {}
693 target_softmmu_arch = {}
694
695 ###############
696 # Trace files #
697 ###############
698
699 # TODO: add each directory to the subdirs from its own meson.build, once
700 # we have those
701 trace_events_subdirs = [
702   'accel/kvm',
703   'accel/tcg',
704   'crypto',
705   'monitor',
706 ]
707 if have_user
708   trace_events_subdirs += [ 'linux-user' ]
709 endif
710 if have_block
711   trace_events_subdirs += [
712     'authz',
713     'block',
714     'io',
715     'nbd',
716     'scsi',
717   ]
718 endif
719 if have_system
720   trace_events_subdirs += [
721     'audio',
722     'backends',
723     'backends/tpm',
724     'chardev',
725     'hw/9pfs',
726     'hw/acpi',
727     'hw/alpha',
728     'hw/arm',
729     'hw/audio',
730     'hw/block',
731     'hw/block/dataplane',
732     'hw/char',
733     'hw/display',
734     'hw/dma',
735     'hw/hppa',
736     'hw/hyperv',
737     'hw/i2c',
738     'hw/i386',
739     'hw/i386/xen',
740     'hw/ide',
741     'hw/input',
742     'hw/intc',
743     'hw/isa',
744     'hw/mem',
745     'hw/mips',
746     'hw/misc',
747     'hw/misc/macio',
748     'hw/net',
749     'hw/nvram',
750     'hw/pci',
751     'hw/pci-host',
752     'hw/ppc',
753     'hw/rdma',
754     'hw/rdma/vmw',
755     'hw/rtc',
756     'hw/s390x',
757     'hw/scsi',
758     'hw/sd',
759     'hw/sparc',
760     'hw/sparc64',
761     'hw/ssi',
762     'hw/timer',
763     'hw/tpm',
764     'hw/usb',
765     'hw/vfio',
766     'hw/virtio',
767     'hw/watchdog',
768     'hw/xen',
769     'hw/gpio',
770     'migration',
771     'net',
772     'softmmu',
773     'ui',
774   ]
775 endif
776 trace_events_subdirs += [
777   'hw/core',
778   'qapi',
779   'qom',
780   'target/arm',
781   'target/hppa',
782   'target/i386',
783   'target/mips',
784   'target/ppc',
785   'target/riscv',
786   'target/s390x',
787   'target/sparc',
788   'util',
789 ]
790
791 subdir('qapi')
792 subdir('qobject')
793 subdir('stubs')
794 subdir('trace')
795 subdir('util')
796 subdir('qom')
797 subdir('authz')
798 subdir('crypto')
799 subdir('ui')
800
801
802 if enable_modules
803   libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
804   modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
805 endif
806
807 # Build targets from sourcesets
808
809 stub_ss = stub_ss.apply(config_all, strict: false)
810
811 util_ss.add_all(trace_ss)
812 util_ss = util_ss.apply(config_all, strict: false)
813 libqemuutil = static_library('qemuutil',
814                              sources: util_ss.sources() + stub_ss.sources() + genh,
815                              dependencies: [util_ss.dependencies(), m, glib, socket])
816 qemuutil = declare_dependency(link_with: libqemuutil,
817                               sources: genh + version_res)
818
819 decodetree = generator(find_program('scripts/decodetree.py'),
820                        output: 'decode-@BASENAME@.c.inc',
821                        arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
822
823 subdir('audio')
824 subdir('io')
825 subdir('chardev')
826 subdir('fsdev')
827 subdir('libdecnumber')
828 subdir('target')
829 subdir('dump')
830
831 block_ss.add(files(
832   'block.c',
833   'blockjob.c',
834   'job.c',
835   'qemu-io-cmds.c',
836 ))
837 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
838
839 subdir('nbd')
840 subdir('scsi')
841 subdir('block')
842
843 blockdev_ss.add(files(
844   'blockdev.c',
845   'blockdev-nbd.c',
846   'iothread.c',
847   'job-qmp.c',
848 ))
849
850 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
851 # os-win32.c does not
852 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
853 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
854
855 softmmu_ss.add_all(blockdev_ss)
856 softmmu_ss.add(files(
857   'bootdevice.c',
858   'dma-helpers.c',
859   'qdev-monitor.c',
860 ), sdl)
861
862 softmmu_ss.add(when: 'CONFIG_TPM', if_true: files('tpm.c'))
863 softmmu_ss.add(when: 'CONFIG_SECCOMP', if_true: [files('qemu-seccomp.c'), seccomp])
864 softmmu_ss.add(when: ['CONFIG_FDT', fdt],  if_true: [files('device_tree.c')])
865
866 common_ss.add(files('cpus-common.c'))
867
868 subdir('softmmu')
869
870 specific_ss.add(files('disas.c', 'exec.c', 'gdbstub.c'), capstone, libpmem, libdaxctl)
871 specific_ss.add(files('exec-vary.c'))
872 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
873   'fpu/softfloat.c',
874   'tcg/optimize.c',
875   'tcg/tcg-common.c',
876   'tcg/tcg-op-gvec.c',
877   'tcg/tcg-op-vec.c',
878   'tcg/tcg-op.c',
879   'tcg/tcg.c',
880 ))
881 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
882
883 subdir('backends')
884 subdir('disas')
885 subdir('migration')
886 subdir('monitor')
887 subdir('net')
888 subdir('replay')
889 subdir('hw')
890 subdir('accel')
891 subdir('plugins')
892 subdir('bsd-user')
893 subdir('linux-user')
894
895 bsd_user_ss.add(files('gdbstub.c'))
896 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
897
898 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
899 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
900
901 # needed for fuzzing binaries
902 subdir('tests/qtest/libqos')
903 subdir('tests/qtest/fuzz')
904
905 block_mods = []
906 softmmu_mods = []
907 foreach d, list : modules
908   foreach m, module_ss : list
909     if enable_modules and targetos != 'windows'
910       module_ss = module_ss.apply(config_all, strict: false)
911       sl = static_library(d + '-' + m, [genh, module_ss.sources()],
912                           dependencies: [modulecommon, module_ss.dependencies()], pic: true)
913       if d == 'block'
914         block_mods += sl
915       else
916         softmmu_mods += sl
917       endif
918     else
919       if d == 'block'
920         block_ss.add_all(module_ss)
921       else
922         softmmu_ss.add_all(module_ss)
923       endif
924     endif
925   endforeach
926 endforeach
927
928 nm = find_program('nm')
929 undefsym = find_program('scripts/undefsym.py')
930 block_syms = custom_target('block.syms', output: 'block.syms',
931                              input: [libqemuutil, block_mods],
932                              capture: true,
933                              command: [undefsym, nm, '@INPUT@'])
934 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
935                              input: [libqemuutil, softmmu_mods],
936                              capture: true,
937                              command: [undefsym, nm, '@INPUT@'])
938
939 block_ss = block_ss.apply(config_host, strict: false)
940 libblock = static_library('block', block_ss.sources() + genh,
941                           dependencies: block_ss.dependencies(),
942                           link_depends: block_syms,
943                           name_suffix: 'fa',
944                           build_by_default: false)
945
946 block = declare_dependency(link_whole: [libblock],
947                            link_args: '@block.syms',
948                            dependencies: [crypto, io])
949
950 qmp_ss = qmp_ss.apply(config_host, strict: false)
951 libqmp = static_library('qmp', qmp_ss.sources() + genh,
952                         dependencies: qmp_ss.dependencies(),
953                         name_suffix: 'fa',
954                         build_by_default: false)
955
956 qmp = declare_dependency(link_whole: [libqmp])
957
958 foreach m : block_mods + softmmu_mods
959   shared_module(m.name(),
960                 name_prefix: '',
961                 link_whole: m,
962                 install: true,
963                 install_dir: config_host['qemu_moddir'])
964 endforeach
965
966 softmmu_ss.add(authz, block, chardev, crypto, io, qmp)
967 common_ss.add(qom, qemuutil)
968
969 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
970 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
971
972 common_all = common_ss.apply(config_all, strict: false)
973 common_all = static_library('common',
974                             build_by_default: false,
975                             sources: common_all.sources() + genh,
976                             dependencies: common_all.dependencies(),
977                             name_suffix: 'fa')
978
979 feature_to_c = find_program('scripts/feature_to_c.sh')
980
981 emulators = []
982 foreach target : target_dirs
983   config_target = config_target_mak[target]
984   target_name = config_target['TARGET_NAME']
985   arch = config_target['TARGET_BASE_ARCH']
986   arch_srcs = [config_target_h[target]]
987   arch_deps = []
988   c_args = ['-DNEED_CPU_H',
989             '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
990             '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
991   link_args = []
992
993   config_target += config_host
994   target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
995   if targetos == 'linux'
996     target_inc += include_directories('linux-headers', is_system: true)
997   endif
998   if target.endswith('-softmmu')
999     qemu_target_name = 'qemu-system-' + target_name
1000     target_type='system'
1001     t = target_softmmu_arch[arch].apply(config_target, strict: false)
1002     arch_srcs += t.sources()
1003     arch_deps += t.dependencies()
1004
1005     hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
1006     hw = hw_arch[hw_dir].apply(config_target, strict: false)
1007     arch_srcs += hw.sources()
1008     arch_deps += hw.dependencies()
1009
1010     arch_srcs += config_devices_h[target]
1011     link_args += ['@block.syms', '@qemu.syms']
1012   else
1013     abi = config_target['TARGET_ABI_DIR']
1014     target_type='user'
1015     qemu_target_name = 'qemu-' + target_name
1016     if 'CONFIG_LINUX_USER' in config_target
1017       base_dir = 'linux-user'
1018       target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
1019     else
1020       base_dir = 'bsd-user'
1021     endif
1022     target_inc += include_directories(
1023       base_dir,
1024       base_dir / abi,
1025     )
1026     if 'CONFIG_LINUX_USER' in config_target
1027       dir = base_dir / abi
1028       arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
1029       if config_target.has_key('TARGET_SYSTBL_ABI')
1030         arch_srcs += \
1031           syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
1032                                              extra_args : config_target['TARGET_SYSTBL_ABI'])
1033       endif
1034     endif
1035   endif
1036
1037   if 'TARGET_XML_FILES' in config_target
1038     gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
1039                                 output: target + '-gdbstub-xml.c',
1040                                 input: files(config_target['TARGET_XML_FILES'].split()),
1041                                 command: [feature_to_c, '@INPUT@'],
1042                                 capture: true)
1043     arch_srcs += gdbstub_xml
1044   endif
1045
1046   t = target_arch[arch].apply(config_target, strict: false)
1047   arch_srcs += t.sources()
1048   arch_deps += t.dependencies()
1049
1050   target_common = common_ss.apply(config_target, strict: false)
1051   objects = common_all.extract_objects(target_common.sources())
1052   deps = target_common.dependencies()
1053
1054   target_specific = specific_ss.apply(config_target, strict: false)
1055   arch_srcs += target_specific.sources()
1056   arch_deps += target_specific.dependencies()
1057
1058   lib = static_library('qemu-' + target,
1059                  sources: arch_srcs + genh,
1060                  dependencies: arch_deps,
1061                  objects: objects,
1062                  include_directories: target_inc,
1063                  c_args: c_args,
1064                  build_by_default: false,
1065                  name_suffix: 'fa')
1066
1067   if target.endswith('-softmmu')
1068     execs = [{
1069       'name': 'qemu-system-' + target_name,
1070       'gui': false,
1071       'sources': files('softmmu/main.c'),
1072       'dependencies': []
1073     }]
1074     if targetos == 'windows' and (sdl.found() or gtk.found())
1075       execs += [{
1076         'name': 'qemu-system-' + target_name + 'w',
1077         'gui': true,
1078         'sources': files('softmmu/main.c'),
1079         'dependencies': []
1080       }]
1081     endif
1082     if config_host.has_key('CONFIG_FUZZ')
1083       specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
1084       execs += [{
1085         'name': 'qemu-fuzz-' + target_name,
1086         'gui': false,
1087         'sources': specific_fuzz.sources(),
1088         'dependencies': specific_fuzz.dependencies(),
1089       }]
1090     endif
1091   else
1092     execs = [{
1093       'name': 'qemu-' + target_name,
1094       'gui': false,
1095       'sources': [],
1096       'dependencies': []
1097     }]
1098   endif
1099   foreach exe: execs
1100     emulators += executable(exe['name'], exe['sources'],
1101                install: true,
1102                c_args: c_args,
1103                dependencies: arch_deps + deps + exe['dependencies'],
1104                objects: lib.extract_all_objects(recursive: true),
1105                link_language: link_language,
1106                link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
1107                link_args: link_args,
1108                gui_app: exe['gui'])
1109
1110     if 'CONFIG_TRACE_SYSTEMTAP' in config_host
1111       foreach stp: [
1112         {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
1113         {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
1114         {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
1115         {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
1116       ]
1117         custom_target(exe['name'] + stp['ext'],
1118                       input: trace_events_all,
1119                       output: exe['name'] + stp['ext'],
1120                       capture: true,
1121                       install: stp['install'],
1122                       install_dir: qemu_datadir / '../systemtap/tapset',
1123                       command: [
1124                         tracetool, '--group=all', '--format=' + stp['fmt'],
1125                         '--binary=' + stp['bin'],
1126                         '--target-name=' + target_name,
1127                         '--target-type=' + target_type,
1128                         '--probe-prefix=qemu.' + target_type + '.' + target_name,
1129                         '@INPUT@',
1130                       ])
1131       endforeach
1132     endif
1133   endforeach
1134 endforeach
1135
1136 # Other build targets
1137
1138 if 'CONFIG_PLUGIN' in config_host
1139   install_headers('include/qemu/qemu-plugin.h')
1140 endif
1141
1142 if 'CONFIG_GUEST_AGENT' in config_host
1143   subdir('qga')
1144 endif
1145
1146 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
1147 # when we don't build tools or system
1148 if xkbcommon.found()
1149   # used for the update-keymaps target, so include rules even if !have_tools
1150   qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
1151                            dependencies: [qemuutil, xkbcommon], install: have_tools)
1152 endif
1153
1154 qemu_block_tools = []
1155 if have_tools
1156   qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
1157              dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
1158   qemu_io = executable('qemu-io', files('qemu-io.c'),
1159              dependencies: [block, qemuutil], install: true)
1160   qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
1161                dependencies: [block, qemuutil], install: true)
1162
1163   subdir('storage-daemon')
1164   subdir('contrib/rdmacm-mux')
1165   subdir('contrib/elf2dmp')
1166
1167   executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
1168              dependencies: qemuutil,
1169              install: true)
1170
1171   if 'CONFIG_VHOST_USER' in config_host
1172     subdir('contrib/libvhost-user')
1173     subdir('contrib/vhost-user-blk')
1174     subdir('contrib/vhost-user-gpu')
1175     subdir('contrib/vhost-user-input')
1176     subdir('contrib/vhost-user-scsi')
1177   endif
1178
1179   if targetos == 'linux'
1180     executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
1181                dependencies: [qemuutil, libcap_ng],
1182                install: true,
1183                install_dir: get_option('libexecdir'))
1184
1185     executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
1186                dependencies: [authz, crypto, io, qom, qemuutil,
1187                               libcap_ng, libudev, libmpathpersist],
1188                install: true)
1189   endif
1190
1191   if 'CONFIG_IVSHMEM' in config_host
1192     subdir('contrib/ivshmem-client')
1193     subdir('contrib/ivshmem-server')
1194   endif
1195 endif
1196
1197 subdir('scripts')
1198 subdir('tools')
1199 subdir('pc-bios')
1200 subdir('tests')
1201 subdir('docs')
1202 if 'CONFIG_GTK' in config_host
1203   subdir('po')
1204 endif
1205
1206 if build_docs
1207   makeinfo = find_program('makeinfo', required: build_docs)
1208
1209   docs_inc = [
1210     '-I', meson.current_source_dir(),
1211     '-I', meson.current_build_dir() / 'docs',
1212     '-I', '@OUTDIR@',
1213   ]
1214
1215   version_texi = configure_file(output: 'version.texi',
1216                               input: 'version.texi.in',
1217                               configuration: {'VERSION': meson.project_version(),
1218                                               'qemu_confdir': config_host['qemu_confdir']})
1219
1220   texi = {
1221     'qemu-qmp-ref': ['docs/interop/qemu-qmp-ref.texi', qapi_doc_texi, version_texi],
1222   }
1223   if 'CONFIG_GUEST_AGENT' in config_host
1224     texi += {'qemu-ga-ref': ['docs/interop/qemu-ga-ref.texi', qga_qapi_doc_texi, version_texi]}
1225   endif
1226
1227   if makeinfo.found()
1228     cmd = [
1229       'env', 'LC_ALL=C', makeinfo, '--no-split', '--number-sections', docs_inc,
1230       '@INPUT0@', '-o', '@OUTPUT@',
1231     ]
1232     foreach ext, args: {
1233         'info': [],
1234         'html': ['--no-headers', '--html'],
1235         'txt': ['--no-headers', '--plaintext'],
1236     }
1237       t = []
1238       foreach doc, input: texi
1239         output = doc + '.' + ext
1240         t += custom_target(output,
1241                       input: input,
1242                       output: output,
1243                       install: true,
1244                       install_dir: qemu_docdir / 'interop',
1245                       command: cmd + args)
1246       endforeach
1247       alias_target(ext, t)
1248     endforeach
1249   endif
1250
1251   texi2pdf = find_program('texi2pdf', required: false)
1252
1253   if texi2pdf.found()
1254     pdfs = []
1255     foreach doc, input: texi
1256       output = doc + '.pdf'
1257       pdfs += custom_target(output,
1258                     input: input,
1259                     output: output,
1260                     command: [texi2pdf, '-q', docs_inc, '@INPUT0@', '-o', '@OUTPUT@'],
1261                     build_by_default: false)
1262     endforeach
1263     alias_target('pdf', pdfs)
1264   endif
1265
1266   texi2pod = find_program('scripts/texi2pod.pl')
1267   pod2man = find_program('pod2man', required: build_docs)
1268
1269   if pod2man.found()
1270     foreach doc, input: texi
1271       man = doc + '.7'
1272       pod = custom_target(man + '.pod',
1273                           input: input,
1274                           output: man + '.pod',
1275                           command: [texi2pod,
1276                                     '-DVERSION="' + meson.project_version() + '"',
1277                                     '-DCONFDIR="' + config_host['qemu_confdir'] + '"',
1278                                     '@INPUT0@', '@OUTPUT@'])
1279       man = custom_target(man,
1280                           input: pod,
1281                           output: man,
1282                           capture: true,
1283                           install: true,
1284                           install_dir: get_option('mandir') / 'man7',
1285                           command: [pod2man, '--utf8', '--section=7', '--center=" "',
1286                                     '--release=" "', '@INPUT@'])
1287     endforeach
1288   endif
1289 endif
1290
1291 if host_machine.system() == 'windows'
1292   nsis_cmd = [
1293     find_program('scripts/nsis.py'),
1294     '@OUTPUT@',
1295     get_option('prefix'),
1296     meson.current_source_dir(),
1297     host_machine.cpu_family(),
1298     '--',
1299     '-DDISPLAYVERSION=' + meson.project_version(),
1300   ]
1301   if build_docs
1302     nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
1303   endif
1304   if 'CONFIG_GTK' in config_host
1305     nsis_cmd += '-DCONFIG_GTK=y'
1306   endif
1307
1308   nsis = custom_target('nsis',
1309                        output: 'qemu-setup-' + meson.project_version() + '.exe',
1310                        input: files('qemu.nsi'),
1311                        build_always_stale: true,
1312                        command: nsis_cmd + ['@INPUT@'])
1313   alias_target('installer', nsis)
1314 endif
1315
1316 summary_info = {}
1317 summary_info += {'Install prefix':    config_host['prefix']}
1318 summary_info += {'BIOS directory':    config_host['qemu_datadir']}
1319 summary_info += {'firmware path':     config_host['qemu_firmwarepath']}
1320 summary_info += {'binary directory':  config_host['bindir']}
1321 summary_info += {'library directory': config_host['libdir']}
1322 summary_info += {'module directory':  config_host['qemu_moddir']}
1323 summary_info += {'libexec directory': config_host['libexecdir']}
1324 summary_info += {'include directory': config_host['includedir']}
1325 summary_info += {'config directory':  config_host['sysconfdir']}
1326 if targetos != 'windows'
1327   summary_info += {'local state directory': config_host['qemu_localstatedir']}
1328   summary_info += {'Manual directory':      get_option('mandir')}
1329 else
1330   summary_info += {'local state directory': 'queried at runtime'}
1331 endif
1332 summary_info += {'Doc directory':     get_option('docdir')}
1333 summary_info += {'Build directory':   meson.current_build_dir()}
1334 summary_info += {'Source path':       meson.current_source_dir()}
1335 summary_info += {'GIT binary':        config_host['GIT']}
1336 summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
1337 summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
1338 summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
1339 if link_language == 'cpp'
1340   summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
1341 else
1342   summary_info += {'C++ compiler':      false}
1343 endif
1344 if targetos == 'darwin'
1345   summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
1346 endif
1347 summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
1348 summary_info += {'CFLAGS':            config_host['CFLAGS']}
1349 summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
1350 summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
1351 summary_info += {'make':              config_host['MAKE']}
1352 summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
1353 summary_info += {'sphinx-build':      config_host['SPHINX_BUILD']}
1354 summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
1355 # TODO: add back version
1356 summary_info += {'slirp support':     config_host.has_key('CONFIG_SLIRP')}
1357 if config_host.has_key('CONFIG_SLIRP')
1358   summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
1359 endif
1360 summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
1361 if config_host.has_key('CONFIG_MODULES')
1362   summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
1363 endif
1364 summary_info += {'host CPU':          cpu}
1365 summary_info += {'host endianness':   build_machine.endian()}
1366 summary_info += {'target list':       config_host['TARGET_DIRS']}
1367 summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
1368 summary_info += {'sparse enabled':    meson.get_compiler('c').cmd_array().contains('cgcc')}
1369 summary_info += {'strip binaries':    get_option('strip')}
1370 summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
1371 summary_info += {'static build':      config_host.has_key('CONFIG_TOOLS')}
1372 if targetos == 'darwin'
1373   summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
1374 endif
1375 # TODO: add back version
1376 summary_info += {'SDL support':       sdl.found()}
1377 summary_info += {'SDL image support': sdl_image.found()}
1378 # TODO: add back version
1379 summary_info += {'GTK support':       config_host.has_key('CONFIG_GTK')}
1380 summary_info += {'GTK GL support':    config_host.has_key('CONFIG_GTK_GL')}
1381 summary_info += {'pixman':            pixman.found()}
1382 # TODO: add back version
1383 summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
1384 summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
1385 summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
1386 # TODO: add back version
1387 summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
1388 if config_host.has_key('CONFIG_GCRYPT')
1389    summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
1390    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1391 endif
1392 # TODO: add back version
1393 summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
1394 if config_host.has_key('CONFIG_NETTLE')
1395    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1396 endif
1397 summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
1398 summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
1399 summary_info += {'iconv support':     config_host.has_key('CONFIG_ICONV')}
1400 summary_info += {'curses support':    config_host.has_key('CONFIG_CURSES')}
1401 # TODO: add back version
1402 summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
1403 summary_info += {'curl support':      config_host.has_key('CONFIG_CURL')}
1404 summary_info += {'mingw32 support':   targetos == 'windows'}
1405 summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
1406 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
1407 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
1408 summary_info += {'VirtFS support':    config_host.has_key('CONFIG_VIRTFS')}
1409 summary_info += {'Multipath support': config_host.has_key('CONFIG_MPATH')}
1410 summary_info += {'VNC support':       vnc.found()}
1411 if vnc.found()
1412   summary_info += {'VNC SASL support':  sasl.found()}
1413   summary_info += {'VNC JPEG support':  jpeg.found()}
1414   summary_info += {'VNC PNG support':   png.found()}
1415 endif
1416 summary_info += {'xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
1417 if config_host.has_key('CONFIG_XEN_BACKEND')
1418   summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
1419 endif
1420 summary_info += {'brlapi support':    config_host.has_key('CONFIG_BRLAPI')}
1421 summary_info += {'Documentation':     config_host.has_key('BUILD_DOCS')}
1422 summary_info += {'PIE':               get_option('b_pie')}
1423 summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
1424 summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
1425 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
1426 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
1427 summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
1428 summary_info += {'Install blobs':     config_host.has_key('INSTALL_BLOBS')}
1429 # TODO: add back KVM/HAX/HVF/WHPX/TCG
1430 #summary_info += {'KVM support':       have_kvm'}
1431 #summary_info += {'HAX support':       have_hax'}
1432 #summary_info += {'HVF support':       have_hvf'}
1433 #summary_info += {'WHPX support':      have_whpx'}
1434 #summary_info += {'TCG support':       have_tcg'}
1435 #if get_option('tcg')
1436 #  summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
1437 #  summary_info += {'TCG interpreter':   config_host.has_key('CONFIG_TCG_INTERPRETER')}
1438 #endif
1439 summary_info += {'malloc trim support': config_host.has_key('CONFIG_MALLOC_TRIM')}
1440 summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
1441 summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
1442 summary_info += {'fdt support':       config_host.has_key('CONFIG_FDT')}
1443 summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
1444 summary_info += {'preadv support':    config_host.has_key('CONFIG_PREADV')}
1445 summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
1446 summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
1447 summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
1448 summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
1449 summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
1450 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
1451 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
1452 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
1453 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
1454 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_KERNEL')}
1455 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
1456 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
1457 summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
1458 if config_host['TRACE_BACKENDS'].split().contains('simple')
1459   summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
1460 endif
1461 # TODO: add back protocol and server version
1462 summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
1463 summary_info += {'rbd support':       config_host.has_key('CONFIG_RBD')}
1464 summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
1465 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
1466 summary_info += {'U2F support':       u2f.found()}
1467 summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
1468 summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
1469 summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
1470 summary_info += {'OpenGL dmabufs':    config_host.has_key('CONFIG_OPENGL_DMABUF')}
1471 summary_info += {'libiscsi support':  config_host.has_key('CONFIG_LIBISCSI')}
1472 summary_info += {'libnfs support':    config_host.has_key('CONFIG_LIBNFS')}
1473 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
1474 if targetos == 'windows'
1475   if 'WIN_SDK' in config_host
1476     summary_info += {'Windows SDK':       config_host['WIN_SDK']}
1477   endif
1478   summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
1479   summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
1480   summary_info += {'QGA MSI support':   config_host.has_key('CONFIG_QGA_MSI_ENABLED')}
1481 endif
1482 summary_info += {'seccomp support':   config_host.has_key('CONFIG_SECCOMP')}
1483 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
1484 summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
1485 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
1486 summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
1487 summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
1488 summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
1489 summary_info += {'gcov':              get_option('b_coverage')}
1490 summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
1491 summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
1492 summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
1493 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
1494 summary_info += {'lzo support':       config_host.has_key('CONFIG_LZO')}
1495 summary_info += {'snappy support':    config_host.has_key('CONFIG_SNAPPY')}
1496 summary_info += {'bzip2 support':     config_host.has_key('CONFIG_BZIP2')}
1497 summary_info += {'lzfse support':     config_host.has_key('CONFIG_LZFSE')}
1498 summary_info += {'zstd support':      config_host.has_key('CONFIG_ZSTD')}
1499 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
1500 summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
1501 summary_info += {'tcmalloc support':  config_host.has_key('CONFIG_TCMALLOC')}
1502 summary_info += {'jemalloc support':  config_host.has_key('CONFIG_JEMALLOC')}
1503 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
1504 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
1505 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
1506 summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
1507 summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
1508 summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
1509 summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
1510 summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
1511 summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
1512 summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
1513 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
1514 summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
1515 summary_info += {'capstone':          config_host.has_key('CONFIG_CAPSTONE')}
1516 summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
1517 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
1518 summary_info += {'libudev':           config_host.has_key('CONFIG_LIBUDEV')}
1519 summary_info += {'default devices':   config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
1520 summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
1521 summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
1522 if config_host.has_key('HAVE_GDB_BIN')
1523   summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
1524 endif
1525 summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
1526 summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
1527 summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
1528 summary(summary_info, bool_yn: true)
1529
1530 if not supported_cpus.contains(cpu)
1531   message()
1532   warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
1533   message()
1534   message('CPU host architecture ' + cpu + ' support is not currently maintained.')
1535   message('The QEMU project intends to remove support for this host CPU in')
1536   message('a future release if nobody volunteers to maintain it and to')
1537   message('provide a build host for our continuous integration setup.')
1538   message('configure has succeeded and you can continue to build, but')
1539   message('if you care about QEMU on this platform you should contact')
1540   message('us upstream at qemu-devel@nongnu.org.')
1541 endif
1542
1543 if not supported_oses.contains(targetos)
1544   message()
1545   warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
1546   message()
1547   message('Host OS ' + targetos + 'support is not currently maintained.')
1548   message('The QEMU project intends to remove support for this host OS in')
1549   message('a future release if nobody volunteers to maintain it and to')
1550   message('provide a build host for our continuous integration setup.')
1551   message('configure has succeeded and you can continue to build, but')
1552   message('if you care about QEMU on this platform you should contact')
1553   message('us upstream at qemu-devel@nongnu.org.')
1554 endif