configure, meson: convert libtasn1 detection to meson
[qemu/rayw.git] / meson.build
blobd4ce2ca57bbe84e0af091bffa366119ff0cec6ec
1 project('qemu', ['c'], meson_version: '>=0.55.0',
2         default_options: ['warning_level=1', 'c_std=gnu11', '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 # Allow both shared and static libraries unless --enable-static
22 static_kwargs = enable_static ? {'static': true} : {}
24 # Temporary directory used for files created while
25 # configure runs. Since it is in the build directory
26 # we can safely blow away any previous version of it
27 # (and we need not jump through hoops to try to delete
28 # it when configure exits.)
29 tmpdir = meson.current_build_dir() / 'meson-private/temp'
31 if get_option('qemu_suffix').startswith('/')
32   error('qemu_suffix cannot start with a /')
33 endif
35 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
36 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
37 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
38 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
40 qemu_desktopdir = get_option('datadir') / 'applications'
41 qemu_icondir = get_option('datadir') / 'icons'
43 config_host_data = configuration_data()
44 genh = []
46 target_dirs = config_host['TARGET_DIRS'].split()
47 have_user = false
48 have_system = false
49 foreach target : target_dirs
50   have_user = have_user or target.endswith('-user')
51   have_system = have_system or target.endswith('-softmmu')
52 endforeach
53 have_tools = 'CONFIG_TOOLS' in config_host
54 have_block = have_system or have_tools
56 python = import('python').find_installation()
58 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
59 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
60   'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
62 cpu = host_machine.cpu_family()
63 targetos = host_machine.system()
65 if cpu in ['x86', 'x86_64']
66   kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
67 elif cpu == 'aarch64'
68   kvm_targets = ['aarch64-softmmu']
69 elif cpu == 's390x'
70   kvm_targets = ['s390x-softmmu']
71 elif cpu in ['ppc', 'ppc64']
72   kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
73 elif cpu in ['mips', 'mips64']
74   kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
75 else
76   kvm_targets = []
77 endif
79 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
80 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
81   # i368 emulator provides xenpv machine type for multiple architectures
82   accelerator_targets += {
83     'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
84   }
85 endif
86 if cpu in ['x86', 'x86_64']
87   accelerator_targets += {
88     'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
89     'CONFIG_HVF': ['x86_64-softmmu'],
90     'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
91     'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
92   }
93 endif
95 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
96 install_edk2_blobs = false
97 if get_option('install_blobs')
98   foreach target : target_dirs
99     install_edk2_blobs = install_edk2_blobs or target in edk2_targets
100   endforeach
101 endif
103 bzip2 = find_program('bzip2', required: install_edk2_blobs)
105 ##################
106 # Compiler flags #
107 ##################
109 # Specify linker-script with add_project_link_arguments so that it is not placed
110 # within a linker --start-group/--end-group pair
111 if 'CONFIG_FUZZ' in config_host
112    add_project_link_arguments(['-Wl,-T,',
113                                (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
114                               native: false, language: ['c', 'cpp', 'objc'])
115 endif
117 add_global_arguments(config_host['QEMU_CFLAGS'].split(),
118                      native: false, language: ['c', 'objc'])
119 add_global_arguments(config_host['QEMU_CXXFLAGS'].split(),
120                      native: false, language: 'cpp')
121 add_global_link_arguments(config_host['QEMU_LDFLAGS'].split(),
122                           native: false, language: ['c', 'cpp', 'objc'])
124 if targetos == 'linux'
125   add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
126                         '-isystem', 'linux-headers',
127                         language: ['c', 'cpp'])
128 endif
130 add_project_arguments('-iquote', '.',
131                       '-iquote', meson.current_source_dir(),
132                       '-iquote', meson.current_source_dir() / 'include',
133                       '-iquote', meson.current_source_dir() / 'disas/libvixl',
134                       language: ['c', 'cpp', 'objc'])
136 link_language = meson.get_external_property('link_language', 'cpp')
137 if link_language == 'cpp'
138   add_languages('cpp', required: true, native: false)
139 endif
140 if host_machine.system() == 'darwin'
141   add_languages('objc', required: false, native: false)
142 endif
144 sparse = find_program('cgcc', required: get_option('sparse'))
145 if sparse.found()
146   run_target('sparse',
147              command: [find_program('scripts/check_sparse.py'),
148                        'compile_commands.json', sparse.full_path(), '-Wbitwise',
149                        '-Wno-transparent-union', '-Wno-old-initializer',
150                        '-Wno-non-pointer-null'])
151 endif
153 ###########################################
154 # Target-specific checks and dependencies #
155 ###########################################
157 if targetos != 'linux' and get_option('mpath').enabled()
158   error('Multipath is supported only on Linux')
159 endif
161 if targetos != 'linux' and get_option('multiprocess').enabled()
162   error('Multiprocess QEMU is supported only on Linux')
163 endif
164 multiprocess_allowed = targetos == 'linux' and not get_option('multiprocess').disabled()
166 libm = cc.find_library('m', required: false)
167 util = cc.find_library('util', required: false)
168 winmm = []
169 socket = []
170 version_res = []
171 coref = []
172 iokit = []
173 emulator_link_args = []
174 nvmm =not_found
175 hvf = not_found
176 if targetos == 'windows'
177   socket = cc.find_library('ws2_32')
178   winmm = cc.find_library('winmm')
180   win = import('windows')
181   version_res = win.compile_resources('version.rc',
182                                       depend_files: files('pc-bios/qemu-nsis.ico'),
183                                       include_directories: include_directories('.'))
184 elif targetos == 'darwin'
185   coref = dependency('appleframeworks', modules: 'CoreFoundation')
186   iokit = dependency('appleframeworks', modules: 'IOKit')
187 elif targetos == 'sunos'
188   socket = [cc.find_library('socket'),
189             cc.find_library('nsl'),
190             cc.find_library('resolv')]
191 elif targetos == 'haiku'
192   socket = [cc.find_library('posix_error_mapper'),
193             cc.find_library('network'),
194             cc.find_library('bsd')]
195 elif targetos == 'openbsd'
196   if not get_option('tcg').disabled() and target_dirs.length() > 0
197     # Disable OpenBSD W^X if available
198     emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
199   endif
200 endif
202 accelerators = []
203 if not get_option('kvm').disabled() and targetos == 'linux'
204   accelerators += 'CONFIG_KVM'
205 endif
206 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
207   accelerators += 'CONFIG_XEN'
208   have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
209 else
210   have_xen_pci_passthrough = false
211 endif
212 if not get_option('whpx').disabled() and targetos == 'windows'
213   if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
214     error('WHPX requires 64-bit host')
215   elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
216        cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
217     accelerators += 'CONFIG_WHPX'
218   endif
219 endif
220 if not get_option('hvf').disabled()
221   hvf = dependency('appleframeworks', modules: 'Hypervisor',
222                    required: get_option('hvf'))
223   if hvf.found()
224     accelerators += 'CONFIG_HVF'
225   endif
226 endif
227 if not get_option('hax').disabled()
228   if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
229     accelerators += 'CONFIG_HAX'
230   endif
231 endif
232 if targetos == 'netbsd'
233   if cc.has_header_symbol('nvmm.h', 'nvmm_cpu_stop', required: get_option('nvmm'))
234     nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
235   endif
236   if nvmm.found()
237     accelerators += 'CONFIG_NVMM'
238   endif
239 endif
241 tcg_arch = config_host['ARCH']
242 if not get_option('tcg').disabled()
243   if cpu not in supported_cpus
244     if get_option('tcg_interpreter')
245       warning('Unsupported CPU @0@, will use TCG with TCI (experimental and slow)'.format(cpu))
246     else
247       error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
248     endif
249   elif get_option('tcg_interpreter')
250     warning('Use of the TCG interpretor is not recommended on this host')
251     warning('architecture. There is a native TCG execution backend available')
252     warning('which provides substantially better performance and reliability.')
253     warning('It is strongly recommended to remove the --enable-tcg-interpreter')
254     warning('configuration option on this architecture to use the native')
255     warning('backend.')
256   endif
257   if get_option('tcg_interpreter')
258     tcg_arch = 'tci'
259   elif config_host['ARCH'] == 'sparc64'
260     tcg_arch = 'sparc'
261   elif config_host['ARCH'] == 's390x'
262     tcg_arch = 's390'
263   elif config_host['ARCH'] in ['x86_64', 'x32']
264     tcg_arch = 'i386'
265   elif config_host['ARCH'] == 'ppc64'
266     tcg_arch = 'ppc'
267   elif config_host['ARCH'] in ['riscv32', 'riscv64']
268     tcg_arch = 'riscv'
269   endif
270   add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
271                         language: ['c', 'cpp', 'objc'])
273   accelerators += 'CONFIG_TCG'
274   config_host += { 'CONFIG_TCG': 'y' }
275 endif
277 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
278   error('KVM not available on this platform')
279 endif
280 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
281   error('HVF not available on this platform')
282 endif
283 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
284   error('NVMM not available on this platform')
285 endif
286 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
287   error('WHPX not available on this platform')
288 endif
289 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
290   if 'CONFIG_XEN' in accelerators
291     error('Xen PCI passthrough not available on this platform')
292   else
293     error('Xen PCI passthrough requested but Xen not enabled')
294   endif
295 endif
297 ################
298 # Dependencies #
299 ################
301 # The path to glib.h is added to all compilation commands.  This was
302 # grandfathered in from the QEMU Makefiles.
303 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
304                       native: false, language: ['c', 'cpp', 'objc'])
305 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
306                           link_args: config_host['GLIB_LIBS'].split())
307 # override glib dep with the configure results (for subprojects)
308 meson.override_dependency('glib-2.0', glib)
310 gio = not_found
311 if 'CONFIG_GIO' in config_host
312   gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
313                            link_args: config_host['GIO_LIBS'].split())
314 endif
315 lttng = not_found
316 if 'CONFIG_TRACE_UST' in config_host
317   lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
318 endif
319 urcubp = not_found
320 if 'CONFIG_TRACE_UST' in config_host
321   urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
322 endif
323 pixman = not_found
324 if have_system or have_tools
325   pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
326                       method: 'pkg-config', kwargs: static_kwargs)
327 endif
328 pam = not_found
329 if 'CONFIG_AUTH_PAM' in config_host
330   pam = cc.find_library('pam')
331 endif
332 libaio = cc.find_library('aio', required: false)
333 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
334 linux_io_uring = not_found
335 if 'CONFIG_LINUX_IO_URING' in config_host
336   linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
337                                       link_args: config_host['LINUX_IO_URING_LIBS'].split())
338 endif
339 libxml2 = not_found
340 if 'CONFIG_LIBXML2' in config_host
341   libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
342                                link_args: config_host['LIBXML2_LIBS'].split())
343 endif
344 libnfs = not_found
345 if not get_option('libnfs').auto() or have_block
346   libnfs = dependency('libnfs', version: '>=1.9.3',
347                       required: get_option('libnfs'),
348                       method: 'pkg-config', kwargs: static_kwargs)
349 endif
351 libattr_test = '''
352   #include <stddef.h>
353   #include <sys/types.h>
354   #ifdef CONFIG_LIBATTR
355   #include <attr/xattr.h>
356   #else
357   #include <sys/xattr.h>
358   #endif
359   int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
361 libattr = not_found
362 have_old_libattr = false
363 if not get_option('attr').disabled()
364   if cc.links(libattr_test)
365     libattr = declare_dependency()
366   else
367     libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
368                               required: get_option('attr'),
369                               kwargs: static_kwargs)
370     if libattr.found() and not \
371       cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
372       libattr = not_found
373       if get_option('attr').enabled()
374         error('could not link libattr')
375       else
376         warning('could not link libattr, disabling')
377       endif
378     else
379       have_old_libattr = libattr.found()
380     endif
381   endif
382 endif
384 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
385 if cocoa.found() and get_option('sdl').enabled()
386   error('Cocoa and SDL cannot be enabled at the same time')
387 endif
388 if cocoa.found() and get_option('gtk').enabled()
389   error('Cocoa and GTK+ cannot be enabled at the same time')
390 endif
392 seccomp = not_found
393 if not get_option('seccomp').auto() or have_system or have_tools
394   seccomp = dependency('libseccomp', version: '>=2.3.0',
395                        required: get_option('seccomp'),
396                        method: 'pkg-config', kwargs: static_kwargs)
397 endif
399 libcap_ng = not_found
400 if not get_option('cap_ng').auto() or have_system or have_tools
401   libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
402                               required: get_option('cap_ng'),
403                               kwargs: static_kwargs)
404 endif
405 if libcap_ng.found() and not cc.links('''
406    #include <cap-ng.h>
407    int main(void)
408    {
409      capng_capability_to_name(CAPNG_EFFECTIVE);
410      return 0;
411    }''', dependencies: libcap_ng)
412   libcap_ng = not_found
413   if get_option('cap_ng').enabled()
414     error('could not link libcap-ng')
415   else
416     warning('could not link libcap-ng, disabling')
417   endif
418 endif
420 if get_option('xkbcommon').auto() and not have_system and not have_tools
421   xkbcommon = not_found
422 else
423   xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
424                          method: 'pkg-config', kwargs: static_kwargs)
425 endif
426 vde = not_found
427 if config_host.has_key('CONFIG_VDE')
428   vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
429 endif
430 pulse = not_found
431 if 'CONFIG_LIBPULSE' in config_host
432   pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
433                              link_args: config_host['PULSE_LIBS'].split())
434 endif
435 alsa = not_found
436 if 'CONFIG_ALSA' in config_host
437   alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
438                             link_args: config_host['ALSA_LIBS'].split())
439 endif
440 jack = not_found
441 if 'CONFIG_LIBJACK' in config_host
442   jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
443 endif
444 spice = not_found
445 spice_headers = not_found
446 spice_protocol = not_found
447 if 'CONFIG_SPICE' in config_host
448   spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
449                              link_args: config_host['SPICE_LIBS'].split())
450   spice_headers = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split())
451 endif
452 if 'CONFIG_SPICE_PROTOCOL' in config_host
453   spice_protocol = declare_dependency(compile_args: config_host['SPICE_PROTOCOL_CFLAGS'].split())
454 endif
455 rt = cc.find_library('rt', required: false)
456 libdl = not_found
457 if 'CONFIG_PLUGIN' in config_host
458   libdl = cc.find_library('dl', required: true)
459 endif
460 libiscsi = not_found
461 if not get_option('libiscsi').auto() or have_block
462   libiscsi = dependency('libiscsi', version: '>=1.9.0',
463                          required: get_option('libiscsi'),
464                          method: 'pkg-config', kwargs: static_kwargs)
465 endif
466 zstd = not_found
467 if not get_option('zstd').auto() or have_block
468   zstd = dependency('libzstd', version: '>=1.4.0',
469                     required: get_option('zstd'),
470                     method: 'pkg-config', kwargs: static_kwargs)
471 endif
472 gbm = not_found
473 if 'CONFIG_GBM' in config_host
474   gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
475                            link_args: config_host['GBM_LIBS'].split())
476 endif
477 virgl = not_found
478 if 'CONFIG_VIRGL' in config_host
479   virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
480                              link_args: config_host['VIRGL_LIBS'].split())
481 endif
482 curl = not_found
483 if not get_option('curl').auto() or have_block
484   curl = dependency('libcurl', version: '>=7.29.0',
485                     method: 'pkg-config',
486                     required: get_option('curl'),
487                     kwargs: static_kwargs)
488 endif
489 libudev = not_found
490 if targetos == 'linux' and (have_system or have_tools)
491   libudev = dependency('libudev',
492                        method: 'pkg-config',
493                        required: get_option('libudev'),
494                        kwargs: static_kwargs)
495 endif
497 mpathlibs = [libudev]
498 mpathpersist = not_found
499 mpathpersist_new_api = false
500 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
501   mpath_test_source_new = '''
502     #include <libudev.h>
503     #include <mpath_persist.h>
504     unsigned mpath_mx_alloc_len = 1024;
505     int logsink;
506     static struct config *multipath_conf;
507     extern struct udev *udev;
508     extern struct config *get_multipath_config(void);
509     extern void put_multipath_config(struct config *conf);
510     struct udev *udev;
511     struct config *get_multipath_config(void) { return multipath_conf; }
512     void put_multipath_config(struct config *conf) { }
513     int main(void) {
514         udev = udev_new();
515         multipath_conf = mpath_lib_init();
516         return 0;
517     }'''
518   mpath_test_source_old = '''
519       #include <libudev.h>
520       #include <mpath_persist.h>
521       unsigned mpath_mx_alloc_len = 1024;
522       int logsink;
523       int main(void) {
524           struct udev *udev = udev_new();
525           mpath_lib_init(udev);
526           return 0;
527       }'''
528   libmpathpersist = cc.find_library('mpathpersist',
529                                     required: get_option('mpath'),
530                                     kwargs: static_kwargs)
531   if libmpathpersist.found()
532     mpathlibs += libmpathpersist
533     if enable_static
534       mpathlibs += cc.find_library('devmapper',
535                                      required: get_option('mpath'),
536                                      kwargs: static_kwargs)
537     endif
538     mpathlibs += cc.find_library('multipath',
539                                  required: get_option('mpath'),
540                                  kwargs: static_kwargs)
541     foreach lib: mpathlibs
542       if not lib.found()
543         mpathlibs = []
544         break
545       endif
546     endforeach
547     if mpathlibs.length() == 0
548       msg = 'Dependencies missing for libmpathpersist'
549     elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
550       mpathpersist = declare_dependency(dependencies: mpathlibs)
551       mpathpersist_new_api = true
552     elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
553       mpathpersist = declare_dependency(dependencies: mpathlibs)
554     else
555       msg = 'Cannot detect libmpathpersist API'
556     endif
557     if not mpathpersist.found()
558       if get_option('mpath').enabled()
559         error(msg)
560       else
561         warning(msg + ', disabling')
562       endif
563     endif
564   endif
565 endif
567 iconv = not_found
568 curses = not_found
569 if have_system and not get_option('curses').disabled()
570   curses_test = '''
571     #include <locale.h>
572     #include <curses.h>
573     #include <wchar.h>
574     int main(void) {
575       wchar_t wch = L'w';
576       setlocale(LC_ALL, "");
577       resize_term(0, 0);
578       addwstr(L"wide chars\n");
579       addnwstr(&wch, 1);
580       add_wch(WACS_DEGREE);
581       return 0;
582     }'''
584   curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
585   foreach curses_dep : curses_dep_list
586     if not curses.found()
587       curses = dependency(curses_dep,
588                           required: false,
589                           method: 'pkg-config',
590                           kwargs: static_kwargs)
591     endif
592   endforeach
593   msg = get_option('curses').enabled() ? 'curses library not found' : ''
594   curses_compile_args = ['-DNCURSES_WIDECHAR']
595   if curses.found()
596     if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
597       curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
598     else
599       msg = 'curses package not usable'
600       curses = not_found
601     endif
602   endif
603   if not curses.found()
604     has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
605     if targetos != 'windows' and not has_curses_h
606       message('Trying with /usr/include/ncursesw')
607       curses_compile_args += ['-I/usr/include/ncursesw']
608       has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
609     endif
610     if has_curses_h
611       curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
612       foreach curses_libname : curses_libname_list
613         libcurses = cc.find_library(curses_libname,
614                                     required: false,
615                                     kwargs: static_kwargs)
616         if libcurses.found()
617           if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
618             curses = declare_dependency(compile_args: curses_compile_args,
619                                         dependencies: [libcurses])
620             break
621           else
622             msg = 'curses library not usable'
623           endif
624         endif
625       endforeach
626     endif
627   endif
628   if not get_option('iconv').disabled()
629     foreach link_args : [ ['-liconv'], [] ]
630       # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
631       # We need to use libiconv if available because mixing libiconv's headers with
632       # the system libc does not work.
633       # However, without adding glib to the dependencies -L/usr/local/lib will not be
634       # included in the command line and libiconv will not be found.
635       if cc.links('''
636         #include <iconv.h>
637         int main(void) {
638           iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
639           return conv != (iconv_t) -1;
640         }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
641         iconv = declare_dependency(link_args: link_args, dependencies: glib)
642         break
643       endif
644     endforeach
645   endif
646   if curses.found() and not iconv.found()
647     if get_option('iconv').enabled()
648       error('iconv not available')
649     endif
650     msg = 'iconv required for curses UI but not available'
651     curses = not_found
652   endif
653   if not curses.found() and msg != ''
654     if get_option('curses').enabled()
655       error(msg)
656     else
657       warning(msg + ', disabling')
658     endif
659   endif
660 endif
662 brlapi = not_found
663 if not get_option('brlapi').auto() or have_system
664   brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
665                          required: get_option('brlapi'),
666                          kwargs: static_kwargs)
667   if brlapi.found() and not cc.links('''
668      #include <brlapi.h>
669      #include <stddef.h>
670      int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
671     brlapi = not_found
672     if get_option('brlapi').enabled()
673       error('could not link brlapi')
674     else
675       warning('could not link brlapi, disabling')
676     endif
677   endif
678 endif
680 sdl = not_found
681 if not get_option('sdl').auto() or (have_system and not cocoa.found())
682   sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
683   sdl_image = not_found
684 endif
685 if sdl.found()
686   # work around 2.0.8 bug
687   sdl = declare_dependency(compile_args: '-Wno-undef',
688                            dependencies: sdl)
689   sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
690                          method: 'pkg-config', kwargs: static_kwargs)
691 else
692   if get_option('sdl_image').enabled()
693     error('sdl-image required, but SDL was @0@'.format(
694           get_option('sdl').disabled() ? 'disabled' : 'not found'))
695   endif
696   sdl_image = not_found
697 endif
699 rbd = not_found
700 if not get_option('rbd').auto() or have_block
701   librados = cc.find_library('rados', required: get_option('rbd'),
702                              kwargs: static_kwargs)
703   librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
704                            required: get_option('rbd'),
705                            kwargs: static_kwargs)
706   if librados.found() and librbd.found()
707     if cc.links('''
708       #include <stdio.h>
709       #include <rbd/librbd.h>
710       int main(void) {
711         rados_t cluster;
712         rados_create(&cluster, NULL);
713         return 0;
714       }''', dependencies: [librbd, librados])
715       rbd = declare_dependency(dependencies: [librbd, librados])
716     elif get_option('rbd').enabled()
717       error('could not link librados')
718     else
719       warning('could not link librados, disabling')
720     endif
721   endif
722 endif
724 glusterfs = not_found
725 glusterfs_ftruncate_has_stat = false
726 glusterfs_iocb_has_stat = false
727 if not get_option('glusterfs').auto() or have_block
728   glusterfs = dependency('glusterfs-api', version: '>=3',
729                          required: get_option('glusterfs'),
730                          method: 'pkg-config', kwargs: static_kwargs)
731   if glusterfs.found()
732     glusterfs_ftruncate_has_stat = cc.links('''
733       #include <glusterfs/api/glfs.h>
735       int
736       main(void)
737       {
738           /* new glfs_ftruncate() passes two additional args */
739           return glfs_ftruncate(NULL, 0, NULL, NULL);
740       }
741     ''', dependencies: glusterfs)
742     glusterfs_iocb_has_stat = cc.links('''
743       #include <glusterfs/api/glfs.h>
745       /* new glfs_io_cbk() passes two additional glfs_stat structs */
746       static void
747       glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
748       {}
750       int
751       main(void)
752       {
753           glfs_io_cbk iocb = &glusterfs_iocb;
754           iocb(NULL, 0 , NULL, NULL, NULL);
755           return 0;
756       }
757     ''', dependencies: glusterfs)
758   endif
759 endif
760 libssh = not_found
761 if 'CONFIG_LIBSSH' in config_host
762   libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
763                               link_args: config_host['LIBSSH_LIBS'].split())
764 endif
765 libbzip2 = not_found
766 if not get_option('bzip2').auto() or have_block
767   libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
768                              required: get_option('bzip2'),
769                              kwargs: static_kwargs)
770   if libbzip2.found() and not cc.links('''
771      #include <bzlib.h>
772      int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
773     libbzip2 = not_found
774     if get_option('bzip2').enabled()
775       error('could not link libbzip2')
776     else
777       warning('could not link libbzip2, disabling')
778     endif
779   endif
780 endif
782 liblzfse = not_found
783 if not get_option('lzfse').auto() or have_block
784   liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
785                              required: get_option('lzfse'),
786                              kwargs: static_kwargs)
787 endif
788 if liblzfse.found() and not cc.links('''
789    #include <lzfse.h>
790    int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
791   liblzfse = not_found
792   if get_option('lzfse').enabled()
793     error('could not link liblzfse')
794   else
795     warning('could not link liblzfse, disabling')
796   endif
797 endif
799 oss = not_found
800 if 'CONFIG_AUDIO_OSS' in config_host
801   oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
802 endif
803 dsound = not_found
804 if 'CONFIG_AUDIO_DSOUND' in config_host
805   dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
806 endif
807 coreaudio = not_found
808 if 'CONFIG_AUDIO_COREAUDIO' in config_host
809   coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
810 endif
811 opengl = not_found
812 if 'CONFIG_OPENGL' in config_host
813   opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
814                               link_args: config_host['OPENGL_LIBS'].split())
815 endif
817 gnutls = not_found
818 if not get_option('gnutls').auto() or have_system
819   gnutls = dependency('gnutls', version: '>=3.5.18',
820                       method: 'pkg-config',
821                       required: get_option('gnutls'),
822                       kwargs: static_kwargs)
823 endif
825 # Nettle has priority over gcrypt
826 gcrypt = not_found
827 nettle = not_found
828 xts = 'private'
829 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
830   error('Only one of gcrypt & nettle can be enabled')
831 elif (not get_option('nettle').auto() or have_system) and not get_option('gcrypt').enabled()
832   nettle = dependency('nettle', version: '>=3.4',
833                       method: 'pkg-config',
834                       required: get_option('nettle'),
835                       kwargs: static_kwargs)
836   if nettle.found() and cc.has_header('nettle/xts.h', dependencies: nettle)
837     xts = 'nettle'
838   endif
839 endif
840 if (not get_option('gcrypt').auto() or have_system) and not nettle.found()
841   gcrypt = dependency('libgcrypt', version: '>=1.5',
842                          method: 'config-tool',
843                          required: get_option('gcrypt'),
844                          kwargs: static_kwargs)
845   if gcrypt.found() and cc.compiles('''
846     #include <gcrypt.h>
847     int main(void) {
848       gcry_cipher_hd_t handle;
849       gcry_cipher_open(&handle, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_XTS, 0);
850       return 0;
851     }
852     ''', dependencies: gcrypt)
853     xts = 'gcrypt'
854   endif
855   # Debian has removed -lgpg-error from libgcrypt-config
856   # as it "spreads unnecessary dependencies" which in
857   # turn breaks static builds...
858   if gcrypt.found() and enable_static
859     gcrypt = declare_dependency(dependencies: [
860       gcrypt,
861       cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
862   endif
863 endif
865 gtk = not_found
866 gtkx11 = not_found
867 if not get_option('gtk').auto() or (have_system and not cocoa.found())
868   gtk = dependency('gtk+-3.0', version: '>=3.22.0',
869                    method: 'pkg-config',
870                    required: get_option('gtk'),
871                    kwargs: static_kwargs)
872   if gtk.found()
873     gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
874                         method: 'pkg-config',
875                         required: false,
876                         kwargs: static_kwargs)
877     gtk = declare_dependency(dependencies: [gtk, gtkx11])
878   endif
879 endif
881 vte = not_found
882 if 'CONFIG_VTE' in config_host
883   vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
884                            link_args: config_host['VTE_LIBS'].split())
885 endif
886 x11 = not_found
887 if gtkx11.found()
888   x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
889                    kwargs: static_kwargs)
890 endif
891 vnc = not_found
892 png = not_found
893 jpeg = not_found
894 sasl = not_found
895 if get_option('vnc').enabled()
896   vnc = declare_dependency() # dummy dependency
897   png = dependency('libpng', required: get_option('vnc_png'),
898                    method: 'pkg-config', kwargs: static_kwargs)
899   jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
900                     method: 'pkg-config', kwargs: static_kwargs)
901   sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
902                          required: get_option('vnc_sasl'),
903                          kwargs: static_kwargs)
904   if sasl.found()
905     sasl = declare_dependency(dependencies: sasl,
906                               compile_args: '-DSTRUCT_IOVEC_DEFINED')
907   endif
908 endif
910 snappy = not_found
911 if not get_option('snappy').auto() or have_system
912   snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
913                            required: get_option('snappy'),
914                            kwargs: static_kwargs)
915 endif
916 if snappy.found() and not cc.links('''
917    #include <snappy-c.h>
918    int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
919   snappy = not_found
920   if get_option('snappy').enabled()
921     error('could not link libsnappy')
922   else
923     warning('could not link libsnappy, disabling')
924   endif
925 endif
927 lzo = not_found
928 if not get_option('lzo').auto() or have_system
929   lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
930                         required: get_option('lzo'),
931                         kwargs: static_kwargs)
932 endif
933 if lzo.found() and not cc.links('''
934    #include <lzo/lzo1x.h>
935    int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
936   lzo = not_found
937   if get_option('lzo').enabled()
938     error('could not link liblzo2')
939   else
940     warning('could not link liblzo2, disabling')
941   endif
942 endif
944 rdma = not_found
945 if 'CONFIG_RDMA' in config_host
946   rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
947 endif
948 numa = not_found
949 if 'CONFIG_NUMA' in config_host
950   numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
951 endif
952 xen = not_found
953 if 'CONFIG_XEN_BACKEND' in config_host
954   xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
955                            link_args: config_host['XEN_LIBS'].split())
956 endif
957 cacard = not_found
958 if 'CONFIG_SMARTCARD' in config_host
959   cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
960                               link_args: config_host['SMARTCARD_LIBS'].split())
961 endif
962 u2f = not_found
963 if have_system
964   u2f = dependency('u2f-emu', required: get_option('u2f'),
965                    method: 'pkg-config',
966                    kwargs: static_kwargs)
967 endif
968 usbredir = not_found
969 if 'CONFIG_USB_REDIR' in config_host
970   usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
971                                 link_args: config_host['USB_REDIR_LIBS'].split())
972 endif
973 libusb = not_found
974 if 'CONFIG_USB_LIBUSB' in config_host
975   libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
976                               link_args: config_host['LIBUSB_LIBS'].split())
977 endif
978 libpmem = not_found
979 if 'CONFIG_LIBPMEM' in config_host
980   libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
981                                link_args: config_host['LIBPMEM_LIBS'].split())
982 endif
983 libdaxctl = not_found
984 if 'CONFIG_LIBDAXCTL' in config_host
985   libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
986 endif
987 tasn1 = not_found
988 if gnutls.found()
989   tasn1 = dependency('libtasn1',
990                      method: 'pkg-config',
991                      kwargs: static_kwargs)
992 endif
993 keyutils = dependency('libkeyutils', required: false,
994                       method: 'pkg-config', kwargs: static_kwargs)
996 has_gettid = cc.has_function('gettid')
998 # Malloc tests
1000 malloc = []
1001 if get_option('malloc') == 'system'
1002   has_malloc_trim = \
1003     not get_option('malloc_trim').disabled() and \
1004     cc.links('''#include <malloc.h>
1005                 int main(void) { malloc_trim(0); return 0; }''')
1006 else
1007   has_malloc_trim = false
1008   malloc = cc.find_library(get_option('malloc'), required: true)
1009 endif
1010 if not has_malloc_trim and get_option('malloc_trim').enabled()
1011   if get_option('malloc') == 'system'
1012     error('malloc_trim not available on this platform.')
1013   else
1014     error('malloc_trim not available with non-libc memory allocator')
1015   endif
1016 endif
1018 # Check whether the glibc provides statx()
1020 statx_test = '''
1021   #ifndef _GNU_SOURCE
1022   #define _GNU_SOURCE
1023   #endif
1024   #include <sys/stat.h>
1025   int main(void) {
1026     struct statx statxbuf;
1027     statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1028     return 0;
1029   }'''
1031 has_statx = cc.links(statx_test)
1033 have_vhost_user_blk_server = (targetos == 'linux' and
1034     'CONFIG_VHOST_USER' in config_host)
1036 if get_option('vhost_user_blk_server').enabled()
1037     if targetos != 'linux'
1038         error('vhost_user_blk_server requires linux')
1039     elif 'CONFIG_VHOST_USER' not in config_host
1040         error('vhost_user_blk_server requires vhost-user support')
1041     endif
1042 elif get_option('vhost_user_blk_server').disabled() or not have_system
1043     have_vhost_user_blk_server = false
1044 endif
1047 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1048   error('Cannot enable fuse-lseek while fuse is disabled')
1049 endif
1051 fuse = dependency('fuse3', required: get_option('fuse'),
1052                   version: '>=3.1', method: 'pkg-config',
1053                   kwargs: static_kwargs)
1055 fuse_lseek = not_found
1056 if not get_option('fuse_lseek').disabled()
1057   if fuse.version().version_compare('>=3.8')
1058     # Dummy dependency
1059     fuse_lseek = declare_dependency()
1060   elif get_option('fuse_lseek').enabled()
1061     if fuse.found()
1062       error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1063     else
1064       error('fuse-lseek requires libfuse, which was not found')
1065     endif
1066   endif
1067 endif
1069 # libbpf
1070 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1071 if libbpf.found() and not cc.links('''
1072    #include <bpf/libbpf.h>
1073    int main(void)
1074    {
1075      bpf_object__destroy_skeleton(NULL);
1076      return 0;
1077    }''', dependencies: libbpf)
1078   libbpf = not_found
1079   if get_option('bpf').enabled()
1080     error('libbpf skeleton test failed')
1081   else
1082     warning('libbpf skeleton test failed, disabling')
1083   endif
1084 endif
1086 if get_option('cfi')
1087   cfi_flags=[]
1088   # Check for dependency on LTO
1089   if not get_option('b_lto')
1090     error('Selected Control-Flow Integrity but LTO is disabled')
1091   endif
1092   if config_host.has_key('CONFIG_MODULES')
1093     error('Selected Control-Flow Integrity is not compatible with modules')
1094   endif
1095   # Check for cfi flags. CFI requires LTO so we can't use
1096   # get_supported_arguments, but need a more complex "compiles" which allows
1097   # custom arguments
1098   if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1099                  args: ['-flto', '-fsanitize=cfi-icall'] )
1100     cfi_flags += '-fsanitize=cfi-icall'
1101   else
1102     error('-fsanitize=cfi-icall is not supported by the compiler')
1103   endif
1104   if cc.compiles('int main () { return 0; }',
1105                  name: '-fsanitize-cfi-icall-generalize-pointers',
1106                  args: ['-flto', '-fsanitize=cfi-icall',
1107                         '-fsanitize-cfi-icall-generalize-pointers'] )
1108     cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1109   else
1110     error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1111   endif
1112   if get_option('cfi_debug')
1113     if cc.compiles('int main () { return 0; }',
1114                    name: '-fno-sanitize-trap=cfi-icall',
1115                    args: ['-flto', '-fsanitize=cfi-icall',
1116                           '-fno-sanitize-trap=cfi-icall'] )
1117       cfi_flags += '-fno-sanitize-trap=cfi-icall'
1118     else
1119       error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1120     endif
1121   endif
1122   add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1123   add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1124 endif
1126 #################
1127 # config-host.h #
1128 #################
1130 have_virtfs = (targetos == 'linux' and
1131     have_system and
1132     libattr.found() and
1133     libcap_ng.found())
1135 have_virtfs_proxy_helper = have_virtfs and have_tools
1137 if get_option('virtfs').enabled()
1138   if not have_virtfs
1139     if targetos != 'linux'
1140       error('virtio-9p (virtfs) requires Linux')
1141     elif not libcap_ng.found() or not libattr.found()
1142       error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel')
1143     elif not have_system
1144       error('virtio-9p (virtfs) needs system emulation support')
1145     endif
1146   endif
1147 elif get_option('virtfs').disabled()
1148   have_virtfs = false
1149 endif
1151 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1152 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1153 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1154 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1155 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1156 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1157 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1158 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1159 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1160 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1161 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1162 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1164 config_host_data.set('CONFIG_ATTR', libattr.found())
1165 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1166 config_host_data.set('CONFIG_COCOA', cocoa.found())
1167 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1168 config_host_data.set('CONFIG_LZO', lzo.found())
1169 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1170 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1171 config_host_data.set('CONFIG_CURL', curl.found())
1172 config_host_data.set('CONFIG_CURSES', curses.found())
1173 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1174 if glusterfs.found()
1175   config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1176   config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1177   config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1178   config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1179   config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1180   config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1181 endif
1182 config_host_data.set('CONFIG_GTK', gtk.found())
1183 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1184 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1185 config_host_data.set('CONFIG_EBPF', libbpf.found())
1186 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1187 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1188 config_host_data.set('CONFIG_RBD', rbd.found())
1189 config_host_data.set('CONFIG_SDL', sdl.found())
1190 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1191 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1192 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1193 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1194 config_host_data.set('CONFIG_VNC', vnc.found())
1195 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1196 config_host_data.set('CONFIG_VNC_PNG', png.found())
1197 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1198 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1199 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1200 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1201 config_host_data.set('CONFIG_GETTID', has_gettid)
1202 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1203 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1204 config_host_data.set('CONFIG_NETTLE', nettle.found())
1205 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1206 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1207 config_host_data.set('CONFIG_STATX', has_statx)
1208 config_host_data.set('CONFIG_ZSTD', zstd.found())
1209 config_host_data.set('CONFIG_FUSE', fuse.found())
1210 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1211 config_host_data.set('CONFIG_X11', x11.found())
1212 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1213 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1214 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1215 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1216 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1218 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1219 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1220 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1221 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1222 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1223 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1225 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1227 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
1228 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1229 strings = ['HOST_DSOSUF', 'CONFIG_IASL']
1230 foreach k, v: config_host
1231   if ignored.contains(k)
1232     # do nothing
1233   elif arrays.contains(k)
1234     if v != ''
1235       v = '"' + '", "'.join(v.split()) + '", '
1236     endif
1237     config_host_data.set(k, v)
1238   elif k == 'ARCH'
1239     config_host_data.set('HOST_' + v.to_upper(), 1)
1240   elif strings.contains(k)
1241     if not k.startswith('CONFIG_')
1242       k = 'CONFIG_' + k.to_upper()
1243     endif
1244     config_host_data.set_quoted(k, v)
1245   elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
1246     config_host_data.set(k, v == 'y' ? 1 : v)
1247   endif
1248 endforeach
1250 ########################
1251 # Target configuration #
1252 ########################
1254 minikconf = find_program('scripts/minikconf.py')
1255 config_all = {}
1256 config_all_devices = {}
1257 config_all_disas = {}
1258 config_devices_mak_list = []
1259 config_devices_h = {}
1260 config_target_h = {}
1261 config_target_mak = {}
1263 disassemblers = {
1264   'alpha' : ['CONFIG_ALPHA_DIS'],
1265   'arm' : ['CONFIG_ARM_DIS'],
1266   'avr' : ['CONFIG_AVR_DIS'],
1267   'cris' : ['CONFIG_CRIS_DIS'],
1268   'hexagon' : ['CONFIG_HEXAGON_DIS'],
1269   'hppa' : ['CONFIG_HPPA_DIS'],
1270   'i386' : ['CONFIG_I386_DIS'],
1271   'x86_64' : ['CONFIG_I386_DIS'],
1272   'x32' : ['CONFIG_I386_DIS'],
1273   'm68k' : ['CONFIG_M68K_DIS'],
1274   'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1275   'mips' : ['CONFIG_MIPS_DIS'],
1276   'nios2' : ['CONFIG_NIOS2_DIS'],
1277   'or1k' : ['CONFIG_OPENRISC_DIS'],
1278   'ppc' : ['CONFIG_PPC_DIS'],
1279   'riscv' : ['CONFIG_RISCV_DIS'],
1280   'rx' : ['CONFIG_RX_DIS'],
1281   's390' : ['CONFIG_S390_DIS'],
1282   'sh4' : ['CONFIG_SH4_DIS'],
1283   'sparc' : ['CONFIG_SPARC_DIS'],
1284   'xtensa' : ['CONFIG_XTENSA_DIS'],
1286 if link_language == 'cpp'
1287   disassemblers += {
1288     'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1289     'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1290     'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1291   }
1292 endif
1294 host_kconfig = \
1295   ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1296   ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
1297   ('CONFIG_IVSHMEM' in config_host ? ['CONFIG_IVSHMEM=y'] : []) + \
1298   ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1299   (x11.found() ? ['CONFIG_X11=y'] : []) + \
1300   ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1301   ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1302   ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1303   (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1304   ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1305   ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
1306   (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
1308 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1310 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1311 actual_target_dirs = []
1312 fdt_required = []
1313 foreach target : target_dirs
1314   config_target = { 'TARGET_NAME': target.split('-')[0] }
1315   if target.endswith('linux-user')
1316     if targetos != 'linux'
1317       if default_targets
1318         continue
1319       endif
1320       error('Target @0@ is only available on a Linux host'.format(target))
1321     endif
1322     config_target += { 'CONFIG_LINUX_USER': 'y' }
1323   elif target.endswith('bsd-user')
1324     if 'CONFIG_BSD' not in config_host
1325       if default_targets
1326         continue
1327       endif
1328       error('Target @0@ is only available on a BSD host'.format(target))
1329     endif
1330     config_target += { 'CONFIG_BSD_USER': 'y' }
1331   elif target.endswith('softmmu')
1332     config_target += { 'CONFIG_SOFTMMU': 'y' }
1333   endif
1334   if target.endswith('-user')
1335     config_target += {
1336       'CONFIG_USER_ONLY': 'y',
1337       'CONFIG_QEMU_INTERP_PREFIX':
1338         config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1339     }
1340   endif
1342   accel_kconfig = []
1343   foreach sym: accelerators
1344     if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1345       config_target += { sym: 'y' }
1346       config_all += { sym: 'y' }
1347       if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
1348         config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
1349       elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1350         config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1351       endif
1352       accel_kconfig += [ sym + '=y' ]
1353     endif
1354   endforeach
1355   if accel_kconfig.length() == 0
1356     if default_targets
1357       continue
1358     endif
1359     error('No accelerator available for target @0@'.format(target))
1360   endif
1362   actual_target_dirs += target
1363   config_target += keyval.load('default-configs/targets' / target + '.mak')
1364   config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1366   if 'TARGET_NEED_FDT' in config_target
1367     fdt_required += target
1368   endif
1370   # Add default keys
1371   if 'TARGET_BASE_ARCH' not in config_target
1372     config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1373   endif
1374   if 'TARGET_ABI_DIR' not in config_target
1375     config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1376   endif
1378   foreach k, v: disassemblers
1379     if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1380       foreach sym: v
1381         config_target += { sym: 'y' }
1382         config_all_disas += { sym: 'y' }
1383       endforeach
1384     endif
1385   endforeach
1387   config_target_data = configuration_data()
1388   foreach k, v: config_target
1389     if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1390       # do nothing
1391     elif ignored.contains(k)
1392       # do nothing
1393     elif k == 'TARGET_BASE_ARCH'
1394       # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1395       # not used to select files from sourcesets.
1396       config_target_data.set('TARGET_' + v.to_upper(), 1)
1397     elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1398       config_target_data.set_quoted(k, v)
1399     elif v == 'y'
1400       config_target_data.set(k, 1)
1401     else
1402       config_target_data.set(k, v)
1403     endif
1404   endforeach
1405   config_target_h += {target: configure_file(output: target + '-config-target.h',
1406                                                configuration: config_target_data)}
1408   if target.endswith('-softmmu')
1409     config_devices_mak = target + '-config-devices.mak'
1410     config_devices_mak = configure_file(
1411       input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
1412       output: config_devices_mak,
1413       depfile: config_devices_mak + '.d',
1414       capture: true,
1415       command: [minikconf,
1416                 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1417                 config_devices_mak, '@DEPFILE@', '@INPUT@',
1418                 host_kconfig, accel_kconfig])
1420     config_devices_data = configuration_data()
1421     config_devices = keyval.load(config_devices_mak)
1422     foreach k, v: config_devices
1423       config_devices_data.set(k, 1)
1424     endforeach
1425     config_devices_mak_list += config_devices_mak
1426     config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1427                                                 configuration: config_devices_data)}
1428     config_target += config_devices
1429     config_all_devices += config_devices
1430   endif
1431   config_target_mak += {target: config_target}
1432 endforeach
1433 target_dirs = actual_target_dirs
1435 # This configuration is used to build files that are shared by
1436 # multiple binaries, and then extracted out of the "common"
1437 # static_library target.
1439 # We do not use all_sources()/all_dependencies(), because it would
1440 # build literally all source files, including devices only used by
1441 # targets that are not built for this compilation.  The CONFIG_ALL
1442 # pseudo symbol replaces it.
1444 config_all += config_all_devices
1445 config_all += config_host
1446 config_all += config_all_disas
1447 config_all += {
1448   'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1449   'CONFIG_SOFTMMU': have_system,
1450   'CONFIG_USER_ONLY': have_user,
1451   'CONFIG_ALL': true,
1454 ##############
1455 # Submodules #
1456 ##############
1458 capstone = not_found
1459 capstone_opt = get_option('capstone')
1460 if capstone_opt in ['enabled', 'auto', 'system']
1461   have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1462   capstone = dependency('capstone', version: '>=4.0',
1463                         kwargs: static_kwargs, method: 'pkg-config',
1464                         required: capstone_opt == 'system' or
1465                                   capstone_opt == 'enabled' and not have_internal)
1466   if capstone.found()
1467     capstone_opt = 'system'
1468   elif have_internal
1469     capstone_opt = 'internal'
1470   else
1471     capstone_opt = 'disabled'
1472   endif
1473 endif
1474 if capstone_opt == 'internal'
1475   capstone_data = configuration_data()
1476   capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1478   capstone_files = files(
1479     'capstone/cs.c',
1480     'capstone/MCInst.c',
1481     'capstone/MCInstrDesc.c',
1482     'capstone/MCRegisterInfo.c',
1483     'capstone/SStream.c',
1484     'capstone/utils.c'
1485   )
1487   if 'CONFIG_ARM_DIS' in config_all_disas
1488     capstone_data.set('CAPSTONE_HAS_ARM', '1')
1489     capstone_files += files(
1490       'capstone/arch/ARM/ARMDisassembler.c',
1491       'capstone/arch/ARM/ARMInstPrinter.c',
1492       'capstone/arch/ARM/ARMMapping.c',
1493       'capstone/arch/ARM/ARMModule.c'
1494     )
1495   endif
1497   # FIXME: This config entry currently depends on a c++ compiler.
1498   # Which is needed for building libvixl, but not for capstone.
1499   if 'CONFIG_ARM_A64_DIS' in config_all_disas
1500     capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1501     capstone_files += files(
1502       'capstone/arch/AArch64/AArch64BaseInfo.c',
1503       'capstone/arch/AArch64/AArch64Disassembler.c',
1504       'capstone/arch/AArch64/AArch64InstPrinter.c',
1505       'capstone/arch/AArch64/AArch64Mapping.c',
1506       'capstone/arch/AArch64/AArch64Module.c'
1507     )
1508   endif
1510   if 'CONFIG_PPC_DIS' in config_all_disas
1511     capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1512     capstone_files += files(
1513       'capstone/arch/PowerPC/PPCDisassembler.c',
1514       'capstone/arch/PowerPC/PPCInstPrinter.c',
1515       'capstone/arch/PowerPC/PPCMapping.c',
1516       'capstone/arch/PowerPC/PPCModule.c'
1517     )
1518   endif
1520   if 'CONFIG_S390_DIS' in config_all_disas
1521     capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1522     capstone_files += files(
1523       'capstone/arch/SystemZ/SystemZDisassembler.c',
1524       'capstone/arch/SystemZ/SystemZInstPrinter.c',
1525       'capstone/arch/SystemZ/SystemZMapping.c',
1526       'capstone/arch/SystemZ/SystemZModule.c',
1527       'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1528     )
1529   endif
1531   if 'CONFIG_I386_DIS' in config_all_disas
1532     capstone_data.set('CAPSTONE_HAS_X86', 1)
1533     capstone_files += files(
1534       'capstone/arch/X86/X86Disassembler.c',
1535       'capstone/arch/X86/X86DisassemblerDecoder.c',
1536       'capstone/arch/X86/X86ATTInstPrinter.c',
1537       'capstone/arch/X86/X86IntelInstPrinter.c',
1538       'capstone/arch/X86/X86InstPrinterCommon.c',
1539       'capstone/arch/X86/X86Mapping.c',
1540       'capstone/arch/X86/X86Module.c'
1541     )
1542   endif
1544   configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1546   capstone_cargs = [
1547     # FIXME: There does not seem to be a way to completely replace the c_args
1548     # that come from add_project_arguments() -- we can only add to them.
1549     # So: disable all warnings with a big hammer.
1550     '-Wno-error', '-w',
1552     # Include all configuration defines via a header file, which will wind up
1553     # as a dependency on the object file, and thus changes here will result
1554     # in a rebuild.
1555     '-include', 'capstone-defs.h'
1556   ]
1558   libcapstone = static_library('capstone',
1559                                build_by_default: false,
1560                                sources: capstone_files,
1561                                c_args: capstone_cargs,
1562                                include_directories: 'capstone/include')
1563   capstone = declare_dependency(link_with: libcapstone,
1564                                 include_directories: 'capstone/include/capstone')
1565 endif
1567 slirp = not_found
1568 slirp_opt = 'disabled'
1569 if have_system
1570   slirp_opt = get_option('slirp')
1571   if slirp_opt in ['enabled', 'auto', 'system']
1572     have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1573     slirp = dependency('slirp', kwargs: static_kwargs,
1574                        method: 'pkg-config',
1575                        required: slirp_opt == 'system' or
1576                                  slirp_opt == 'enabled' and not have_internal)
1577     if slirp.found()
1578       slirp_opt = 'system'
1579     elif have_internal
1580       slirp_opt = 'internal'
1581     else
1582       slirp_opt = 'disabled'
1583     endif
1584   endif
1585   if slirp_opt == 'internal'
1586     slirp_deps = []
1587     if targetos == 'windows'
1588       slirp_deps = cc.find_library('iphlpapi')
1589     endif
1590     slirp_conf = configuration_data()
1591     slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1592     slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1593     slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1594     slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1595     slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1596     slirp_files = [
1597       'slirp/src/arp_table.c',
1598       'slirp/src/bootp.c',
1599       'slirp/src/cksum.c',
1600       'slirp/src/dhcpv6.c',
1601       'slirp/src/dnssearch.c',
1602       'slirp/src/if.c',
1603       'slirp/src/ip6_icmp.c',
1604       'slirp/src/ip6_input.c',
1605       'slirp/src/ip6_output.c',
1606       'slirp/src/ip_icmp.c',
1607       'slirp/src/ip_input.c',
1608       'slirp/src/ip_output.c',
1609       'slirp/src/mbuf.c',
1610       'slirp/src/misc.c',
1611       'slirp/src/ncsi.c',
1612       'slirp/src/ndp_table.c',
1613       'slirp/src/sbuf.c',
1614       'slirp/src/slirp.c',
1615       'slirp/src/socket.c',
1616       'slirp/src/state.c',
1617       'slirp/src/stream.c',
1618       'slirp/src/tcp_input.c',
1619       'slirp/src/tcp_output.c',
1620       'slirp/src/tcp_subr.c',
1621       'slirp/src/tcp_timer.c',
1622       'slirp/src/tftp.c',
1623       'slirp/src/udp.c',
1624       'slirp/src/udp6.c',
1625       'slirp/src/util.c',
1626       'slirp/src/version.c',
1627       'slirp/src/vmstate.c',
1628     ]
1630     configure_file(
1631       input : 'slirp/src/libslirp-version.h.in',
1632       output : 'libslirp-version.h',
1633       configuration: slirp_conf)
1635     slirp_inc = include_directories('slirp', 'slirp/src')
1636     libslirp = static_library('slirp',
1637                               build_by_default: false,
1638                               sources: slirp_files,
1639                               c_args: slirp_cargs,
1640                               include_directories: slirp_inc)
1641     slirp = declare_dependency(link_with: libslirp,
1642                                dependencies: slirp_deps,
1643                                include_directories: slirp_inc)
1644   endif
1645 endif
1647 # For CFI, we need to compile slirp as a static library together with qemu.
1648 # This is because we register slirp functions as callbacks for QEMU Timers.
1649 # When using a system-wide shared libslirp, the type information for the
1650 # callback is missing and the timer call produces a false positive with CFI.
1652 # Now that slirp_opt has been defined, check if the selected slirp is compatible
1653 # with control-flow integrity.
1654 if get_option('cfi') and slirp_opt == 'system'
1655   error('Control-Flow Integrity is not compatible with system-wide slirp.' \
1656          + ' Please configure with --enable-slirp=git')
1657 endif
1659 fdt = not_found
1660 fdt_opt = get_option('fdt')
1661 if have_system
1662   if fdt_opt in ['enabled', 'auto', 'system']
1663     have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1664     fdt = cc.find_library('fdt', kwargs: static_kwargs,
1665                           required: fdt_opt == 'system' or
1666                                     fdt_opt == 'enabled' and not have_internal)
1667     if fdt.found() and cc.links('''
1668        #include <libfdt.h>
1669        #include <libfdt_env.h>
1670        int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1671          dependencies: fdt)
1672       fdt_opt = 'system'
1673     elif have_internal
1674       fdt_opt = 'internal'
1675     else
1676       fdt_opt = 'disabled'
1677     endif
1678   endif
1679   if fdt_opt == 'internal'
1680     fdt_files = files(
1681       'dtc/libfdt/fdt.c',
1682       'dtc/libfdt/fdt_ro.c',
1683       'dtc/libfdt/fdt_wip.c',
1684       'dtc/libfdt/fdt_sw.c',
1685       'dtc/libfdt/fdt_rw.c',
1686       'dtc/libfdt/fdt_strerror.c',
1687       'dtc/libfdt/fdt_empty_tree.c',
1688       'dtc/libfdt/fdt_addresses.c',
1689       'dtc/libfdt/fdt_overlay.c',
1690       'dtc/libfdt/fdt_check.c',
1691     )
1693     fdt_inc = include_directories('dtc/libfdt')
1694     libfdt = static_library('fdt',
1695                             build_by_default: false,
1696                             sources: fdt_files,
1697                             include_directories: fdt_inc)
1698     fdt = declare_dependency(link_with: libfdt,
1699                              include_directories: fdt_inc)
1700   endif
1701 endif
1702 if not fdt.found() and fdt_required.length() > 0
1703   error('fdt not available but required by targets ' + ', '.join(fdt_required))
1704 endif
1706 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1707 config_host_data.set('CONFIG_FDT', fdt.found())
1708 config_host_data.set('CONFIG_SLIRP', slirp.found())
1710 #####################
1711 # Generated sources #
1712 #####################
1714 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1716 hxtool = find_program('scripts/hxtool')
1717 shaderinclude = find_program('scripts/shaderinclude.pl')
1718 qapi_gen = find_program('scripts/qapi-gen.py')
1719 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1720                      meson.source_root() / 'scripts/qapi/commands.py',
1721                      meson.source_root() / 'scripts/qapi/common.py',
1722                      meson.source_root() / 'scripts/qapi/error.py',
1723                      meson.source_root() / 'scripts/qapi/events.py',
1724                      meson.source_root() / 'scripts/qapi/expr.py',
1725                      meson.source_root() / 'scripts/qapi/gen.py',
1726                      meson.source_root() / 'scripts/qapi/introspect.py',
1727                      meson.source_root() / 'scripts/qapi/parser.py',
1728                      meson.source_root() / 'scripts/qapi/schema.py',
1729                      meson.source_root() / 'scripts/qapi/source.py',
1730                      meson.source_root() / 'scripts/qapi/types.py',
1731                      meson.source_root() / 'scripts/qapi/visit.py',
1732                      meson.source_root() / 'scripts/qapi/common.py',
1733                      meson.source_root() / 'scripts/qapi-gen.py'
1736 tracetool = [
1737   python, files('scripts/tracetool.py'),
1738    '--backend=' + config_host['TRACE_BACKENDS']
1740 tracetool_depends = files(
1741   'scripts/tracetool/backend/log.py',
1742   'scripts/tracetool/backend/__init__.py',
1743   'scripts/tracetool/backend/dtrace.py',
1744   'scripts/tracetool/backend/ftrace.py',
1745   'scripts/tracetool/backend/simple.py',
1746   'scripts/tracetool/backend/syslog.py',
1747   'scripts/tracetool/backend/ust.py',
1748   'scripts/tracetool/format/tcg_h.py',
1749   'scripts/tracetool/format/ust_events_c.py',
1750   'scripts/tracetool/format/ust_events_h.py',
1751   'scripts/tracetool/format/__init__.py',
1752   'scripts/tracetool/format/d.py',
1753   'scripts/tracetool/format/tcg_helper_c.py',
1754   'scripts/tracetool/format/simpletrace_stap.py',
1755   'scripts/tracetool/format/c.py',
1756   'scripts/tracetool/format/h.py',
1757   'scripts/tracetool/format/tcg_helper_h.py',
1758   'scripts/tracetool/format/log_stap.py',
1759   'scripts/tracetool/format/stap.py',
1760   'scripts/tracetool/format/tcg_helper_wrapper_h.py',
1761   'scripts/tracetool/__init__.py',
1762   'scripts/tracetool/transform.py',
1763   'scripts/tracetool/vcpu.py'
1766 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1767                     meson.current_source_dir(),
1768                     config_host['PKGVERSION'], meson.project_version()]
1769 qemu_version = custom_target('qemu-version.h',
1770                              output: 'qemu-version.h',
1771                              command: qemu_version_cmd,
1772                              capture: true,
1773                              build_by_default: true,
1774                              build_always_stale: true)
1775 genh += qemu_version
1777 hxdep = []
1778 hx_headers = [
1779   ['qemu-options.hx', 'qemu-options.def'],
1780   ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1782 if have_system
1783   hx_headers += [
1784     ['hmp-commands.hx', 'hmp-commands.h'],
1785     ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1786   ]
1787 endif
1788 foreach d : hx_headers
1789   hxdep += custom_target(d[1],
1790                 input: files(d[0]),
1791                 output: d[1],
1792                 capture: true,
1793                 build_by_default: true, # to be removed when added to a target
1794                 command: [hxtool, '-h', '@INPUT0@'])
1795 endforeach
1796 genh += hxdep
1798 ###################
1799 # Collect sources #
1800 ###################
1802 authz_ss = ss.source_set()
1803 blockdev_ss = ss.source_set()
1804 block_ss = ss.source_set()
1805 bsd_user_ss = ss.source_set()
1806 chardev_ss = ss.source_set()
1807 common_ss = ss.source_set()
1808 crypto_ss = ss.source_set()
1809 io_ss = ss.source_set()
1810 linux_user_ss = ss.source_set()
1811 qmp_ss = ss.source_set()
1812 qom_ss = ss.source_set()
1813 softmmu_ss = ss.source_set()
1814 specific_fuzz_ss = ss.source_set()
1815 specific_ss = ss.source_set()
1816 stub_ss = ss.source_set()
1817 trace_ss = ss.source_set()
1818 user_ss = ss.source_set()
1819 util_ss = ss.source_set()
1821 modules = {}
1822 hw_arch = {}
1823 target_arch = {}
1824 target_softmmu_arch = {}
1825 target_user_arch = {}
1827 ###############
1828 # Trace files #
1829 ###############
1831 # TODO: add each directory to the subdirs from its own meson.build, once
1832 # we have those
1833 trace_events_subdirs = [
1834   'crypto',
1835   'qapi',
1836   'qom',
1837   'monitor',
1838   'util',
1840 if have_user
1841   trace_events_subdirs += [ 'linux-user' ]
1842 endif
1843 if have_block
1844   trace_events_subdirs += [
1845     'authz',
1846     'block',
1847     'io',
1848     'nbd',
1849     'scsi',
1850   ]
1851 endif
1852 if have_system
1853   trace_events_subdirs += [
1854     'accel/kvm',
1855     'audio',
1856     'backends',
1857     'backends/tpm',
1858     'chardev',
1859     'ebpf',
1860     'hw/9pfs',
1861     'hw/acpi',
1862     'hw/adc',
1863     'hw/alpha',
1864     'hw/arm',
1865     'hw/audio',
1866     'hw/block',
1867     'hw/block/dataplane',
1868     'hw/char',
1869     'hw/display',
1870     'hw/dma',
1871     'hw/hppa',
1872     'hw/hyperv',
1873     'hw/i2c',
1874     'hw/i386',
1875     'hw/i386/xen',
1876     'hw/ide',
1877     'hw/input',
1878     'hw/intc',
1879     'hw/isa',
1880     'hw/mem',
1881     'hw/mips',
1882     'hw/misc',
1883     'hw/misc/macio',
1884     'hw/net',
1885     'hw/net/can',
1886     'hw/nvme',
1887     'hw/nvram',
1888     'hw/pci',
1889     'hw/pci-host',
1890     'hw/ppc',
1891     'hw/rdma',
1892     'hw/rdma/vmw',
1893     'hw/rtc',
1894     'hw/s390x',
1895     'hw/scsi',
1896     'hw/sd',
1897     'hw/sparc',
1898     'hw/sparc64',
1899     'hw/ssi',
1900     'hw/timer',
1901     'hw/tpm',
1902     'hw/usb',
1903     'hw/vfio',
1904     'hw/virtio',
1905     'hw/watchdog',
1906     'hw/xen',
1907     'hw/gpio',
1908     'migration',
1909     'net',
1910     'softmmu',
1911     'ui',
1912     'hw/remote',
1913   ]
1914 endif
1915 if have_system or have_user
1916   trace_events_subdirs += [
1917     'accel/tcg',
1918     'hw/core',
1919     'target/arm',
1920     'target/hppa',
1921     'target/i386',
1922     'target/i386/kvm',
1923     'target/mips',
1924     'target/ppc',
1925     'target/riscv',
1926     'target/s390x',
1927     'target/sparc',
1928   ]
1929 endif
1931 vhost_user = not_found
1932 if 'CONFIG_VHOST_USER' in config_host
1933   libvhost_user = subproject('libvhost-user')
1934   vhost_user = libvhost_user.get_variable('vhost_user_dep')
1935 endif
1937 subdir('qapi')
1938 subdir('qobject')
1939 subdir('stubs')
1940 subdir('trace')
1941 subdir('util')
1942 subdir('qom')
1943 subdir('authz')
1944 subdir('crypto')
1945 subdir('ui')
1948 if enable_modules
1949   libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1950   modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1951 endif
1953 stub_ss = stub_ss.apply(config_all, strict: false)
1955 util_ss.add_all(trace_ss)
1956 util_ss = util_ss.apply(config_all, strict: false)
1957 libqemuutil = static_library('qemuutil',
1958                              sources: util_ss.sources() + stub_ss.sources() + genh,
1959                              dependencies: [util_ss.dependencies(), libm, glib, socket, malloc, pixman])
1960 qemuutil = declare_dependency(link_with: libqemuutil,
1961                               sources: genh + version_res)
1963 if have_system or have_user
1964   decodetree = generator(find_program('scripts/decodetree.py'),
1965                          output: 'decode-@BASENAME@.c.inc',
1966                          arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1967   subdir('libdecnumber')
1968   subdir('target')
1969 endif
1971 subdir('audio')
1972 subdir('io')
1973 subdir('chardev')
1974 subdir('fsdev')
1975 subdir('dump')
1977 if have_block
1978   block_ss.add(files(
1979     'block.c',
1980     'blockjob.c',
1981     'job.c',
1982     'qemu-io-cmds.c',
1983   ))
1984   block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1986   subdir('nbd')
1987   subdir('scsi')
1988   subdir('block')
1990   blockdev_ss.add(files(
1991     'blockdev.c',
1992     'blockdev-nbd.c',
1993     'iothread.c',
1994     'job-qmp.c',
1995   ), gnutls)
1997   # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1998   # os-win32.c does not
1999   blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
2000   softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
2001 endif
2003 common_ss.add(files('cpus-common.c'))
2005 subdir('softmmu')
2007 common_ss.add(capstone)
2008 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
2010 # Work around a gcc bug/misfeature wherein constant propagation looks
2011 # through an alias:
2012 #   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
2013 # to guess that a const variable is always zero.  Without lto, this is
2014 # impossible, as the alias is restricted to page-vary-common.c.  Indeed,
2015 # without lto, not even the alias is required -- we simply use different
2016 # declarations in different compilation units.
2017 pagevary = files('page-vary-common.c')
2018 if get_option('b_lto')
2019   pagevary_flags = ['-fno-lto']
2020   if get_option('cfi')
2021     pagevary_flags += '-fno-sanitize=cfi-icall'
2022   endif
2023   pagevary = static_library('page-vary-common', sources: pagevary,
2024                             c_args: pagevary_flags)
2025   pagevary = declare_dependency(link_with: pagevary)
2026 endif
2027 common_ss.add(pagevary)
2028 specific_ss.add(files('page-vary.c'))
2030 subdir('backends')
2031 subdir('disas')
2032 subdir('migration')
2033 subdir('monitor')
2034 subdir('net')
2035 subdir('replay')
2036 subdir('semihosting')
2037 subdir('hw')
2038 subdir('tcg')
2039 subdir('fpu')
2040 subdir('accel')
2041 subdir('plugins')
2042 subdir('bsd-user')
2043 subdir('linux-user')
2044 subdir('ebpf')
2046 common_ss.add(libbpf)
2048 bsd_user_ss.add(files('gdbstub.c'))
2049 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
2051 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
2052 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
2054 # needed for fuzzing binaries
2055 subdir('tests/qtest/libqos')
2056 subdir('tests/qtest/fuzz')
2058 ########################
2059 # Library dependencies #
2060 ########################
2062 block_mods = []
2063 softmmu_mods = []
2064 foreach d, list : modules
2065   foreach m, module_ss : list
2066     if enable_modules and targetos != 'windows'
2067       module_ss = module_ss.apply(config_all, strict: false)
2068       sl = static_library(d + '-' + m, [genh, module_ss.sources()],
2069                           dependencies: [modulecommon, module_ss.dependencies()], pic: true)
2070       if d == 'block'
2071         block_mods += sl
2072       else
2073         softmmu_mods += sl
2074       endif
2075     else
2076       if d == 'block'
2077         block_ss.add_all(module_ss)
2078       else
2079         softmmu_ss.add_all(module_ss)
2080       endif
2081     endif
2082   endforeach
2083 endforeach
2085 nm = find_program('nm')
2086 undefsym = find_program('scripts/undefsym.py')
2087 block_syms = custom_target('block.syms', output: 'block.syms',
2088                              input: [libqemuutil, block_mods],
2089                              capture: true,
2090                              command: [undefsym, nm, '@INPUT@'])
2091 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
2092                              input: [libqemuutil, softmmu_mods],
2093                              capture: true,
2094                              command: [undefsym, nm, '@INPUT@'])
2096 qom_ss = qom_ss.apply(config_host, strict: false)
2097 libqom = static_library('qom', qom_ss.sources() + genh,
2098                         dependencies: [qom_ss.dependencies()],
2099                         name_suffix: 'fa')
2101 qom = declare_dependency(link_whole: libqom)
2103 authz_ss = authz_ss.apply(config_host, strict: false)
2104 libauthz = static_library('authz', authz_ss.sources() + genh,
2105                           dependencies: [authz_ss.dependencies()],
2106                           name_suffix: 'fa',
2107                           build_by_default: false)
2109 authz = declare_dependency(link_whole: libauthz,
2110                            dependencies: qom)
2112 crypto_ss = crypto_ss.apply(config_host, strict: false)
2113 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2114                            dependencies: [crypto_ss.dependencies()],
2115                            name_suffix: 'fa',
2116                            build_by_default: false)
2118 crypto = declare_dependency(link_whole: libcrypto,
2119                             dependencies: [authz, qom])
2121 io_ss = io_ss.apply(config_host, strict: false)
2122 libio = static_library('io', io_ss.sources() + genh,
2123                        dependencies: [io_ss.dependencies()],
2124                        link_with: libqemuutil,
2125                        name_suffix: 'fa',
2126                        build_by_default: false)
2128 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2130 libmigration = static_library('migration', sources: migration_files + genh,
2131                               name_suffix: 'fa',
2132                               build_by_default: false)
2133 migration = declare_dependency(link_with: libmigration,
2134                                dependencies: [zlib, qom, io])
2135 softmmu_ss.add(migration)
2137 block_ss = block_ss.apply(config_host, strict: false)
2138 libblock = static_library('block', block_ss.sources() + genh,
2139                           dependencies: block_ss.dependencies(),
2140                           link_depends: block_syms,
2141                           name_suffix: 'fa',
2142                           build_by_default: false)
2144 block = declare_dependency(link_whole: [libblock],
2145                            link_args: '@block.syms',
2146                            dependencies: [crypto, io])
2148 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2149 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2150                              dependencies: blockdev_ss.dependencies(),
2151                              name_suffix: 'fa',
2152                              build_by_default: false)
2154 blockdev = declare_dependency(link_whole: [libblockdev],
2155                               dependencies: [block])
2157 qmp_ss = qmp_ss.apply(config_host, strict: false)
2158 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2159                         dependencies: qmp_ss.dependencies(),
2160                         name_suffix: 'fa',
2161                         build_by_default: false)
2163 qmp = declare_dependency(link_whole: [libqmp])
2165 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2166                             name_suffix: 'fa',
2167                             dependencies: [gnutls],
2168                             build_by_default: false)
2170 chardev = declare_dependency(link_whole: libchardev)
2172 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
2173                            name_suffix: 'fa',
2174                            build_by_default: false)
2175 hwcore = declare_dependency(link_whole: libhwcore)
2176 common_ss.add(hwcore)
2178 ###########
2179 # Targets #
2180 ###########
2182 foreach m : block_mods + softmmu_mods
2183   shared_module(m.name(),
2184                 name_prefix: '',
2185                 link_whole: m,
2186                 install: true,
2187                 install_dir: qemu_moddir)
2188 endforeach
2190 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2191 common_ss.add(qom, qemuutil)
2193 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2194 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2196 common_all = common_ss.apply(config_all, strict: false)
2197 common_all = static_library('common',
2198                             build_by_default: false,
2199                             sources: common_all.sources() + genh,
2200                             implicit_include_directories: false,
2201                             dependencies: common_all.dependencies(),
2202                             name_suffix: 'fa')
2204 feature_to_c = find_program('scripts/feature_to_c.sh')
2206 emulators = {}
2207 foreach target : target_dirs
2208   config_target = config_target_mak[target]
2209   target_name = config_target['TARGET_NAME']
2210   arch = config_target['TARGET_BASE_ARCH']
2211   arch_srcs = [config_target_h[target]]
2212   arch_deps = []
2213   c_args = ['-DNEED_CPU_H',
2214             '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2215             '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2216   link_args = emulator_link_args
2218   config_target += config_host
2219   target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2220   if targetos == 'linux'
2221     target_inc += include_directories('linux-headers', is_system: true)
2222   endif
2223   if target.endswith('-softmmu')
2224     qemu_target_name = 'qemu-system-' + target_name
2225     target_type='system'
2226     t = target_softmmu_arch[arch].apply(config_target, strict: false)
2227     arch_srcs += t.sources()
2228     arch_deps += t.dependencies()
2230     hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2231     hw = hw_arch[hw_dir].apply(config_target, strict: false)
2232     arch_srcs += hw.sources()
2233     arch_deps += hw.dependencies()
2235     arch_srcs += config_devices_h[target]
2236     link_args += ['@block.syms', '@qemu.syms']
2237   else
2238     abi = config_target['TARGET_ABI_DIR']
2239     target_type='user'
2240     qemu_target_name = 'qemu-' + target_name
2241     if arch in target_user_arch
2242       t = target_user_arch[arch].apply(config_target, strict: false)
2243       arch_srcs += t.sources()
2244       arch_deps += t.dependencies()
2245     endif
2246     if 'CONFIG_LINUX_USER' in config_target
2247       base_dir = 'linux-user'
2248       target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2249     else
2250       base_dir = 'bsd-user'
2251       target_inc += include_directories('bsd-user/freebsd')
2252     endif
2253     target_inc += include_directories(
2254       base_dir,
2255       base_dir / abi,
2256     )
2257     if 'CONFIG_LINUX_USER' in config_target
2258       dir = base_dir / abi
2259       arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2260       if config_target.has_key('TARGET_SYSTBL_ABI')
2261         arch_srcs += \
2262           syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2263                                              extra_args : config_target['TARGET_SYSTBL_ABI'])
2264       endif
2265     endif
2266   endif
2268   if 'TARGET_XML_FILES' in config_target
2269     gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2270                                 output: target + '-gdbstub-xml.c',
2271                                 input: files(config_target['TARGET_XML_FILES'].split()),
2272                                 command: [feature_to_c, '@INPUT@'],
2273                                 capture: true)
2274     arch_srcs += gdbstub_xml
2275   endif
2277   t = target_arch[arch].apply(config_target, strict: false)
2278   arch_srcs += t.sources()
2279   arch_deps += t.dependencies()
2281   target_common = common_ss.apply(config_target, strict: false)
2282   objects = common_all.extract_objects(target_common.sources())
2283   deps = target_common.dependencies()
2285   target_specific = specific_ss.apply(config_target, strict: false)
2286   arch_srcs += target_specific.sources()
2287   arch_deps += target_specific.dependencies()
2289   lib = static_library('qemu-' + target,
2290                  sources: arch_srcs + genh,
2291                  dependencies: arch_deps,
2292                  objects: objects,
2293                  include_directories: target_inc,
2294                  c_args: c_args,
2295                  build_by_default: false,
2296                  name_suffix: 'fa')
2298   if target.endswith('-softmmu')
2299     execs = [{
2300       'name': 'qemu-system-' + target_name,
2301       'gui': false,
2302       'sources': files('softmmu/main.c'),
2303       'dependencies': []
2304     }]
2305     if targetos == 'windows' and (sdl.found() or gtk.found())
2306       execs += [{
2307         'name': 'qemu-system-' + target_name + 'w',
2308         'gui': true,
2309         'sources': files('softmmu/main.c'),
2310         'dependencies': []
2311       }]
2312     endif
2313     if config_host.has_key('CONFIG_FUZZ')
2314       specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2315       execs += [{
2316         'name': 'qemu-fuzz-' + target_name,
2317         'gui': false,
2318         'sources': specific_fuzz.sources(),
2319         'dependencies': specific_fuzz.dependencies(),
2320       }]
2321     endif
2322   else
2323     execs = [{
2324       'name': 'qemu-' + target_name,
2325       'gui': false,
2326       'sources': [],
2327       'dependencies': []
2328     }]
2329   endif
2330   foreach exe: execs
2331     exe_name = exe['name']
2332     exe_sign = 'CONFIG_HVF' in config_target
2333     if exe_sign
2334       exe_name += '-unsigned'
2335     endif
2337     emulator = executable(exe_name, exe['sources'],
2338                install: true,
2339                c_args: c_args,
2340                dependencies: arch_deps + deps + exe['dependencies'],
2341                objects: lib.extract_all_objects(recursive: true),
2342                link_language: link_language,
2343                link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2344                link_args: link_args,
2345                gui_app: exe['gui'])
2347     if exe_sign
2348       emulators += {exe['name'] : custom_target(exe['name'],
2349                    depends: emulator,
2350                    output: exe['name'],
2351                    command: [
2352                      meson.current_source_dir() / 'scripts/entitlement.sh',
2353                      meson.current_build_dir() / exe_name,
2354                      meson.current_build_dir() / exe['name'],
2355                      meson.current_source_dir() / 'accel/hvf/entitlements.plist'
2356                    ])
2357       }
2359       meson.add_install_script('scripts/entitlement.sh', '--install',
2360                                get_option('bindir') / exe_name,
2361                                get_option('bindir') / exe['name'],
2362                                meson.current_source_dir() / 'accel/hvf/entitlements.plist')
2363     else
2364       emulators += {exe['name']: emulator}
2365     endif
2367     if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2368       foreach stp: [
2369         {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2370         {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2371         {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2372         {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2373       ]
2374         custom_target(exe['name'] + stp['ext'],
2375                       input: trace_events_all,
2376                       output: exe['name'] + stp['ext'],
2377                       install: stp['install'],
2378                       install_dir: get_option('datadir') / 'systemtap/tapset',
2379                       command: [
2380                         tracetool, '--group=all', '--format=' + stp['fmt'],
2381                         '--binary=' + stp['bin'],
2382                         '--target-name=' + target_name,
2383                         '--target-type=' + target_type,
2384                         '--probe-prefix=qemu.' + target_type + '.' + target_name,
2385                         '@INPUT@', '@OUTPUT@'
2386                       ],
2387                       depend_files: tracetool_depends)
2388       endforeach
2389     endif
2390   endforeach
2391 endforeach
2393 # Other build targets
2395 if 'CONFIG_PLUGIN' in config_host
2396   install_headers('include/qemu/qemu-plugin.h')
2397 endif
2399 if 'CONFIG_GUEST_AGENT' in config_host
2400   subdir('qga')
2401 elif get_option('guest_agent_msi').enabled()
2402   error('Guest agent MSI requested, but the guest agent is not being built')
2403 endif
2405 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2406 # when we don't build tools or system
2407 if xkbcommon.found()
2408   # used for the update-keymaps target, so include rules even if !have_tools
2409   qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2410                            dependencies: [qemuutil, xkbcommon], install: have_tools)
2411 endif
2413 if have_tools
2414   qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2415              dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2416   qemu_io = executable('qemu-io', files('qemu-io.c'),
2417              dependencies: [block, qemuutil], install: true)
2418   qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2419                dependencies: [blockdev, qemuutil, gnutls], install: true)
2421   subdir('storage-daemon')
2422   subdir('contrib/rdmacm-mux')
2423   subdir('contrib/elf2dmp')
2425   executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2426              dependencies: qemuutil,
2427              install: true)
2429   if 'CONFIG_VHOST_USER' in config_host
2430     subdir('contrib/vhost-user-blk')
2431     subdir('contrib/vhost-user-gpu')
2432     subdir('contrib/vhost-user-input')
2433     subdir('contrib/vhost-user-scsi')
2434   endif
2436   if targetos == 'linux'
2437     executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2438                dependencies: [qemuutil, libcap_ng],
2439                install: true,
2440                install_dir: get_option('libexecdir'))
2442     executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2443                dependencies: [authz, crypto, io, qom, qemuutil,
2444                               libcap_ng, mpathpersist],
2445                install: true)
2446   endif
2448   if 'CONFIG_IVSHMEM' in config_host
2449     subdir('contrib/ivshmem-client')
2450     subdir('contrib/ivshmem-server')
2451   endif
2452 endif
2454 subdir('scripts')
2455 subdir('tools')
2456 subdir('pc-bios')
2457 subdir('docs')
2458 subdir('tests')
2459 if gtk.found()
2460   subdir('po')
2461 endif
2463 if host_machine.system() == 'windows'
2464   nsis_cmd = [
2465     find_program('scripts/nsis.py'),
2466     '@OUTPUT@',
2467     get_option('prefix'),
2468     meson.current_source_dir(),
2469     host_machine.cpu(),
2470     '--',
2471     '-DDISPLAYVERSION=' + meson.project_version(),
2472   ]
2473   if build_docs
2474     nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2475   endif
2476   if gtk.found()
2477     nsis_cmd += '-DCONFIG_GTK=y'
2478   endif
2480   nsis = custom_target('nsis',
2481                        output: 'qemu-setup-' + meson.project_version() + '.exe',
2482                        input: files('qemu.nsi'),
2483                        build_always_stale: true,
2484                        command: nsis_cmd + ['@INPUT@'])
2485   alias_target('installer', nsis)
2486 endif
2488 #########################
2489 # Configuration summary #
2490 #########################
2492 # Directories
2493 summary_info = {}
2494 summary_info += {'Install prefix':    get_option('prefix')}
2495 summary_info += {'BIOS directory':    qemu_datadir}
2496 summary_info += {'firmware path':     get_option('qemu_firmwarepath')}
2497 summary_info += {'binary directory':  get_option('bindir')}
2498 summary_info += {'library directory': get_option('libdir')}
2499 summary_info += {'module directory':  qemu_moddir}
2500 summary_info += {'libexec directory': get_option('libexecdir')}
2501 summary_info += {'include directory': get_option('includedir')}
2502 summary_info += {'config directory':  get_option('sysconfdir')}
2503 if targetos != 'windows'
2504   summary_info += {'local state directory': get_option('localstatedir')}
2505   summary_info += {'Manual directory':      get_option('mandir')}
2506 else
2507   summary_info += {'local state directory': 'queried at runtime'}
2508 endif
2509 summary_info += {'Doc directory':     get_option('docdir')}
2510 summary_info += {'Build directory':   meson.current_build_dir()}
2511 summary_info += {'Source path':       meson.current_source_dir()}
2512 summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
2513 summary(summary_info, bool_yn: true, section: 'Directories')
2515 # Host binaries
2516 summary_info = {}
2517 summary_info += {'git':               config_host['GIT']}
2518 summary_info += {'make':              config_host['MAKE']}
2519 summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2520 summary_info += {'sphinx-build':      sphinx_build.found()}
2521 if config_host.has_key('HAVE_GDB_BIN')
2522   summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
2523 endif
2524 summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
2525 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
2526   summary_info += {'wixl':            wixl.found() ? wixl.full_path() : false}
2527 endif
2528 if slirp_opt != 'disabled' and 'CONFIG_SLIRP_SMBD' in config_host
2529   summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
2530 endif
2531 summary(summary_info, bool_yn: true, section: 'Host binaries')
2533 # Configurable features
2534 summary_info = {}
2535 summary_info += {'Documentation':     build_docs}
2536 summary_info += {'system-mode emulation': have_system}
2537 summary_info += {'user-mode emulation': have_user}
2538 summary_info += {'block layer':       have_block}
2539 summary_info += {'Install blobs':     get_option('install_blobs')}
2540 summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
2541 if config_host.has_key('CONFIG_MODULES')
2542   summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2543 endif
2544 summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
2545 summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
2546 if have_system
2547   summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
2548 endif
2549 summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
2550 if config_host['TRACE_BACKENDS'].split().contains('simple')
2551   summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2552 endif
2553 summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2554 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2555 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2556 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2557 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2558 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2559 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2560 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2561 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2562 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2563 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2564 summary(summary_info, bool_yn: true, section: 'Configurable features')
2566 # Compilation information
2567 summary_info = {}
2568 summary_info += {'host CPU':          cpu}
2569 summary_info += {'host endianness':   build_machine.endian()}
2570 summary_info += {'C compiler':        ' '.join(meson.get_compiler('c').cmd_array())}
2571 summary_info += {'Host C compiler':   ' '.join(meson.get_compiler('c', native: true).cmd_array())}
2572 if link_language == 'cpp'
2573   summary_info += {'C++ compiler':    ' '.join(meson.get_compiler('cpp').cmd_array())}
2574 else
2575   summary_info += {'C++ compiler':      false}
2576 endif
2577 if targetos == 'darwin'
2578   summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
2579 endif
2580 if targetos == 'windows'
2581   if 'WIN_SDK' in config_host
2582     summary_info += {'Windows SDK':   config_host['WIN_SDK']}
2583   endif
2584 endif
2585 summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
2586 summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
2587                                                + ['-O' + get_option('optimization')]
2588                                                + (get_option('debug') ? ['-g'] : []))}
2589 if link_language == 'cpp'
2590   summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
2591                                                + ['-O' + get_option('optimization')]
2592                                                + (get_option('debug') ? ['-g'] : []))}
2593 endif
2594 link_args = get_option(link_language + '_link_args')
2595 if link_args.length() > 0
2596   summary_info += {'LDFLAGS':         ' '.join(link_args)}
2597 endif
2598 summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
2599 summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
2600 summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
2601 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2602 summary_info += {'PIE':               get_option('b_pie')}
2603 summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
2604 summary_info += {'malloc trim support': has_malloc_trim}
2605 summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
2606 summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
2607 summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
2608 summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
2609 summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2610 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2611 summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
2612 summary_info += {'memory allocator':  get_option('malloc')}
2613 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2614 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2615 summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
2616 summary_info += {'gcov':              get_option('b_coverage')}
2617 summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
2618 summary_info += {'CFI support':       get_option('cfi')}
2619 if get_option('cfi')
2620   summary_info += {'CFI debug support': get_option('cfi_debug')}
2621 endif
2622 summary_info += {'strip binaries':    get_option('strip')}
2623 summary_info += {'sparse':            sparse.found() ? sparse.full_path() : false}
2624 summary_info += {'mingw32 support':   targetos == 'windows'}
2626 # snarf the cross-compilation information for tests
2627 foreach target: target_dirs
2628   tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
2629   if fs.exists(tcg_mak)
2630     config_cross_tcg = keyval.load(tcg_mak)
2631     target = config_cross_tcg['TARGET_NAME']
2632     compiler = ''
2633     if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
2634       summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
2635                                           ' via ' + config_cross_tcg['DOCKER_IMAGE']}
2636     elif 'CROSS_CC_GUEST' in config_cross_tcg
2637       summary_info += {target + ' tests'
2638                                 : config_cross_tcg['CROSS_CC_GUEST'] }
2639     endif
2640    endif
2641 endforeach
2643 summary(summary_info, bool_yn: true, section: 'Compilation')
2645 # Targets and accelerators
2646 summary_info = {}
2647 if have_system
2648   summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
2649   summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
2650   summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
2651   summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
2652   summary_info += {'NVMM support':      config_all.has_key('CONFIG_NVMM')}
2653   summary_info += {'Xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
2654   if config_host.has_key('CONFIG_XEN_BACKEND')
2655     summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2656   endif
2657 endif
2658 summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
2659 if config_all.has_key('CONFIG_TCG')
2660   if get_option('tcg_interpreter')
2661     summary_info += {'TCG backend':   'TCI (TCG with bytecode interpreter, experimental and slow)'}
2662   else
2663     summary_info += {'TCG backend':   'native (@0@)'.format(cpu)}
2664   endif
2665   summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2666 endif
2667 summary_info += {'target list':       ' '.join(target_dirs)}
2668 if have_system
2669   summary_info += {'default devices':   get_option('default_devices')}
2670   summary_info += {'out of process emulation': multiprocess_allowed}
2671 endif
2672 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
2674 # Block layer
2675 summary_info = {}
2676 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2677 summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
2678 if have_block
2679   summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2680   summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2681   summary_info += {'VirtFS support':    have_virtfs}
2682   summary_info += {'build virtiofs daemon': have_virtiofsd}
2683   summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2684   summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2685   summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
2686   summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
2687   summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
2688   summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
2689   summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
2690   summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
2691   summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
2692   summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2693   summary_info += {'FUSE exports':      fuse.found()}
2694 endif
2695 summary(summary_info, bool_yn: true, section: 'Block layer support')
2697 # Crypto
2698 summary_info = {}
2699 summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
2700 summary_info += {'GNUTLS support':    gnutls.found()}
2701 # TODO: add back version
2702 summary_info += {'libgcrypt':         gcrypt.found()}
2703 if gcrypt.found()
2704    summary_info += {'  XTS':             xts != 'private'}
2705 endif
2706 # TODO: add back version
2707 summary_info += {'nettle':            nettle.found()}
2708 if nettle.found()
2709    summary_info += {'  XTS':             xts != 'private'}
2710 endif
2711 summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
2712 summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
2713 summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
2714 summary(summary_info, bool_yn: true, section: 'Crypto')
2716 # Libraries
2717 summary_info = {}
2718 if targetos == 'darwin'
2719   summary_info += {'Cocoa support':   cocoa.found()}
2720 endif
2721 # TODO: add back version
2722 summary_info += {'SDL support':       sdl.found()}
2723 summary_info += {'SDL image support': sdl_image.found()}
2724 # TODO: add back version
2725 summary_info += {'GTK support':       gtk.found()}
2726 summary_info += {'pixman':            pixman.found()}
2727 # TODO: add back version
2728 summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
2729 # TODO: add back version
2730 summary_info += {'slirp support':     slirp_opt == 'disabled' ? false : slirp_opt}
2731 summary_info += {'libtasn1':          tasn1.found()}
2732 summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
2733 summary_info += {'iconv support':     iconv.found()}
2734 summary_info += {'curses support':    curses.found()}
2735 # TODO: add back version
2736 summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
2737 summary_info += {'curl support':      curl.found()}
2738 summary_info += {'Multipath support': mpathpersist.found()}
2739 summary_info += {'VNC support':       vnc.found()}
2740 if vnc.found()
2741   summary_info += {'VNC SASL support':  sasl.found()}
2742   summary_info += {'VNC JPEG support':  jpeg.found()}
2743   summary_info += {'VNC PNG support':   png.found()}
2744 endif
2745 summary_info += {'brlapi support':    brlapi.found()}
2746 summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
2747 summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
2748 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2749 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2750 summary_info += {'ATTR/XATTR support': libattr.found()}
2751 summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
2752 summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
2753 summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
2754 summary_info += {'libcap-ng support': libcap_ng.found()}
2755 summary_info += {'bpf support': libbpf.found()}
2756 # TODO: add back protocol and server version
2757 summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
2758 summary_info += {'rbd support':       rbd.found()}
2759 summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
2760 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2761 summary_info += {'U2F support':       u2f.found()}
2762 summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
2763 summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
2764 summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
2765 summary_info += {'GBM':               config_host.has_key('CONFIG_GBM')}
2766 summary_info += {'libiscsi support':  libiscsi.found()}
2767 summary_info += {'libnfs support':    libnfs.found()}
2768 if targetos == 'windows'
2769   if config_host.has_key('CONFIG_GUEST_AGENT')
2770     summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
2771     summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2772   endif
2773 endif
2774 summary_info += {'seccomp support':   seccomp.found()}
2775 summary_info += {'GlusterFS support': glusterfs.found()}
2776 summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
2777 summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
2778 summary_info += {'lzo support':       lzo.found()}
2779 summary_info += {'snappy support':    snappy.found()}
2780 summary_info += {'bzip2 support':     libbzip2.found()}
2781 summary_info += {'lzfse support':     liblzfse.found()}
2782 summary_info += {'zstd support':      zstd.found()}
2783 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2784 summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
2785 summary_info += {'capstone':          capstone_opt == 'disabled' ? false : capstone_opt}
2786 summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
2787 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2788 summary_info += {'libudev':           libudev.found()}
2789 summary_info += {'FUSE lseek':        fuse_lseek.found()}
2790 summary(summary_info, bool_yn: true, section: 'Dependencies')
2792 if not supported_cpus.contains(cpu)
2793   message()
2794   warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2795   message()
2796   message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2797   message('The QEMU project intends to remove support for this host CPU in')
2798   message('a future release if nobody volunteers to maintain it and to')
2799   message('provide a build host for our continuous integration setup.')
2800   message('configure has succeeded and you can continue to build, but')
2801   message('if you care about QEMU on this platform you should contact')
2802   message('us upstream at qemu-devel@nongnu.org.')
2803 endif
2805 if not supported_oses.contains(targetos)
2806   message()
2807   warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2808   message()
2809   message('Host OS ' + targetos + 'support is not currently maintained.')
2810   message('The QEMU project intends to remove support for this host OS in')
2811   message('a future release if nobody volunteers to maintain it and to')
2812   message('provide a build host for our continuous integration setup.')
2813   message('configure has succeeded and you can continue to build, but')
2814   message('if you care about QEMU on this platform you should contact')
2815   message('us upstream at qemu-devel@nongnu.org.')
2816 endif