qemu-storage-daemon: avoid compiling blockdev_ss twice
[qemu/kevin.git] / meson.build
blob880683407fd7e80d0e03651d6f26ede567489c1e
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')
13 fs = import('fs')
15 sh = find_program('sh')
16 cc = meson.get_compiler('c')
17 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
18 enable_modules = 'CONFIG_MODULES' in config_host
19 enable_static = 'CONFIG_STATIC' in config_host
21 # Temporary directory used for files created while
22 # configure runs. Since it is in the build directory
23 # we can safely blow away any previous version of it
24 # (and we need not jump through hoops to try to delete
25 # it when configure exits.)
26 tmpdir = meson.current_build_dir() / 'meson-private/temp'
28 if get_option('qemu_suffix').startswith('/')
29   error('qemu_suffix cannot start with a /')
30 endif
32 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
33 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
34 config_host_data = configuration_data()
35 genh = []
37 target_dirs = config_host['TARGET_DIRS'].split()
38 have_user = false
39 have_system = false
40 foreach target : target_dirs
41   have_user = have_user or target.endswith('-user')
42   have_system = have_system or target.endswith('-softmmu')
43 endforeach
44 have_tools = 'CONFIG_TOOLS' in config_host
45 have_block = have_system or have_tools
47 python = import('python').find_installation()
49 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
50 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
51   'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
53 cpu = host_machine.cpu_family()
54 targetos = host_machine.system()
56 if cpu in ['x86', 'x86_64']
57   kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
58 elif cpu == 'aarch64'
59   kvm_targets = ['aarch64-softmmu']
60 elif cpu == 's390x'
61   kvm_targets = ['s390x-softmmu']
62 elif cpu in ['ppc', 'ppc64']
63   kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
64 elif cpu in ['mips', 'mips64']
65   kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
66 else
67   kvm_targets = []
68 endif
70 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
71 if cpu in ['x86', 'x86_64']
72   accelerator_targets += {
73     'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
74     'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
75     'CONFIG_HVF': ['x86_64-softmmu'],
76     'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
77   }
78 endif
80 ##################
81 # Compiler flags #
82 ##################
84 # Specify linker-script with add_project_link_arguments so that it is not placed
85 # within a linker --start-group/--end-group pair
86 if 'CONFIG_FUZZ' in config_host
87    add_project_link_arguments(['-Wl,-T,',
88                                (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
89                               native: false, language: ['c', 'cpp', 'objc'])
90 endif
92 add_project_arguments(config_host['QEMU_CFLAGS'].split(),
93                       native: false, language: ['c', 'objc'])
94 add_project_arguments(config_host['QEMU_CXXFLAGS'].split(),
95                       native: false, language: 'cpp')
96 add_project_link_arguments(config_host['QEMU_LDFLAGS'].split(),
97                            native: false, language: ['c', 'cpp', 'objc'])
99 if targetos == 'linux'
100   add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
101                         '-isystem', 'linux-headers',
102                         language: ['c', 'cpp'])
103 endif
105 if 'CONFIG_TCG_INTERPRETER' in config_host
106   tcg_arch = 'tci'
107 elif config_host['ARCH'] == 'sparc64'
108   tcg_arch = 'sparc'
109 elif config_host['ARCH'] == 's390x'
110   tcg_arch = 's390'
111 elif config_host['ARCH'] in ['x86_64', 'x32']
112   tcg_arch = 'i386'
113 elif config_host['ARCH'] == 'ppc64'
114   tcg_arch = 'ppc'
115 elif config_host['ARCH'] in ['riscv32', 'riscv64']
116   tcg_arch = 'riscv'
117 else
118   tcg_arch = config_host['ARCH']
119 endif
120 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
121                       '-iquote', '.',
122                       '-iquote', meson.current_source_dir(),
123                       '-iquote', meson.current_source_dir() / 'accel/tcg',
124                       '-iquote', meson.current_source_dir() / 'include',
125                       '-iquote', meson.current_source_dir() / 'disas/libvixl',
126                       language: ['c', 'cpp', 'objc'])
128 link_language = meson.get_external_property('link_language', 'cpp')
129 if link_language == 'cpp'
130   add_languages('cpp', required: true, native: false)
131 endif
132 if host_machine.system() == 'darwin'
133   add_languages('objc', required: false, native: false)
134 endif
136 sparse = find_program('cgcc', required: get_option('sparse'))
137 if sparse.found()
138   run_target('sparse',
139              command: [find_program('scripts/check_sparse.py'),
140                        'compile_commands.json', sparse.full_path(), '-Wbitwise',
141                        '-Wno-transparent-union', '-Wno-old-initializer',
142                        '-Wno-non-pointer-null'])
143 endif
145 ###########################################
146 # Target-specific checks and dependencies #
147 ###########################################
149 if targetos != 'linux' and get_option('mpath').enabled()
150   error('Multipath is supported only on Linux')
151 endif
153 m = cc.find_library('m', required: false)
154 util = cc.find_library('util', required: false)
155 winmm = []
156 socket = []
157 version_res = []
158 coref = []
159 iokit = []
160 emulator_link_args = []
161 cocoa = not_found
162 hvf = not_found
163 if targetos == 'windows'
164   socket = cc.find_library('ws2_32')
165   winmm = cc.find_library('winmm')
167   win = import('windows')
168   version_res = win.compile_resources('version.rc',
169                                       depend_files: files('pc-bios/qemu-nsis.ico'),
170                                       include_directories: include_directories('.'))
171 elif targetos == 'darwin'
172   coref = dependency('appleframeworks', modules: 'CoreFoundation')
173   iokit = dependency('appleframeworks', modules: 'IOKit')
174   cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
175 elif targetos == 'sunos'
176   socket = [cc.find_library('socket'),
177             cc.find_library('nsl'),
178             cc.find_library('resolv')]
179 elif targetos == 'haiku'
180   socket = [cc.find_library('posix_error_mapper'),
181             cc.find_library('network'),
182             cc.find_library('bsd')]
183 elif targetos == 'openbsd'
184   if not get_option('tcg').disabled() and target_dirs.length() > 0
185     # Disable OpenBSD W^X if available
186     emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
187   endif
188 endif
190 accelerators = []
191 if not get_option('kvm').disabled() and targetos == 'linux'
192   accelerators += 'CONFIG_KVM'
193 endif
194 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
195   accelerators += 'CONFIG_XEN'
196   have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
197 else
198   have_xen_pci_passthrough = false
199 endif
200 if not get_option('whpx').disabled() and targetos == 'windows'
201   if get_option('whpx').enabled() and cpu != 'x86_64'
202     error('WHPX requires 64-bit host')
203   elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
204        cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
205     accelerators += 'CONFIG_WHPX'
206   endif
207 endif
208 if not get_option('hvf').disabled()
209   hvf = dependency('appleframeworks', modules: 'Hypervisor',
210                    required: get_option('hvf'))
211   if hvf.found()
212     accelerators += 'CONFIG_HVF'
213   endif
214 endif
215 if not get_option('hax').disabled()
216   if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
217     accelerators += 'CONFIG_HAX'
218   endif
219 endif
220 if not get_option('tcg').disabled()
221   if cpu not in supported_cpus
222     if 'CONFIG_TCG_INTERPRETER' in config_host
223       warning('Unsupported CPU @0@, will use TCG with TCI (experimental)'.format(cpu))
224     else
225       error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
226     endif
227   endif
228   accelerators += 'CONFIG_TCG'
229   config_host += { 'CONFIG_TCG': 'y' }
230 endif
232 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
233   error('KVM not available on this platform')
234 endif
235 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
236   error('HVF not available on this platform')
237 endif
238 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
239   error('WHPX not available on this platform')
240 endif
241 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
242   if 'CONFIG_XEN' in accelerators
243     error('Xen PCI passthrough not available on this platform')
244   else
245     error('Xen PCI passthrough requested but Xen not enabled')
246   endif
247 endif
248 if not cocoa.found() and get_option('cocoa').enabled()
249   error('Cocoa not available on this platform')
250 endif
252 ################
253 # Dependencies #
254 ################
256 # The path to glib.h is added to all compilation commands.  This was
257 # grandfathered in from the QEMU Makefiles.
258 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
259                       native: false, language: ['c', 'cpp', 'objc'])
260 glib = declare_dependency(link_args: config_host['GLIB_LIBS'].split())
261 gio = not_found
262 if 'CONFIG_GIO' in config_host
263   gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
264                            link_args: config_host['GIO_LIBS'].split())
265 endif
266 lttng = not_found
267 if 'CONFIG_TRACE_UST' in config_host
268   lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
269 endif
270 urcubp = not_found
271 if 'CONFIG_TRACE_UST' in config_host
272   urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
273 endif
274 gcrypt = not_found
275 if 'CONFIG_GCRYPT' in config_host
276   gcrypt = declare_dependency(compile_args: config_host['GCRYPT_CFLAGS'].split(),
277                               link_args: config_host['GCRYPT_LIBS'].split())
278 endif
279 nettle = not_found
280 if 'CONFIG_NETTLE' in config_host
281   nettle = declare_dependency(compile_args: config_host['NETTLE_CFLAGS'].split(),
282                               link_args: config_host['NETTLE_LIBS'].split())
283 endif
284 gnutls = not_found
285 if 'CONFIG_GNUTLS' in config_host
286   gnutls = declare_dependency(compile_args: config_host['GNUTLS_CFLAGS'].split(),
287                               link_args: config_host['GNUTLS_LIBS'].split())
288 endif
289 pixman = not_found
290 if have_system or have_tools
291   pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
292                       method: 'pkg-config', static: enable_static)
293 endif
294 pam = not_found
295 if 'CONFIG_AUTH_PAM' in config_host
296   pam = cc.find_library('pam')
297 endif
298 libaio = cc.find_library('aio', required: false)
299 zlib = dependency('zlib', required: true, static: enable_static)
300 linux_io_uring = not_found
301 if 'CONFIG_LINUX_IO_URING' in config_host
302   linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
303                                       link_args: config_host['LINUX_IO_URING_LIBS'].split())
304 endif
305 libxml2 = not_found
306 if 'CONFIG_LIBXML2' in config_host
307   libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
308                                link_args: config_host['LIBXML2_LIBS'].split())
309 endif
310 libnfs = not_found
311 if 'CONFIG_LIBNFS' in config_host
312   libnfs = declare_dependency(link_args: config_host['LIBNFS_LIBS'].split())
313 endif
314 libattr = not_found
315 if 'CONFIG_ATTR' in config_host
316   libattr = declare_dependency(link_args: config_host['LIBATTR_LIBS'].split())
317 endif
318 seccomp = not_found
319 if 'CONFIG_SECCOMP' in config_host
320   seccomp = declare_dependency(compile_args: config_host['SECCOMP_CFLAGS'].split(),
321                                link_args: config_host['SECCOMP_LIBS'].split())
322 endif
323 libcap_ng = not_found
324 if 'CONFIG_LIBCAP_NG' in config_host
325   libcap_ng = declare_dependency(link_args: config_host['LIBCAP_NG_LIBS'].split())
326 endif
327 if get_option('xkbcommon').auto() and not have_system and not have_tools
328   xkbcommon = not_found
329 else
330   xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
331                          method: 'pkg-config', static: enable_static)
332 endif
333 vde = not_found
334 if config_host.has_key('CONFIG_VDE')
335   vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
336 endif
337 pulse = not_found
338 if 'CONFIG_LIBPULSE' in config_host
339   pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
340                              link_args: config_host['PULSE_LIBS'].split())
341 endif
342 alsa = not_found
343 if 'CONFIG_ALSA' in config_host
344   alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
345                             link_args: config_host['ALSA_LIBS'].split())
346 endif
347 jack = not_found
348 if 'CONFIG_LIBJACK' in config_host
349   jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
350 endif
351 spice = not_found
352 spice_headers = not_found
353 if 'CONFIG_SPICE' in config_host
354   spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
355                              link_args: config_host['SPICE_LIBS'].split())
356   spice_headers = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split())
357 endif
358 rt = cc.find_library('rt', required: false)
359 libdl = not_found
360 if 'CONFIG_PLUGIN' in config_host
361   libdl = cc.find_library('dl', required: true)
362 endif
363 libiscsi = not_found
364 if 'CONFIG_LIBISCSI' in config_host
365   libiscsi = declare_dependency(compile_args: config_host['LIBISCSI_CFLAGS'].split(),
366                                 link_args: config_host['LIBISCSI_LIBS'].split())
367 endif
368 zstd = not_found
369 if 'CONFIG_ZSTD' in config_host
370   zstd = declare_dependency(compile_args: config_host['ZSTD_CFLAGS'].split(),
371                             link_args: config_host['ZSTD_LIBS'].split())
372 endif
373 gbm = not_found
374 if 'CONFIG_GBM' in config_host
375   gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
376                            link_args: config_host['GBM_LIBS'].split())
377 endif
378 virgl = not_found
379 if 'CONFIG_VIRGL' in config_host
380   virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
381                              link_args: config_host['VIRGL_LIBS'].split())
382 endif
383 curl = not_found
384 if 'CONFIG_CURL' in config_host
385   curl = declare_dependency(compile_args: config_host['CURL_CFLAGS'].split(),
386                             link_args: config_host['CURL_LIBS'].split())
387 endif
388 libudev = not_found
389 if targetos == 'linux' and (have_system or have_tools)
390   libudev = dependency('libudev',
391                        required: get_option('libudev'),
392                        static: enable_static)
393 endif
395 mpathlibs = [libudev]
396 mpathpersist = not_found
397 mpathpersist_new_api = false
398 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
399   mpath_test_source_new = '''
400     #include <libudev.h>
401     #include <mpath_persist.h>
402     unsigned mpath_mx_alloc_len = 1024;
403     int logsink;
404     static struct config *multipath_conf;
405     extern struct udev *udev;
406     extern struct config *get_multipath_config(void);
407     extern void put_multipath_config(struct config *conf);
408     struct udev *udev;
409     struct config *get_multipath_config(void) { return multipath_conf; }
410     void put_multipath_config(struct config *conf) { }
411     int main(void) {
412         udev = udev_new();
413         multipath_conf = mpath_lib_init();
414         return 0;
415     }'''
416   mpath_test_source_old = '''
417       #include <libudev.h>
418       #include <mpath_persist.h>
419       unsigned mpath_mx_alloc_len = 1024;
420       int logsink;
421       int main(void) {
422           struct udev *udev = udev_new();
423           mpath_lib_init(udev);
424           return 0;
425       }'''
426   libmpathpersist = cc.find_library('mpathpersist',
427                                     required: get_option('mpath'),
428                                     static: enable_static)
429   if libmpathpersist.found()
430     mpathlibs += libmpathpersist
431     if enable_static
432       mpathlibs += cc.find_library('devmapper',
433                                      required: get_option('mpath'),
434                                      static: enable_static)
435     endif
436     mpathlibs += cc.find_library('multipath',
437                                  required: get_option('mpath'),
438                                  static: enable_static)
439     foreach lib: mpathlibs
440       if not lib.found()
441         mpathlibs = []
442         break
443       endif
444     endforeach
445     if mpathlibs.length() == 0
446       msg = 'Dependencies missing for libmpathpersist'
447     elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
448       mpathpersist = declare_dependency(dependencies: mpathlibs)
449       mpathpersist_new_api = true
450     elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
451       mpathpersist = declare_dependency(dependencies: mpathlibs)
452     else
453       msg = 'Cannot detect libmpathpersist API'
454     endif
455     if not mpathpersist.found()
456       if get_option('mpath').enabled()
457         error(msg)
458       else
459         warning(msg + ', disabling')
460       endif
461     endif
462   endif
463 endif
465 iconv = not_found
466 curses = not_found
467 if have_system and not get_option('curses').disabled()
468   if not get_option('iconv').disabled()
469     libiconv = cc.find_library('iconv',
470                                required: false,
471                                static: enable_static)
472     if cc.links('''
473       #include <iconv.h>
474       int main(void) {
475         iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
476         return conv != (iconv_t) -1;
477       }''', dependencies: [libiconv])
478       iconv = declare_dependency(dependencies: [libiconv])
479     endif
480   endif
481   if get_option('iconv').enabled() and not iconv.found()
482     error('Cannot detect iconv API')
483   endif
484   if iconv.found()
485     curses_libname_list = ['ncursesw', 'ncurses', 'cursesw', 'pdcurses']
486     curses_test = '''
487       #include <locale.h>
488       #include <curses.h>
489       #include <wchar.h>
490       int main(void) {
491         wchar_t wch = L'w';
492         setlocale(LC_ALL, "");
493         resize_term(0, 0);
494         addwstr(L"wide chars\n");
495         addnwstr(&wch, 1);
496         add_wch(WACS_DEGREE);
497         return 0;
498       }'''
499     foreach curses_libname : curses_libname_list
500       libcurses = dependency(curses_libname,
501                              required: false,
502                              method: 'pkg-config',
503                              static: enable_static)
505       if not libcurses.found()
506         dirs = ['/usr/include/ncursesw']
507         if targetos == 'windows'
508           dirs = []
509         endif
510         libcurses = cc.find_library(curses_libname,
511                                     required: false,
512                                     dirs: dirs,
513                                     static: enable_static)
514       endif
515       if libcurses.found()
516         if cc.links(curses_test, dependencies: [libcurses])
517           curses = declare_dependency(compile_args: '-DNCURSES_WIDECHAR', dependencies: [libcurses])
518           break
519         endif
520       endif
521     endforeach
522   endif
523   if not curses.found()
524     if iconv.found()
525       if get_option('curses').enabled()
526         error('Cannot find curses')
527       endif
528     elif get_option('curses').enabled()
529       error('iconv required for curses UI but not available')
530     else
531       warning('iconv required for curses UI but not available, disabling')
532     endif
533   endif
534 endif
536 brlapi = not_found
537 if 'CONFIG_BRLAPI' in config_host
538   brlapi = declare_dependency(link_args: config_host['BRLAPI_LIBS'].split())
539 endif
541 sdl = not_found
542 if have_system
543   sdl = dependency('sdl2', required: get_option('sdl'), static: enable_static)
544   sdl_image = not_found
545 endif
546 if sdl.found()
547   # work around 2.0.8 bug
548   sdl = declare_dependency(compile_args: '-Wno-undef',
549                            dependencies: sdl)
550   sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
551                          method: 'pkg-config', static: enable_static)
552 else
553   if get_option('sdl_image').enabled()
554     error('sdl-image required, but SDL was @0@'.format(
555           get_option('sdl').disabled() ? 'disabled' : 'not found'))
556   endif
557   sdl_image = not_found
558 endif
560 rbd = not_found
561 if 'CONFIG_RBD' in config_host
562   rbd = declare_dependency(link_args: config_host['RBD_LIBS'].split())
563 endif
564 glusterfs = not_found
565 if 'CONFIG_GLUSTERFS' in config_host
566   glusterfs = declare_dependency(compile_args: config_host['GLUSTERFS_CFLAGS'].split(),
567                                  link_args: config_host['GLUSTERFS_LIBS'].split())
568 endif
569 libssh = not_found
570 if 'CONFIG_LIBSSH' in config_host
571   libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
572                               link_args: config_host['LIBSSH_LIBS'].split())
573 endif
574 libbzip2 = not_found
575 if 'CONFIG_BZIP2' in config_host
576   libbzip2 = declare_dependency(link_args: config_host['BZIP2_LIBS'].split())
577 endif
578 liblzfse = not_found
579 if 'CONFIG_LZFSE' in config_host
580   liblzfse = declare_dependency(link_args: config_host['LZFSE_LIBS'].split())
581 endif
582 oss = not_found
583 if 'CONFIG_AUDIO_OSS' in config_host
584   oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
585 endif
586 dsound = not_found
587 if 'CONFIG_AUDIO_DSOUND' in config_host
588   dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
589 endif
590 coreaudio = not_found
591 if 'CONFIG_AUDIO_COREAUDIO' in config_host
592   coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
593 endif
594 opengl = not_found
595 if 'CONFIG_OPENGL' in config_host
596   opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
597                               link_args: config_host['OPENGL_LIBS'].split())
598 endif
599 gtk = not_found
600 if 'CONFIG_GTK' in config_host
601   gtk = declare_dependency(compile_args: config_host['GTK_CFLAGS'].split(),
602                               link_args: config_host['GTK_LIBS'].split())
603 endif
604 vte = not_found
605 if 'CONFIG_VTE' in config_host
606   vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
607                            link_args: config_host['VTE_LIBS'].split())
608 endif
609 x11 = not_found
610 if 'CONFIG_X11' in config_host
611   x11 = declare_dependency(compile_args: config_host['X11_CFLAGS'].split(),
612                            link_args: config_host['X11_LIBS'].split())
613 endif
614 vnc = not_found
615 png = not_found
616 jpeg = not_found
617 sasl = not_found
618 if get_option('vnc').enabled()
619   vnc = declare_dependency() # dummy dependency
620   png = dependency('libpng', required: get_option('vnc_png'),
621                    method: 'pkg-config', static: enable_static)
622   jpeg = cc.find_library('jpeg', has_headers: ['jpeglib.h'],
623                          required: get_option('vnc_jpeg'),
624                          static: enable_static)
625   sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
626                          required: get_option('vnc_sasl'),
627                          static: enable_static)
628   if sasl.found()
629     sasl = declare_dependency(dependencies: sasl,
630                               compile_args: '-DSTRUCT_IOVEC_DEFINED')
631   endif
632 endif
633 snappy = not_found
634 if 'CONFIG_SNAPPY' in config_host
635   snappy = declare_dependency(link_args: config_host['SNAPPY_LIBS'].split())
636 endif
637 lzo = not_found
638 if 'CONFIG_LZO' in config_host
639   lzo = declare_dependency(link_args: config_host['LZO_LIBS'].split())
640 endif
641 rdma = not_found
642 if 'CONFIG_RDMA' in config_host
643   rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
644 endif
645 numa = not_found
646 if 'CONFIG_NUMA' in config_host
647   numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
648 endif
649 xen = not_found
650 if 'CONFIG_XEN_BACKEND' in config_host
651   xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
652                            link_args: config_host['XEN_LIBS'].split())
653 endif
654 cacard = not_found
655 if 'CONFIG_SMARTCARD' in config_host
656   cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
657                               link_args: config_host['SMARTCARD_LIBS'].split())
658 endif
659 u2f = not_found
660 if have_system
661   u2f = dependency('u2f-emu', required: get_option('u2f'),
662                    method: 'pkg-config',
663                    static: enable_static)
664 endif
665 usbredir = not_found
666 if 'CONFIG_USB_REDIR' in config_host
667   usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
668                                 link_args: config_host['USB_REDIR_LIBS'].split())
669 endif
670 libusb = not_found
671 if 'CONFIG_USB_LIBUSB' in config_host
672   libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
673                               link_args: config_host['LIBUSB_LIBS'].split())
674 endif
675 libpmem = not_found
676 if 'CONFIG_LIBPMEM' in config_host
677   libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
678                                link_args: config_host['LIBPMEM_LIBS'].split())
679 endif
680 libdaxctl = not_found
681 if 'CONFIG_LIBDAXCTL' in config_host
682   libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
683 endif
684 tasn1 = not_found
685 if 'CONFIG_TASN1' in config_host
686   tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(),
687                              link_args: config_host['TASN1_LIBS'].split())
688 endif
689 keyutils = dependency('libkeyutils', required: false,
690                       method: 'pkg-config', static: enable_static)
692 has_gettid = cc.has_function('gettid')
694 # Malloc tests
696 malloc = []
697 if get_option('malloc') == 'system'
698   has_malloc_trim = \
699     not get_option('malloc_trim').disabled() and \
700     cc.links('''#include <malloc.h>
701                 int main(void) { malloc_trim(0); return 0; }''')
702 else
703   has_malloc_trim = false
704   malloc = cc.find_library(get_option('malloc'), required: true)
705 endif
706 if not has_malloc_trim and get_option('malloc_trim').enabled()
707   if get_option('malloc') == 'system'
708     error('malloc_trim not available on this platform.')
709   else
710     error('malloc_trim not available with non-libc memory allocator')
711   endif
712 endif
714 #################
715 # config-host.h #
716 #################
718 config_host_data.set('CONFIG_COCOA', cocoa.found())
719 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
720 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
721 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
722 config_host_data.set('CONFIG_CURSES', curses.found())
723 config_host_data.set('CONFIG_SDL', sdl.found())
724 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
725 config_host_data.set('CONFIG_VNC', vnc.found())
726 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
727 config_host_data.set('CONFIG_VNC_PNG', png.found())
728 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
729 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
730 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
731 config_host_data.set('CONFIG_GETTID', has_gettid)
732 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
733 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
734 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
735 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
736 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
738 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
739 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
740 strings = ['HOST_DSOSUF', 'CONFIG_IASL', 'bindir', 'prefix', 'qemu_confdir', 'qemu_datadir',
741            'qemu_moddir', 'qemu_localstatedir', 'qemu_helperdir', 'qemu_localedir',
742            'qemu_icondir', 'qemu_desktopdir', 'qemu_firmwarepath', 'sysconfdir']
743 foreach k, v: config_host
744   if ignored.contains(k)
745     # do nothing
746   elif arrays.contains(k)
747     if v != ''
748       v = '"' + '", "'.join(v.split()) + '", '
749     endif
750     config_host_data.set(k, v)
751   elif k == 'ARCH'
752     config_host_data.set('HOST_' + v.to_upper(), 1)
753   elif strings.contains(k)
754     if not k.startswith('CONFIG_')
755       k = 'CONFIG_' + k.to_upper()
756     endif
757     config_host_data.set_quoted(k, v)
758   elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
759     config_host_data.set(k, v == 'y' ? 1 : v)
760   endif
761 endforeach
763 ########################
764 # Target configuration #
765 ########################
767 minikconf = find_program('scripts/minikconf.py')
768 config_all = {}
769 config_all_devices = {}
770 config_all_disas = {}
771 config_devices_mak_list = []
772 config_devices_h = {}
773 config_target_h = {}
774 config_target_mak = {}
776 disassemblers = {
777   'alpha' : ['CONFIG_ALPHA_DIS'],
778   'arm' : ['CONFIG_ARM_DIS'],
779   'avr' : ['CONFIG_AVR_DIS'],
780   'cris' : ['CONFIG_CRIS_DIS'],
781   'hppa' : ['CONFIG_HPPA_DIS'],
782   'i386' : ['CONFIG_I386_DIS'],
783   'x86_64' : ['CONFIG_I386_DIS'],
784   'x32' : ['CONFIG_I386_DIS'],
785   'lm32' : ['CONFIG_LM32_DIS'],
786   'm68k' : ['CONFIG_M68K_DIS'],
787   'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
788   'mips' : ['CONFIG_MIPS_DIS'],
789   'moxie' : ['CONFIG_MOXIE_DIS'],
790   'nios2' : ['CONFIG_NIOS2_DIS'],
791   'or1k' : ['CONFIG_OPENRISC_DIS'],
792   'ppc' : ['CONFIG_PPC_DIS'],
793   'riscv' : ['CONFIG_RISCV_DIS'],
794   'rx' : ['CONFIG_RX_DIS'],
795   's390' : ['CONFIG_S390_DIS'],
796   'sh4' : ['CONFIG_SH4_DIS'],
797   'sparc' : ['CONFIG_SPARC_DIS'],
798   'xtensa' : ['CONFIG_XTENSA_DIS'],
800 if link_language == 'cpp'
801   disassemblers += {
802     'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
803     'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
804     'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
805   }
806 endif
808 kconfig_external_symbols = [
809   'CONFIG_KVM',
810   'CONFIG_XEN',
811   'CONFIG_TPM',
812   'CONFIG_SPICE',
813   'CONFIG_IVSHMEM',
814   'CONFIG_OPENGL',
815   'CONFIG_X11',
816   'CONFIG_VHOST_USER',
817   'CONFIG_VHOST_VDPA',
818   'CONFIG_VHOST_KERNEL',
819   'CONFIG_VIRTFS',
820   'CONFIG_LINUX',
821   'CONFIG_PVRDMA',
823 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
825 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
826 actual_target_dirs = []
827 fdt_required = []
828 foreach target : target_dirs
829   config_target = { 'TARGET_NAME': target.split('-')[0] }
830   if target.endswith('linux-user')
831     if targetos != 'linux'
832       if default_targets
833         continue
834       endif
835       error('Target @0@ is only available on a Linux host'.format(target))
836     endif
837     config_target += { 'CONFIG_LINUX_USER': 'y' }
838   elif target.endswith('bsd-user')
839     if 'CONFIG_BSD' not in config_host
840       if default_targets
841         continue
842       endif
843       error('Target @0@ is only available on a BSD host'.format(target))
844     endif
845     config_target += { 'CONFIG_BSD_USER': 'y' }
846   elif target.endswith('softmmu')
847     config_target += { 'CONFIG_SOFTMMU': 'y' }
848   endif
849   if target.endswith('-user')
850     config_target += {
851       'CONFIG_USER_ONLY': 'y',
852       'CONFIG_QEMU_INTERP_PREFIX':
853         config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
854     }
855   endif
857   have_accel = false
858   foreach sym: accelerators
859     if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
860       config_target += { sym: 'y' }
861       config_all += { sym: 'y' }
862       if sym == 'CONFIG_XEN' and have_xen_pci_passthrough
863         config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
864       endif
865       have_accel = true
866     endif
867   endforeach
868   if not have_accel
869     if default_targets
870       continue
871     endif
872     error('No accelerator available for target @0@'.format(target))
873   endif
875   actual_target_dirs += target
876   config_target += keyval.load('default-configs/targets' / target + '.mak')
877   config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
879   if 'TARGET_NEED_FDT' in config_target
880     fdt_required += target
881   endif
883   # Add default keys
884   if 'TARGET_BASE_ARCH' not in config_target
885     config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
886   endif
887   if 'TARGET_ABI_DIR' not in config_target
888     config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
889   endif
891   foreach k, v: disassemblers
892     if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
893       foreach sym: v
894         config_target += { sym: 'y' }
895         config_all_disas += { sym: 'y' }
896       endforeach
897     endif
898   endforeach
900   config_target_data = configuration_data()
901   foreach k, v: config_target
902     if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
903       # do nothing
904     elif ignored.contains(k)
905       # do nothing
906     elif k == 'TARGET_BASE_ARCH'
907       # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
908       # not used to select files from sourcesets.
909       config_target_data.set('TARGET_' + v.to_upper(), 1)
910     elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
911       config_target_data.set_quoted(k, v)
912     elif v == 'y'
913       config_target_data.set(k, 1)
914     else
915       config_target_data.set(k, v)
916     endif
917   endforeach
918   config_target_h += {target: configure_file(output: target + '-config-target.h',
919                                                configuration: config_target_data)}
921   if target.endswith('-softmmu')
922     base_kconfig = []
923     foreach sym : kconfig_external_symbols
924       if sym in config_target or sym in config_host
925         base_kconfig += '@0@=y'.format(sym)
926       endif
927     endforeach
929     config_devices_mak = target + '-config-devices.mak'
930     config_devices_mak = configure_file(
931       input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
932       output: config_devices_mak,
933       depfile: config_devices_mak + '.d',
934       capture: true,
935       command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'],
936                 config_devices_mak, '@DEPFILE@', '@INPUT@',
937                 base_kconfig])
939     config_devices_data = configuration_data()
940     config_devices = keyval.load(config_devices_mak)
941     foreach k, v: config_devices
942       config_devices_data.set(k, 1)
943     endforeach
944     config_devices_mak_list += config_devices_mak
945     config_devices_h += {target: configure_file(output: target + '-config-devices.h',
946                                                 configuration: config_devices_data)}
947     config_target += config_devices
948     config_all_devices += config_devices
949   endif
950   config_target_mak += {target: config_target}
951 endforeach
952 target_dirs = actual_target_dirs
954 # This configuration is used to build files that are shared by
955 # multiple binaries, and then extracted out of the "common"
956 # static_library target.
958 # We do not use all_sources()/all_dependencies(), because it would
959 # build literally all source files, including devices only used by
960 # targets that are not built for this compilation.  The CONFIG_ALL
961 # pseudo symbol replaces it.
963 config_all += config_all_devices
964 config_all += config_host
965 config_all += config_all_disas
966 config_all += {
967   'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
968   'CONFIG_SOFTMMU': have_system,
969   'CONFIG_USER_ONLY': have_user,
970   'CONFIG_ALL': true,
973 ##############
974 # Submodules #
975 ##############
977 capstone = not_found
978 capstone_opt = get_option('capstone')
979 if capstone_opt in ['enabled', 'auto', 'system']
980   have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
981   capstone = dependency('capstone', version: '>=4.0',
982                         static: enable_static, method: 'pkg-config',
983                         required: capstone_opt == 'system' or
984                                   capstone_opt == 'enabled' and not have_internal)
985   if capstone.found()
986     capstone_opt = 'system'
987   elif have_internal
988     capstone_opt = 'internal'
989   else
990     capstone_opt = 'disabled'
991   endif
992 endif
993 if capstone_opt == 'internal'
994   capstone_data = configuration_data()
995   capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
997   capstone_files = files(
998     'capstone/cs.c',
999     'capstone/MCInst.c',
1000     'capstone/MCInstrDesc.c',
1001     'capstone/MCRegisterInfo.c',
1002     'capstone/SStream.c',
1003     'capstone/utils.c'
1004   )
1006   if 'CONFIG_ARM_DIS' in config_all_disas
1007     capstone_data.set('CAPSTONE_HAS_ARM', '1')
1008     capstone_files += files(
1009       'capstone/arch/ARM/ARMDisassembler.c',
1010       'capstone/arch/ARM/ARMInstPrinter.c',
1011       'capstone/arch/ARM/ARMMapping.c',
1012       'capstone/arch/ARM/ARMModule.c'
1013     )
1014   endif
1016   # FIXME: This config entry currently depends on a c++ compiler.
1017   # Which is needed for building libvixl, but not for capstone.
1018   if 'CONFIG_ARM_A64_DIS' in config_all_disas
1019     capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1020     capstone_files += files(
1021       'capstone/arch/AArch64/AArch64BaseInfo.c',
1022       'capstone/arch/AArch64/AArch64Disassembler.c',
1023       'capstone/arch/AArch64/AArch64InstPrinter.c',
1024       'capstone/arch/AArch64/AArch64Mapping.c',
1025       'capstone/arch/AArch64/AArch64Module.c'
1026     )
1027   endif
1029   if 'CONFIG_PPC_DIS' in config_all_disas
1030     capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1031     capstone_files += files(
1032       'capstone/arch/PowerPC/PPCDisassembler.c',
1033       'capstone/arch/PowerPC/PPCInstPrinter.c',
1034       'capstone/arch/PowerPC/PPCMapping.c',
1035       'capstone/arch/PowerPC/PPCModule.c'
1036     )
1037   endif
1039   if 'CONFIG_S390_DIS' in config_all_disas
1040     capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1041     capstone_files += files(
1042       'capstone/arch/SystemZ/SystemZDisassembler.c',
1043       'capstone/arch/SystemZ/SystemZInstPrinter.c',
1044       'capstone/arch/SystemZ/SystemZMapping.c',
1045       'capstone/arch/SystemZ/SystemZModule.c',
1046       'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1047     )
1048   endif
1050   if 'CONFIG_I386_DIS' in config_all_disas
1051     capstone_data.set('CAPSTONE_HAS_X86', 1)
1052     capstone_files += files(
1053       'capstone/arch/X86/X86Disassembler.c',
1054       'capstone/arch/X86/X86DisassemblerDecoder.c',
1055       'capstone/arch/X86/X86ATTInstPrinter.c',
1056       'capstone/arch/X86/X86IntelInstPrinter.c',
1057       'capstone/arch/X86/X86InstPrinterCommon.c',
1058       'capstone/arch/X86/X86Mapping.c',
1059       'capstone/arch/X86/X86Module.c'
1060     )
1061   endif
1063   configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1065   capstone_cargs = [
1066     # FIXME: There does not seem to be a way to completely replace the c_args
1067     # that come from add_project_arguments() -- we can only add to them.
1068     # So: disable all warnings with a big hammer.
1069     '-Wno-error', '-w',
1071     # Include all configuration defines via a header file, which will wind up
1072     # as a dependency on the object file, and thus changes here will result
1073     # in a rebuild.
1074     '-include', 'capstone-defs.h'
1075   ]
1077   libcapstone = static_library('capstone',
1078                                sources: capstone_files,
1079                                c_args: capstone_cargs,
1080                                include_directories: 'capstone/include')
1081   capstone = declare_dependency(link_with: libcapstone,
1082                                 include_directories: 'capstone/include/capstone')
1083 endif
1085 slirp = not_found
1086 slirp_opt = 'disabled'
1087 if have_system
1088   slirp_opt = get_option('slirp')
1089   if slirp_opt in ['enabled', 'auto', 'system']
1090     have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1091     slirp = dependency('slirp', static: enable_static,
1092                        method: 'pkg-config',
1093                        required: slirp_opt == 'system' or
1094                                  slirp_opt == 'enabled' and not have_internal)
1095     if slirp.found()
1096       slirp_opt = 'system'
1097     elif have_internal
1098       slirp_opt = 'internal'
1099     else
1100       slirp_opt = 'disabled'
1101     endif
1102   endif
1103   if slirp_opt == 'internal'
1104     slirp_deps = []
1105     if targetos == 'windows'
1106       slirp_deps = cc.find_library('iphlpapi')
1107     endif
1108     slirp_conf = configuration_data()
1109     slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1110     slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1111     slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1112     slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1113     slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1114     slirp_files = [
1115       'slirp/src/arp_table.c',
1116       'slirp/src/bootp.c',
1117       'slirp/src/cksum.c',
1118       'slirp/src/dhcpv6.c',
1119       'slirp/src/dnssearch.c',
1120       'slirp/src/if.c',
1121       'slirp/src/ip6_icmp.c',
1122       'slirp/src/ip6_input.c',
1123       'slirp/src/ip6_output.c',
1124       'slirp/src/ip_icmp.c',
1125       'slirp/src/ip_input.c',
1126       'slirp/src/ip_output.c',
1127       'slirp/src/mbuf.c',
1128       'slirp/src/misc.c',
1129       'slirp/src/ncsi.c',
1130       'slirp/src/ndp_table.c',
1131       'slirp/src/sbuf.c',
1132       'slirp/src/slirp.c',
1133       'slirp/src/socket.c',
1134       'slirp/src/state.c',
1135       'slirp/src/stream.c',
1136       'slirp/src/tcp_input.c',
1137       'slirp/src/tcp_output.c',
1138       'slirp/src/tcp_subr.c',
1139       'slirp/src/tcp_timer.c',
1140       'slirp/src/tftp.c',
1141       'slirp/src/udp.c',
1142       'slirp/src/udp6.c',
1143       'slirp/src/util.c',
1144       'slirp/src/version.c',
1145       'slirp/src/vmstate.c',
1146     ]
1148     configure_file(
1149       input : 'slirp/src/libslirp-version.h.in',
1150       output : 'libslirp-version.h',
1151       configuration: slirp_conf)
1153     slirp_inc = include_directories('slirp', 'slirp/src')
1154     libslirp = static_library('slirp',
1155                               sources: slirp_files,
1156                               c_args: slirp_cargs,
1157                               include_directories: slirp_inc)
1158     slirp = declare_dependency(link_with: libslirp,
1159                                dependencies: slirp_deps,
1160                                include_directories: slirp_inc)
1161   endif
1162 endif
1164 fdt = not_found
1165 fdt_opt = get_option('fdt')
1166 if have_system
1167   if fdt_opt in ['enabled', 'auto', 'system']
1168     have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1169     fdt = cc.find_library('fdt', static: enable_static,
1170                           required: fdt_opt == 'system' or
1171                                     fdt_opt == 'enabled' and not have_internal)
1172     if fdt.found() and cc.links('''
1173        #include <libfdt.h>
1174        #include <libfdt_env.h>
1175        int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1176          dependencies: fdt)
1177       fdt_opt = 'system'
1178     elif have_internal
1179       fdt_opt = 'internal'
1180     else
1181       fdt_opt = 'disabled'
1182     endif
1183   endif
1184   if fdt_opt == 'internal'
1185     fdt_files = files(
1186       'dtc/libfdt/fdt.c',
1187       'dtc/libfdt/fdt_ro.c',
1188       'dtc/libfdt/fdt_wip.c',
1189       'dtc/libfdt/fdt_sw.c',
1190       'dtc/libfdt/fdt_rw.c',
1191       'dtc/libfdt/fdt_strerror.c',
1192       'dtc/libfdt/fdt_empty_tree.c',
1193       'dtc/libfdt/fdt_addresses.c',
1194       'dtc/libfdt/fdt_overlay.c',
1195       'dtc/libfdt/fdt_check.c',
1196     )
1198     fdt_inc = include_directories('dtc/libfdt')
1199     libfdt = static_library('fdt',
1200                             sources: fdt_files,
1201                             include_directories: fdt_inc)
1202     fdt = declare_dependency(link_with: libfdt,
1203                              include_directories: fdt_inc)
1204   endif
1205 endif
1206 if not fdt.found() and fdt_required.length() > 0
1207   error('fdt not available but required by targets ' + ', '.join(fdt_required))
1208 endif
1210 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1211 config_host_data.set('CONFIG_FDT', fdt.found())
1212 config_host_data.set('CONFIG_SLIRP', slirp.found())
1214 #####################
1215 # Generated sources #
1216 #####################
1218 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1220 hxtool = find_program('scripts/hxtool')
1221 shaderinclude = find_program('scripts/shaderinclude.pl')
1222 qapi_gen = find_program('scripts/qapi-gen.py')
1223 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1224                      meson.source_root() / 'scripts/qapi/commands.py',
1225                      meson.source_root() / 'scripts/qapi/common.py',
1226                      meson.source_root() / 'scripts/qapi/error.py',
1227                      meson.source_root() / 'scripts/qapi/events.py',
1228                      meson.source_root() / 'scripts/qapi/expr.py',
1229                      meson.source_root() / 'scripts/qapi/gen.py',
1230                      meson.source_root() / 'scripts/qapi/introspect.py',
1231                      meson.source_root() / 'scripts/qapi/parser.py',
1232                      meson.source_root() / 'scripts/qapi/schema.py',
1233                      meson.source_root() / 'scripts/qapi/source.py',
1234                      meson.source_root() / 'scripts/qapi/types.py',
1235                      meson.source_root() / 'scripts/qapi/visit.py',
1236                      meson.source_root() / 'scripts/qapi/common.py',
1237                      meson.source_root() / 'scripts/qapi-gen.py'
1240 tracetool = [
1241   python, files('scripts/tracetool.py'),
1242    '--backend=' + config_host['TRACE_BACKENDS']
1245 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1246                     meson.current_source_dir(),
1247                     config_host['PKGVERSION'], meson.project_version()]
1248 qemu_version = custom_target('qemu-version.h',
1249                              output: 'qemu-version.h',
1250                              command: qemu_version_cmd,
1251                              capture: true,
1252                              build_by_default: true,
1253                              build_always_stale: true)
1254 genh += qemu_version
1256 hxdep = []
1257 hx_headers = [
1258   ['qemu-options.hx', 'qemu-options.def'],
1259   ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1261 if have_system
1262   hx_headers += [
1263     ['hmp-commands.hx', 'hmp-commands.h'],
1264     ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1265   ]
1266 endif
1267 foreach d : hx_headers
1268   hxdep += custom_target(d[1],
1269                 input: files(d[0]),
1270                 output: d[1],
1271                 capture: true,
1272                 build_by_default: true, # to be removed when added to a target
1273                 command: [hxtool, '-h', '@INPUT0@'])
1274 endforeach
1275 genh += hxdep
1277 ###################
1278 # Collect sources #
1279 ###################
1281 authz_ss = ss.source_set()
1282 blockdev_ss = ss.source_set()
1283 block_ss = ss.source_set()
1284 bsd_user_ss = ss.source_set()
1285 chardev_ss = ss.source_set()
1286 common_ss = ss.source_set()
1287 crypto_ss = ss.source_set()
1288 io_ss = ss.source_set()
1289 linux_user_ss = ss.source_set()
1290 qmp_ss = ss.source_set()
1291 qom_ss = ss.source_set()
1292 softmmu_ss = ss.source_set()
1293 specific_fuzz_ss = ss.source_set()
1294 specific_ss = ss.source_set()
1295 stub_ss = ss.source_set()
1296 trace_ss = ss.source_set()
1297 user_ss = ss.source_set()
1298 util_ss = ss.source_set()
1300 modules = {}
1301 hw_arch = {}
1302 target_arch = {}
1303 target_softmmu_arch = {}
1305 ###############
1306 # Trace files #
1307 ###############
1309 # TODO: add each directory to the subdirs from its own meson.build, once
1310 # we have those
1311 trace_events_subdirs = [
1312   'accel/kvm',
1313   'accel/tcg',
1314   'crypto',
1315   'monitor',
1317 if have_user
1318   trace_events_subdirs += [ 'linux-user' ]
1319 endif
1320 if have_block
1321   trace_events_subdirs += [
1322     'authz',
1323     'block',
1324     'io',
1325     'nbd',
1326     'scsi',
1327   ]
1328 endif
1329 if have_system
1330   trace_events_subdirs += [
1331     'audio',
1332     'backends',
1333     'backends/tpm',
1334     'chardev',
1335     'hw/9pfs',
1336     'hw/acpi',
1337     'hw/alpha',
1338     'hw/arm',
1339     'hw/audio',
1340     'hw/block',
1341     'hw/block/dataplane',
1342     'hw/char',
1343     'hw/display',
1344     'hw/dma',
1345     'hw/hppa',
1346     'hw/hyperv',
1347     'hw/i2c',
1348     'hw/i386',
1349     'hw/i386/xen',
1350     'hw/ide',
1351     'hw/input',
1352     'hw/intc',
1353     'hw/isa',
1354     'hw/mem',
1355     'hw/mips',
1356     'hw/misc',
1357     'hw/misc/macio',
1358     'hw/net',
1359     'hw/nvram',
1360     'hw/pci',
1361     'hw/pci-host',
1362     'hw/ppc',
1363     'hw/rdma',
1364     'hw/rdma/vmw',
1365     'hw/rtc',
1366     'hw/s390x',
1367     'hw/scsi',
1368     'hw/sd',
1369     'hw/sparc',
1370     'hw/sparc64',
1371     'hw/ssi',
1372     'hw/timer',
1373     'hw/tpm',
1374     'hw/usb',
1375     'hw/vfio',
1376     'hw/virtio',
1377     'hw/watchdog',
1378     'hw/xen',
1379     'hw/gpio',
1380     'migration',
1381     'net',
1382     'softmmu',
1383     'ui',
1384   ]
1385 endif
1386 trace_events_subdirs += [
1387   'hw/core',
1388   'qapi',
1389   'qom',
1390   'target/arm',
1391   'target/hppa',
1392   'target/i386',
1393   'target/mips',
1394   'target/ppc',
1395   'target/riscv',
1396   'target/s390x',
1397   'target/sparc',
1398   'util',
1401 vhost_user = not_found
1402 if 'CONFIG_VHOST_USER' in config_host
1403   subdir('contrib/libvhost-user')
1404 endif
1406 subdir('qapi')
1407 subdir('qobject')
1408 subdir('stubs')
1409 subdir('trace')
1410 subdir('util')
1411 subdir('qom')
1412 subdir('authz')
1413 subdir('crypto')
1414 subdir('ui')
1417 if enable_modules
1418   libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1419   modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1420 endif
1422 stub_ss = stub_ss.apply(config_all, strict: false)
1424 util_ss.add_all(trace_ss)
1425 util_ss = util_ss.apply(config_all, strict: false)
1426 libqemuutil = static_library('qemuutil',
1427                              sources: util_ss.sources() + stub_ss.sources() + genh,
1428                              dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1429 qemuutil = declare_dependency(link_with: libqemuutil,
1430                               sources: genh + version_res)
1432 decodetree = generator(find_program('scripts/decodetree.py'),
1433                        output: 'decode-@BASENAME@.c.inc',
1434                        arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1436 subdir('audio')
1437 subdir('io')
1438 subdir('chardev')
1439 subdir('fsdev')
1440 subdir('libdecnumber')
1441 subdir('target')
1442 subdir('dump')
1444 block_ss.add(files(
1445   'block.c',
1446   'blockdev-nbd.c',
1447   'blockjob.c',
1448   'job.c',
1449   'qemu-io-cmds.c',
1451 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1453 subdir('nbd')
1454 subdir('scsi')
1455 subdir('block')
1457 blockdev_ss.add(files(
1458   'blockdev.c',
1459   'iothread.c',
1460   'job-qmp.c',
1463 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1464 # os-win32.c does not
1465 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1466 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1468 common_ss.add(files('cpus-common.c'))
1470 subdir('softmmu')
1472 common_ss.add(capstone)
1473 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
1474 specific_ss.add(files('exec-vary.c'))
1475 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1476   'fpu/softfloat.c',
1477   'tcg/optimize.c',
1478   'tcg/tcg-common.c',
1479   'tcg/tcg-op-gvec.c',
1480   'tcg/tcg-op-vec.c',
1481   'tcg/tcg-op.c',
1482   'tcg/tcg.c',
1484 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1486 subdir('backends')
1487 subdir('disas')
1488 subdir('migration')
1489 subdir('monitor')
1490 subdir('net')
1491 subdir('replay')
1492 subdir('hw')
1493 subdir('accel')
1494 subdir('plugins')
1495 subdir('bsd-user')
1496 subdir('linux-user')
1498 bsd_user_ss.add(files('gdbstub.c'))
1499 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1501 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1502 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1504 # needed for fuzzing binaries
1505 subdir('tests/qtest/libqos')
1506 subdir('tests/qtest/fuzz')
1508 ########################
1509 # Library dependencies #
1510 ########################
1512 block_mods = []
1513 softmmu_mods = []
1514 foreach d, list : modules
1515   foreach m, module_ss : list
1516     if enable_modules and targetos != 'windows'
1517       module_ss = module_ss.apply(config_all, strict: false)
1518       sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1519                           dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1520       if d == 'block'
1521         block_mods += sl
1522       else
1523         softmmu_mods += sl
1524       endif
1525     else
1526       if d == 'block'
1527         block_ss.add_all(module_ss)
1528       else
1529         softmmu_ss.add_all(module_ss)
1530       endif
1531     endif
1532   endforeach
1533 endforeach
1535 nm = find_program('nm')
1536 undefsym = find_program('scripts/undefsym.py')
1537 block_syms = custom_target('block.syms', output: 'block.syms',
1538                              input: [libqemuutil, block_mods],
1539                              capture: true,
1540                              command: [undefsym, nm, '@INPUT@'])
1541 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1542                              input: [libqemuutil, softmmu_mods],
1543                              capture: true,
1544                              command: [undefsym, nm, '@INPUT@'])
1546 qom_ss = qom_ss.apply(config_host, strict: false)
1547 libqom = static_library('qom', qom_ss.sources() + genh,
1548                         dependencies: [qom_ss.dependencies()],
1549                         name_suffix: 'fa')
1551 qom = declare_dependency(link_whole: libqom)
1553 authz_ss = authz_ss.apply(config_host, strict: false)
1554 libauthz = static_library('authz', authz_ss.sources() + genh,
1555                           dependencies: [authz_ss.dependencies()],
1556                           name_suffix: 'fa',
1557                           build_by_default: false)
1559 authz = declare_dependency(link_whole: libauthz,
1560                            dependencies: qom)
1562 crypto_ss = crypto_ss.apply(config_host, strict: false)
1563 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
1564                            dependencies: [crypto_ss.dependencies()],
1565                            name_suffix: 'fa',
1566                            build_by_default: false)
1568 crypto = declare_dependency(link_whole: libcrypto,
1569                             dependencies: [authz, qom])
1571 io_ss = io_ss.apply(config_host, strict: false)
1572 libio = static_library('io', io_ss.sources() + genh,
1573                        dependencies: [io_ss.dependencies()],
1574                        link_with: libqemuutil,
1575                        name_suffix: 'fa',
1576                        build_by_default: false)
1578 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
1580 libmigration = static_library('migration', sources: migration_files + genh,
1581                               name_suffix: 'fa',
1582                               build_by_default: false)
1583 migration = declare_dependency(link_with: libmigration,
1584                                dependencies: [zlib, qom, io])
1585 softmmu_ss.add(migration)
1587 block_ss = block_ss.apply(config_host, strict: false)
1588 libblock = static_library('block', block_ss.sources() + genh,
1589                           dependencies: block_ss.dependencies(),
1590                           link_depends: block_syms,
1591                           name_suffix: 'fa',
1592                           build_by_default: false)
1594 block = declare_dependency(link_whole: [libblock],
1595                            link_args: '@block.syms',
1596                            dependencies: [crypto, io])
1598 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
1599 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
1600                              dependencies: blockdev_ss.dependencies(),
1601                              name_suffix: 'fa',
1602                              build_by_default: false)
1604 blockdev = declare_dependency(link_whole: [libblockdev],
1605                               dependencies: [block])
1607 qmp_ss = qmp_ss.apply(config_host, strict: false)
1608 libqmp = static_library('qmp', qmp_ss.sources() + genh,
1609                         dependencies: qmp_ss.dependencies(),
1610                         name_suffix: 'fa',
1611                         build_by_default: false)
1613 qmp = declare_dependency(link_whole: [libqmp])
1615 libchardev = static_library('chardev', chardev_ss.sources() + genh,
1616                             name_suffix: 'fa',
1617                             build_by_default: false)
1619 chardev = declare_dependency(link_whole: libchardev)
1621 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
1622                            name_suffix: 'fa',
1623                            build_by_default: false)
1624 hwcore = declare_dependency(link_whole: libhwcore)
1625 common_ss.add(hwcore)
1627 ###########
1628 # Targets #
1629 ###########
1631 foreach m : block_mods + softmmu_mods
1632   shared_module(m.name(),
1633                 name_prefix: '',
1634                 link_whole: m,
1635                 install: true,
1636                 install_dir: config_host['qemu_moddir'])
1637 endforeach
1639 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
1640 common_ss.add(qom, qemuutil)
1642 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
1643 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
1645 common_all = common_ss.apply(config_all, strict: false)
1646 common_all = static_library('common',
1647                             build_by_default: false,
1648                             sources: common_all.sources() + genh,
1649                             dependencies: common_all.dependencies(),
1650                             name_suffix: 'fa')
1652 feature_to_c = find_program('scripts/feature_to_c.sh')
1654 emulators = {}
1655 foreach target : target_dirs
1656   config_target = config_target_mak[target]
1657   target_name = config_target['TARGET_NAME']
1658   arch = config_target['TARGET_BASE_ARCH']
1659   arch_srcs = [config_target_h[target]]
1660   arch_deps = []
1661   c_args = ['-DNEED_CPU_H',
1662             '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
1663             '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
1664   link_args = emulator_link_args
1666   config_target += config_host
1667   target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
1668   if targetos == 'linux'
1669     target_inc += include_directories('linux-headers', is_system: true)
1670   endif
1671   if target.endswith('-softmmu')
1672     qemu_target_name = 'qemu-system-' + target_name
1673     target_type='system'
1674     t = target_softmmu_arch[arch].apply(config_target, strict: false)
1675     arch_srcs += t.sources()
1676     arch_deps += t.dependencies()
1678     hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
1679     hw = hw_arch[hw_dir].apply(config_target, strict: false)
1680     arch_srcs += hw.sources()
1681     arch_deps += hw.dependencies()
1683     arch_srcs += config_devices_h[target]
1684     link_args += ['@block.syms', '@qemu.syms']
1685   else
1686     abi = config_target['TARGET_ABI_DIR']
1687     target_type='user'
1688     qemu_target_name = 'qemu-' + target_name
1689     if 'CONFIG_LINUX_USER' in config_target
1690       base_dir = 'linux-user'
1691       target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
1692     else
1693       base_dir = 'bsd-user'
1694     endif
1695     target_inc += include_directories(
1696       base_dir,
1697       base_dir / abi,
1698     )
1699     if 'CONFIG_LINUX_USER' in config_target
1700       dir = base_dir / abi
1701       arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
1702       if config_target.has_key('TARGET_SYSTBL_ABI')
1703         arch_srcs += \
1704           syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
1705                                              extra_args : config_target['TARGET_SYSTBL_ABI'])
1706       endif
1707     endif
1708   endif
1710   if 'TARGET_XML_FILES' in config_target
1711     gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
1712                                 output: target + '-gdbstub-xml.c',
1713                                 input: files(config_target['TARGET_XML_FILES'].split()),
1714                                 command: [feature_to_c, '@INPUT@'],
1715                                 capture: true)
1716     arch_srcs += gdbstub_xml
1717   endif
1719   t = target_arch[arch].apply(config_target, strict: false)
1720   arch_srcs += t.sources()
1721   arch_deps += t.dependencies()
1723   target_common = common_ss.apply(config_target, strict: false)
1724   objects = common_all.extract_objects(target_common.sources())
1725   deps = target_common.dependencies()
1727   target_specific = specific_ss.apply(config_target, strict: false)
1728   arch_srcs += target_specific.sources()
1729   arch_deps += target_specific.dependencies()
1731   lib = static_library('qemu-' + target,
1732                  sources: arch_srcs + genh,
1733                  dependencies: arch_deps,
1734                  objects: objects,
1735                  include_directories: target_inc,
1736                  c_args: c_args,
1737                  build_by_default: false,
1738                  name_suffix: 'fa')
1740   if target.endswith('-softmmu')
1741     execs = [{
1742       'name': 'qemu-system-' + target_name,
1743       'gui': false,
1744       'sources': files('softmmu/main.c'),
1745       'dependencies': []
1746     }]
1747     if targetos == 'windows' and (sdl.found() or gtk.found())
1748       execs += [{
1749         'name': 'qemu-system-' + target_name + 'w',
1750         'gui': true,
1751         'sources': files('softmmu/main.c'),
1752         'dependencies': []
1753       }]
1754     endif
1755     if config_host.has_key('CONFIG_FUZZ')
1756       specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
1757       execs += [{
1758         'name': 'qemu-fuzz-' + target_name,
1759         'gui': false,
1760         'sources': specific_fuzz.sources(),
1761         'dependencies': specific_fuzz.dependencies(),
1762       }]
1763     endif
1764   else
1765     execs = [{
1766       'name': 'qemu-' + target_name,
1767       'gui': false,
1768       'sources': [],
1769       'dependencies': []
1770     }]
1771   endif
1772   foreach exe: execs
1773     emulators += {exe['name']:
1774          executable(exe['name'], exe['sources'],
1775                install: true,
1776                c_args: c_args,
1777                dependencies: arch_deps + deps + exe['dependencies'],
1778                objects: lib.extract_all_objects(recursive: true),
1779                link_language: link_language,
1780                link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
1781                link_args: link_args,
1782                gui_app: exe['gui'])
1783     }
1785     if 'CONFIG_TRACE_SYSTEMTAP' in config_host
1786       foreach stp: [
1787         {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
1788         {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
1789         {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
1790         {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
1791       ]
1792         custom_target(exe['name'] + stp['ext'],
1793                       input: trace_events_all,
1794                       output: exe['name'] + stp['ext'],
1795                       capture: true,
1796                       install: stp['install'],
1797                       install_dir: qemu_datadir / '../systemtap/tapset',
1798                       command: [
1799                         tracetool, '--group=all', '--format=' + stp['fmt'],
1800                         '--binary=' + stp['bin'],
1801                         '--target-name=' + target_name,
1802                         '--target-type=' + target_type,
1803                         '--probe-prefix=qemu.' + target_type + '.' + target_name,
1804                         '@INPUT@',
1805                       ])
1806       endforeach
1807     endif
1808   endforeach
1809 endforeach
1811 # Other build targets
1813 if 'CONFIG_PLUGIN' in config_host
1814   install_headers('include/qemu/qemu-plugin.h')
1815 endif
1817 if 'CONFIG_GUEST_AGENT' in config_host
1818   subdir('qga')
1819 endif
1821 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
1822 # when we don't build tools or system
1823 if xkbcommon.found()
1824   # used for the update-keymaps target, so include rules even if !have_tools
1825   qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
1826                            dependencies: [qemuutil, xkbcommon], install: have_tools)
1827 endif
1829 if have_tools
1830   qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
1831              dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
1832   qemu_io = executable('qemu-io', files('qemu-io.c'),
1833              dependencies: [block, qemuutil], install: true)
1834   qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
1835                dependencies: [block, qemuutil], install: true)
1837   subdir('storage-daemon')
1838   subdir('contrib/rdmacm-mux')
1839   subdir('contrib/elf2dmp')
1841   executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
1842              dependencies: qemuutil,
1843              install: true)
1845   if 'CONFIG_VHOST_USER' in config_host
1846     subdir('contrib/vhost-user-blk')
1847     subdir('contrib/vhost-user-gpu')
1848     subdir('contrib/vhost-user-input')
1849     subdir('contrib/vhost-user-scsi')
1850   endif
1852   if targetos == 'linux'
1853     executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
1854                dependencies: [qemuutil, libcap_ng],
1855                install: true,
1856                install_dir: get_option('libexecdir'))
1858     executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
1859                dependencies: [authz, crypto, io, qom, qemuutil,
1860                               libcap_ng, mpathpersist],
1861                install: true)
1862   endif
1864   if 'CONFIG_IVSHMEM' in config_host
1865     subdir('contrib/ivshmem-client')
1866     subdir('contrib/ivshmem-server')
1867   endif
1868 endif
1870 subdir('scripts')
1871 subdir('tools')
1872 subdir('pc-bios')
1873 subdir('docs')
1874 subdir('tests')
1875 if 'CONFIG_GTK' in config_host
1876   subdir('po')
1877 endif
1879 if host_machine.system() == 'windows'
1880   nsis_cmd = [
1881     find_program('scripts/nsis.py'),
1882     '@OUTPUT@',
1883     get_option('prefix'),
1884     meson.current_source_dir(),
1885     host_machine.cpu_family(),
1886     '--',
1887     '-DDISPLAYVERSION=' + meson.project_version(),
1888   ]
1889   if build_docs
1890     nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
1891   endif
1892   if 'CONFIG_GTK' in config_host
1893     nsis_cmd += '-DCONFIG_GTK=y'
1894   endif
1896   nsis = custom_target('nsis',
1897                        output: 'qemu-setup-' + meson.project_version() + '.exe',
1898                        input: files('qemu.nsi'),
1899                        build_always_stale: true,
1900                        command: nsis_cmd + ['@INPUT@'])
1901   alias_target('installer', nsis)
1902 endif
1904 #########################
1905 # Configuration summary #
1906 #########################
1908 summary_info = {}
1909 summary_info += {'Install prefix':    config_host['prefix']}
1910 summary_info += {'BIOS directory':    config_host['qemu_datadir']}
1911 summary_info += {'firmware path':     config_host['qemu_firmwarepath']}
1912 summary_info += {'binary directory':  config_host['bindir']}
1913 summary_info += {'library directory': config_host['libdir']}
1914 summary_info += {'module directory':  config_host['qemu_moddir']}
1915 summary_info += {'libexec directory': config_host['libexecdir']}
1916 summary_info += {'include directory': config_host['includedir']}
1917 summary_info += {'config directory':  config_host['sysconfdir']}
1918 if targetos != 'windows'
1919   summary_info += {'local state directory': config_host['qemu_localstatedir']}
1920   summary_info += {'Manual directory':      get_option('mandir')}
1921 else
1922   summary_info += {'local state directory': 'queried at runtime'}
1923 endif
1924 summary_info += {'Doc directory':     get_option('docdir')}
1925 summary_info += {'Build directory':   meson.current_build_dir()}
1926 summary_info += {'Source path':       meson.current_source_dir()}
1927 summary_info += {'GIT binary':        config_host['GIT']}
1928 summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
1929 summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
1930 summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
1931 if link_language == 'cpp'
1932   summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
1933 else
1934   summary_info += {'C++ compiler':      false}
1935 endif
1936 if targetos == 'darwin'
1937   summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
1938 endif
1939 summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
1940 summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
1941                                                + ['-O' + get_option('optimization')]
1942                                                + (get_option('debug') ? ['-g'] : []))}
1943 if link_language == 'cpp'
1944   summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
1945                                                + ['-O' + get_option('optimization')]
1946                                                + (get_option('debug') ? ['-g'] : []))}
1947 endif
1948 link_args = get_option(link_language + '_link_args')
1949 if link_args.length() > 0
1950   summary_info += {'LDFLAGS':         ' '.join(link_args)}
1951 endif
1952 summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
1953 summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
1954 summary_info += {'make':              config_host['MAKE']}
1955 summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
1956 summary_info += {'sphinx-build':      sphinx_build.found()}
1957 summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
1958 # TODO: add back version
1959 summary_info += {'slirp support':     slirp_opt == 'disabled' ? false : slirp_opt}
1960 if slirp_opt != 'disabled'
1961   summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
1962 endif
1963 summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
1964 if config_host.has_key('CONFIG_MODULES')
1965   summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
1966 endif
1967 summary_info += {'host CPU':          cpu}
1968 summary_info += {'host endianness':   build_machine.endian()}
1969 summary_info += {'target list':       ' '.join(target_dirs)}
1970 summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
1971 summary_info += {'sparse enabled':    sparse.found()}
1972 summary_info += {'strip binaries':    get_option('strip')}
1973 summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
1974 summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
1975 if targetos == 'darwin'
1976   summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
1977 endif
1978 # TODO: add back version
1979 summary_info += {'SDL support':       sdl.found()}
1980 summary_info += {'SDL image support': sdl_image.found()}
1981 # TODO: add back version
1982 summary_info += {'GTK support':       config_host.has_key('CONFIG_GTK')}
1983 summary_info += {'GTK GL support':    config_host.has_key('CONFIG_GTK_GL')}
1984 summary_info += {'pixman':            pixman.found()}
1985 # TODO: add back version
1986 summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
1987 summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
1988 summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
1989 # TODO: add back version
1990 summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
1991 if config_host.has_key('CONFIG_GCRYPT')
1992    summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
1993    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1994 endif
1995 # TODO: add back version
1996 summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
1997 if config_host.has_key('CONFIG_NETTLE')
1998    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
1999 endif
2000 summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
2001 summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
2002 summary_info += {'iconv support':     iconv.found()}
2003 summary_info += {'curses support':    curses.found()}
2004 # TODO: add back version
2005 summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
2006 summary_info += {'curl support':      config_host.has_key('CONFIG_CURL')}
2007 summary_info += {'mingw32 support':   targetos == 'windows'}
2008 summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
2009 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2010 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2011 summary_info += {'VirtFS support':    config_host.has_key('CONFIG_VIRTFS')}
2012 summary_info += {'Multipath support': mpathpersist.found()}
2013 summary_info += {'VNC support':       vnc.found()}
2014 if vnc.found()
2015   summary_info += {'VNC SASL support':  sasl.found()}
2016   summary_info += {'VNC JPEG support':  jpeg.found()}
2017   summary_info += {'VNC PNG support':   png.found()}
2018 endif
2019 summary_info += {'xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
2020 if config_host.has_key('CONFIG_XEN_BACKEND')
2021   summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2022 endif
2023 summary_info += {'brlapi support':    config_host.has_key('CONFIG_BRLAPI')}
2024 summary_info += {'Documentation':     build_docs}
2025 summary_info += {'PIE':               get_option('b_pie')}
2026 summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
2027 summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
2028 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2029 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2030 summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
2031 summary_info += {'Install blobs':     config_host.has_key('INSTALL_BLOBS')}
2032 summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
2033 summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
2034 summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
2035 summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
2036 summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
2037 if config_all.has_key('CONFIG_TCG')
2038   summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2039   summary_info += {'TCG interpreter':   config_host.has_key('CONFIG_TCG_INTERPRETER')}
2040 endif
2041 summary_info += {'malloc trim support': has_malloc_trim}
2042 summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
2043 summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
2044 summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
2045 summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
2046 summary_info += {'preadv support':    config_host.has_key('CONFIG_PREADV')}
2047 summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
2048 summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
2049 summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
2050 summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2051 summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
2052 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2053 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2054 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2055 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2056 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2057 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2058 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2059 summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
2060 if config_host['TRACE_BACKENDS'].split().contains('simple')
2061   summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2062 endif
2063 # TODO: add back protocol and server version
2064 summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
2065 summary_info += {'rbd support':       config_host.has_key('CONFIG_RBD')}
2066 summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
2067 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2068 summary_info += {'U2F support':       u2f.found()}
2069 summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
2070 summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
2071 summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
2072 summary_info += {'OpenGL dmabufs':    config_host.has_key('CONFIG_OPENGL_DMABUF')}
2073 summary_info += {'libiscsi support':  config_host.has_key('CONFIG_LIBISCSI')}
2074 summary_info += {'libnfs support':    config_host.has_key('CONFIG_LIBNFS')}
2075 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2076 if targetos == 'windows'
2077   if 'WIN_SDK' in config_host
2078     summary_info += {'Windows SDK':       config_host['WIN_SDK']}
2079   endif
2080   summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
2081   summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2082   summary_info += {'QGA MSI support':   config_host.has_key('CONFIG_QGA_MSI')}
2083 endif
2084 summary_info += {'seccomp support':   config_host.has_key('CONFIG_SECCOMP')}
2085 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2086 summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
2087 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2088 summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
2089 summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
2090 summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
2091 summary_info += {'gcov':              get_option('b_coverage')}
2092 summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
2093 summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
2094 summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2095 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2096 summary_info += {'lzo support':       config_host.has_key('CONFIG_LZO')}
2097 summary_info += {'snappy support':    config_host.has_key('CONFIG_SNAPPY')}
2098 summary_info += {'bzip2 support':     config_host.has_key('CONFIG_BZIP2')}
2099 summary_info += {'lzfse support':     config_host.has_key('CONFIG_LZFSE')}
2100 summary_info += {'zstd support':      config_host.has_key('CONFIG_ZSTD')}
2101 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2102 summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
2103 summary_info += {'memory allocator':  get_option('malloc')}
2104 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2105 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2106 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2107 summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
2108 summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
2109 summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
2110 summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
2111 summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
2112 summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
2113 summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
2114 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2115 summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
2116 summary_info += {'capstone':          capstone_opt == 'disabled' ? false : capstone_opt}
2117 summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
2118 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2119 summary_info += {'libudev':           libudev.found()}
2120 summary_info += {'default devices':   config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
2121 summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
2122 summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
2123 if config_host.has_key('HAVE_GDB_BIN')
2124   summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
2125 endif
2126 summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
2127 summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
2128 summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
2129 summary(summary_info, bool_yn: true)
2131 if not supported_cpus.contains(cpu)
2132   message()
2133   warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2134   message()
2135   message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2136   message('The QEMU project intends to remove support for this host CPU in')
2137   message('a future release if nobody volunteers to maintain it and to')
2138   message('provide a build host for our continuous integration setup.')
2139   message('configure has succeeded and you can continue to build, but')
2140   message('if you care about QEMU on this platform you should contact')
2141   message('us upstream at qemu-devel@nongnu.org.')
2142 endif
2144 if not supported_oses.contains(targetos)
2145   message()
2146   warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2147   message()
2148   message('Host OS ' + targetos + 'support is not currently maintained.')
2149   message('The QEMU project intends to remove support for this host OS in')
2150   message('a future release if nobody volunteers to maintain it and to')
2151   message('provide a build host for our continuous integration setup.')
2152   message('configure has succeeded and you can continue to build, but')
2153   message('if you care about QEMU on this platform you should contact')
2154   message('us upstream at qemu-devel@nongnu.org.')
2155 endif