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