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