tests/vm: update NetBSD to 9.1
[qemu/ar7.git] / meson.build
blob30f86ddafbf3dbedb378813eaf43a3f00456f576
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 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
799 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
800 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
801 strings = ['HOST_DSOSUF', 'CONFIG_IASL']
802 foreach k, v: config_host
803   if ignored.contains(k)
804     # do nothing
805   elif arrays.contains(k)
806     if v != ''
807       v = '"' + '", "'.join(v.split()) + '", '
808     endif
809     config_host_data.set(k, v)
810   elif k == 'ARCH'
811     config_host_data.set('HOST_' + v.to_upper(), 1)
812   elif strings.contains(k)
813     if not k.startswith('CONFIG_')
814       k = 'CONFIG_' + k.to_upper()
815     endif
816     config_host_data.set_quoted(k, v)
817   elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
818     config_host_data.set(k, v == 'y' ? 1 : v)
819   endif
820 endforeach
822 ########################
823 # Target configuration #
824 ########################
826 minikconf = find_program('scripts/minikconf.py')
827 config_all = {}
828 config_all_devices = {}
829 config_all_disas = {}
830 config_devices_mak_list = []
831 config_devices_h = {}
832 config_target_h = {}
833 config_target_mak = {}
835 disassemblers = {
836   'alpha' : ['CONFIG_ALPHA_DIS'],
837   'arm' : ['CONFIG_ARM_DIS'],
838   'avr' : ['CONFIG_AVR_DIS'],
839   'cris' : ['CONFIG_CRIS_DIS'],
840   'hppa' : ['CONFIG_HPPA_DIS'],
841   'i386' : ['CONFIG_I386_DIS'],
842   'x86_64' : ['CONFIG_I386_DIS'],
843   'x32' : ['CONFIG_I386_DIS'],
844   'lm32' : ['CONFIG_LM32_DIS'],
845   'm68k' : ['CONFIG_M68K_DIS'],
846   'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
847   'mips' : ['CONFIG_MIPS_DIS'],
848   'moxie' : ['CONFIG_MOXIE_DIS'],
849   'nios2' : ['CONFIG_NIOS2_DIS'],
850   'or1k' : ['CONFIG_OPENRISC_DIS'],
851   'ppc' : ['CONFIG_PPC_DIS'],
852   'riscv' : ['CONFIG_RISCV_DIS'],
853   'rx' : ['CONFIG_RX_DIS'],
854   's390' : ['CONFIG_S390_DIS'],
855   'sh4' : ['CONFIG_SH4_DIS'],
856   'sparc' : ['CONFIG_SPARC_DIS'],
857   'xtensa' : ['CONFIG_XTENSA_DIS'],
859 if link_language == 'cpp'
860   disassemblers += {
861     'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
862     'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
863     'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
864   }
865 endif
867 kconfig_external_symbols = [
868   'CONFIG_KVM',
869   'CONFIG_XEN',
870   'CONFIG_TPM',
871   'CONFIG_SPICE',
872   'CONFIG_IVSHMEM',
873   'CONFIG_OPENGL',
874   'CONFIG_X11',
875   'CONFIG_VHOST_USER',
876   'CONFIG_VHOST_VDPA',
877   'CONFIG_VHOST_KERNEL',
878   'CONFIG_VIRTFS',
879   'CONFIG_LINUX',
880   'CONFIG_PVRDMA',
882 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
884 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
885 actual_target_dirs = []
886 fdt_required = []
887 foreach target : target_dirs
888   config_target = { 'TARGET_NAME': target.split('-')[0] }
889   if target.endswith('linux-user')
890     if targetos != 'linux'
891       if default_targets
892         continue
893       endif
894       error('Target @0@ is only available on a Linux host'.format(target))
895     endif
896     config_target += { 'CONFIG_LINUX_USER': 'y' }
897   elif target.endswith('bsd-user')
898     if 'CONFIG_BSD' not in config_host
899       if default_targets
900         continue
901       endif
902       error('Target @0@ is only available on a BSD host'.format(target))
903     endif
904     config_target += { 'CONFIG_BSD_USER': 'y' }
905   elif target.endswith('softmmu')
906     config_target += { 'CONFIG_SOFTMMU': 'y' }
907   endif
908   if target.endswith('-user')
909     config_target += {
910       'CONFIG_USER_ONLY': 'y',
911       'CONFIG_QEMU_INTERP_PREFIX':
912         config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
913     }
914   endif
916   have_accel = false
917   foreach sym: accelerators
918     if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
919       config_target += { sym: 'y' }
920       config_all += { sym: 'y' }
921       if sym == 'CONFIG_XEN' and have_xen_pci_passthrough
922         config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
923       endif
924       have_accel = true
925     endif
926   endforeach
927   if not have_accel
928     if default_targets
929       continue
930     endif
931     error('No accelerator available for target @0@'.format(target))
932   endif
934   actual_target_dirs += target
935   config_target += keyval.load('default-configs/targets' / target + '.mak')
936   config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
938   if 'TARGET_NEED_FDT' in config_target
939     fdt_required += target
940   endif
942   # Add default keys
943   if 'TARGET_BASE_ARCH' not in config_target
944     config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
945   endif
946   if 'TARGET_ABI_DIR' not in config_target
947     config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
948   endif
950   foreach k, v: disassemblers
951     if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
952       foreach sym: v
953         config_target += { sym: 'y' }
954         config_all_disas += { sym: 'y' }
955       endforeach
956     endif
957   endforeach
959   config_target_data = configuration_data()
960   foreach k, v: config_target
961     if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
962       # do nothing
963     elif ignored.contains(k)
964       # do nothing
965     elif k == 'TARGET_BASE_ARCH'
966       # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
967       # not used to select files from sourcesets.
968       config_target_data.set('TARGET_' + v.to_upper(), 1)
969     elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
970       config_target_data.set_quoted(k, v)
971     elif v == 'y'
972       config_target_data.set(k, 1)
973     else
974       config_target_data.set(k, v)
975     endif
976   endforeach
977   config_target_h += {target: configure_file(output: target + '-config-target.h',
978                                                configuration: config_target_data)}
980   if target.endswith('-softmmu')
981     base_kconfig = []
982     foreach sym : kconfig_external_symbols
983       if sym in config_target or sym in config_host
984         base_kconfig += '@0@=y'.format(sym)
985       endif
986     endforeach
988     config_devices_mak = target + '-config-devices.mak'
989     config_devices_mak = configure_file(
990       input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
991       output: config_devices_mak,
992       depfile: config_devices_mak + '.d',
993       capture: true,
994       command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'],
995                 config_devices_mak, '@DEPFILE@', '@INPUT@',
996                 base_kconfig])
998     config_devices_data = configuration_data()
999     config_devices = keyval.load(config_devices_mak)
1000     foreach k, v: config_devices
1001       config_devices_data.set(k, 1)
1002     endforeach
1003     config_devices_mak_list += config_devices_mak
1004     config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1005                                                 configuration: config_devices_data)}
1006     config_target += config_devices
1007     config_all_devices += config_devices
1008   endif
1009   config_target_mak += {target: config_target}
1010 endforeach
1011 target_dirs = actual_target_dirs
1013 # This configuration is used to build files that are shared by
1014 # multiple binaries, and then extracted out of the "common"
1015 # static_library target.
1017 # We do not use all_sources()/all_dependencies(), because it would
1018 # build literally all source files, including devices only used by
1019 # targets that are not built for this compilation.  The CONFIG_ALL
1020 # pseudo symbol replaces it.
1022 config_all += config_all_devices
1023 config_all += config_host
1024 config_all += config_all_disas
1025 config_all += {
1026   'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1027   'CONFIG_SOFTMMU': have_system,
1028   'CONFIG_USER_ONLY': have_user,
1029   'CONFIG_ALL': true,
1032 ##############
1033 # Submodules #
1034 ##############
1036 capstone = not_found
1037 capstone_opt = get_option('capstone')
1038 if capstone_opt in ['enabled', 'auto', 'system']
1039   have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1040   capstone = dependency('capstone', version: '>=4.0',
1041                         static: enable_static, method: 'pkg-config',
1042                         required: capstone_opt == 'system' or
1043                                   capstone_opt == 'enabled' and not have_internal)
1044   if capstone.found()
1045     capstone_opt = 'system'
1046   elif have_internal
1047     capstone_opt = 'internal'
1048   else
1049     capstone_opt = 'disabled'
1050   endif
1051 endif
1052 if capstone_opt == 'internal'
1053   capstone_data = configuration_data()
1054   capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1056   capstone_files = files(
1057     'capstone/cs.c',
1058     'capstone/MCInst.c',
1059     'capstone/MCInstrDesc.c',
1060     'capstone/MCRegisterInfo.c',
1061     'capstone/SStream.c',
1062     'capstone/utils.c'
1063   )
1065   if 'CONFIG_ARM_DIS' in config_all_disas
1066     capstone_data.set('CAPSTONE_HAS_ARM', '1')
1067     capstone_files += files(
1068       'capstone/arch/ARM/ARMDisassembler.c',
1069       'capstone/arch/ARM/ARMInstPrinter.c',
1070       'capstone/arch/ARM/ARMMapping.c',
1071       'capstone/arch/ARM/ARMModule.c'
1072     )
1073   endif
1075   # FIXME: This config entry currently depends on a c++ compiler.
1076   # Which is needed for building libvixl, but not for capstone.
1077   if 'CONFIG_ARM_A64_DIS' in config_all_disas
1078     capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1079     capstone_files += files(
1080       'capstone/arch/AArch64/AArch64BaseInfo.c',
1081       'capstone/arch/AArch64/AArch64Disassembler.c',
1082       'capstone/arch/AArch64/AArch64InstPrinter.c',
1083       'capstone/arch/AArch64/AArch64Mapping.c',
1084       'capstone/arch/AArch64/AArch64Module.c'
1085     )
1086   endif
1088   if 'CONFIG_PPC_DIS' in config_all_disas
1089     capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1090     capstone_files += files(
1091       'capstone/arch/PowerPC/PPCDisassembler.c',
1092       'capstone/arch/PowerPC/PPCInstPrinter.c',
1093       'capstone/arch/PowerPC/PPCMapping.c',
1094       'capstone/arch/PowerPC/PPCModule.c'
1095     )
1096   endif
1098   if 'CONFIG_S390_DIS' in config_all_disas
1099     capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1100     capstone_files += files(
1101       'capstone/arch/SystemZ/SystemZDisassembler.c',
1102       'capstone/arch/SystemZ/SystemZInstPrinter.c',
1103       'capstone/arch/SystemZ/SystemZMapping.c',
1104       'capstone/arch/SystemZ/SystemZModule.c',
1105       'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1106     )
1107   endif
1109   if 'CONFIG_I386_DIS' in config_all_disas
1110     capstone_data.set('CAPSTONE_HAS_X86', 1)
1111     capstone_files += files(
1112       'capstone/arch/X86/X86Disassembler.c',
1113       'capstone/arch/X86/X86DisassemblerDecoder.c',
1114       'capstone/arch/X86/X86ATTInstPrinter.c',
1115       'capstone/arch/X86/X86IntelInstPrinter.c',
1116       'capstone/arch/X86/X86InstPrinterCommon.c',
1117       'capstone/arch/X86/X86Mapping.c',
1118       'capstone/arch/X86/X86Module.c'
1119     )
1120   endif
1122   configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1124   capstone_cargs = [
1125     # FIXME: There does not seem to be a way to completely replace the c_args
1126     # that come from add_project_arguments() -- we can only add to them.
1127     # So: disable all warnings with a big hammer.
1128     '-Wno-error', '-w',
1130     # Include all configuration defines via a header file, which will wind up
1131     # as a dependency on the object file, and thus changes here will result
1132     # in a rebuild.
1133     '-include', 'capstone-defs.h'
1134   ]
1136   libcapstone = static_library('capstone',
1137                                sources: capstone_files,
1138                                c_args: capstone_cargs,
1139                                include_directories: 'capstone/include')
1140   capstone = declare_dependency(link_with: libcapstone,
1141                                 include_directories: 'capstone/include/capstone')
1142 endif
1144 slirp = not_found
1145 slirp_opt = 'disabled'
1146 if have_system
1147   slirp_opt = get_option('slirp')
1148   if slirp_opt in ['enabled', 'auto', 'system']
1149     have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1150     slirp = dependency('slirp', static: enable_static,
1151                        method: 'pkg-config',
1152                        required: slirp_opt == 'system' or
1153                                  slirp_opt == 'enabled' and not have_internal)
1154     if slirp.found()
1155       slirp_opt = 'system'
1156     elif have_internal
1157       slirp_opt = 'internal'
1158     else
1159       slirp_opt = 'disabled'
1160     endif
1161   endif
1162   if slirp_opt == 'internal'
1163     slirp_deps = []
1164     if targetos == 'windows'
1165       slirp_deps = cc.find_library('iphlpapi')
1166     endif
1167     slirp_conf = configuration_data()
1168     slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1169     slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1170     slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1171     slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1172     slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1173     slirp_files = [
1174       'slirp/src/arp_table.c',
1175       'slirp/src/bootp.c',
1176       'slirp/src/cksum.c',
1177       'slirp/src/dhcpv6.c',
1178       'slirp/src/dnssearch.c',
1179       'slirp/src/if.c',
1180       'slirp/src/ip6_icmp.c',
1181       'slirp/src/ip6_input.c',
1182       'slirp/src/ip6_output.c',
1183       'slirp/src/ip_icmp.c',
1184       'slirp/src/ip_input.c',
1185       'slirp/src/ip_output.c',
1186       'slirp/src/mbuf.c',
1187       'slirp/src/misc.c',
1188       'slirp/src/ncsi.c',
1189       'slirp/src/ndp_table.c',
1190       'slirp/src/sbuf.c',
1191       'slirp/src/slirp.c',
1192       'slirp/src/socket.c',
1193       'slirp/src/state.c',
1194       'slirp/src/stream.c',
1195       'slirp/src/tcp_input.c',
1196       'slirp/src/tcp_output.c',
1197       'slirp/src/tcp_subr.c',
1198       'slirp/src/tcp_timer.c',
1199       'slirp/src/tftp.c',
1200       'slirp/src/udp.c',
1201       'slirp/src/udp6.c',
1202       'slirp/src/util.c',
1203       'slirp/src/version.c',
1204       'slirp/src/vmstate.c',
1205     ]
1207     configure_file(
1208       input : 'slirp/src/libslirp-version.h.in',
1209       output : 'libslirp-version.h',
1210       configuration: slirp_conf)
1212     slirp_inc = include_directories('slirp', 'slirp/src')
1213     libslirp = static_library('slirp',
1214                               sources: slirp_files,
1215                               c_args: slirp_cargs,
1216                               include_directories: slirp_inc)
1217     slirp = declare_dependency(link_with: libslirp,
1218                                dependencies: slirp_deps,
1219                                include_directories: slirp_inc)
1220   endif
1221 endif
1223 fdt = not_found
1224 fdt_opt = get_option('fdt')
1225 if have_system
1226   if fdt_opt in ['enabled', 'auto', 'system']
1227     have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1228     fdt = cc.find_library('fdt', static: enable_static,
1229                           required: fdt_opt == 'system' or
1230                                     fdt_opt == 'enabled' and not have_internal)
1231     if fdt.found() and cc.links('''
1232        #include <libfdt.h>
1233        #include <libfdt_env.h>
1234        int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1235          dependencies: fdt)
1236       fdt_opt = 'system'
1237     elif have_internal
1238       fdt_opt = 'internal'
1239     else
1240       fdt_opt = 'disabled'
1241     endif
1242   endif
1243   if fdt_opt == 'internal'
1244     fdt_files = files(
1245       'dtc/libfdt/fdt.c',
1246       'dtc/libfdt/fdt_ro.c',
1247       'dtc/libfdt/fdt_wip.c',
1248       'dtc/libfdt/fdt_sw.c',
1249       'dtc/libfdt/fdt_rw.c',
1250       'dtc/libfdt/fdt_strerror.c',
1251       'dtc/libfdt/fdt_empty_tree.c',
1252       'dtc/libfdt/fdt_addresses.c',
1253       'dtc/libfdt/fdt_overlay.c',
1254       'dtc/libfdt/fdt_check.c',
1255     )
1257     fdt_inc = include_directories('dtc/libfdt')
1258     libfdt = static_library('fdt',
1259                             sources: fdt_files,
1260                             include_directories: fdt_inc)
1261     fdt = declare_dependency(link_with: libfdt,
1262                              include_directories: fdt_inc)
1263   endif
1264 endif
1265 if not fdt.found() and fdt_required.length() > 0
1266   error('fdt not available but required by targets ' + ', '.join(fdt_required))
1267 endif
1269 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1270 config_host_data.set('CONFIG_FDT', fdt.found())
1271 config_host_data.set('CONFIG_SLIRP', slirp.found())
1273 #####################
1274 # Generated sources #
1275 #####################
1277 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1279 hxtool = find_program('scripts/hxtool')
1280 shaderinclude = find_program('scripts/shaderinclude.pl')
1281 qapi_gen = find_program('scripts/qapi-gen.py')
1282 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1283                      meson.source_root() / 'scripts/qapi/commands.py',
1284                      meson.source_root() / 'scripts/qapi/common.py',
1285                      meson.source_root() / 'scripts/qapi/error.py',
1286                      meson.source_root() / 'scripts/qapi/events.py',
1287                      meson.source_root() / 'scripts/qapi/expr.py',
1288                      meson.source_root() / 'scripts/qapi/gen.py',
1289                      meson.source_root() / 'scripts/qapi/introspect.py',
1290                      meson.source_root() / 'scripts/qapi/parser.py',
1291                      meson.source_root() / 'scripts/qapi/schema.py',
1292                      meson.source_root() / 'scripts/qapi/source.py',
1293                      meson.source_root() / 'scripts/qapi/types.py',
1294                      meson.source_root() / 'scripts/qapi/visit.py',
1295                      meson.source_root() / 'scripts/qapi/common.py',
1296                      meson.source_root() / 'scripts/qapi-gen.py'
1299 tracetool = [
1300   python, files('scripts/tracetool.py'),
1301    '--backend=' + config_host['TRACE_BACKENDS']
1304 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1305                     meson.current_source_dir(),
1306                     config_host['PKGVERSION'], meson.project_version()]
1307 qemu_version = custom_target('qemu-version.h',
1308                              output: 'qemu-version.h',
1309                              command: qemu_version_cmd,
1310                              capture: true,
1311                              build_by_default: true,
1312                              build_always_stale: true)
1313 genh += qemu_version
1315 hxdep = []
1316 hx_headers = [
1317   ['qemu-options.hx', 'qemu-options.def'],
1318   ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1320 if have_system
1321   hx_headers += [
1322     ['hmp-commands.hx', 'hmp-commands.h'],
1323     ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1324   ]
1325 endif
1326 foreach d : hx_headers
1327   hxdep += custom_target(d[1],
1328                 input: files(d[0]),
1329                 output: d[1],
1330                 capture: true,
1331                 build_by_default: true, # to be removed when added to a target
1332                 command: [hxtool, '-h', '@INPUT0@'])
1333 endforeach
1334 genh += hxdep
1336 ###################
1337 # Collect sources #
1338 ###################
1340 authz_ss = ss.source_set()
1341 blockdev_ss = ss.source_set()
1342 block_ss = ss.source_set()
1343 bsd_user_ss = ss.source_set()
1344 chardev_ss = ss.source_set()
1345 common_ss = ss.source_set()
1346 crypto_ss = ss.source_set()
1347 io_ss = ss.source_set()
1348 linux_user_ss = ss.source_set()
1349 qmp_ss = ss.source_set()
1350 qom_ss = ss.source_set()
1351 softmmu_ss = ss.source_set()
1352 specific_fuzz_ss = ss.source_set()
1353 specific_ss = ss.source_set()
1354 stub_ss = ss.source_set()
1355 trace_ss = ss.source_set()
1356 user_ss = ss.source_set()
1357 util_ss = ss.source_set()
1359 modules = {}
1360 hw_arch = {}
1361 target_arch = {}
1362 target_softmmu_arch = {}
1364 ###############
1365 # Trace files #
1366 ###############
1368 # TODO: add each directory to the subdirs from its own meson.build, once
1369 # we have those
1370 trace_events_subdirs = [
1371   'accel/kvm',
1372   'accel/tcg',
1373   'crypto',
1374   'monitor',
1376 if have_user
1377   trace_events_subdirs += [ 'linux-user' ]
1378 endif
1379 if have_block
1380   trace_events_subdirs += [
1381     'authz',
1382     'block',
1383     'io',
1384     'nbd',
1385     'scsi',
1386   ]
1387 endif
1388 if have_system
1389   trace_events_subdirs += [
1390     'audio',
1391     'backends',
1392     'backends/tpm',
1393     'chardev',
1394     'hw/9pfs',
1395     'hw/acpi',
1396     'hw/alpha',
1397     'hw/arm',
1398     'hw/audio',
1399     'hw/block',
1400     'hw/block/dataplane',
1401     'hw/char',
1402     'hw/display',
1403     'hw/dma',
1404     'hw/hppa',
1405     'hw/hyperv',
1406     'hw/i2c',
1407     'hw/i386',
1408     'hw/i386/xen',
1409     'hw/ide',
1410     'hw/input',
1411     'hw/intc',
1412     'hw/isa',
1413     'hw/mem',
1414     'hw/mips',
1415     'hw/misc',
1416     'hw/misc/macio',
1417     'hw/net',
1418     'hw/nvram',
1419     'hw/pci',
1420     'hw/pci-host',
1421     'hw/ppc',
1422     'hw/rdma',
1423     'hw/rdma/vmw',
1424     'hw/rtc',
1425     'hw/s390x',
1426     'hw/scsi',
1427     'hw/sd',
1428     'hw/sparc',
1429     'hw/sparc64',
1430     'hw/ssi',
1431     'hw/timer',
1432     'hw/tpm',
1433     'hw/usb',
1434     'hw/vfio',
1435     'hw/virtio',
1436     'hw/watchdog',
1437     'hw/xen',
1438     'hw/gpio',
1439     'migration',
1440     'net',
1441     'softmmu',
1442     'ui',
1443   ]
1444 endif
1445 trace_events_subdirs += [
1446   'hw/core',
1447   'qapi',
1448   'qom',
1449   'target/arm',
1450   'target/hppa',
1451   'target/i386',
1452   'target/mips',
1453   'target/ppc',
1454   'target/riscv',
1455   'target/s390x',
1456   'target/sparc',
1457   'util',
1460 subdir('contrib/libvhost-user')
1461 subdir('qapi')
1462 subdir('qobject')
1463 subdir('stubs')
1464 subdir('trace')
1465 subdir('util')
1466 subdir('qom')
1467 subdir('authz')
1468 subdir('crypto')
1469 subdir('ui')
1472 if enable_modules
1473   libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1474   modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1475 endif
1477 stub_ss = stub_ss.apply(config_all, strict: false)
1479 util_ss.add_all(trace_ss)
1480 util_ss = util_ss.apply(config_all, strict: false)
1481 libqemuutil = static_library('qemuutil',
1482                              sources: util_ss.sources() + stub_ss.sources() + genh,
1483                              dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1484 qemuutil = declare_dependency(link_with: libqemuutil,
1485                               sources: genh + version_res)
1487 decodetree = generator(find_program('scripts/decodetree.py'),
1488                        output: 'decode-@BASENAME@.c.inc',
1489                        arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1491 subdir('audio')
1492 subdir('io')
1493 subdir('chardev')
1494 subdir('fsdev')
1495 subdir('libdecnumber')
1496 subdir('target')
1497 subdir('dump')
1499 block_ss.add(files(
1500   'block.c',
1501   'blockjob.c',
1502   'job.c',
1503   'qemu-io-cmds.c',
1505 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1507 subdir('nbd')
1508 subdir('scsi')
1509 subdir('block')
1511 blockdev_ss.add(files(
1512   'blockdev.c',
1513   'blockdev-nbd.c',
1514   'iothread.c',
1515   'job-qmp.c',
1518 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1519 # os-win32.c does not
1520 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1521 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1523 common_ss.add(files('cpus-common.c'))
1525 subdir('softmmu')
1527 common_ss.add(capstone)
1528 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
1529 specific_ss.add(files('exec-vary.c'))
1530 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1531   'fpu/softfloat.c',
1532   'tcg/optimize.c',
1533   'tcg/tcg-common.c',
1534   'tcg/tcg-op-gvec.c',
1535   'tcg/tcg-op-vec.c',
1536   'tcg/tcg-op.c',
1537   'tcg/tcg.c',
1539 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1541 subdir('backends')
1542 subdir('disas')
1543 subdir('migration')
1544 subdir('monitor')
1545 subdir('net')
1546 subdir('replay')
1547 subdir('hw')
1548 subdir('accel')
1549 subdir('plugins')
1550 subdir('bsd-user')
1551 subdir('linux-user')
1553 bsd_user_ss.add(files('gdbstub.c'))
1554 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1556 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1557 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1559 # needed for fuzzing binaries
1560 subdir('tests/qtest/libqos')
1561 subdir('tests/qtest/fuzz')
1563 ########################
1564 # Library dependencies #
1565 ########################
1567 block_mods = []
1568 softmmu_mods = []
1569 foreach d, list : modules
1570   foreach m, module_ss : list
1571     if enable_modules and targetos != 'windows'
1572       module_ss = module_ss.apply(config_all, strict: false)
1573       sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1574                           dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1575       if d == 'block'
1576         block_mods += sl
1577       else
1578         softmmu_mods += sl
1579       endif
1580     else
1581       if d == 'block'
1582         block_ss.add_all(module_ss)
1583       else
1584         softmmu_ss.add_all(module_ss)
1585       endif
1586     endif
1587   endforeach
1588 endforeach
1590 nm = find_program('nm')
1591 undefsym = find_program('scripts/undefsym.py')
1592 block_syms = custom_target('block.syms', output: 'block.syms',
1593                              input: [libqemuutil, block_mods],
1594                              capture: true,
1595                              command: [undefsym, nm, '@INPUT@'])
1596 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1597                              input: [libqemuutil, softmmu_mods],
1598                              capture: true,
1599                              command: [undefsym, nm, '@INPUT@'])
1601 qom_ss = qom_ss.apply(config_host, strict: false)
1602 libqom = static_library('qom', qom_ss.sources() + genh,
1603                         dependencies: [qom_ss.dependencies()],
1604                         name_suffix: 'fa')
1606 qom = declare_dependency(link_whole: libqom)
1608 authz_ss = authz_ss.apply(config_host, strict: false)
1609 libauthz = static_library('authz', authz_ss.sources() + genh,
1610                           dependencies: [authz_ss.dependencies()],
1611                           name_suffix: 'fa',
1612                           build_by_default: false)
1614 authz = declare_dependency(link_whole: libauthz,
1615                            dependencies: qom)
1617 crypto_ss = crypto_ss.apply(config_host, strict: false)
1618 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
1619                            dependencies: [crypto_ss.dependencies()],
1620                            name_suffix: 'fa',
1621                            build_by_default: false)
1623 crypto = declare_dependency(link_whole: libcrypto,
1624                             dependencies: [authz, qom])
1626 io_ss = io_ss.apply(config_host, strict: false)
1627 libio = static_library('io', io_ss.sources() + genh,
1628                        dependencies: [io_ss.dependencies()],
1629                        link_with: libqemuutil,
1630                        name_suffix: 'fa',
1631                        build_by_default: false)
1633 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
1635 libmigration = static_library('migration', sources: migration_files + genh,
1636                               name_suffix: 'fa',
1637                               build_by_default: false)
1638 migration = declare_dependency(link_with: libmigration,
1639                                dependencies: [zlib, qom, io])
1640 softmmu_ss.add(migration)
1642 block_ss = block_ss.apply(config_host, strict: false)
1643 libblock = static_library('block', block_ss.sources() + genh,
1644                           dependencies: block_ss.dependencies(),
1645                           link_depends: block_syms,
1646                           name_suffix: 'fa',
1647                           build_by_default: false)
1649 block = declare_dependency(link_whole: [libblock],
1650                            link_args: '@block.syms',
1651                            dependencies: [crypto, io])
1653 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
1654 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
1655                              dependencies: blockdev_ss.dependencies(),
1656                              name_suffix: 'fa',
1657                              build_by_default: false)
1659 blockdev = declare_dependency(link_whole: [libblockdev],
1660                               dependencies: [block])
1662 qmp_ss = qmp_ss.apply(config_host, strict: false)
1663 libqmp = static_library('qmp', qmp_ss.sources() + genh,
1664                         dependencies: qmp_ss.dependencies(),
1665                         name_suffix: 'fa',
1666                         build_by_default: false)
1668 qmp = declare_dependency(link_whole: [libqmp])
1670 libchardev = static_library('chardev', chardev_ss.sources() + genh,
1671                             name_suffix: 'fa',
1672                             build_by_default: false)
1674 chardev = declare_dependency(link_whole: libchardev)
1676 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
1677                            name_suffix: 'fa',
1678                            build_by_default: false)
1679 hwcore = declare_dependency(link_whole: libhwcore)
1680 common_ss.add(hwcore)
1682 ###########
1683 # Targets #
1684 ###########
1686 foreach m : block_mods + softmmu_mods
1687   shared_module(m.name(),
1688                 name_prefix: '',
1689                 link_whole: m,
1690                 install: true,
1691                 install_dir: qemu_moddir)
1692 endforeach
1694 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
1695 common_ss.add(qom, qemuutil)
1697 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
1698 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
1700 common_all = common_ss.apply(config_all, strict: false)
1701 common_all = static_library('common',
1702                             build_by_default: false,
1703                             sources: common_all.sources() + genh,
1704                             dependencies: common_all.dependencies(),
1705                             name_suffix: 'fa')
1707 feature_to_c = find_program('scripts/feature_to_c.sh')
1709 emulators = {}
1710 foreach target : target_dirs
1711   config_target = config_target_mak[target]
1712   target_name = config_target['TARGET_NAME']
1713   arch = config_target['TARGET_BASE_ARCH']
1714   arch_srcs = [config_target_h[target]]
1715   arch_deps = []
1716   c_args = ['-DNEED_CPU_H',
1717             '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
1718             '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
1719   link_args = emulator_link_args
1721   config_target += config_host
1722   target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
1723   if targetos == 'linux'
1724     target_inc += include_directories('linux-headers', is_system: true)
1725   endif
1726   if target.endswith('-softmmu')
1727     qemu_target_name = 'qemu-system-' + target_name
1728     target_type='system'
1729     t = target_softmmu_arch[arch].apply(config_target, strict: false)
1730     arch_srcs += t.sources()
1731     arch_deps += t.dependencies()
1733     hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
1734     hw = hw_arch[hw_dir].apply(config_target, strict: false)
1735     arch_srcs += hw.sources()
1736     arch_deps += hw.dependencies()
1738     arch_srcs += config_devices_h[target]
1739     link_args += ['@block.syms', '@qemu.syms']
1740   else
1741     abi = config_target['TARGET_ABI_DIR']
1742     target_type='user'
1743     qemu_target_name = 'qemu-' + target_name
1744     if 'CONFIG_LINUX_USER' in config_target
1745       base_dir = 'linux-user'
1746       target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
1747     else
1748       base_dir = 'bsd-user'
1749     endif
1750     target_inc += include_directories(
1751       base_dir,
1752       base_dir / abi,
1753     )
1754     if 'CONFIG_LINUX_USER' in config_target
1755       dir = base_dir / abi
1756       arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
1757       if config_target.has_key('TARGET_SYSTBL_ABI')
1758         arch_srcs += \
1759           syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
1760                                              extra_args : config_target['TARGET_SYSTBL_ABI'])
1761       endif
1762     endif
1763   endif
1765   if 'TARGET_XML_FILES' in config_target
1766     gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
1767                                 output: target + '-gdbstub-xml.c',
1768                                 input: files(config_target['TARGET_XML_FILES'].split()),
1769                                 command: [feature_to_c, '@INPUT@'],
1770                                 capture: true)
1771     arch_srcs += gdbstub_xml
1772   endif
1774   t = target_arch[arch].apply(config_target, strict: false)
1775   arch_srcs += t.sources()
1776   arch_deps += t.dependencies()
1778   target_common = common_ss.apply(config_target, strict: false)
1779   objects = common_all.extract_objects(target_common.sources())
1780   deps = target_common.dependencies()
1782   target_specific = specific_ss.apply(config_target, strict: false)
1783   arch_srcs += target_specific.sources()
1784   arch_deps += target_specific.dependencies()
1786   lib = static_library('qemu-' + target,
1787                  sources: arch_srcs + genh,
1788                  dependencies: arch_deps,
1789                  objects: objects,
1790                  include_directories: target_inc,
1791                  c_args: c_args,
1792                  build_by_default: false,
1793                  name_suffix: 'fa')
1795   if target.endswith('-softmmu')
1796     execs = [{
1797       'name': 'qemu-system-' + target_name,
1798       'gui': false,
1799       'sources': files('softmmu/main.c'),
1800       'dependencies': []
1801     }]
1802     if targetos == 'windows' and (sdl.found() or gtk.found())
1803       execs += [{
1804         'name': 'qemu-system-' + target_name + 'w',
1805         'gui': true,
1806         'sources': files('softmmu/main.c'),
1807         'dependencies': []
1808       }]
1809     endif
1810     if config_host.has_key('CONFIG_FUZZ')
1811       specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
1812       execs += [{
1813         'name': 'qemu-fuzz-' + target_name,
1814         'gui': false,
1815         'sources': specific_fuzz.sources(),
1816         'dependencies': specific_fuzz.dependencies(),
1817       }]
1818     endif
1819   else
1820     execs = [{
1821       'name': 'qemu-' + target_name,
1822       'gui': false,
1823       'sources': [],
1824       'dependencies': []
1825     }]
1826   endif
1827   foreach exe: execs
1828     emulators += {exe['name']:
1829          executable(exe['name'], exe['sources'],
1830                install: true,
1831                c_args: c_args,
1832                dependencies: arch_deps + deps + exe['dependencies'],
1833                objects: lib.extract_all_objects(recursive: true),
1834                link_language: link_language,
1835                link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
1836                link_args: link_args,
1837                gui_app: exe['gui'])
1838     }
1840     if 'CONFIG_TRACE_SYSTEMTAP' in config_host
1841       foreach stp: [
1842         {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
1843         {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
1844         {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
1845         {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
1846       ]
1847         custom_target(exe['name'] + stp['ext'],
1848                       input: trace_events_all,
1849                       output: exe['name'] + stp['ext'],
1850                       capture: true,
1851                       install: stp['install'],
1852                       install_dir: get_option('datadir') / 'systemtap/tapset',
1853                       command: [
1854                         tracetool, '--group=all', '--format=' + stp['fmt'],
1855                         '--binary=' + stp['bin'],
1856                         '--target-name=' + target_name,
1857                         '--target-type=' + target_type,
1858                         '--probe-prefix=qemu.' + target_type + '.' + target_name,
1859                         '@INPUT@',
1860                       ])
1861       endforeach
1862     endif
1863   endforeach
1864 endforeach
1866 # Other build targets
1868 if 'CONFIG_PLUGIN' in config_host
1869   install_headers('include/qemu/qemu-plugin.h')
1870 endif
1872 if 'CONFIG_GUEST_AGENT' in config_host
1873   subdir('qga')
1874 endif
1876 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
1877 # when we don't build tools or system
1878 if xkbcommon.found()
1879   # used for the update-keymaps target, so include rules even if !have_tools
1880   qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
1881                            dependencies: [qemuutil, xkbcommon], install: have_tools)
1882 endif
1884 if have_tools
1885   qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
1886              dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
1887   qemu_io = executable('qemu-io', files('qemu-io.c'),
1888              dependencies: [block, qemuutil], install: true)
1889   qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
1890                dependencies: [blockdev, qemuutil], install: true)
1892   subdir('storage-daemon')
1893   subdir('contrib/rdmacm-mux')
1894   subdir('contrib/elf2dmp')
1896   executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
1897              dependencies: qemuutil,
1898              install: true)
1900   if 'CONFIG_VHOST_USER' in config_host
1901     subdir('contrib/vhost-user-blk')
1902     subdir('contrib/vhost-user-gpu')
1903     subdir('contrib/vhost-user-input')
1904     subdir('contrib/vhost-user-scsi')
1905   endif
1907   if targetos == 'linux'
1908     executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
1909                dependencies: [qemuutil, libcap_ng],
1910                install: true,
1911                install_dir: get_option('libexecdir'))
1913     executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
1914                dependencies: [authz, crypto, io, qom, qemuutil,
1915                               libcap_ng, mpathpersist],
1916                install: true)
1917   endif
1919   if 'CONFIG_IVSHMEM' in config_host
1920     subdir('contrib/ivshmem-client')
1921     subdir('contrib/ivshmem-server')
1922   endif
1923 endif
1925 subdir('scripts')
1926 subdir('tools')
1927 subdir('pc-bios')
1928 subdir('docs')
1929 subdir('tests')
1930 if 'CONFIG_GTK' in config_host
1931   subdir('po')
1932 endif
1934 if host_machine.system() == 'windows'
1935   nsis_cmd = [
1936     find_program('scripts/nsis.py'),
1937     '@OUTPUT@',
1938     get_option('prefix'),
1939     meson.current_source_dir(),
1940     host_machine.cpu_family(),
1941     '--',
1942     '-DDISPLAYVERSION=' + meson.project_version(),
1943   ]
1944   if build_docs
1945     nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
1946   endif
1947   if 'CONFIG_GTK' in config_host
1948     nsis_cmd += '-DCONFIG_GTK=y'
1949   endif
1951   nsis = custom_target('nsis',
1952                        output: 'qemu-setup-' + meson.project_version() + '.exe',
1953                        input: files('qemu.nsi'),
1954                        build_always_stale: true,
1955                        command: nsis_cmd + ['@INPUT@'])
1956   alias_target('installer', nsis)
1957 endif
1959 #########################
1960 # Configuration summary #
1961 #########################
1963 summary_info = {}
1964 summary_info += {'Install prefix':    get_option('prefix')}
1965 summary_info += {'BIOS directory':    qemu_datadir}
1966 summary_info += {'firmware path':     get_option('qemu_firmwarepath')}
1967 summary_info += {'binary directory':  get_option('bindir')}
1968 summary_info += {'library directory': get_option('libdir')}
1969 summary_info += {'module directory':  qemu_moddir}
1970 summary_info += {'libexec directory': get_option('libexecdir')}
1971 summary_info += {'include directory': get_option('includedir')}
1972 summary_info += {'config directory':  get_option('sysconfdir')}
1973 if targetos != 'windows'
1974   summary_info += {'local state directory': get_option('localstatedir')}
1975   summary_info += {'Manual directory':      get_option('mandir')}
1976 else
1977   summary_info += {'local state directory': 'queried at runtime'}
1978 endif
1979 summary_info += {'Doc directory':     get_option('docdir')}
1980 summary_info += {'Build directory':   meson.current_build_dir()}
1981 summary_info += {'Source path':       meson.current_source_dir()}
1982 summary_info += {'GIT binary':        config_host['GIT']}
1983 summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
1984 summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
1985 summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
1986 if link_language == 'cpp'
1987   summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
1988 else
1989   summary_info += {'C++ compiler':      false}
1990 endif
1991 if targetos == 'darwin'
1992   summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
1993 endif
1994 summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
1995 summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
1996                                                + ['-O' + get_option('optimization')]
1997                                                + (get_option('debug') ? ['-g'] : []))}
1998 if link_language == 'cpp'
1999   summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
2000                                                + ['-O' + get_option('optimization')]
2001                                                + (get_option('debug') ? ['-g'] : []))}
2002 endif
2003 link_args = get_option(link_language + '_link_args')
2004 if link_args.length() > 0
2005   summary_info += {'LDFLAGS':         ' '.join(link_args)}
2006 endif
2007 summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
2008 summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
2009 summary_info += {'make':              config_host['MAKE']}
2010 summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2011 summary_info += {'sphinx-build':      sphinx_build.found()}
2012 summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
2013 # TODO: add back version
2014 summary_info += {'slirp support':     slirp_opt == 'disabled' ? false : slirp_opt}
2015 if slirp_opt != 'disabled'
2016   summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
2017 endif
2018 summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
2019 if config_host.has_key('CONFIG_MODULES')
2020   summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2021 endif
2022 summary_info += {'host CPU':          cpu}
2023 summary_info += {'host endianness':   build_machine.endian()}
2024 summary_info += {'target list':       ' '.join(target_dirs)}
2025 summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
2026 summary_info += {'sparse enabled':    sparse.found()}
2027 summary_info += {'strip binaries':    get_option('strip')}
2028 summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
2029 summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
2030 if targetos == 'darwin'
2031   summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
2032 endif
2033 # TODO: add back version
2034 summary_info += {'SDL support':       sdl.found()}
2035 summary_info += {'SDL image support': sdl_image.found()}
2036 # TODO: add back version
2037 summary_info += {'GTK support':       config_host.has_key('CONFIG_GTK')}
2038 summary_info += {'GTK GL support':    config_host.has_key('CONFIG_GTK_GL')}
2039 summary_info += {'pixman':            pixman.found()}
2040 # TODO: add back version
2041 summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
2042 summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
2043 summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
2044 # TODO: add back version
2045 summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
2046 if config_host.has_key('CONFIG_GCRYPT')
2047    summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
2048    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2049 endif
2050 # TODO: add back version
2051 summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
2052 if config_host.has_key('CONFIG_NETTLE')
2053    summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2054 endif
2055 summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
2056 summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
2057 summary_info += {'iconv support':     iconv.found()}
2058 summary_info += {'curses support':    curses.found()}
2059 # TODO: add back version
2060 summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
2061 summary_info += {'curl support':      config_host.has_key('CONFIG_CURL')}
2062 summary_info += {'mingw32 support':   targetos == 'windows'}
2063 summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
2064 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2065 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2066 summary_info += {'VirtFS support':    config_host.has_key('CONFIG_VIRTFS')}
2067 summary_info += {'build virtiofs daemon': have_virtiofsd}
2068 summary_info += {'Multipath support': mpathpersist.found()}
2069 summary_info += {'VNC support':       vnc.found()}
2070 if vnc.found()
2071   summary_info += {'VNC SASL support':  sasl.found()}
2072   summary_info += {'VNC JPEG support':  jpeg.found()}
2073   summary_info += {'VNC PNG support':   png.found()}
2074 endif
2075 summary_info += {'xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
2076 if config_host.has_key('CONFIG_XEN_BACKEND')
2077   summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2078 endif
2079 summary_info += {'brlapi support':    config_host.has_key('CONFIG_BRLAPI')}
2080 summary_info += {'Documentation':     build_docs}
2081 summary_info += {'PIE':               get_option('b_pie')}
2082 summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
2083 summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
2084 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2085 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2086 summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
2087 summary_info += {'Install blobs':     get_option('install_blobs')}
2088 summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
2089 summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
2090 summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
2091 summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
2092 summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
2093 if config_all.has_key('CONFIG_TCG')
2094   summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2095   summary_info += {'TCG interpreter':   config_host.has_key('CONFIG_TCG_INTERPRETER')}
2096 endif
2097 summary_info += {'malloc trim support': has_malloc_trim}
2098 summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
2099 summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
2100 summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
2101 summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
2102 summary_info += {'preadv support':    config_host.has_key('CONFIG_PREADV')}
2103 summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
2104 summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
2105 summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
2106 summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2107 summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
2108 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2109 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2110 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2111 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2112 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2113 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2114 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2115 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2116 summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
2117 if config_host['TRACE_BACKENDS'].split().contains('simple')
2118   summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2119 endif
2120 # TODO: add back protocol and server version
2121 summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
2122 summary_info += {'rbd support':       config_host.has_key('CONFIG_RBD')}
2123 summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
2124 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2125 summary_info += {'U2F support':       u2f.found()}
2126 summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
2127 summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
2128 summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
2129 summary_info += {'OpenGL dmabufs':    config_host.has_key('CONFIG_OPENGL_DMABUF')}
2130 summary_info += {'libiscsi support':  config_host.has_key('CONFIG_LIBISCSI')}
2131 summary_info += {'libnfs support':    config_host.has_key('CONFIG_LIBNFS')}
2132 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2133 if targetos == 'windows'
2134   if 'WIN_SDK' in config_host
2135     summary_info += {'Windows SDK':       config_host['WIN_SDK']}
2136   endif
2137   summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
2138   summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2139   summary_info += {'QGA MSI support':   config_host.has_key('CONFIG_QGA_MSI')}
2140 endif
2141 summary_info += {'seccomp support':   config_host.has_key('CONFIG_SECCOMP')}
2142 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2143 summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
2144 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2145 summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
2146 summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
2147 summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
2148 summary_info += {'gcov':              get_option('b_coverage')}
2149 summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
2150 summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
2151 summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2152 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2153 summary_info += {'lzo support':       config_host.has_key('CONFIG_LZO')}
2154 summary_info += {'snappy support':    config_host.has_key('CONFIG_SNAPPY')}
2155 summary_info += {'bzip2 support':     config_host.has_key('CONFIG_BZIP2')}
2156 summary_info += {'lzfse support':     config_host.has_key('CONFIG_LZFSE')}
2157 summary_info += {'zstd support':      config_host.has_key('CONFIG_ZSTD')}
2158 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2159 summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
2160 summary_info += {'memory allocator':  get_option('malloc')}
2161 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2162 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2163 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2164 summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
2165 summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
2166 summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
2167 summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
2168 summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
2169 summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
2170 summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
2171 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2172 summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
2173 summary_info += {'capstone':          capstone_opt == 'disabled' ? false : capstone_opt}
2174 summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
2175 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2176 summary_info += {'libudev':           libudev.found()}
2177 summary_info += {'default devices':   config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
2178 summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
2179 summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
2180 if config_host.has_key('HAVE_GDB_BIN')
2181   summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
2182 endif
2183 summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
2184 summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
2185 summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
2186 summary(summary_info, bool_yn: true)
2188 if not supported_cpus.contains(cpu)
2189   message()
2190   warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2191   message()
2192   message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2193   message('The QEMU project intends to remove support for this host CPU in')
2194   message('a future release if nobody volunteers to maintain it and to')
2195   message('provide a build host for our continuous integration setup.')
2196   message('configure has succeeded and you can continue to build, but')
2197   message('if you care about QEMU on this platform you should contact')
2198   message('us upstream at qemu-devel@nongnu.org.')
2199 endif
2201 if not supported_oses.contains(targetos)
2202   message()
2203   warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2204   message()
2205   message('Host OS ' + targetos + 'support is not currently maintained.')
2206   message('The QEMU project intends to remove support for this host OS in')
2207   message('a future release if nobody volunteers to maintain it and to')
2208   message('provide a build host for our continuous integration setup.')
2209   message('configure has succeeded and you can continue to build, but')
2210   message('if you care about QEMU on this platform you should contact')
2211   message('us upstream at qemu-devel@nongnu.org.')
2212 endif