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