]> git.proxmox.com Git - mirror_qemu.git/blob - meson.build
configure, meson: move libaio check to meson.build
[mirror_qemu.git] / meson.build
1 project('qemu', ['c'], meson_version: '>=0.58.2',
2 default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto',
3 'b_staticpic=false'],
4 version: files('VERSION'))
5
6 not_found = dependency('', required: false)
7 keyval = import('keyval')
8 ss = import('sourceset')
9 fs = import('fs')
10
11 sh = find_program('sh')
12 cc = meson.get_compiler('c')
13 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
14 enable_modules = 'CONFIG_MODULES' in config_host
15 enable_static = 'CONFIG_STATIC' in config_host
16
17 # Allow both shared and static libraries unless --enable-static
18 static_kwargs = enable_static ? {'static': true} : {}
19
20 # Temporary directory used for files created while
21 # configure runs. Since it is in the build directory
22 # we can safely blow away any previous version of it
23 # (and we need not jump through hoops to try to delete
24 # it when configure exits.)
25 tmpdir = meson.current_build_dir() / 'meson-private/temp'
26
27 if get_option('qemu_suffix').startswith('/')
28 error('qemu_suffix cannot start with a /')
29 endif
30
31 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
32 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
33 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
34 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
35
36 qemu_desktopdir = get_option('datadir') / 'applications'
37 qemu_icondir = get_option('datadir') / 'icons'
38
39 config_host_data = configuration_data()
40 genh = []
41
42 target_dirs = config_host['TARGET_DIRS'].split()
43 have_user = false
44 have_system = false
45 foreach target : target_dirs
46 have_user = have_user or target.endswith('-user')
47 have_system = have_system or target.endswith('-softmmu')
48 endforeach
49 have_tools = 'CONFIG_TOOLS' in config_host
50 have_block = have_system or have_tools
51
52 python = import('python').find_installation()
53
54 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
55 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
56 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
57
58 cpu = host_machine.cpu_family()
59 targetos = host_machine.system()
60
61 if cpu in ['x86', 'x86_64']
62 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
63 elif cpu == 'aarch64'
64 kvm_targets = ['aarch64-softmmu']
65 elif cpu == 's390x'
66 kvm_targets = ['s390x-softmmu']
67 elif cpu in ['ppc', 'ppc64']
68 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
69 elif cpu in ['mips', 'mips64']
70 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
71 else
72 kvm_targets = []
73 endif
74
75 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
76
77 if cpu in ['aarch64']
78 accelerator_targets += {
79 'CONFIG_HVF': ['aarch64-softmmu']
80 }
81 endif
82
83 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
84 # i386 emulator provides xenpv machine type for multiple architectures
85 accelerator_targets += {
86 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
87 }
88 endif
89 if cpu in ['x86', 'x86_64']
90 accelerator_targets += {
91 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
92 'CONFIG_HVF': ['x86_64-softmmu'],
93 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
94 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
95 }
96 endif
97
98 modular_tcg = []
99 # Darwin does not support references to thread-local variables in modules
100 if targetos != 'darwin'
101 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
102 endif
103
104 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
105 unpack_edk2_blobs = false
106 foreach target : edk2_targets
107 if target in target_dirs
108 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
109 unpack_edk2_blobs = bzip2.found()
110 break
111 endif
112 endforeach
113
114 dtrace = not_found
115 stap = not_found
116 if 'dtrace' in get_option('trace_backends')
117 dtrace = find_program('dtrace', required: true)
118 stap = find_program('stap', required: false)
119 if stap.found()
120 # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
121 # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
122 # instead. QEMU --enable-modules depends on this because the SystemTap
123 # semaphores are linked into the main binary and not the module's shared
124 # object.
125 add_global_arguments('-DSTAP_SDT_V2',
126 native: false, language: ['c', 'cpp', 'objc'])
127 endif
128 endif
129
130 ##################
131 # Compiler flags #
132 ##################
133
134 # Specify linker-script with add_project_link_arguments so that it is not placed
135 # within a linker --start-group/--end-group pair
136 if get_option('fuzzing')
137 add_project_link_arguments(['-Wl,-T,',
138 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
139 native: false, language: ['c', 'cpp', 'objc'])
140
141 # Specify a filter to only instrument code that is directly related to
142 # virtual-devices.
143 configure_file(output: 'instrumentation-filter',
144 input: 'scripts/oss-fuzz/instrumentation-filter-template',
145 copy: true)
146 add_global_arguments(
147 cc.get_supported_arguments('-fsanitize-coverage-allowlist=instrumentation-filter'),
148 native: false, language: ['c', 'cpp', 'objc'])
149
150 if get_option('fuzzing_engine') == ''
151 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
152 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
153 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
154 # unable to bind the fuzzer-related callbacks added by instrumentation.
155 add_global_arguments('-fsanitize=fuzzer-no-link',
156 native: false, language: ['c', 'cpp', 'objc'])
157 add_global_link_arguments('-fsanitize=fuzzer-no-link',
158 native: false, language: ['c', 'cpp', 'objc'])
159 # For the actual fuzzer binaries, we need to link against the libfuzzer
160 # library. They need to be configurable, to support OSS-Fuzz
161 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
162 else
163 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
164 # the needed CFLAGS have already been provided
165 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
166 endif
167 endif
168
169 add_global_arguments(config_host['QEMU_CFLAGS'].split(),
170 native: false, language: ['c', 'objc'])
171 add_global_arguments(config_host['QEMU_CXXFLAGS'].split(),
172 native: false, language: 'cpp')
173 add_global_link_arguments(config_host['QEMU_LDFLAGS'].split(),
174 native: false, language: ['c', 'cpp', 'objc'])
175
176 if targetos == 'linux'
177 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
178 '-isystem', 'linux-headers',
179 language: ['c', 'cpp'])
180 endif
181
182 add_project_arguments('-iquote', '.',
183 '-iquote', meson.current_source_dir(),
184 '-iquote', meson.current_source_dir() / 'include',
185 '-iquote', meson.current_source_dir() / 'disas/libvixl',
186 language: ['c', 'cpp', 'objc'])
187
188 link_language = meson.get_external_property('link_language', 'cpp')
189 if link_language == 'cpp'
190 add_languages('cpp', required: true, native: false)
191 endif
192 if host_machine.system() == 'darwin'
193 add_languages('objc', required: false, native: false)
194 endif
195
196 sparse = find_program('cgcc', required: get_option('sparse'))
197 if sparse.found()
198 run_target('sparse',
199 command: [find_program('scripts/check_sparse.py'),
200 'compile_commands.json', sparse.full_path(), '-Wbitwise',
201 '-Wno-transparent-union', '-Wno-old-initializer',
202 '-Wno-non-pointer-null'])
203 endif
204
205 ###########################################
206 # Target-specific checks and dependencies #
207 ###########################################
208
209 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
210 not cc.links('''
211 #include <stdint.h>
212 #include <sys/types.h>
213 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
214 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
215 ''',
216 args: ['-Werror', '-fsanitize=fuzzer'])
217 error('Your compiler does not support -fsanitize=fuzzer')
218 endif
219
220 if 'ftrace' in get_option('trace_backends') and targetos != 'linux'
221 error('ftrace is supported only on Linux')
222 endif
223 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
224 #include <syslog.h>
225 int main(void) {
226 openlog("qemu", LOG_PID, LOG_DAEMON);
227 syslog(LOG_INFO, "configure");
228 return 0;
229 }''')
230 error('syslog is not supported on this system')
231 endif
232
233 if targetos != 'linux' and get_option('mpath').enabled()
234 error('Multipath is supported only on Linux')
235 endif
236
237 if targetos != 'linux' and get_option('multiprocess').enabled()
238 error('Multiprocess QEMU is supported only on Linux')
239 endif
240 multiprocess_allowed = targetos == 'linux' and not get_option('multiprocess').disabled()
241
242 libm = cc.find_library('m', required: false)
243 threads = dependency('threads')
244 util = cc.find_library('util', required: false)
245 winmm = []
246 socket = []
247 version_res = []
248 coref = []
249 iokit = []
250 emulator_link_args = []
251 nvmm =not_found
252 hvf = not_found
253 host_dsosuf = '.so'
254 if targetos == 'windows'
255 socket = cc.find_library('ws2_32')
256 winmm = cc.find_library('winmm')
257
258 win = import('windows')
259 version_res = win.compile_resources('version.rc',
260 depend_files: files('pc-bios/qemu-nsis.ico'),
261 include_directories: include_directories('.'))
262 host_dsosuf = '.dll'
263 elif targetos == 'darwin'
264 coref = dependency('appleframeworks', modules: 'CoreFoundation')
265 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
266 host_dsosuf = '.dylib'
267 elif targetos == 'sunos'
268 socket = [cc.find_library('socket'),
269 cc.find_library('nsl'),
270 cc.find_library('resolv')]
271 elif targetos == 'haiku'
272 socket = [cc.find_library('posix_error_mapper'),
273 cc.find_library('network'),
274 cc.find_library('bsd')]
275 elif targetos == 'openbsd'
276 if not get_option('tcg').disabled() and target_dirs.length() > 0
277 # Disable OpenBSD W^X if available
278 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
279 endif
280 endif
281
282 accelerators = []
283 if not get_option('kvm').disabled() and targetos == 'linux'
284 accelerators += 'CONFIG_KVM'
285 endif
286 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
287 accelerators += 'CONFIG_XEN'
288 have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
289 else
290 have_xen_pci_passthrough = false
291 endif
292 if not get_option('whpx').disabled() and targetos == 'windows'
293 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
294 error('WHPX requires 64-bit host')
295 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
296 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
297 accelerators += 'CONFIG_WHPX'
298 endif
299 endif
300 if not get_option('hvf').disabled()
301 hvf = dependency('appleframeworks', modules: 'Hypervisor',
302 required: get_option('hvf'))
303 if hvf.found()
304 accelerators += 'CONFIG_HVF'
305 endif
306 endif
307 if not get_option('hax').disabled()
308 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
309 accelerators += 'CONFIG_HAX'
310 endif
311 endif
312 if targetos == 'netbsd'
313 if cc.has_header_symbol('nvmm.h', 'nvmm_cpu_stop', required: get_option('nvmm'))
314 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
315 endif
316 if nvmm.found()
317 accelerators += 'CONFIG_NVMM'
318 endif
319 endif
320
321 tcg_arch = config_host['ARCH']
322 if not get_option('tcg').disabled()
323 if cpu not in supported_cpus
324 if get_option('tcg_interpreter')
325 warning('Unsupported CPU @0@, will use TCG with TCI (experimental and slow)'.format(cpu))
326 else
327 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
328 endif
329 elif get_option('tcg_interpreter')
330 warning('Use of the TCG interpretor is not recommended on this host')
331 warning('architecture. There is a native TCG execution backend available')
332 warning('which provides substantially better performance and reliability.')
333 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
334 warning('configuration option on this architecture to use the native')
335 warning('backend.')
336 endif
337 if get_option('tcg_interpreter')
338 tcg_arch = 'tci'
339 elif config_host['ARCH'] == 'sparc64'
340 tcg_arch = 'sparc'
341 elif config_host['ARCH'] in ['x86_64', 'x32']
342 tcg_arch = 'i386'
343 elif config_host['ARCH'] == 'ppc64'
344 tcg_arch = 'ppc'
345 elif config_host['ARCH'] in ['riscv32', 'riscv64']
346 tcg_arch = 'riscv'
347 endif
348 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
349 language: ['c', 'cpp', 'objc'])
350
351 accelerators += 'CONFIG_TCG'
352 config_host += { 'CONFIG_TCG': 'y' }
353 endif
354
355 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
356 error('KVM not available on this platform')
357 endif
358 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
359 error('HVF not available on this platform')
360 endif
361 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
362 error('NVMM not available on this platform')
363 endif
364 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
365 error('WHPX not available on this platform')
366 endif
367 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
368 if 'CONFIG_XEN' in accelerators
369 error('Xen PCI passthrough not available on this platform')
370 else
371 error('Xen PCI passthrough requested but Xen not enabled')
372 endif
373 endif
374
375 ################
376 # Dependencies #
377 ################
378
379 # The path to glib.h is added to all compilation commands. This was
380 # grandfathered in from the QEMU Makefiles.
381 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
382 native: false, language: ['c', 'cpp', 'objc'])
383 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
384 link_args: config_host['GLIB_LIBS'].split())
385 # override glib dep with the configure results (for subprojects)
386 meson.override_dependency('glib-2.0', glib)
387
388 gio = not_found
389 if 'CONFIG_GIO' in config_host
390 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
391 link_args: config_host['GIO_LIBS'].split())
392 endif
393 lttng = not_found
394 if 'ust' in get_option('trace_backends')
395 lttng = dependency('lttng-ust', required: true, method: 'pkg-config',
396 kwargs: static_kwargs)
397 endif
398 pixman = not_found
399 if have_system or have_tools
400 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
401 method: 'pkg-config', kwargs: static_kwargs)
402 endif
403 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
404
405 libaio = not_found
406 if not get_option('linux_aio').auto() or have_block
407 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
408 required: get_option('linux_aio'),
409 kwargs: static_kwargs)
410 endif
411 linux_io_uring = not_found
412 if not get_option('linux_io_uring').auto() or have_block
413 linux_io_uring = dependency('liburing', required: get_option('linux_io_uring'),
414 method: 'pkg-config', kwargs: static_kwargs)
415 endif
416 libxml2 = not_found
417 if not get_option('libxml2').auto() or have_block
418 libxml2 = dependency('libxml-2.0', required: get_option('libxml2'),
419 method: 'pkg-config', kwargs: static_kwargs)
420 endif
421 libnfs = not_found
422 if not get_option('libnfs').auto() or have_block
423 libnfs = dependency('libnfs', version: '>=1.9.3',
424 required: get_option('libnfs'),
425 method: 'pkg-config', kwargs: static_kwargs)
426 endif
427
428 libattr_test = '''
429 #include <stddef.h>
430 #include <sys/types.h>
431 #ifdef CONFIG_LIBATTR
432 #include <attr/xattr.h>
433 #else
434 #include <sys/xattr.h>
435 #endif
436 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
437
438 libattr = not_found
439 have_old_libattr = false
440 if not get_option('attr').disabled()
441 if cc.links(libattr_test)
442 libattr = declare_dependency()
443 else
444 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
445 required: get_option('attr'),
446 kwargs: static_kwargs)
447 if libattr.found() and not \
448 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
449 libattr = not_found
450 if get_option('attr').enabled()
451 error('could not link libattr')
452 else
453 warning('could not link libattr, disabling')
454 endif
455 else
456 have_old_libattr = libattr.found()
457 endif
458 endif
459 endif
460
461 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
462 if cocoa.found() and get_option('sdl').enabled()
463 error('Cocoa and SDL cannot be enabled at the same time')
464 endif
465 if cocoa.found() and get_option('gtk').enabled()
466 error('Cocoa and GTK+ cannot be enabled at the same time')
467 endif
468
469 seccomp = not_found
470 if not get_option('seccomp').auto() or have_system or have_tools
471 seccomp = dependency('libseccomp', version: '>=2.3.0',
472 required: get_option('seccomp'),
473 method: 'pkg-config', kwargs: static_kwargs)
474 endif
475
476 libcap_ng = not_found
477 if not get_option('cap_ng').auto() or have_system or have_tools
478 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
479 required: get_option('cap_ng'),
480 kwargs: static_kwargs)
481 endif
482 if libcap_ng.found() and not cc.links('''
483 #include <cap-ng.h>
484 int main(void)
485 {
486 capng_capability_to_name(CAPNG_EFFECTIVE);
487 return 0;
488 }''', dependencies: libcap_ng)
489 libcap_ng = not_found
490 if get_option('cap_ng').enabled()
491 error('could not link libcap-ng')
492 else
493 warning('could not link libcap-ng, disabling')
494 endif
495 endif
496
497 if get_option('xkbcommon').auto() and not have_system and not have_tools
498 xkbcommon = not_found
499 else
500 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
501 method: 'pkg-config', kwargs: static_kwargs)
502 endif
503 vde = not_found
504 if config_host.has_key('CONFIG_VDE')
505 vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
506 endif
507
508 pulse = not_found
509 if not get_option('pa').auto() or (targetos == 'linux' and have_system)
510 pulse = dependency('libpulse', required: get_option('pa'),
511 method: 'pkg-config', kwargs: static_kwargs)
512 endif
513 alsa = not_found
514 if not get_option('alsa').auto() or (targetos == 'linux' and have_system)
515 alsa = dependency('alsa', required: get_option('alsa'),
516 method: 'pkg-config', kwargs: static_kwargs)
517 endif
518 jack = not_found
519 if not get_option('jack').auto() or have_system
520 jack = dependency('jack', required: get_option('jack'),
521 method: 'pkg-config', kwargs: static_kwargs)
522 endif
523
524 spice = not_found
525 spice_headers = not_found
526 spice_protocol = not_found
527 if 'CONFIG_SPICE' in config_host
528 spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
529 link_args: config_host['SPICE_LIBS'].split())
530 spice_headers = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split())
531 endif
532 if 'CONFIG_SPICE_PROTOCOL' in config_host
533 spice_protocol = declare_dependency(compile_args: config_host['SPICE_PROTOCOL_CFLAGS'].split())
534 endif
535 rt = cc.find_library('rt', required: false)
536 libdl = not_found
537 if 'CONFIG_PLUGIN' in config_host
538 libdl = cc.find_library('dl', required: false)
539 if not cc.has_function('dlopen', dependencies: libdl)
540 error('dlopen not found')
541 endif
542 endif
543 libiscsi = not_found
544 if not get_option('libiscsi').auto() or have_block
545 libiscsi = dependency('libiscsi', version: '>=1.9.0',
546 required: get_option('libiscsi'),
547 method: 'pkg-config', kwargs: static_kwargs)
548 endif
549 zstd = not_found
550 if not get_option('zstd').auto() or have_block
551 zstd = dependency('libzstd', version: '>=1.4.0',
552 required: get_option('zstd'),
553 method: 'pkg-config', kwargs: static_kwargs)
554 endif
555 virgl = not_found
556 if not get_option('virglrenderer').auto() or have_system
557 virgl = dependency('virglrenderer',
558 method: 'pkg-config',
559 required: get_option('virglrenderer'),
560 kwargs: static_kwargs)
561 endif
562 curl = not_found
563 if not get_option('curl').auto() or have_block
564 curl = dependency('libcurl', version: '>=7.29.0',
565 method: 'pkg-config',
566 required: get_option('curl'),
567 kwargs: static_kwargs)
568 endif
569 libudev = not_found
570 if targetos == 'linux' and (have_system or have_tools)
571 libudev = dependency('libudev',
572 method: 'pkg-config',
573 required: get_option('libudev'),
574 kwargs: static_kwargs)
575 endif
576
577 mpathlibs = [libudev]
578 mpathpersist = not_found
579 mpathpersist_new_api = false
580 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
581 mpath_test_source_new = '''
582 #include <libudev.h>
583 #include <mpath_persist.h>
584 unsigned mpath_mx_alloc_len = 1024;
585 int logsink;
586 static struct config *multipath_conf;
587 extern struct udev *udev;
588 extern struct config *get_multipath_config(void);
589 extern void put_multipath_config(struct config *conf);
590 struct udev *udev;
591 struct config *get_multipath_config(void) { return multipath_conf; }
592 void put_multipath_config(struct config *conf) { }
593 int main(void) {
594 udev = udev_new();
595 multipath_conf = mpath_lib_init();
596 return 0;
597 }'''
598 mpath_test_source_old = '''
599 #include <libudev.h>
600 #include <mpath_persist.h>
601 unsigned mpath_mx_alloc_len = 1024;
602 int logsink;
603 int main(void) {
604 struct udev *udev = udev_new();
605 mpath_lib_init(udev);
606 return 0;
607 }'''
608 libmpathpersist = cc.find_library('mpathpersist',
609 required: get_option('mpath'),
610 kwargs: static_kwargs)
611 if libmpathpersist.found()
612 mpathlibs += libmpathpersist
613 if enable_static
614 mpathlibs += cc.find_library('devmapper',
615 required: get_option('mpath'),
616 kwargs: static_kwargs)
617 endif
618 mpathlibs += cc.find_library('multipath',
619 required: get_option('mpath'),
620 kwargs: static_kwargs)
621 foreach lib: mpathlibs
622 if not lib.found()
623 mpathlibs = []
624 break
625 endif
626 endforeach
627 if mpathlibs.length() == 0
628 msg = 'Dependencies missing for libmpathpersist'
629 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
630 mpathpersist = declare_dependency(dependencies: mpathlibs)
631 mpathpersist_new_api = true
632 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
633 mpathpersist = declare_dependency(dependencies: mpathlibs)
634 else
635 msg = 'Cannot detect libmpathpersist API'
636 endif
637 if not mpathpersist.found()
638 if get_option('mpath').enabled()
639 error(msg)
640 else
641 warning(msg + ', disabling')
642 endif
643 endif
644 endif
645 endif
646
647 iconv = not_found
648 curses = not_found
649 if have_system and not get_option('curses').disabled()
650 curses_test = '''
651 #include <locale.h>
652 #include <curses.h>
653 #include <wchar.h>
654 int main(void) {
655 wchar_t wch = L'w';
656 setlocale(LC_ALL, "");
657 resize_term(0, 0);
658 addwstr(L"wide chars\n");
659 addnwstr(&wch, 1);
660 add_wch(WACS_DEGREE);
661 return 0;
662 }'''
663
664 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
665 foreach curses_dep : curses_dep_list
666 if not curses.found()
667 curses = dependency(curses_dep,
668 required: false,
669 method: 'pkg-config',
670 kwargs: static_kwargs)
671 endif
672 endforeach
673 msg = get_option('curses').enabled() ? 'curses library not found' : ''
674 curses_compile_args = ['-DNCURSES_WIDECHAR']
675 if curses.found()
676 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
677 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
678 else
679 msg = 'curses package not usable'
680 curses = not_found
681 endif
682 endif
683 if not curses.found()
684 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
685 if targetos != 'windows' and not has_curses_h
686 message('Trying with /usr/include/ncursesw')
687 curses_compile_args += ['-I/usr/include/ncursesw']
688 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
689 endif
690 if has_curses_h
691 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
692 foreach curses_libname : curses_libname_list
693 libcurses = cc.find_library(curses_libname,
694 required: false,
695 kwargs: static_kwargs)
696 if libcurses.found()
697 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
698 curses = declare_dependency(compile_args: curses_compile_args,
699 dependencies: [libcurses])
700 break
701 else
702 msg = 'curses library not usable'
703 endif
704 endif
705 endforeach
706 endif
707 endif
708 if not get_option('iconv').disabled()
709 foreach link_args : [ ['-liconv'], [] ]
710 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
711 # We need to use libiconv if available because mixing libiconv's headers with
712 # the system libc does not work.
713 # However, without adding glib to the dependencies -L/usr/local/lib will not be
714 # included in the command line and libiconv will not be found.
715 if cc.links('''
716 #include <iconv.h>
717 int main(void) {
718 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
719 return conv != (iconv_t) -1;
720 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
721 iconv = declare_dependency(link_args: link_args, dependencies: glib)
722 break
723 endif
724 endforeach
725 endif
726 if curses.found() and not iconv.found()
727 if get_option('iconv').enabled()
728 error('iconv not available')
729 endif
730 msg = 'iconv required for curses UI but not available'
731 curses = not_found
732 endif
733 if not curses.found() and msg != ''
734 if get_option('curses').enabled()
735 error(msg)
736 else
737 warning(msg + ', disabling')
738 endif
739 endif
740 endif
741
742 brlapi = not_found
743 if not get_option('brlapi').auto() or have_system
744 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
745 required: get_option('brlapi'),
746 kwargs: static_kwargs)
747 if brlapi.found() and not cc.links('''
748 #include <brlapi.h>
749 #include <stddef.h>
750 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
751 brlapi = not_found
752 if get_option('brlapi').enabled()
753 error('could not link brlapi')
754 else
755 warning('could not link brlapi, disabling')
756 endif
757 endif
758 endif
759
760 sdl = not_found
761 if not get_option('sdl').auto() or (have_system and not cocoa.found())
762 sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
763 sdl_image = not_found
764 endif
765 if sdl.found()
766 # work around 2.0.8 bug
767 sdl = declare_dependency(compile_args: '-Wno-undef',
768 dependencies: sdl)
769 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
770 method: 'pkg-config', kwargs: static_kwargs)
771 else
772 if get_option('sdl_image').enabled()
773 error('sdl-image required, but SDL was @0@'.format(
774 get_option('sdl').disabled() ? 'disabled' : 'not found'))
775 endif
776 sdl_image = not_found
777 endif
778
779 rbd = not_found
780 if not get_option('rbd').auto() or have_block
781 librados = cc.find_library('rados', required: get_option('rbd'),
782 kwargs: static_kwargs)
783 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
784 required: get_option('rbd'),
785 kwargs: static_kwargs)
786 if librados.found() and librbd.found()
787 if cc.links('''
788 #include <stdio.h>
789 #include <rbd/librbd.h>
790 int main(void) {
791 rados_t cluster;
792 rados_create(&cluster, NULL);
793 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
794 #error
795 #endif
796 return 0;
797 }''', dependencies: [librbd, librados])
798 rbd = declare_dependency(dependencies: [librbd, librados])
799 elif get_option('rbd').enabled()
800 error('librbd >= 1.12.0 required')
801 else
802 warning('librbd >= 1.12.0 not found, disabling')
803 endif
804 endif
805 endif
806
807 glusterfs = not_found
808 glusterfs_ftruncate_has_stat = false
809 glusterfs_iocb_has_stat = false
810 if not get_option('glusterfs').auto() or have_block
811 glusterfs = dependency('glusterfs-api', version: '>=3',
812 required: get_option('glusterfs'),
813 method: 'pkg-config', kwargs: static_kwargs)
814 if glusterfs.found()
815 glusterfs_ftruncate_has_stat = cc.links('''
816 #include <glusterfs/api/glfs.h>
817
818 int
819 main(void)
820 {
821 /* new glfs_ftruncate() passes two additional args */
822 return glfs_ftruncate(NULL, 0, NULL, NULL);
823 }
824 ''', dependencies: glusterfs)
825 glusterfs_iocb_has_stat = cc.links('''
826 #include <glusterfs/api/glfs.h>
827
828 /* new glfs_io_cbk() passes two additional glfs_stat structs */
829 static void
830 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
831 {}
832
833 int
834 main(void)
835 {
836 glfs_io_cbk iocb = &glusterfs_iocb;
837 iocb(NULL, 0 , NULL, NULL, NULL);
838 return 0;
839 }
840 ''', dependencies: glusterfs)
841 endif
842 endif
843 libssh = not_found
844 if 'CONFIG_LIBSSH' in config_host
845 libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
846 link_args: config_host['LIBSSH_LIBS'].split())
847 endif
848 libbzip2 = not_found
849 if not get_option('bzip2').auto() or have_block
850 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
851 required: get_option('bzip2'),
852 kwargs: static_kwargs)
853 if libbzip2.found() and not cc.links('''
854 #include <bzlib.h>
855 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
856 libbzip2 = not_found
857 if get_option('bzip2').enabled()
858 error('could not link libbzip2')
859 else
860 warning('could not link libbzip2, disabling')
861 endif
862 endif
863 endif
864
865 liblzfse = not_found
866 if not get_option('lzfse').auto() or have_block
867 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
868 required: get_option('lzfse'),
869 kwargs: static_kwargs)
870 endif
871 if liblzfse.found() and not cc.links('''
872 #include <lzfse.h>
873 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
874 liblzfse = not_found
875 if get_option('lzfse').enabled()
876 error('could not link liblzfse')
877 else
878 warning('could not link liblzfse, disabling')
879 endif
880 endif
881
882 oss = not_found
883 if not get_option('oss').auto() or have_system
884 if not cc.has_header('sys/soundcard.h')
885 # not found
886 elif targetos == 'netbsd'
887 oss = cc.find_library('ossaudio', required: get_option('oss'),
888 kwargs: static_kwargs)
889 else
890 oss = declare_dependency()
891 endif
892
893 if not oss.found()
894 if get_option('oss').enabled()
895 error('OSS not found')
896 else
897 warning('OSS not found, disabling')
898 endif
899 endif
900 endif
901 dsound = not_found
902 if not get_option('dsound').auto() or (targetos == 'windows' and have_system)
903 if cc.has_header('dsound.h')
904 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
905 endif
906
907 if not dsound.found()
908 if get_option('dsound').enabled()
909 error('DirectSound not found')
910 else
911 warning('DirectSound not found, disabling')
912 endif
913 endif
914 endif
915
916 coreaudio = not_found
917 if not get_option('coreaudio').auto() or (targetos == 'darwin' and have_system)
918 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
919 required: get_option('coreaudio'))
920 if coreaudio.found() and not cc.links('''
921 #include <CoreAudio/CoreAudio.h>
922 int main(void)
923 {
924 return (int)AudioGetCurrentHostTime();
925 }''')
926 coreaudio = not_found
927 endif
928
929 if not coreaudio.found()
930 if get_option('coreaudio').enabled()
931 error('CoreAudio not found')
932 else
933 warning('CoreAudio not found, disabling')
934 endif
935 endif
936 endif
937
938 opengl = not_found
939 if 'CONFIG_OPENGL' in config_host
940 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
941 link_args: config_host['OPENGL_LIBS'].split())
942 endif
943 gbm = not_found
944 if (have_system or have_tools) and (virgl.found() or opengl.found())
945 gbm = dependency('gbm', method: 'pkg-config', required: false,
946 kwargs: static_kwargs)
947 endif
948
949 gnutls = not_found
950 gnutls_crypto = not_found
951 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
952 # For general TLS support our min gnutls matches
953 # that implied by our platform support matrix
954 #
955 # For the crypto backends, we look for a newer
956 # gnutls:
957 #
958 # Version 3.6.8 is needed to get XTS
959 # Version 3.6.13 is needed to get PBKDF
960 # Version 3.6.14 is needed to get HW accelerated XTS
961 #
962 # If newer enough gnutls isn't available, we can
963 # still use a different crypto backend to satisfy
964 # the platform support requirements
965 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
966 method: 'pkg-config',
967 required: false,
968 kwargs: static_kwargs)
969 if gnutls_crypto.found()
970 gnutls = gnutls_crypto
971 else
972 # Our min version if all we need is TLS
973 gnutls = dependency('gnutls', version: '>=3.5.18',
974 method: 'pkg-config',
975 required: get_option('gnutls'),
976 kwargs: static_kwargs)
977 endif
978 endif
979
980 # We prefer use of gnutls for crypto, unless the options
981 # explicitly asked for nettle or gcrypt.
982 #
983 # If gnutls isn't available for crypto, then we'll prefer
984 # gcrypt over nettle for performance reasons.
985 gcrypt = not_found
986 nettle = not_found
987 xts = 'none'
988
989 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
990 error('Only one of gcrypt & nettle can be enabled')
991 endif
992
993 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
994 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
995 gnutls_crypto = not_found
996 endif
997
998 if not gnutls_crypto.found()
999 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1000 gcrypt = dependency('libgcrypt', version: '>=1.8',
1001 method: 'config-tool',
1002 required: get_option('gcrypt'),
1003 kwargs: static_kwargs)
1004 # Debian has removed -lgpg-error from libgcrypt-config
1005 # as it "spreads unnecessary dependencies" which in
1006 # turn breaks static builds...
1007 if gcrypt.found() and enable_static
1008 gcrypt = declare_dependency(dependencies: [
1009 gcrypt,
1010 cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
1011 endif
1012 endif
1013 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1014 nettle = dependency('nettle', version: '>=3.4',
1015 method: 'pkg-config',
1016 required: get_option('nettle'),
1017 kwargs: static_kwargs)
1018 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1019 xts = 'private'
1020 endif
1021 endif
1022 endif
1023
1024 gtk = not_found
1025 gtkx11 = not_found
1026 vte = not_found
1027 if not get_option('gtk').auto() or (have_system and not cocoa.found())
1028 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1029 method: 'pkg-config',
1030 required: get_option('gtk'),
1031 kwargs: static_kwargs)
1032 if gtk.found()
1033 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1034 method: 'pkg-config',
1035 required: false,
1036 kwargs: static_kwargs)
1037 gtk = declare_dependency(dependencies: [gtk, gtkx11])
1038
1039 if not get_option('vte').auto() or have_system
1040 vte = dependency('vte-2.91',
1041 method: 'pkg-config',
1042 required: get_option('vte'),
1043 kwargs: static_kwargs)
1044 endif
1045 endif
1046 endif
1047
1048 x11 = not_found
1049 if gtkx11.found()
1050 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
1051 kwargs: static_kwargs)
1052 endif
1053 vnc = not_found
1054 png = not_found
1055 jpeg = not_found
1056 sasl = not_found
1057 if have_system and not get_option('vnc').disabled()
1058 vnc = declare_dependency() # dummy dependency
1059 png = dependency('libpng', required: get_option('vnc_png'),
1060 method: 'pkg-config', kwargs: static_kwargs)
1061 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1062 method: 'pkg-config', kwargs: static_kwargs)
1063 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1064 required: get_option('vnc_sasl'),
1065 kwargs: static_kwargs)
1066 if sasl.found()
1067 sasl = declare_dependency(dependencies: sasl,
1068 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1069 endif
1070 endif
1071
1072 pam = not_found
1073 if not get_option('auth_pam').auto() or have_system
1074 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1075 required: get_option('auth_pam'),
1076 kwargs: static_kwargs)
1077 endif
1078 if pam.found() and not cc.links('''
1079 #include <stddef.h>
1080 #include <security/pam_appl.h>
1081 int main(void) {
1082 const char *service_name = "qemu";
1083 const char *user = "frank";
1084 const struct pam_conv pam_conv = { 0 };
1085 pam_handle_t *pamh = NULL;
1086 pam_start(service_name, user, &pam_conv, &pamh);
1087 return 0;
1088 }''', dependencies: pam)
1089 pam = not_found
1090 if get_option('auth_pam').enabled()
1091 error('could not link libpam')
1092 else
1093 warning('could not link libpam, disabling')
1094 endif
1095 endif
1096
1097 snappy = not_found
1098 if not get_option('snappy').auto() or have_system
1099 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1100 required: get_option('snappy'),
1101 kwargs: static_kwargs)
1102 endif
1103 if snappy.found() and not cc.links('''
1104 #include <snappy-c.h>
1105 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1106 snappy = not_found
1107 if get_option('snappy').enabled()
1108 error('could not link libsnappy')
1109 else
1110 warning('could not link libsnappy, disabling')
1111 endif
1112 endif
1113
1114 lzo = not_found
1115 if not get_option('lzo').auto() or have_system
1116 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1117 required: get_option('lzo'),
1118 kwargs: static_kwargs)
1119 endif
1120 if lzo.found() and not cc.links('''
1121 #include <lzo/lzo1x.h>
1122 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1123 lzo = not_found
1124 if get_option('lzo').enabled()
1125 error('could not link liblzo2')
1126 else
1127 warning('could not link liblzo2, disabling')
1128 endif
1129 endif
1130
1131 rdma = not_found
1132 if 'CONFIG_RDMA' in config_host
1133 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
1134 endif
1135 numa = not_found
1136 if 'CONFIG_NUMA' in config_host
1137 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
1138 endif
1139 xen = not_found
1140 if 'CONFIG_XEN_BACKEND' in config_host
1141 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
1142 link_args: config_host['XEN_LIBS'].split())
1143 endif
1144 cacard = not_found
1145 if not get_option('smartcard').auto() or have_system
1146 cacard = dependency('libcacard', required: get_option('smartcard'),
1147 version: '>=2.5.1', method: 'pkg-config',
1148 kwargs: static_kwargs)
1149 endif
1150 u2f = not_found
1151 if have_system
1152 u2f = dependency('u2f-emu', required: get_option('u2f'),
1153 method: 'pkg-config',
1154 kwargs: static_kwargs)
1155 endif
1156 usbredir = not_found
1157 if not get_option('usb_redir').auto() or have_system
1158 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1159 version: '>=0.6', method: 'pkg-config',
1160 kwargs: static_kwargs)
1161 endif
1162 libusb = not_found
1163 if not get_option('libusb').auto() or have_system
1164 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1165 version: '>=1.0.13', method: 'pkg-config',
1166 kwargs: static_kwargs)
1167 endif
1168
1169 libpmem = not_found
1170 if not get_option('libpmem').auto() or have_system
1171 libpmem = dependency('libpmem', required: get_option('libpmem'),
1172 method: 'pkg-config', kwargs: static_kwargs)
1173 endif
1174 libdaxctl = not_found
1175 if not get_option('libdaxctl').auto() or have_system
1176 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1177 version: '>=57', method: 'pkg-config',
1178 kwargs: static_kwargs)
1179 endif
1180 tasn1 = not_found
1181 if gnutls.found()
1182 tasn1 = dependency('libtasn1',
1183 method: 'pkg-config',
1184 kwargs: static_kwargs)
1185 endif
1186 keyutils = dependency('libkeyutils', required: false,
1187 method: 'pkg-config', kwargs: static_kwargs)
1188
1189 has_gettid = cc.has_function('gettid')
1190
1191 # Malloc tests
1192
1193 malloc = []
1194 if get_option('malloc') == 'system'
1195 has_malloc_trim = \
1196 not get_option('malloc_trim').disabled() and \
1197 cc.links('''#include <malloc.h>
1198 int main(void) { malloc_trim(0); return 0; }''')
1199 else
1200 has_malloc_trim = false
1201 malloc = cc.find_library(get_option('malloc'), required: true)
1202 endif
1203 if not has_malloc_trim and get_option('malloc_trim').enabled()
1204 if get_option('malloc') == 'system'
1205 error('malloc_trim not available on this platform.')
1206 else
1207 error('malloc_trim not available with non-libc memory allocator')
1208 endif
1209 endif
1210
1211 # Check whether the glibc provides statx()
1212
1213 gnu_source_prefix = '''
1214 #ifndef _GNU_SOURCE
1215 #define _GNU_SOURCE
1216 #endif
1217 '''
1218 statx_test = gnu_source_prefix + '''
1219 #include <sys/stat.h>
1220 int main(void) {
1221 struct statx statxbuf;
1222 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1223 return 0;
1224 }'''
1225
1226 has_statx = cc.links(statx_test)
1227
1228 have_vhost_user_blk_server = (targetos == 'linux' and
1229 'CONFIG_VHOST_USER' in config_host)
1230
1231 if get_option('vhost_user_blk_server').enabled()
1232 if targetos != 'linux'
1233 error('vhost_user_blk_server requires linux')
1234 elif 'CONFIG_VHOST_USER' not in config_host
1235 error('vhost_user_blk_server requires vhost-user support')
1236 endif
1237 elif get_option('vhost_user_blk_server').disabled() or not have_system
1238 have_vhost_user_blk_server = false
1239 endif
1240
1241
1242 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1243 error('Cannot enable fuse-lseek while fuse is disabled')
1244 endif
1245
1246 fuse = dependency('fuse3', required: get_option('fuse'),
1247 version: '>=3.1', method: 'pkg-config',
1248 kwargs: static_kwargs)
1249
1250 fuse_lseek = not_found
1251 if not get_option('fuse_lseek').disabled()
1252 if fuse.version().version_compare('>=3.8')
1253 # Dummy dependency
1254 fuse_lseek = declare_dependency()
1255 elif get_option('fuse_lseek').enabled()
1256 if fuse.found()
1257 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1258 else
1259 error('fuse-lseek requires libfuse, which was not found')
1260 endif
1261 endif
1262 endif
1263
1264 # libbpf
1265 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1266 if libbpf.found() and not cc.links('''
1267 #include <bpf/libbpf.h>
1268 int main(void)
1269 {
1270 bpf_object__destroy_skeleton(NULL);
1271 return 0;
1272 }''', dependencies: libbpf)
1273 libbpf = not_found
1274 if get_option('bpf').enabled()
1275 error('libbpf skeleton test failed')
1276 else
1277 warning('libbpf skeleton test failed, disabling')
1278 endif
1279 endif
1280
1281 #################
1282 # config-host.h #
1283 #################
1284
1285 audio_drivers_selected = []
1286 if have_system
1287 audio_drivers_available = {
1288 'alsa': alsa.found(),
1289 'coreaudio': coreaudio.found(),
1290 'dsound': dsound.found(),
1291 'jack': jack.found(),
1292 'oss': oss.found(),
1293 'pa': pulse.found(),
1294 'sdl': sdl.found(),
1295 }
1296 foreach k, v: audio_drivers_available
1297 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
1298 endforeach
1299
1300 # Default to native drivers first, OSS second, SDL third
1301 audio_drivers_priority = \
1302 [ 'pa', 'coreaudio', 'dsound', 'oss' ] + \
1303 (targetos == 'linux' ? [] : [ 'sdl' ])
1304 audio_drivers_default = []
1305 foreach k: audio_drivers_priority
1306 if audio_drivers_available[k]
1307 audio_drivers_default += k
1308 endif
1309 endforeach
1310
1311 foreach k: get_option('audio_drv_list')
1312 if k == 'default'
1313 audio_drivers_selected += audio_drivers_default
1314 elif not audio_drivers_available[k]
1315 error('Audio driver "@0@" not available.'.format(k))
1316 else
1317 audio_drivers_selected += k
1318 endif
1319 endforeach
1320 endif
1321 config_host_data.set('CONFIG_AUDIO_DRIVERS',
1322 '"' + '", "'.join(audio_drivers_selected) + '", ')
1323
1324 if get_option('cfi')
1325 cfi_flags=[]
1326 # Check for dependency on LTO
1327 if not get_option('b_lto')
1328 error('Selected Control-Flow Integrity but LTO is disabled')
1329 endif
1330 if config_host.has_key('CONFIG_MODULES')
1331 error('Selected Control-Flow Integrity is not compatible with modules')
1332 endif
1333 # Check for cfi flags. CFI requires LTO so we can't use
1334 # get_supported_arguments, but need a more complex "compiles" which allows
1335 # custom arguments
1336 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1337 args: ['-flto', '-fsanitize=cfi-icall'] )
1338 cfi_flags += '-fsanitize=cfi-icall'
1339 else
1340 error('-fsanitize=cfi-icall is not supported by the compiler')
1341 endif
1342 if cc.compiles('int main () { return 0; }',
1343 name: '-fsanitize-cfi-icall-generalize-pointers',
1344 args: ['-flto', '-fsanitize=cfi-icall',
1345 '-fsanitize-cfi-icall-generalize-pointers'] )
1346 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1347 else
1348 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1349 endif
1350 if get_option('cfi_debug')
1351 if cc.compiles('int main () { return 0; }',
1352 name: '-fno-sanitize-trap=cfi-icall',
1353 args: ['-flto', '-fsanitize=cfi-icall',
1354 '-fno-sanitize-trap=cfi-icall'] )
1355 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1356 else
1357 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1358 endif
1359 endif
1360 add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1361 add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1362 endif
1363
1364 have_host_block_device = (targetos != 'darwin' or
1365 cc.has_header('IOKit/storage/IOMedia.h'))
1366
1367 have_virtfs = (targetos == 'linux' and
1368 have_system and
1369 libattr.found() and
1370 libcap_ng.found())
1371
1372 have_virtfs_proxy_helper = have_virtfs and have_tools
1373
1374 if get_option('virtfs').enabled()
1375 if not have_virtfs
1376 if targetos != 'linux'
1377 error('virtio-9p (virtfs) requires Linux')
1378 elif not libcap_ng.found() or not libattr.found()
1379 error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel')
1380 elif not have_system
1381 error('virtio-9p (virtfs) needs system emulation support')
1382 endif
1383 endif
1384 elif get_option('virtfs').disabled()
1385 have_virtfs = false
1386 endif
1387
1388 foreach k : get_option('trace_backends')
1389 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
1390 endforeach
1391 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
1392
1393 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1394 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1395 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1396 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1397 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1398 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1399 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1400 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1401 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1402 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1403 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1404 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1405
1406 config_host_data.set('CONFIG_ATTR', libattr.found())
1407 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1408 config_host_data.set('CONFIG_COCOA', cocoa.found())
1409 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
1410 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
1411 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1412 config_host_data.set('CONFIG_LZO', lzo.found())
1413 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1414 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1415 config_host_data.set('CONFIG_CURL', curl.found())
1416 config_host_data.set('CONFIG_CURSES', curses.found())
1417 config_host_data.set('CONFIG_GBM', gbm.found())
1418 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1419 if glusterfs.found()
1420 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1421 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1422 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1423 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1424 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1425 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1426 endif
1427 config_host_data.set('CONFIG_GTK', gtk.found())
1428 config_host_data.set('CONFIG_VTE', vte.found())
1429 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1430 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1431 config_host_data.set('CONFIG_EBPF', libbpf.found())
1432 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1433 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1434 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1435 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
1436 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1437 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1438 config_host_data.set('CONFIG_RBD', rbd.found())
1439 config_host_data.set('CONFIG_SDL', sdl.found())
1440 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1441 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1442 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1443 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1444 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1445 config_host_data.set('CONFIG_VNC', vnc.found())
1446 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1447 config_host_data.set('CONFIG_VNC_PNG', png.found())
1448 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1449 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1450 config_host_data.set('CONFIG_VTE', vte.found())
1451 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1452 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1453 config_host_data.set('CONFIG_GETTID', has_gettid)
1454 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1455 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1456 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1457 config_host_data.set('CONFIG_NETTLE', nettle.found())
1458 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1459 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1460 config_host_data.set('CONFIG_STATX', has_statx)
1461 config_host_data.set('CONFIG_ZSTD', zstd.found())
1462 config_host_data.set('CONFIG_FUSE', fuse.found())
1463 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1464 config_host_data.set('CONFIG_X11', x11.found())
1465 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1466 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1467 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1468 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1469 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1470
1471 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
1472 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1473 config_host_data.set('HOST_WORDS_BIGENDIAN', host_machine.endian() == 'big')
1474
1475 # has_header
1476 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1477 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1478 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1479 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1480 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1481 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1482 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1483 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1484 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1485
1486 # has_function
1487 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1488 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1489 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1490 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1491 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1492 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign'))
1493 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1494 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1495 config_host_data.set('CONFIG_SEM_TIMEDWAIT', cc.has_function('sem_timedwait', dependencies: threads))
1496 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1497 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1498 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1499 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1500 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1501 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1502 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1503 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1504 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1505
1506 # has_header_symbol
1507 config_host_data.set('CONFIG_BYTESWAP_H',
1508 cc.has_header_symbol('byteswap.h', 'bswap_32'))
1509 config_host_data.set('CONFIG_EPOLL_CREATE1',
1510 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1511 config_host_data.set('CONFIG_HAS_ENVIRON',
1512 cc.has_header_symbol('unistd.h', 'environ', prefix: gnu_source_prefix))
1513 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1514 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1515 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1516 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1517 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1518 config_host_data.set('CONFIG_FIEMAP',
1519 cc.has_header('linux/fiemap.h') and
1520 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1521 config_host_data.set('CONFIG_GETRANDOM',
1522 cc.has_function('getrandom') and
1523 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1524 config_host_data.set('CONFIG_INOTIFY',
1525 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1526 config_host_data.set('CONFIG_INOTIFY1',
1527 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1528 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1529 cc.has_header_symbol('machine/bswap.h', 'bswap32',
1530 prefix: '''#include <sys/endian.h>
1531 #include <sys/types.h>'''))
1532 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1533 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1534 config_host_data.set('CONFIG_RTNETLINK',
1535 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1536 config_host_data.set('CONFIG_SYSMACROS',
1537 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1538 config_host_data.set('HAVE_OPTRESET',
1539 cc.has_header_symbol('getopt.h', 'optreset'))
1540 config_host_data.set('HAVE_UTMPX',
1541 cc.has_header_symbol('utmpx.h', 'struct utmpx'))
1542 config_host_data.set('HAVE_IPPROTO_MPTCP',
1543 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
1544
1545 # has_member
1546 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1547 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1548 prefix: '#include <signal.h>'))
1549 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1550 cc.has_member('struct stat', 'st_atim',
1551 prefix: '#include <sys/stat.h>'))
1552
1553 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1554 #include <sys/eventfd.h>
1555 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1556 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1557 #include <unistd.h>
1558 int main(void) {
1559 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1560 return fdatasync(0);
1561 #else
1562 #error Not supported
1563 #endif
1564 }'''))
1565 config_host_data.set('CONFIG_MADVISE', cc.links(gnu_source_prefix + '''
1566 #include <sys/types.h>
1567 #include <sys/mman.h>
1568 #include <stddef.h>
1569 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }'''))
1570 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
1571 #include <sys/mman.h>
1572 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
1573 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
1574 #include <fcntl.h>
1575 #if !defined(AT_EMPTY_PATH)
1576 # error missing definition
1577 #else
1578 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
1579 #endif'''))
1580 config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
1581 #include <unistd.h>
1582 #include <fcntl.h>
1583
1584 int main(void)
1585 {
1586 int pipefd[2];
1587 return pipe2(pipefd, O_CLOEXEC);
1588 }'''))
1589 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
1590 #include <sys/mman.h>
1591 #include <stddef.h>
1592 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
1593
1594 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links('''
1595 #include <pthread.h>
1596
1597 static void *f(void *p) { return NULL; }
1598 int main(void)
1599 {
1600 pthread_t thread;
1601 pthread_create(&thread, 0, f, 0);
1602 pthread_setname_np(thread, "QEMU");
1603 return 0;
1604 }''', dependencies: threads))
1605 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links('''
1606 #include <pthread.h>
1607
1608 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
1609 int main(void)
1610 {
1611 pthread_t thread;
1612 pthread_create(&thread, 0, f, 0);
1613 return 0;
1614 }''', dependencies: threads))
1615
1616 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
1617 #include <sys/signalfd.h>
1618 #include <stddef.h>
1619 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
1620 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
1621 #include <unistd.h>
1622 #include <fcntl.h>
1623 #include <limits.h>
1624
1625 int main(void)
1626 {
1627 int len, fd = 0;
1628 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
1629 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
1630 return 0;
1631 }'''))
1632
1633 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
1634 #include <sys/mman.h>
1635 int main(int argc, char *argv[]) {
1636 return mlockall(MCL_FUTURE);
1637 }'''))
1638
1639 # Work around a system header bug with some kernel/XFS header
1640 # versions where they both try to define 'struct fsxattr':
1641 # xfs headers will not try to redefine structs from linux headers
1642 # if this macro is set.
1643 config_host_data.set('HAVE_FSXATTR', cc.links('''
1644 #include <linux/fs.h>'
1645 struct fsxattr foo;
1646 int main(void) {
1647 return 0;
1648 }'''))
1649
1650 # Some versions of Mac OS X incorrectly define SIZE_MAX
1651 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
1652 #include <stdint.h>
1653 #include <stdio.h>
1654 int main(int argc, char *argv[]) {
1655 return printf("%zu", SIZE_MAX);
1656 }''', args: ['-Werror']))
1657
1658 ignored = ['CONFIG_QEMU_INTERP_PREFIX', # actually per-target
1659 'HAVE_GDB_BIN']
1660 arrays = ['CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1661 strings = ['CONFIG_IASL']
1662 foreach k, v: config_host
1663 if ignored.contains(k)
1664 # do nothing
1665 elif arrays.contains(k)
1666 if v != ''
1667 v = '"' + '", "'.join(v.split()) + '", '
1668 endif
1669 config_host_data.set(k, v)
1670 elif k == 'ARCH'
1671 config_host_data.set('HOST_' + v.to_upper(), 1)
1672 elif strings.contains(k)
1673 config_host_data.set_quoted(k, v)
1674 elif k.startswith('CONFIG_')
1675 config_host_data.set(k, v == 'y' ? 1 : v)
1676 endif
1677 endforeach
1678
1679 ########################
1680 # Target configuration #
1681 ########################
1682
1683 minikconf = find_program('scripts/minikconf.py')
1684 config_all = {}
1685 config_all_devices = {}
1686 config_all_disas = {}
1687 config_devices_mak_list = []
1688 config_devices_h = {}
1689 config_target_h = {}
1690 config_target_mak = {}
1691
1692 disassemblers = {
1693 'alpha' : ['CONFIG_ALPHA_DIS'],
1694 'arm' : ['CONFIG_ARM_DIS'],
1695 'avr' : ['CONFIG_AVR_DIS'],
1696 'cris' : ['CONFIG_CRIS_DIS'],
1697 'hexagon' : ['CONFIG_HEXAGON_DIS'],
1698 'hppa' : ['CONFIG_HPPA_DIS'],
1699 'i386' : ['CONFIG_I386_DIS'],
1700 'x86_64' : ['CONFIG_I386_DIS'],
1701 'x32' : ['CONFIG_I386_DIS'],
1702 'm68k' : ['CONFIG_M68K_DIS'],
1703 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1704 'mips' : ['CONFIG_MIPS_DIS'],
1705 'nios2' : ['CONFIG_NIOS2_DIS'],
1706 'or1k' : ['CONFIG_OPENRISC_DIS'],
1707 'ppc' : ['CONFIG_PPC_DIS'],
1708 'riscv' : ['CONFIG_RISCV_DIS'],
1709 'rx' : ['CONFIG_RX_DIS'],
1710 's390' : ['CONFIG_S390_DIS'],
1711 'sh4' : ['CONFIG_SH4_DIS'],
1712 'sparc' : ['CONFIG_SPARC_DIS'],
1713 'xtensa' : ['CONFIG_XTENSA_DIS'],
1714 }
1715 if link_language == 'cpp'
1716 disassemblers += {
1717 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1718 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1719 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1720 }
1721 endif
1722
1723 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
1724 host_kconfig = \
1725 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
1726 ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1727 ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
1728 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
1729 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1730 (x11.found() ? ['CONFIG_X11=y'] : []) + \
1731 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1732 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1733 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1734 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1735 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1736 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
1737 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
1738
1739 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1740
1741 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1742 actual_target_dirs = []
1743 fdt_required = []
1744 foreach target : target_dirs
1745 config_target = { 'TARGET_NAME': target.split('-')[0] }
1746 if target.endswith('linux-user')
1747 if targetos != 'linux'
1748 if default_targets
1749 continue
1750 endif
1751 error('Target @0@ is only available on a Linux host'.format(target))
1752 endif
1753 config_target += { 'CONFIG_LINUX_USER': 'y' }
1754 elif target.endswith('bsd-user')
1755 if 'CONFIG_BSD' not in config_host
1756 if default_targets
1757 continue
1758 endif
1759 error('Target @0@ is only available on a BSD host'.format(target))
1760 endif
1761 config_target += { 'CONFIG_BSD_USER': 'y' }
1762 elif target.endswith('softmmu')
1763 config_target += { 'CONFIG_SOFTMMU': 'y' }
1764 endif
1765 if target.endswith('-user')
1766 config_target += {
1767 'CONFIG_USER_ONLY': 'y',
1768 'CONFIG_QEMU_INTERP_PREFIX':
1769 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1770 }
1771 endif
1772
1773 accel_kconfig = []
1774 foreach sym: accelerators
1775 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1776 config_target += { sym: 'y' }
1777 config_all += { sym: 'y' }
1778 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
1779 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
1780 elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1781 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1782 endif
1783 if target in modular_tcg
1784 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
1785 else
1786 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
1787 endif
1788 accel_kconfig += [ sym + '=y' ]
1789 endif
1790 endforeach
1791 if accel_kconfig.length() == 0
1792 if default_targets
1793 continue
1794 endif
1795 error('No accelerator available for target @0@'.format(target))
1796 endif
1797
1798 actual_target_dirs += target
1799 config_target += keyval.load('configs/targets' / target + '.mak')
1800 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1801
1802 if 'TARGET_NEED_FDT' in config_target
1803 fdt_required += target
1804 endif
1805
1806 # Add default keys
1807 if 'TARGET_BASE_ARCH' not in config_target
1808 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1809 endif
1810 if 'TARGET_ABI_DIR' not in config_target
1811 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1812 endif
1813
1814 foreach k, v: disassemblers
1815 if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1816 foreach sym: v
1817 config_target += { sym: 'y' }
1818 config_all_disas += { sym: 'y' }
1819 endforeach
1820 endif
1821 endforeach
1822
1823 config_target_data = configuration_data()
1824 foreach k, v: config_target
1825 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1826 # do nothing
1827 elif ignored.contains(k)
1828 # do nothing
1829 elif k == 'TARGET_BASE_ARCH'
1830 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1831 # not used to select files from sourcesets.
1832 config_target_data.set('TARGET_' + v.to_upper(), 1)
1833 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1834 config_target_data.set_quoted(k, v)
1835 elif v == 'y'
1836 config_target_data.set(k, 1)
1837 else
1838 config_target_data.set(k, v)
1839 endif
1840 endforeach
1841 config_target_data.set('QEMU_ARCH',
1842 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
1843 config_target_h += {target: configure_file(output: target + '-config-target.h',
1844 configuration: config_target_data)}
1845
1846 if target.endswith('-softmmu')
1847 config_input = meson.get_external_property(target, 'default')
1848 config_devices_mak = target + '-config-devices.mak'
1849 config_devices_mak = configure_file(
1850 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
1851 output: config_devices_mak,
1852 depfile: config_devices_mak + '.d',
1853 capture: true,
1854 command: [minikconf,
1855 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1856 config_devices_mak, '@DEPFILE@', '@INPUT@',
1857 host_kconfig, accel_kconfig,
1858 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
1859
1860 config_devices_data = configuration_data()
1861 config_devices = keyval.load(config_devices_mak)
1862 foreach k, v: config_devices
1863 config_devices_data.set(k, 1)
1864 endforeach
1865 config_devices_mak_list += config_devices_mak
1866 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1867 configuration: config_devices_data)}
1868 config_target += config_devices
1869 config_all_devices += config_devices
1870 endif
1871 config_target_mak += {target: config_target}
1872 endforeach
1873 target_dirs = actual_target_dirs
1874
1875 # This configuration is used to build files that are shared by
1876 # multiple binaries, and then extracted out of the "common"
1877 # static_library target.
1878 #
1879 # We do not use all_sources()/all_dependencies(), because it would
1880 # build literally all source files, including devices only used by
1881 # targets that are not built for this compilation. The CONFIG_ALL
1882 # pseudo symbol replaces it.
1883
1884 config_all += config_all_devices
1885 config_all += config_host
1886 config_all += config_all_disas
1887 config_all += {
1888 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1889 'CONFIG_SOFTMMU': have_system,
1890 'CONFIG_USER_ONLY': have_user,
1891 'CONFIG_ALL': true,
1892 }
1893
1894 ##############
1895 # Submodules #
1896 ##############
1897
1898 capstone = not_found
1899 capstone_opt = get_option('capstone')
1900 if capstone_opt in ['enabled', 'auto', 'system']
1901 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1902 capstone = dependency('capstone', version: '>=4.0',
1903 kwargs: static_kwargs, method: 'pkg-config',
1904 required: capstone_opt == 'system' or
1905 capstone_opt == 'enabled' and not have_internal)
1906
1907 # Some versions of capstone have broken pkg-config file
1908 # that reports a wrong -I path, causing the #include to
1909 # fail later. If the system has such a broken version
1910 # do not use it.
1911 if capstone.found() and not cc.compiles('#include <capstone.h>',
1912 dependencies: [capstone])
1913 capstone = not_found
1914 if capstone_opt == 'system'
1915 error('system capstone requested, it does not appear to work')
1916 endif
1917 endif
1918
1919 if capstone.found()
1920 capstone_opt = 'system'
1921 elif have_internal
1922 capstone_opt = 'internal'
1923 else
1924 capstone_opt = 'disabled'
1925 endif
1926 endif
1927 if capstone_opt == 'internal'
1928 capstone_data = configuration_data()
1929 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1930
1931 capstone_files = files(
1932 'capstone/cs.c',
1933 'capstone/MCInst.c',
1934 'capstone/MCInstrDesc.c',
1935 'capstone/MCRegisterInfo.c',
1936 'capstone/SStream.c',
1937 'capstone/utils.c'
1938 )
1939
1940 if 'CONFIG_ARM_DIS' in config_all_disas
1941 capstone_data.set('CAPSTONE_HAS_ARM', '1')
1942 capstone_files += files(
1943 'capstone/arch/ARM/ARMDisassembler.c',
1944 'capstone/arch/ARM/ARMInstPrinter.c',
1945 'capstone/arch/ARM/ARMMapping.c',
1946 'capstone/arch/ARM/ARMModule.c'
1947 )
1948 endif
1949
1950 # FIXME: This config entry currently depends on a c++ compiler.
1951 # Which is needed for building libvixl, but not for capstone.
1952 if 'CONFIG_ARM_A64_DIS' in config_all_disas
1953 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1954 capstone_files += files(
1955 'capstone/arch/AArch64/AArch64BaseInfo.c',
1956 'capstone/arch/AArch64/AArch64Disassembler.c',
1957 'capstone/arch/AArch64/AArch64InstPrinter.c',
1958 'capstone/arch/AArch64/AArch64Mapping.c',
1959 'capstone/arch/AArch64/AArch64Module.c'
1960 )
1961 endif
1962
1963 if 'CONFIG_PPC_DIS' in config_all_disas
1964 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1965 capstone_files += files(
1966 'capstone/arch/PowerPC/PPCDisassembler.c',
1967 'capstone/arch/PowerPC/PPCInstPrinter.c',
1968 'capstone/arch/PowerPC/PPCMapping.c',
1969 'capstone/arch/PowerPC/PPCModule.c'
1970 )
1971 endif
1972
1973 if 'CONFIG_S390_DIS' in config_all_disas
1974 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1975 capstone_files += files(
1976 'capstone/arch/SystemZ/SystemZDisassembler.c',
1977 'capstone/arch/SystemZ/SystemZInstPrinter.c',
1978 'capstone/arch/SystemZ/SystemZMapping.c',
1979 'capstone/arch/SystemZ/SystemZModule.c',
1980 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1981 )
1982 endif
1983
1984 if 'CONFIG_I386_DIS' in config_all_disas
1985 capstone_data.set('CAPSTONE_HAS_X86', 1)
1986 capstone_files += files(
1987 'capstone/arch/X86/X86Disassembler.c',
1988 'capstone/arch/X86/X86DisassemblerDecoder.c',
1989 'capstone/arch/X86/X86ATTInstPrinter.c',
1990 'capstone/arch/X86/X86IntelInstPrinter.c',
1991 'capstone/arch/X86/X86InstPrinterCommon.c',
1992 'capstone/arch/X86/X86Mapping.c',
1993 'capstone/arch/X86/X86Module.c'
1994 )
1995 endif
1996
1997 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1998
1999 capstone_cargs = [
2000 # FIXME: There does not seem to be a way to completely replace the c_args
2001 # that come from add_project_arguments() -- we can only add to them.
2002 # So: disable all warnings with a big hammer.
2003 '-Wno-error', '-w',
2004
2005 # Include all configuration defines via a header file, which will wind up
2006 # as a dependency on the object file, and thus changes here will result
2007 # in a rebuild.
2008 '-include', 'capstone-defs.h'
2009 ]
2010
2011 libcapstone = static_library('capstone',
2012 build_by_default: false,
2013 sources: capstone_files,
2014 c_args: capstone_cargs,
2015 include_directories: 'capstone/include')
2016 capstone = declare_dependency(link_with: libcapstone,
2017 include_directories: 'capstone/include/capstone')
2018 endif
2019
2020 slirp = not_found
2021 slirp_opt = 'disabled'
2022 if have_system
2023 slirp_opt = get_option('slirp')
2024 if slirp_opt in ['enabled', 'auto', 'system']
2025 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
2026 slirp = dependency('slirp', kwargs: static_kwargs,
2027 method: 'pkg-config',
2028 required: slirp_opt == 'system' or
2029 slirp_opt == 'enabled' and not have_internal)
2030 if slirp.found()
2031 slirp_opt = 'system'
2032 elif have_internal
2033 slirp_opt = 'internal'
2034 else
2035 slirp_opt = 'disabled'
2036 endif
2037 endif
2038 if slirp_opt == 'internal'
2039 slirp_deps = []
2040 if targetos == 'windows'
2041 slirp_deps = cc.find_library('iphlpapi')
2042 elif targetos == 'darwin'
2043 slirp_deps = cc.find_library('resolv')
2044 endif
2045 slirp_conf = configuration_data()
2046 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
2047 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
2048 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
2049 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
2050 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
2051 slirp_files = [
2052 'slirp/src/arp_table.c',
2053 'slirp/src/bootp.c',
2054 'slirp/src/cksum.c',
2055 'slirp/src/dhcpv6.c',
2056 'slirp/src/dnssearch.c',
2057 'slirp/src/if.c',
2058 'slirp/src/ip6_icmp.c',
2059 'slirp/src/ip6_input.c',
2060 'slirp/src/ip6_output.c',
2061 'slirp/src/ip_icmp.c',
2062 'slirp/src/ip_input.c',
2063 'slirp/src/ip_output.c',
2064 'slirp/src/mbuf.c',
2065 'slirp/src/misc.c',
2066 'slirp/src/ncsi.c',
2067 'slirp/src/ndp_table.c',
2068 'slirp/src/sbuf.c',
2069 'slirp/src/slirp.c',
2070 'slirp/src/socket.c',
2071 'slirp/src/state.c',
2072 'slirp/src/stream.c',
2073 'slirp/src/tcp_input.c',
2074 'slirp/src/tcp_output.c',
2075 'slirp/src/tcp_subr.c',
2076 'slirp/src/tcp_timer.c',
2077 'slirp/src/tftp.c',
2078 'slirp/src/udp.c',
2079 'slirp/src/udp6.c',
2080 'slirp/src/util.c',
2081 'slirp/src/version.c',
2082 'slirp/src/vmstate.c',
2083 ]
2084
2085 configure_file(
2086 input : 'slirp/src/libslirp-version.h.in',
2087 output : 'libslirp-version.h',
2088 configuration: slirp_conf)
2089
2090 slirp_inc = include_directories('slirp', 'slirp/src')
2091 libslirp = static_library('slirp',
2092 build_by_default: false,
2093 sources: slirp_files,
2094 c_args: slirp_cargs,
2095 include_directories: slirp_inc)
2096 slirp = declare_dependency(link_with: libslirp,
2097 dependencies: slirp_deps,
2098 include_directories: slirp_inc)
2099 endif
2100 endif
2101
2102 # For CFI, we need to compile slirp as a static library together with qemu.
2103 # This is because we register slirp functions as callbacks for QEMU Timers.
2104 # When using a system-wide shared libslirp, the type information for the
2105 # callback is missing and the timer call produces a false positive with CFI.
2106 #
2107 # Now that slirp_opt has been defined, check if the selected slirp is compatible
2108 # with control-flow integrity.
2109 if get_option('cfi') and slirp_opt == 'system'
2110 error('Control-Flow Integrity is not compatible with system-wide slirp.' \
2111 + ' Please configure with --enable-slirp=git')
2112 endif
2113
2114 fdt = not_found
2115 fdt_opt = get_option('fdt')
2116 if have_system
2117 if fdt_opt in ['enabled', 'auto', 'system']
2118 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2119 fdt = cc.find_library('fdt', kwargs: static_kwargs,
2120 required: fdt_opt == 'system' or
2121 fdt_opt == 'enabled' and not have_internal)
2122 if fdt.found() and cc.links('''
2123 #include <libfdt.h>
2124 #include <libfdt_env.h>
2125 int main(void) { fdt_check_full(NULL, 0); return 0; }''',
2126 dependencies: fdt)
2127 fdt_opt = 'system'
2128 elif fdt_opt == 'system'
2129 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2130 elif have_internal
2131 fdt_opt = 'internal'
2132 else
2133 fdt_opt = 'disabled'
2134 fdt = not_found
2135 endif
2136 endif
2137 if fdt_opt == 'internal'
2138 fdt_files = files(
2139 'dtc/libfdt/fdt.c',
2140 'dtc/libfdt/fdt_ro.c',
2141 'dtc/libfdt/fdt_wip.c',
2142 'dtc/libfdt/fdt_sw.c',
2143 'dtc/libfdt/fdt_rw.c',
2144 'dtc/libfdt/fdt_strerror.c',
2145 'dtc/libfdt/fdt_empty_tree.c',
2146 'dtc/libfdt/fdt_addresses.c',
2147 'dtc/libfdt/fdt_overlay.c',
2148 'dtc/libfdt/fdt_check.c',
2149 )
2150
2151 fdt_inc = include_directories('dtc/libfdt')
2152 libfdt = static_library('fdt',
2153 build_by_default: false,
2154 sources: fdt_files,
2155 include_directories: fdt_inc)
2156 fdt = declare_dependency(link_with: libfdt,
2157 include_directories: fdt_inc)
2158 endif
2159 endif
2160 if not fdt.found() and fdt_required.length() > 0
2161 error('fdt not available but required by targets ' + ', '.join(fdt_required))
2162 endif
2163
2164 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2165 config_host_data.set('CONFIG_FDT', fdt.found())
2166 config_host_data.set('CONFIG_SLIRP', slirp.found())
2167
2168 #####################
2169 # Generated sources #
2170 #####################
2171
2172 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2173
2174 hxtool = find_program('scripts/hxtool')
2175 shaderinclude = find_program('scripts/shaderinclude.pl')
2176 qapi_gen = find_program('scripts/qapi-gen.py')
2177 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2178 meson.current_source_dir() / 'scripts/qapi/commands.py',
2179 meson.current_source_dir() / 'scripts/qapi/common.py',
2180 meson.current_source_dir() / 'scripts/qapi/error.py',
2181 meson.current_source_dir() / 'scripts/qapi/events.py',
2182 meson.current_source_dir() / 'scripts/qapi/expr.py',
2183 meson.current_source_dir() / 'scripts/qapi/gen.py',
2184 meson.current_source_dir() / 'scripts/qapi/introspect.py',
2185 meson.current_source_dir() / 'scripts/qapi/parser.py',
2186 meson.current_source_dir() / 'scripts/qapi/schema.py',
2187 meson.current_source_dir() / 'scripts/qapi/source.py',
2188 meson.current_source_dir() / 'scripts/qapi/types.py',
2189 meson.current_source_dir() / 'scripts/qapi/visit.py',
2190 meson.current_source_dir() / 'scripts/qapi/common.py',
2191 meson.current_source_dir() / 'scripts/qapi-gen.py'
2192 ]
2193
2194 tracetool = [
2195 python, files('scripts/tracetool.py'),
2196 '--backend=' + ','.join(get_option('trace_backends'))
2197 ]
2198 tracetool_depends = files(
2199 'scripts/tracetool/backend/log.py',
2200 'scripts/tracetool/backend/__init__.py',
2201 'scripts/tracetool/backend/dtrace.py',
2202 'scripts/tracetool/backend/ftrace.py',
2203 'scripts/tracetool/backend/simple.py',
2204 'scripts/tracetool/backend/syslog.py',
2205 'scripts/tracetool/backend/ust.py',
2206 'scripts/tracetool/format/tcg_h.py',
2207 'scripts/tracetool/format/ust_events_c.py',
2208 'scripts/tracetool/format/ust_events_h.py',
2209 'scripts/tracetool/format/__init__.py',
2210 'scripts/tracetool/format/d.py',
2211 'scripts/tracetool/format/tcg_helper_c.py',
2212 'scripts/tracetool/format/simpletrace_stap.py',
2213 'scripts/tracetool/format/c.py',
2214 'scripts/tracetool/format/h.py',
2215 'scripts/tracetool/format/tcg_helper_h.py',
2216 'scripts/tracetool/format/log_stap.py',
2217 'scripts/tracetool/format/stap.py',
2218 'scripts/tracetool/format/tcg_helper_wrapper_h.py',
2219 'scripts/tracetool/__init__.py',
2220 'scripts/tracetool/transform.py',
2221 'scripts/tracetool/vcpu.py'
2222 )
2223
2224 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2225 meson.current_source_dir(),
2226 config_host['PKGVERSION'], meson.project_version()]
2227 qemu_version = custom_target('qemu-version.h',
2228 output: 'qemu-version.h',
2229 command: qemu_version_cmd,
2230 capture: true,
2231 build_by_default: true,
2232 build_always_stale: true)
2233 genh += qemu_version
2234
2235 hxdep = []
2236 hx_headers = [
2237 ['qemu-options.hx', 'qemu-options.def'],
2238 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2239 ]
2240 if have_system
2241 hx_headers += [
2242 ['hmp-commands.hx', 'hmp-commands.h'],
2243 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2244 ]
2245 endif
2246 foreach d : hx_headers
2247 hxdep += custom_target(d[1],
2248 input: files(d[0]),
2249 output: d[1],
2250 capture: true,
2251 build_by_default: true, # to be removed when added to a target
2252 command: [hxtool, '-h', '@INPUT0@'])
2253 endforeach
2254 genh += hxdep
2255
2256 ###################
2257 # Collect sources #
2258 ###################
2259
2260 authz_ss = ss.source_set()
2261 blockdev_ss = ss.source_set()
2262 block_ss = ss.source_set()
2263 bsd_user_ss = ss.source_set()
2264 chardev_ss = ss.source_set()
2265 common_ss = ss.source_set()
2266 crypto_ss = ss.source_set()
2267 io_ss = ss.source_set()
2268 linux_user_ss = ss.source_set()
2269 qmp_ss = ss.source_set()
2270 qom_ss = ss.source_set()
2271 softmmu_ss = ss.source_set()
2272 specific_fuzz_ss = ss.source_set()
2273 specific_ss = ss.source_set()
2274 stub_ss = ss.source_set()
2275 trace_ss = ss.source_set()
2276 user_ss = ss.source_set()
2277 util_ss = ss.source_set()
2278
2279 # accel modules
2280 qtest_module_ss = ss.source_set()
2281 tcg_module_ss = ss.source_set()
2282
2283 modules = {}
2284 target_modules = {}
2285 hw_arch = {}
2286 target_arch = {}
2287 target_softmmu_arch = {}
2288 target_user_arch = {}
2289
2290 ###############
2291 # Trace files #
2292 ###############
2293
2294 # TODO: add each directory to the subdirs from its own meson.build, once
2295 # we have those
2296 trace_events_subdirs = [
2297 'crypto',
2298 'qapi',
2299 'qom',
2300 'monitor',
2301 'util',
2302 ]
2303 if have_user
2304 trace_events_subdirs += [ 'linux-user' ]
2305 endif
2306 if have_block
2307 trace_events_subdirs += [
2308 'authz',
2309 'block',
2310 'io',
2311 'nbd',
2312 'scsi',
2313 ]
2314 endif
2315 if have_system
2316 trace_events_subdirs += [
2317 'accel/kvm',
2318 'audio',
2319 'backends',
2320 'backends/tpm',
2321 'chardev',
2322 'ebpf',
2323 'hw/9pfs',
2324 'hw/acpi',
2325 'hw/adc',
2326 'hw/alpha',
2327 'hw/arm',
2328 'hw/audio',
2329 'hw/block',
2330 'hw/block/dataplane',
2331 'hw/char',
2332 'hw/display',
2333 'hw/dma',
2334 'hw/hppa',
2335 'hw/hyperv',
2336 'hw/i2c',
2337 'hw/i386',
2338 'hw/i386/xen',
2339 'hw/ide',
2340 'hw/input',
2341 'hw/intc',
2342 'hw/isa',
2343 'hw/mem',
2344 'hw/mips',
2345 'hw/misc',
2346 'hw/misc/macio',
2347 'hw/net',
2348 'hw/net/can',
2349 'hw/nubus',
2350 'hw/nvme',
2351 'hw/nvram',
2352 'hw/pci',
2353 'hw/pci-host',
2354 'hw/ppc',
2355 'hw/rdma',
2356 'hw/rdma/vmw',
2357 'hw/rtc',
2358 'hw/s390x',
2359 'hw/scsi',
2360 'hw/sd',
2361 'hw/sparc',
2362 'hw/sparc64',
2363 'hw/ssi',
2364 'hw/timer',
2365 'hw/tpm',
2366 'hw/usb',
2367 'hw/vfio',
2368 'hw/virtio',
2369 'hw/watchdog',
2370 'hw/xen',
2371 'hw/gpio',
2372 'migration',
2373 'net',
2374 'softmmu',
2375 'ui',
2376 'hw/remote',
2377 ]
2378 endif
2379 if have_system or have_user
2380 trace_events_subdirs += [
2381 'accel/tcg',
2382 'hw/core',
2383 'target/arm',
2384 'target/arm/hvf',
2385 'target/hppa',
2386 'target/i386',
2387 'target/i386/kvm',
2388 'target/mips/tcg',
2389 'target/ppc',
2390 'target/riscv',
2391 'target/s390x',
2392 'target/s390x/kvm',
2393 'target/sparc',
2394 ]
2395 endif
2396
2397 vhost_user = not_found
2398 if 'CONFIG_VHOST_USER' in config_host
2399 libvhost_user = subproject('libvhost-user')
2400 vhost_user = libvhost_user.get_variable('vhost_user_dep')
2401 endif
2402
2403 subdir('qapi')
2404 subdir('qobject')
2405 subdir('stubs')
2406 subdir('trace')
2407 subdir('util')
2408 subdir('qom')
2409 subdir('authz')
2410 subdir('crypto')
2411 subdir('ui')
2412
2413
2414 if enable_modules
2415 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
2416 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
2417 endif
2418
2419 stub_ss = stub_ss.apply(config_all, strict: false)
2420
2421 util_ss.add_all(trace_ss)
2422 util_ss = util_ss.apply(config_all, strict: false)
2423 libqemuutil = static_library('qemuutil',
2424 sources: util_ss.sources() + stub_ss.sources() + genh,
2425 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
2426 qemuutil = declare_dependency(link_with: libqemuutil,
2427 sources: genh + version_res)
2428
2429 if have_system or have_user
2430 decodetree = generator(find_program('scripts/decodetree.py'),
2431 output: 'decode-@BASENAME@.c.inc',
2432 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
2433 subdir('libdecnumber')
2434 subdir('target')
2435 endif
2436
2437 subdir('audio')
2438 subdir('io')
2439 subdir('chardev')
2440 subdir('fsdev')
2441 subdir('dump')
2442
2443 if have_block
2444 block_ss.add(files(
2445 'block.c',
2446 'blockjob.c',
2447 'job.c',
2448 'qemu-io-cmds.c',
2449 ))
2450 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
2451
2452 subdir('nbd')
2453 subdir('scsi')
2454 subdir('block')
2455
2456 blockdev_ss.add(files(
2457 'blockdev.c',
2458 'blockdev-nbd.c',
2459 'iothread.c',
2460 'job-qmp.c',
2461 ), gnutls)
2462
2463 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
2464 # os-win32.c does not
2465 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
2466 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
2467 endif
2468
2469 common_ss.add(files('cpus-common.c'))
2470
2471 subdir('softmmu')
2472
2473 common_ss.add(capstone)
2474 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
2475
2476 # Work around a gcc bug/misfeature wherein constant propagation looks
2477 # through an alias:
2478 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
2479 # to guess that a const variable is always zero. Without lto, this is
2480 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
2481 # without lto, not even the alias is required -- we simply use different
2482 # declarations in different compilation units.
2483 pagevary = files('page-vary-common.c')
2484 if get_option('b_lto')
2485 pagevary_flags = ['-fno-lto']
2486 if get_option('cfi')
2487 pagevary_flags += '-fno-sanitize=cfi-icall'
2488 endif
2489 pagevary = static_library('page-vary-common', sources: pagevary,
2490 c_args: pagevary_flags)
2491 pagevary = declare_dependency(link_with: pagevary)
2492 endif
2493 common_ss.add(pagevary)
2494 specific_ss.add(files('page-vary.c'))
2495
2496 subdir('backends')
2497 subdir('disas')
2498 subdir('migration')
2499 subdir('monitor')
2500 subdir('net')
2501 subdir('replay')
2502 subdir('semihosting')
2503 subdir('hw')
2504 subdir('tcg')
2505 subdir('fpu')
2506 subdir('accel')
2507 subdir('plugins')
2508 subdir('bsd-user')
2509 subdir('linux-user')
2510 subdir('ebpf')
2511
2512 bsd_user_ss.add(files('gdbstub.c'))
2513 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
2514
2515 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
2516 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
2517
2518 # needed for fuzzing binaries
2519 subdir('tests/qtest/libqos')
2520 subdir('tests/qtest/fuzz')
2521
2522 # accel modules
2523 tcg_real_module_ss = ss.source_set()
2524 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
2525 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
2526 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
2527 'tcg': tcg_real_module_ss }}
2528
2529 ########################
2530 # Library dependencies #
2531 ########################
2532
2533 modinfo_collect = find_program('scripts/modinfo-collect.py')
2534 modinfo_generate = find_program('scripts/modinfo-generate.py')
2535 modinfo_files = []
2536
2537 block_mods = []
2538 softmmu_mods = []
2539 foreach d, list : modules
2540 foreach m, module_ss : list
2541 if enable_modules and targetos != 'windows'
2542 module_ss = module_ss.apply(config_all, strict: false)
2543 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
2544 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
2545 if d == 'block'
2546 block_mods += sl
2547 else
2548 softmmu_mods += sl
2549 endif
2550 if module_ss.sources() != []
2551 # FIXME: Should use sl.extract_all_objects(recursive: true) as
2552 # input. Sources can be used multiple times but objects are
2553 # unique when it comes to lookup in compile_commands.json.
2554 # Depnds on a mesion version with
2555 # https://github.com/mesonbuild/meson/pull/8900
2556 modinfo_files += custom_target(d + '-' + m + '.modinfo',
2557 output: d + '-' + m + '.modinfo',
2558 input: module_ss.sources() + genh,
2559 capture: true,
2560 command: [modinfo_collect, module_ss.sources()])
2561 endif
2562 else
2563 if d == 'block'
2564 block_ss.add_all(module_ss)
2565 else
2566 softmmu_ss.add_all(module_ss)
2567 endif
2568 endif
2569 endforeach
2570 endforeach
2571
2572 foreach d, list : target_modules
2573 foreach m, module_ss : list
2574 if enable_modules and targetos != 'windows'
2575 foreach target : target_dirs
2576 if target.endswith('-softmmu')
2577 config_target = config_target_mak[target]
2578 config_target += config_host
2579 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2580 c_args = ['-DNEED_CPU_H',
2581 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2582 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2583 target_module_ss = module_ss.apply(config_target, strict: false)
2584 if target_module_ss.sources() != []
2585 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
2586 sl = static_library(module_name,
2587 [genh, target_module_ss.sources()],
2588 dependencies: [modulecommon, target_module_ss.dependencies()],
2589 include_directories: target_inc,
2590 c_args: c_args,
2591 pic: true)
2592 softmmu_mods += sl
2593 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
2594 modinfo_files += custom_target(module_name + '.modinfo',
2595 output: module_name + '.modinfo',
2596 input: target_module_ss.sources() + genh,
2597 capture: true,
2598 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
2599 endif
2600 endif
2601 endforeach
2602 else
2603 specific_ss.add_all(module_ss)
2604 endif
2605 endforeach
2606 endforeach
2607
2608 if enable_modules
2609 modinfo_src = custom_target('modinfo.c',
2610 output: 'modinfo.c',
2611 input: modinfo_files,
2612 command: [modinfo_generate, '@INPUT@'],
2613 capture: true)
2614 modinfo_lib = static_library('modinfo', modinfo_src)
2615 modinfo_dep = declare_dependency(link_whole: modinfo_lib)
2616 softmmu_ss.add(modinfo_dep)
2617 endif
2618
2619 nm = find_program('nm')
2620 undefsym = find_program('scripts/undefsym.py')
2621 block_syms = custom_target('block.syms', output: 'block.syms',
2622 input: [libqemuutil, block_mods],
2623 capture: true,
2624 command: [undefsym, nm, '@INPUT@'])
2625 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
2626 input: [libqemuutil, softmmu_mods],
2627 capture: true,
2628 command: [undefsym, nm, '@INPUT@'])
2629
2630 qom_ss = qom_ss.apply(config_host, strict: false)
2631 libqom = static_library('qom', qom_ss.sources() + genh,
2632 dependencies: [qom_ss.dependencies()],
2633 name_suffix: 'fa')
2634
2635 qom = declare_dependency(link_whole: libqom)
2636
2637 authz_ss = authz_ss.apply(config_host, strict: false)
2638 libauthz = static_library('authz', authz_ss.sources() + genh,
2639 dependencies: [authz_ss.dependencies()],
2640 name_suffix: 'fa',
2641 build_by_default: false)
2642
2643 authz = declare_dependency(link_whole: libauthz,
2644 dependencies: qom)
2645
2646 crypto_ss = crypto_ss.apply(config_host, strict: false)
2647 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2648 dependencies: [crypto_ss.dependencies()],
2649 name_suffix: 'fa',
2650 build_by_default: false)
2651
2652 crypto = declare_dependency(link_whole: libcrypto,
2653 dependencies: [authz, qom])
2654
2655 io_ss = io_ss.apply(config_host, strict: false)
2656 libio = static_library('io', io_ss.sources() + genh,
2657 dependencies: [io_ss.dependencies()],
2658 link_with: libqemuutil,
2659 name_suffix: 'fa',
2660 build_by_default: false)
2661
2662 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2663
2664 libmigration = static_library('migration', sources: migration_files + genh,
2665 name_suffix: 'fa',
2666 build_by_default: false)
2667 migration = declare_dependency(link_with: libmigration,
2668 dependencies: [zlib, qom, io])
2669 softmmu_ss.add(migration)
2670
2671 block_ss = block_ss.apply(config_host, strict: false)
2672 libblock = static_library('block', block_ss.sources() + genh,
2673 dependencies: block_ss.dependencies(),
2674 link_depends: block_syms,
2675 name_suffix: 'fa',
2676 build_by_default: false)
2677
2678 block = declare_dependency(link_whole: [libblock],
2679 link_args: '@block.syms',
2680 dependencies: [crypto, io])
2681
2682 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2683 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2684 dependencies: blockdev_ss.dependencies(),
2685 name_suffix: 'fa',
2686 build_by_default: false)
2687
2688 blockdev = declare_dependency(link_whole: [libblockdev],
2689 dependencies: [block])
2690
2691 qmp_ss = qmp_ss.apply(config_host, strict: false)
2692 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2693 dependencies: qmp_ss.dependencies(),
2694 name_suffix: 'fa',
2695 build_by_default: false)
2696
2697 qmp = declare_dependency(link_whole: [libqmp])
2698
2699 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2700 name_suffix: 'fa',
2701 dependencies: [gnutls],
2702 build_by_default: false)
2703
2704 chardev = declare_dependency(link_whole: libchardev)
2705
2706 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
2707 name_suffix: 'fa',
2708 build_by_default: false)
2709 hwcore = declare_dependency(link_whole: libhwcore)
2710 common_ss.add(hwcore)
2711
2712 ###########
2713 # Targets #
2714 ###########
2715
2716 foreach m : block_mods + softmmu_mods
2717 shared_module(m.name(),
2718 name_prefix: '',
2719 link_whole: m,
2720 install: true,
2721 install_dir: qemu_moddir)
2722 endforeach
2723
2724 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2725 common_ss.add(qom, qemuutil)
2726
2727 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2728 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2729
2730 common_all = common_ss.apply(config_all, strict: false)
2731 common_all = static_library('common',
2732 build_by_default: false,
2733 sources: common_all.sources() + genh,
2734 implicit_include_directories: false,
2735 dependencies: common_all.dependencies(),
2736 name_suffix: 'fa')
2737
2738 feature_to_c = find_program('scripts/feature_to_c.sh')
2739
2740 emulators = {}
2741 foreach target : target_dirs
2742 config_target = config_target_mak[target]
2743 target_name = config_target['TARGET_NAME']
2744 arch = config_target['TARGET_BASE_ARCH']
2745 arch_srcs = [config_target_h[target]]
2746 arch_deps = []
2747 c_args = ['-DNEED_CPU_H',
2748 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2749 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2750 link_args = emulator_link_args
2751
2752 config_target += config_host
2753 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2754 if targetos == 'linux'
2755 target_inc += include_directories('linux-headers', is_system: true)
2756 endif
2757 if target.endswith('-softmmu')
2758 qemu_target_name = 'qemu-system-' + target_name
2759 target_type='system'
2760 t = target_softmmu_arch[arch].apply(config_target, strict: false)
2761 arch_srcs += t.sources()
2762 arch_deps += t.dependencies()
2763
2764 hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2765 hw = hw_arch[hw_dir].apply(config_target, strict: false)
2766 arch_srcs += hw.sources()
2767 arch_deps += hw.dependencies()
2768
2769 arch_srcs += config_devices_h[target]
2770 link_args += ['@block.syms', '@qemu.syms']
2771 else
2772 abi = config_target['TARGET_ABI_DIR']
2773 target_type='user'
2774 qemu_target_name = 'qemu-' + target_name
2775 if arch in target_user_arch
2776 t = target_user_arch[arch].apply(config_target, strict: false)
2777 arch_srcs += t.sources()
2778 arch_deps += t.dependencies()
2779 endif
2780 if 'CONFIG_LINUX_USER' in config_target
2781 base_dir = 'linux-user'
2782 target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2783 endif
2784 if 'CONFIG_BSD_USER' in config_target
2785 base_dir = 'bsd-user'
2786 target_inc += include_directories('bsd-user/' / targetos)
2787 dir = base_dir / abi
2788 arch_srcs += files(dir / 'target_arch_cpu.c')
2789 endif
2790 target_inc += include_directories(
2791 base_dir,
2792 base_dir / abi,
2793 )
2794 if 'CONFIG_LINUX_USER' in config_target
2795 dir = base_dir / abi
2796 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2797 if config_target.has_key('TARGET_SYSTBL_ABI')
2798 arch_srcs += \
2799 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2800 extra_args : config_target['TARGET_SYSTBL_ABI'])
2801 endif
2802 endif
2803 endif
2804
2805 if 'TARGET_XML_FILES' in config_target
2806 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2807 output: target + '-gdbstub-xml.c',
2808 input: files(config_target['TARGET_XML_FILES'].split()),
2809 command: [feature_to_c, '@INPUT@'],
2810 capture: true)
2811 arch_srcs += gdbstub_xml
2812 endif
2813
2814 t = target_arch[arch].apply(config_target, strict: false)
2815 arch_srcs += t.sources()
2816 arch_deps += t.dependencies()
2817
2818 target_common = common_ss.apply(config_target, strict: false)
2819 objects = common_all.extract_objects(target_common.sources())
2820 deps = target_common.dependencies()
2821
2822 target_specific = specific_ss.apply(config_target, strict: false)
2823 arch_srcs += target_specific.sources()
2824 arch_deps += target_specific.dependencies()
2825
2826 lib = static_library('qemu-' + target,
2827 sources: arch_srcs + genh,
2828 dependencies: arch_deps,
2829 objects: objects,
2830 include_directories: target_inc,
2831 c_args: c_args,
2832 build_by_default: false,
2833 name_suffix: 'fa')
2834
2835 if target.endswith('-softmmu')
2836 execs = [{
2837 'name': 'qemu-system-' + target_name,
2838 'win_subsystem': 'console',
2839 'sources': files('softmmu/main.c'),
2840 'dependencies': []
2841 }]
2842 if targetos == 'windows' and (sdl.found() or gtk.found())
2843 execs += [{
2844 'name': 'qemu-system-' + target_name + 'w',
2845 'win_subsystem': 'windows',
2846 'sources': files('softmmu/main.c'),
2847 'dependencies': []
2848 }]
2849 endif
2850 if get_option('fuzzing')
2851 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2852 execs += [{
2853 'name': 'qemu-fuzz-' + target_name,
2854 'win_subsystem': 'console',
2855 'sources': specific_fuzz.sources(),
2856 'dependencies': specific_fuzz.dependencies(),
2857 }]
2858 endif
2859 else
2860 execs = [{
2861 'name': 'qemu-' + target_name,
2862 'win_subsystem': 'console',
2863 'sources': [],
2864 'dependencies': []
2865 }]
2866 endif
2867 foreach exe: execs
2868 exe_name = exe['name']
2869 if targetos == 'darwin'
2870 exe_name += '-unsigned'
2871 endif
2872
2873 emulator = executable(exe_name, exe['sources'],
2874 install: true,
2875 c_args: c_args,
2876 dependencies: arch_deps + deps + exe['dependencies'],
2877 objects: lib.extract_all_objects(recursive: true),
2878 link_language: link_language,
2879 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2880 link_args: link_args,
2881 win_subsystem: exe['win_subsystem'])
2882
2883 if targetos == 'darwin'
2884 icon = 'pc-bios/qemu.rsrc'
2885 build_input = [emulator, files(icon)]
2886 install_input = [
2887 get_option('bindir') / exe_name,
2888 meson.current_source_dir() / icon
2889 ]
2890 if 'CONFIG_HVF' in config_target
2891 entitlements = 'accel/hvf/entitlements.plist'
2892 build_input += files(entitlements)
2893 install_input += meson.current_source_dir() / entitlements
2894 endif
2895
2896 emulators += {exe['name'] : custom_target(exe['name'],
2897 input: build_input,
2898 output: exe['name'],
2899 command: [
2900 files('scripts/entitlement.sh'),
2901 '@OUTPUT@',
2902 '@INPUT@'
2903 ])
2904 }
2905
2906 meson.add_install_script('scripts/entitlement.sh', '--install',
2907 get_option('bindir') / exe['name'],
2908 install_input)
2909 else
2910 emulators += {exe['name']: emulator}
2911 endif
2912
2913 if stap.found()
2914 foreach stp: [
2915 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2916 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2917 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2918 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2919 ]
2920 custom_target(exe['name'] + stp['ext'],
2921 input: trace_events_all,
2922 output: exe['name'] + stp['ext'],
2923 install: stp['install'],
2924 install_dir: get_option('datadir') / 'systemtap/tapset',
2925 command: [
2926 tracetool, '--group=all', '--format=' + stp['fmt'],
2927 '--binary=' + stp['bin'],
2928 '--target-name=' + target_name,
2929 '--target-type=' + target_type,
2930 '--probe-prefix=qemu.' + target_type + '.' + target_name,
2931 '@INPUT@', '@OUTPUT@'
2932 ],
2933 depend_files: tracetool_depends)
2934 endforeach
2935 endif
2936 endforeach
2937 endforeach
2938
2939 # Other build targets
2940
2941 if 'CONFIG_PLUGIN' in config_host
2942 install_headers('include/qemu/qemu-plugin.h')
2943 endif
2944
2945 if 'CONFIG_GUEST_AGENT' in config_host
2946 subdir('qga')
2947 elif get_option('guest_agent_msi').enabled()
2948 error('Guest agent MSI requested, but the guest agent is not being built')
2949 endif
2950
2951 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2952 # when we don't build tools or system
2953 if xkbcommon.found()
2954 # used for the update-keymaps target, so include rules even if !have_tools
2955 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2956 dependencies: [qemuutil, xkbcommon], install: have_tools)
2957 endif
2958
2959 if have_tools
2960 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2961 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2962 qemu_io = executable('qemu-io', files('qemu-io.c'),
2963 dependencies: [block, qemuutil], install: true)
2964 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2965 dependencies: [blockdev, qemuutil, gnutls], install: true)
2966
2967 subdir('storage-daemon')
2968 subdir('contrib/rdmacm-mux')
2969 subdir('contrib/elf2dmp')
2970
2971 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2972 dependencies: qemuutil,
2973 install: true)
2974
2975 if 'CONFIG_VHOST_USER' in config_host
2976 subdir('contrib/vhost-user-blk')
2977 subdir('contrib/vhost-user-gpu')
2978 subdir('contrib/vhost-user-input')
2979 subdir('contrib/vhost-user-scsi')
2980 endif
2981
2982 if targetos == 'linux'
2983 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2984 dependencies: [qemuutil, libcap_ng],
2985 install: true,
2986 install_dir: get_option('libexecdir'))
2987
2988 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2989 dependencies: [authz, crypto, io, qom, qemuutil,
2990 libcap_ng, mpathpersist],
2991 install: true)
2992 endif
2993
2994 if have_ivshmem
2995 subdir('contrib/ivshmem-client')
2996 subdir('contrib/ivshmem-server')
2997 endif
2998 endif
2999
3000 subdir('scripts')
3001 subdir('tools')
3002 subdir('pc-bios')
3003 subdir('docs')
3004 subdir('tests')
3005 if gtk.found()
3006 subdir('po')
3007 endif
3008
3009 if host_machine.system() == 'windows'
3010 nsis_cmd = [
3011 find_program('scripts/nsis.py'),
3012 '@OUTPUT@',
3013 get_option('prefix'),
3014 meson.current_source_dir(),
3015 host_machine.cpu(),
3016 '--',
3017 '-DDISPLAYVERSION=' + meson.project_version(),
3018 ]
3019 if build_docs
3020 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3021 endif
3022 if gtk.found()
3023 nsis_cmd += '-DCONFIG_GTK=y'
3024 endif
3025
3026 nsis = custom_target('nsis',
3027 output: 'qemu-setup-' + meson.project_version() + '.exe',
3028 input: files('qemu.nsi'),
3029 build_always_stale: true,
3030 command: nsis_cmd + ['@INPUT@'])
3031 alias_target('installer', nsis)
3032 endif
3033
3034 #########################
3035 # Configuration summary #
3036 #########################
3037
3038 # Directories
3039 summary_info = {}
3040 summary_info += {'Install prefix': get_option('prefix')}
3041 summary_info += {'BIOS directory': qemu_datadir}
3042 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
3043 summary_info += {'binary directory': get_option('bindir')}
3044 summary_info += {'library directory': get_option('libdir')}
3045 summary_info += {'module directory': qemu_moddir}
3046 summary_info += {'libexec directory': get_option('libexecdir')}
3047 summary_info += {'include directory': get_option('includedir')}
3048 summary_info += {'config directory': get_option('sysconfdir')}
3049 if targetos != 'windows'
3050 summary_info += {'local state directory': get_option('localstatedir')}
3051 summary_info += {'Manual directory': get_option('mandir')}
3052 else
3053 summary_info += {'local state directory': 'queried at runtime'}
3054 endif
3055 summary_info += {'Doc directory': get_option('docdir')}
3056 summary_info += {'Build directory': meson.current_build_dir()}
3057 summary_info += {'Source path': meson.current_source_dir()}
3058 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
3059 summary(summary_info, bool_yn: true, section: 'Directories')
3060
3061 # Host binaries
3062 summary_info = {}
3063 summary_info += {'git': config_host['GIT']}
3064 summary_info += {'make': config_host['MAKE']}
3065 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3066 summary_info += {'sphinx-build': sphinx_build}
3067 if config_host.has_key('HAVE_GDB_BIN')
3068 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
3069 endif
3070 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
3071 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
3072 summary_info += {'wixl': wixl}
3073 endif
3074 if slirp_opt != 'disabled' and 'CONFIG_SLIRP_SMBD' in config_host
3075 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
3076 endif
3077 summary(summary_info, bool_yn: true, section: 'Host binaries')
3078
3079 # Configurable features
3080 summary_info = {}
3081 summary_info += {'Documentation': build_docs}
3082 summary_info += {'system-mode emulation': have_system}
3083 summary_info += {'user-mode emulation': have_user}
3084 summary_info += {'block layer': have_block}
3085 summary_info += {'Install blobs': get_option('install_blobs')}
3086 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
3087 if config_host.has_key('CONFIG_MODULES')
3088 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
3089 endif
3090 summary_info += {'fuzzing support': get_option('fuzzing')}
3091 if have_system
3092 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
3093 endif
3094 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
3095 if 'simple' in get_option('trace_backends')
3096 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3097 endif
3098 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
3099 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
3100 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
3101 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
3102 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
3103 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
3104 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
3105 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3106 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
3107 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
3108 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
3109 summary(summary_info, bool_yn: true, section: 'Configurable features')
3110
3111 # Compilation information
3112 summary_info = {}
3113 summary_info += {'host CPU': cpu}
3114 summary_info += {'host endianness': build_machine.endian()}
3115 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
3116 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3117 if link_language == 'cpp'
3118 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
3119 else
3120 summary_info += {'C++ compiler': false}
3121 endif
3122 if targetos == 'darwin'
3123 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3124 endif
3125 if targetos == 'windows'
3126 if 'WIN_SDK' in config_host
3127 summary_info += {'Windows SDK': config_host['WIN_SDK']}
3128 endif
3129 endif
3130 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
3131 + ['-O' + get_option('optimization')]
3132 + (get_option('debug') ? ['-g'] : []))}
3133 if link_language == 'cpp'
3134 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
3135 + ['-O' + get_option('optimization')]
3136 + (get_option('debug') ? ['-g'] : []))}
3137 endif
3138 link_args = get_option(link_language + '_link_args')
3139 if link_args.length() > 0
3140 summary_info += {'LDFLAGS': ' '.join(link_args)}
3141 endif
3142 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
3143 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
3144 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
3145 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3146 summary_info += {'PIE': get_option('b_pie')}
3147 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
3148 summary_info += {'malloc trim support': has_malloc_trim}
3149 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
3150 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
3151 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
3152 summary_info += {'memory allocator': get_option('malloc')}
3153 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
3154 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
3155 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
3156 summary_info += {'gcov': get_option('b_coverage')}
3157 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
3158 summary_info += {'CFI support': get_option('cfi')}
3159 if get_option('cfi')
3160 summary_info += {'CFI debug support': get_option('cfi_debug')}
3161 endif
3162 summary_info += {'strip binaries': get_option('strip')}
3163 summary_info += {'sparse': sparse}
3164 summary_info += {'mingw32 support': targetos == 'windows'}
3165
3166 # snarf the cross-compilation information for tests
3167 foreach target: target_dirs
3168 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3169 if fs.exists(tcg_mak)
3170 config_cross_tcg = keyval.load(tcg_mak)
3171 target = config_cross_tcg['TARGET_NAME']
3172 compiler = ''
3173 if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
3174 summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
3175 ' via ' + config_cross_tcg['DOCKER_IMAGE']}
3176 elif 'CROSS_CC_GUEST' in config_cross_tcg
3177 summary_info += {target + ' tests'
3178 : config_cross_tcg['CROSS_CC_GUEST'] }
3179 endif
3180 endif
3181 endforeach
3182
3183 summary(summary_info, bool_yn: true, section: 'Compilation')
3184
3185 # Targets and accelerators
3186 summary_info = {}
3187 if have_system
3188 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
3189 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
3190 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
3191 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
3192 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
3193 summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
3194 if config_host.has_key('CONFIG_XEN_BACKEND')
3195 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
3196 endif
3197 endif
3198 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
3199 if config_all.has_key('CONFIG_TCG')
3200 if get_option('tcg_interpreter')
3201 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, experimental and slow)'}
3202 else
3203 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
3204 endif
3205 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3206 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3207 endif
3208 summary_info += {'target list': ' '.join(target_dirs)}
3209 if have_system
3210 summary_info += {'default devices': get_option('default_devices')}
3211 summary_info += {'out of process emulation': multiprocess_allowed}
3212 endif
3213 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3214
3215 # Block layer
3216 summary_info = {}
3217 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3218 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
3219 if have_block
3220 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
3221 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
3222 summary_info += {'Use block whitelist in tools': config_host.has_key('CONFIG_BDRV_WHITELIST_TOOLS')}
3223 summary_info += {'VirtFS support': have_virtfs}
3224 summary_info += {'build virtiofs daemon': have_virtiofsd}
3225 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
3226 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
3227 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
3228 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
3229 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
3230 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
3231 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
3232 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
3233 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
3234 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
3235 summary_info += {'FUSE exports': fuse}
3236 endif
3237 summary(summary_info, bool_yn: true, section: 'Block layer support')
3238
3239 # Crypto
3240 summary_info = {}
3241 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
3242 summary_info += {'GNUTLS support': gnutls}
3243 if gnutls.found()
3244 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
3245 endif
3246 summary_info += {'libgcrypt': gcrypt}
3247 summary_info += {'nettle': nettle}
3248 if nettle.found()
3249 summary_info += {' XTS': xts != 'private'}
3250 endif
3251 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
3252 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
3253 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
3254 summary(summary_info, bool_yn: true, section: 'Crypto')
3255
3256 # Libraries
3257 summary_info = {}
3258 if targetos == 'darwin'
3259 summary_info += {'Cocoa support': cocoa}
3260 endif
3261 summary_info += {'SDL support': sdl}
3262 summary_info += {'SDL image support': sdl_image}
3263 summary_info += {'GTK support': gtk}
3264 summary_info += {'pixman': pixman}
3265 summary_info += {'VTE support': vte}
3266 summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp}
3267 summary_info += {'libtasn1': tasn1}
3268 summary_info += {'PAM': pam}
3269 summary_info += {'iconv support': iconv}
3270 summary_info += {'curses support': curses}
3271 summary_info += {'virgl support': virgl}
3272 summary_info += {'curl support': curl}
3273 summary_info += {'Multipath support': mpathpersist}
3274 summary_info += {'VNC support': vnc}
3275 if vnc.found()
3276 summary_info += {'VNC SASL support': sasl}
3277 summary_info += {'VNC JPEG support': jpeg}
3278 summary_info += {'VNC PNG support': png}
3279 endif
3280 if targetos not in ['darwin', 'haiku', 'windows']
3281 summary_info += {'OSS support': oss}
3282 elif targetos == 'darwin'
3283 summary_info += {'CoreAudio support': coreaudio}
3284 elif targetos == 'windows'
3285 summary_info += {'DirectSound support': dsound}
3286 endif
3287 if targetos == 'linux'
3288 summary_info += {'ALSA support': alsa}
3289 summary_info += {'PulseAudio support': pulse}
3290 endif
3291 summary_info += {'JACK support': jack}
3292 summary_info += {'brlapi support': brlapi}
3293 summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
3294 summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
3295 summary_info += {'Linux AIO support': libaio}
3296 summary_info += {'Linux io_uring support': linux_io_uring}
3297 summary_info += {'ATTR/XATTR support': libattr}
3298 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
3299 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
3300 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3301 summary_info += {'libcap-ng support': libcap_ng}
3302 summary_info += {'bpf support': libbpf}
3303 # TODO: add back protocol and server version
3304 summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')}
3305 summary_info += {'rbd support': rbd}
3306 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
3307 summary_info += {'smartcard support': cacard}
3308 summary_info += {'U2F support': u2f}
3309 summary_info += {'libusb': libusb}
3310 summary_info += {'usb net redir': usbredir}
3311 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
3312 summary_info += {'GBM': gbm}
3313 summary_info += {'libiscsi support': libiscsi}
3314 summary_info += {'libnfs support': libnfs}
3315 if targetos == 'windows'
3316 if config_host.has_key('CONFIG_GUEST_AGENT')
3317 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
3318 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
3319 endif
3320 endif
3321 summary_info += {'seccomp support': seccomp}
3322 summary_info += {'GlusterFS support': glusterfs}
3323 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
3324 summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
3325 summary_info += {'lzo support': lzo}
3326 summary_info += {'snappy support': snappy}
3327 summary_info += {'bzip2 support': libbzip2}
3328 summary_info += {'lzfse support': liblzfse}
3329 summary_info += {'zstd support': zstd}
3330 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
3331 summary_info += {'libxml2': libxml2}
3332 summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone}
3333 summary_info += {'libpmem support': libpmem}
3334 summary_info += {'libdaxctl support': libdaxctl}
3335 summary_info += {'libudev': libudev}
3336 # Dummy dependency, keep .found()
3337 summary_info += {'FUSE lseek': fuse_lseek.found()}
3338 summary(summary_info, bool_yn: true, section: 'Dependencies')
3339
3340 if not supported_cpus.contains(cpu)
3341 message()
3342 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3343 message()
3344 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3345 message('The QEMU project intends to remove support for this host CPU in')
3346 message('a future release if nobody volunteers to maintain it and to')
3347 message('provide a build host for our continuous integration setup.')
3348 message('configure has succeeded and you can continue to build, but')
3349 message('if you care about QEMU on this platform you should contact')
3350 message('us upstream at qemu-devel@nongnu.org.')
3351 endif
3352
3353 if not supported_oses.contains(targetos)
3354 message()
3355 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3356 message()
3357 message('Host OS ' + targetos + 'support is not currently maintained.')
3358 message('The QEMU project intends to remove support for this host OS in')
3359 message('a future release if nobody volunteers to maintain it and to')
3360 message('provide a build host for our continuous integration setup.')
3361 message('configure has succeeded and you can continue to build, but')
3362 message('if you care about QEMU on this platform you should contact')
3363 message('us upstream at qemu-devel@nongnu.org.')
3364 endif