master
build 5,072 lines 181 KB
Raw
1 project('qemu', ['c'], meson_version: '>=1.5.0',
2 default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++23', 'b_colorout=auto',
3 'b_staticpic=false', 'stdsplit=false', 'optimization=2', 'b_pie=true'] +
4
5 # build.rust_std breaks with older meson, but Rust does not
6 # support old meson anyway
7 (meson.version().version_compare('>= 1.9') ? ['rust_std=2021', 'build.rust_std=2021',
8 'rust_nightly=disabled'] : []),
9
10 version: files('VERSION'))
11
12 add_test_setup('quick', exclude_suites: ['slow', 'thorough'], is_default: true,
13 env: ['RUST_BACKTRACE=1'])
14 add_test_setup('slow', exclude_suites: ['thorough'],
15 env: ['G_TEST_SLOW=1', 'SPEED=slow', 'RUST_BACKTRACE=1'])
16 add_test_setup('thorough',
17 env: ['G_TEST_SLOW=1', 'SPEED=thorough', 'RUST_BACKTRACE=1'])
18
19 meson.add_postconf_script(find_program('scripts/symlink-install-tree.py'))
20
21 ####################
22 # Global variables #
23 ####################
24
25 not_found = dependency('', required: false)
26 keyval = import('keyval')
27 rust = import('rust')
28 ss = import('sourceset')
29 fs = import('fs')
30
31 host_os = host_machine.system()
32 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
33
34 # Temporary directory used for files created while
35 # configure runs. Since it is in the build directory
36 # we can safely blow away any previous version of it
37 # (and we need not jump through hoops to try to delete
38 # it when configure exits.)
39 tmpdir = meson.current_build_dir() / 'meson-private/temp'
40
41 if get_option('qemu_suffix').startswith('/')
42 error('qemu_suffix cannot start with a /')
43 endif
44
45 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
46 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
47 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
48 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
49
50 qemu_desktopdir = get_option('datadir') / 'applications'
51 qemu_icondir = get_option('datadir') / 'icons'
52
53 genh = []
54 qapi_trace_events = []
55
56 bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin']
57 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux', 'emscripten']
58 supported_cpus = ['ppc64', 's390x', 'riscv64', 'x86_64',
59 'aarch64', 'loongarch64', 'sparc64', 'wasm64']
60
61 cpu = host_machine.cpu_family()
62
63 target_dirs = config_host['TARGET_DIRS'].split()
64
65 # type of binaries to build
66 have_linux_user = false
67 have_bsd_user = false
68 have_system = false
69 foreach target : target_dirs
70 have_linux_user = have_linux_user or target.endswith('linux-user')
71 have_bsd_user = have_bsd_user or target.endswith('bsd-user')
72 have_system = have_system or target.endswith('-softmmu')
73 endforeach
74 have_user = have_linux_user or have_bsd_user
75
76 ############
77 # Programs #
78 ############
79
80 sh = find_program('sh')
81 python = import('python').find_installation()
82
83 cc = meson.get_compiler('c')
84 all_languages = ['c']
85 enable_cpp = host_os == 'windows' or get_option('plugins')
86 if enable_cpp and add_languages('cpp', required: false, native: false)
87 all_languages += ['cpp']
88 cxx = meson.get_compiler('cpp')
89 endif
90 if host_os == 'darwin' and \
91 add_languages('objc', required: true, native: false)
92 all_languages += ['objc']
93 objc = meson.get_compiler('objc')
94 endif
95
96 have_rust = add_languages('rust', native: false,
97 required: get_option('rust').disable_auto_if(not have_system))
98 have_rust = have_rust and add_languages('rust', native: true,
99 required: get_option('rust').disable_auto_if(not have_system))
100 if have_rust
101 rustc = meson.get_compiler('rust')
102 if rustc.version().version_compare('<1.83.0')
103 if get_option('rust').enabled()
104 error('rustc version ' + rustc.version() + ' is unsupported. Please upgrade to at least 1.83.0')
105 else
106 warning('rustc version ' + rustc.version() + ' is unsupported, disabling Rust compilation.')
107 message('Please upgrade to at least 1.83.0 to use Rust.')
108 have_rust = false
109 endif
110 endif
111 endif
112
113 if have_rust
114 rustdoc = find_program('rustdoc', required: get_option('rust'))
115 bindgen = find_program('bindgen', required: get_option('rust'))
116 if not bindgen.found() or bindgen.version().version_compare('<0.60.0')
117 if get_option('rust').enabled()
118 error('bindgen version ' + bindgen.version() + ' is unsupported. You can install a new version with "cargo install --locked bindgen-cli"')
119 else
120 if bindgen.found()
121 warning('bindgen version ' + bindgen.version() + ' is unsupported, disabling Rust compilation.')
122 else
123 warning('bindgen not found, disabling Rust compilation.')
124 endif
125 message('To use Rust you can install a new version with "cargo install bindgen-cli"')
126 have_rust = false
127 endif
128 endif
129 endif
130
131 if have_rust
132 rustc_args = [find_program('scripts/rust/rustc_args.py'),
133 '--workspace', meson.project_source_root()]
134
135 rustfmt = find_program('rustfmt', required: false)
136
137 rustc_lint_args = get_option('strict_rust_lints') ? ['-Dwarnings', '-Funknown_lints'] : []
138 add_project_arguments(rustc_lint_args + ['--cfg', 'MESON'],
139 native: false, language: 'rust')
140 add_project_arguments(rustc_lint_args + ['--cfg', 'MESON'],
141 native: true, language: 'rust')
142 endif
143
144 dtrace = not_found
145 stap = not_found
146 if 'dtrace' in get_option('trace_backends')
147 dtrace = find_program('dtrace', required: true)
148 stap = find_program('stap', required: false)
149 if stap.found()
150 # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
151 # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
152 # instead. QEMU --enable-modules depends on this because the SystemTap
153 # semaphores are linked into the main binary and not the module's shared
154 # object.
155 add_global_arguments('-DSTAP_SDT_V2',
156 native: false, language: all_languages)
157 endif
158 endif
159
160 if get_option('iasl') == ''
161 iasl = find_program('iasl', required: false)
162 else
163 iasl = find_program(get_option('iasl'), required: true)
164 endif
165
166 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu', 'riscv64-softmmu', 'loongarch64-softmmu' ]
167 unpack_edk2_blobs = false
168 foreach target : edk2_targets
169 if target in target_dirs
170 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
171 unpack_edk2_blobs = bzip2.found()
172 break
173 endif
174 endforeach
175
176 #####################
177 # Option validation #
178 #####################
179
180 # Fuzzing
181 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
182 not cc.links('''
183 #include <stdint.h>
184 #include <sys/types.h>
185 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
186 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
187 ''',
188 args: ['-Werror', '-fsanitize=fuzzer'])
189 error('Your compiler does not support -fsanitize=fuzzer')
190 endif
191
192 # Tracing backends
193 if 'ftrace' in get_option('trace_backends') and host_os != 'linux'
194 error('ftrace is supported only on Linux')
195 endif
196 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
197 #include <syslog.h>
198 int main(void) {
199 openlog("qemu", LOG_PID, LOG_DAEMON);
200 syslog(LOG_INFO, "configure");
201 return 0;
202 }''')
203 error('syslog is not supported on this system')
204 endif
205
206 # Miscellaneous Linux-only features
207 get_option('mpath') \
208 .require(host_os == 'linux', error_message: 'Multipath is supported only on Linux')
209
210 multiprocess_allowed = get_option('multiprocess') \
211 .require(host_os == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \
212 .allowed()
213
214 vfio_user_server_allowed = get_option('vfio_user_server') \
215 .require(host_os == 'linux', error_message: 'vfio-user server is supported only on Linux') \
216 .allowed()
217
218 have_tpm = get_option('tpm') \
219 .require(host_os != 'windows', error_message: 'TPM emulation only available on POSIX systems') \
220 .allowed()
221
222 # vhost
223 have_vhost_user = get_option('vhost_user') \
224 .disable_auto_if(host_os != 'linux') \
225 .require(host_os != 'windows',
226 error_message: 'vhost-user is not available on Windows').allowed()
227 have_vhost_vdpa = get_option('vhost_vdpa') \
228 .require(host_os == 'linux',
229 error_message: 'vhost-vdpa is only available on Linux').allowed()
230 have_vhost_kernel = get_option('vhost_kernel') \
231 .require(host_os == 'linux',
232 error_message: 'vhost-kernel is only available on Linux').allowed()
233 have_vhost_user_crypto = get_option('vhost_crypto') \
234 .require(have_vhost_user,
235 error_message: 'vhost-crypto requires vhost-user to be enabled').allowed()
236
237 have_vhost = have_vhost_user or have_vhost_vdpa or have_vhost_kernel
238
239 have_vhost_net_user = have_vhost_user and get_option('vhost_net').allowed()
240 have_vhost_net_vdpa = have_vhost_vdpa and get_option('vhost_net').allowed()
241 have_vhost_net_kernel = have_vhost_kernel and get_option('vhost_net').allowed()
242 have_vhost_net = have_vhost_net_kernel or have_vhost_net_user or have_vhost_net_vdpa
243
244 have_tcg = get_option('tcg').allowed() and (have_system or have_user)
245
246 have_hmp = get_option('hmp') \
247 .disable_auto_if(not have_system) \
248 .allowed()
249 have_tools = get_option('tools') \
250 .disable_auto_if(not have_system) \
251 .allowed()
252 have_ga = get_option('guest_agent') \
253 .disable_auto_if(not have_system and not have_tools) \
254 .require(host_os in ['sunos', 'linux', 'windows', 'freebsd', 'netbsd', 'openbsd'],
255 error_message: 'unsupported OS for QEMU guest agent') \
256 .allowed()
257 have_block = have_system or have_tools
258
259 enable_modules = get_option('modules') \
260 .require(host_os != 'windows',
261 error_message: 'Modules are not available for Windows') \
262 .require(not get_option('prefer_static'),
263 error_message: 'Modules are incompatible with static linking') \
264 .allowed()
265
266 #######################################
267 # Variables for host and accelerators #
268 #######################################
269
270 if cpu not in supported_cpus
271 host_arch = 'unknown'
272 else
273 host_arch = cpu
274 endif
275
276 if cpu == 'x86_64'
277 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
278 elif cpu == 'aarch64'
279 kvm_targets = ['aarch64-softmmu']
280 elif cpu == 's390x'
281 kvm_targets = ['s390x-softmmu']
282 elif cpu == 'ppc64'
283 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
284 elif cpu == 'riscv64'
285 kvm_targets = ['riscv64-softmmu']
286 elif cpu == 'loongarch64'
287 kvm_targets = ['loongarch64-softmmu']
288 else
289 kvm_targets = []
290 endif
291 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
292
293 if cpu == 'x86_64'
294 xen_targets = ['i386-softmmu', 'x86_64-softmmu']
295 elif cpu == 'aarch64'
296 # i386 emulator provides xenpv machine type for multiple architectures
297 xen_targets = ['i386-softmmu', 'x86_64-softmmu', 'aarch64-softmmu']
298 else
299 xen_targets = []
300 endif
301 accelerator_targets += { 'CONFIG_XEN': xen_targets }
302
303 if cpu == 'aarch64'
304 accelerator_targets += {
305 'CONFIG_HVF': ['aarch64-softmmu'],
306 'CONFIG_NITRO': ['aarch64-softmmu'],
307 'CONFIG_WHPX': ['aarch64-softmmu']
308 }
309 elif cpu == 'x86_64'
310 accelerator_targets += {
311 'CONFIG_HVF': ['x86_64-softmmu'],
312 'CONFIG_NITRO': ['x86_64-softmmu'],
313 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
314 'CONFIG_WHPX': ['x86_64-softmmu'],
315 'CONFIG_MSHV': ['x86_64-softmmu'],
316 }
317 endif
318
319 ##################
320 # Compiler flags #
321 ##################
322
323 if (cc.sizeof('void *') < 8) and (have_system or have_user)
324 error('QEMU emulator requires a 64-bit CPU host architecture. Only tools may be built for 32-bit.')
325 endif
326
327 foreach lang : all_languages
328 compiler = meson.get_compiler(lang)
329 if compiler.get_id() == 'gcc' and compiler.version().version_compare('>=10.4')
330 # ok
331 elif compiler.get_id() == 'clang' and compiler.compiles('''
332 #ifdef __apple_build_version__
333 # if __clang_major__ < 15 || (__clang_major__ == 15 && __clang_minor__ < 0)
334 # error You need at least XCode Clang v15.0 to compile QEMU
335 # endif
336 #else
337 # if __clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 0)
338 # error You need at least Clang v10.0 to compile QEMU
339 # endif
340 #endif''')
341 # ok
342 elif compiler.get_id() == 'emscripten'
343 # ok
344 else
345 error('You either need GCC v10.4 or Clang v10.0 (or XCode Clang v15.0) to compile QEMU')
346 endif
347 endforeach
348
349 # default flags for all hosts
350 # We use -fwrapv to tell the compiler that we require a C dialect where
351 # left shift of signed integers is well defined and has the expected
352 # 2s-complement style results. (Both clang and gcc agree that it
353 # provides these semantics.)
354
355 qemu_common_flags = [
356 '-D_GNU_SOURCE', '-D_FILE_OFFSET_BITS=64', '-D_LARGEFILE_SOURCE',
357 '-fno-strict-aliasing', '-fno-common', '-fwrapv' ]
358 qemu_cflags = []
359 qemu_ldflags = []
360
361 if host_os == 'darwin'
362 # Disable attempts to use ObjectiveC features in os/object.h since they
363 # won't work when we're compiling with gcc as a C compiler.
364 if compiler.get_id() == 'gcc'
365 qemu_common_flags += '-DOS_OBJECT_USE_OBJC=0'
366 endif
367 elif host_os == 'sunos'
368 # needed for CMSG_ macros in sys/socket.h
369 qemu_common_flags += '-D_XOPEN_SOURCE=600'
370 # needed for TIOCWIN* defines in termios.h
371 qemu_common_flags += '-D__EXTENSIONS__'
372 elif host_os == 'haiku'
373 qemu_common_flags += ['-DB_USE_POSITIVE_POSIX_ERRORS', '-D_BSD_SOURCE', '-fPIC']
374 elif host_os == 'windows'
375 # plugins use delaylib, and clang needs to be used with lld to make it work.
376 if compiler.get_id() == 'clang' and compiler.get_linker_id() != 'ld.lld'
377 error('On windows, you need to use lld with clang - use msys2 clang64/clangarm64 env')
378 endif
379 endif
380
381 # Choose instruction set (currently x86-only)
382
383 qemu_isa_flags = []
384
385 # Pick x86-64 baseline version
386 if host_arch == 'x86_64'
387 if get_option('x86_version') == '0'
388 error('x86_64-v1 required for x86-64 hosts')
389 endif
390
391 # add flags for individual instruction set extensions
392 if get_option('x86_version') >= '1'
393 # present on basically all processors but technically not part of
394 # x86-64-v1, so only include -mneeded for x86-64 version 2 and above
395 qemu_isa_flags += ['-mcx16']
396 endif
397 if get_option('x86_version') >= '2'
398 qemu_isa_flags += ['-mpopcnt']
399 qemu_isa_flags += cc.get_supported_arguments('-mneeded')
400 endif
401 if get_option('x86_version') >= '3'
402 qemu_isa_flags += ['-mmovbe', '-mabm', '-mbmi', '-mbmi2', '-mfma', '-mf16c']
403 endif
404
405 # add required vector instruction set (each level implies those below)
406 if get_option('x86_version') == '1'
407 qemu_isa_flags += ['-msse2']
408 elif get_option('x86_version') == '2'
409 qemu_isa_flags += ['-msse4.2']
410 elif get_option('x86_version') == '3'
411 qemu_isa_flags += ['-mavx2']
412 elif get_option('x86_version') == '4'
413 qemu_isa_flags += ['-mavx512f', '-mavx512bw', '-mavx512cd', '-mavx512dq', '-mavx512vl']
414 endif
415 endif
416
417 # GCC >= 16 automatically tries to link libatomic for all programs.
418 #
419 # QEMU explicitly does NOT want to use libatomic for int128 types.
420 #
421 # Later checks assume we won't get atomic ops for int128 without
422 # explicitly asking for -latomic, so we must disable GCC's new
423 # automatic linking with the new -fno-link-libatomic flag.
424 #
425 # When not building the emulators, but qemu helper tools only
426 # (e.g. on 32-bit hosts), libatomic is sometimes required and
427 # thus acceptable.
428 if (have_system or have_user)
429 qemu_isa_flags += cc.get_supported_arguments('-fno-link-libatomic')
430 else
431 qemu_ldflags += cc.get_supported_link_arguments('-latomic')
432 endif
433
434 qemu_common_flags = qemu_isa_flags + qemu_common_flags
435
436 if get_option('prefer_static')
437 qemu_ldflags += get_option('b_pie') ? '-static-pie' : '-static'
438 endif
439
440 # Meson currently only handles pie as a boolean for now, so if the user
441 # has explicitly disabled PIE we need to extend our cflags.
442 #
443 # -no-pie is supposedly a linker flag that has no effect on the compiler
444 # command line, but some distros, that didn't quite know what they were
445 # doing, made local changes to gcc's specs file that turned it into
446 # a compiler command-line flag.
447 #
448 # What about linker flags? For a static build, no PIE is implied by -static
449 # which we added above (and if it's not because of the same specs patching,
450 # there's nothing we can do: compilation will fail, report a bug to your
451 # distro and do not use --disable-pie in the meanwhile). For dynamic linking,
452 # instead, we can't add -no-pie because it overrides -shared: the linker then
453 # tries to build an executable instead of a shared library and fails. So
454 # don't add -no-pie anywhere and cross fingers. :(
455 #
456 # Emscripten doesn't support -no-pie but meson can't catch the compiler
457 # warning. So explicitly omit the flag for Emscripten.
458 if not get_option('b_pie') and host_os != 'emscripten'
459 qemu_common_flags += cc.get_supported_arguments('-fno-pie', '-no-pie')
460 endif
461
462 if not get_option('stack_protector').disabled()
463 stack_protector_probe = '''
464 int main(int argc, char *argv[])
465 {
466 char arr[64], *p = arr, *c = argv[argc - 1];
467 while (*c) {
468 *p++ = *c++;
469 }
470 return 0;
471 }'''
472 have_stack_protector = false
473 foreach arg : ['-fstack-protector-strong', '-fstack-protector-all']
474 # We need to check both a compile and a link, since some compiler
475 # setups fail only on a .c->.o compile and some only at link time
476 if cc.compiles(stack_protector_probe, args: ['-Werror', arg]) and \
477 cc.links(stack_protector_probe, args: ['-Werror', arg])
478 have_stack_protector = true
479 qemu_cflags += arg
480 qemu_ldflags += arg
481 break
482 endif
483 endforeach
484 get_option('stack_protector') \
485 .require(have_stack_protector, error_message: 'Stack protector not supported')
486 endif
487
488 coroutine_backend = get_option('coroutine_backend')
489 ucontext_probe = '''
490 #include <ucontext.h>
491 #ifdef __stub_makecontext
492 #error Ignoring glibc stub makecontext which will always fail
493 #endif
494 int main(void) { makecontext(0, 0, 0); return 0; }'''
495
496 # On Windows the only valid backend is the Windows specific one.
497 # For POSIX prefer ucontext, but it's not always possible. The fallback
498 # is sigcontext.
499 supported_backends = []
500 if host_os == 'windows'
501 supported_backends += ['windows']
502 elif host_os == 'emscripten'
503 supported_backends += ['wasm']
504 else
505 if host_os != 'darwin' and cc.links(ucontext_probe)
506 supported_backends += ['ucontext']
507 endif
508 supported_backends += ['sigaltstack']
509 endif
510
511 if coroutine_backend == 'auto'
512 coroutine_backend = supported_backends[0]
513 elif coroutine_backend not in supported_backends
514 error('"@0@" backend requested but not available. Available backends: @1@' \
515 .format(coroutine_backend, ', '.join(supported_backends)))
516 endif
517
518 # Compiles if SafeStack *not* enabled
519 safe_stack_probe = '''
520 int main(void)
521 {
522 #if defined(__has_feature)
523 #if __has_feature(safe_stack)
524 #error SafeStack Enabled
525 #endif
526 #endif
527 return 0;
528 }'''
529 if get_option('safe_stack') != not cc.compiles(safe_stack_probe)
530 safe_stack_arg = get_option('safe_stack') ? '-fsanitize=safe-stack' : '-fno-sanitize=safe-stack'
531 if get_option('safe_stack') != not cc.compiles(safe_stack_probe, args: safe_stack_arg)
532 error(get_option('safe_stack') \
533 ? 'SafeStack not supported by your compiler' \
534 : 'Cannot disable SafeStack')
535 endif
536 qemu_cflags += safe_stack_arg
537 qemu_ldflags += safe_stack_arg
538 endif
539 if get_option('safe_stack') and coroutine_backend != 'ucontext'
540 error('SafeStack is only supported with the ucontext coroutine backend')
541 endif
542
543 if get_option('asan')
544 if cc.has_argument('-fsanitize=address')
545 qemu_cflags = ['-fsanitize=address'] + qemu_cflags
546 qemu_ldflags = ['-fsanitize=address'] + qemu_ldflags
547 # Ensure complete stack traces for LSan suppressions to match correctly.
548 qemu_cflags += ['-fno-omit-frame-pointer']
549 else
550 error('Your compiler does not support -fsanitize=address')
551 endif
552 endif
553
554 if get_option('ubsan')
555 # Detect static linking issue with ubsan:
556 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84285
557 if cc.links('int main(int argc, char **argv) { return argc + 1; }',
558 args: [qemu_ldflags, '-fsanitize=undefined'])
559 qemu_cflags += ['-fsanitize=undefined']
560 qemu_ldflags += ['-fsanitize=undefined']
561
562 # Suppress undefined behaviour from function call to mismatched type.
563 # In addition, tcg prologue does not emit function type prefix
564 # required by function call sanitizer.
565 if cc.has_argument('-fno-sanitize=function')
566 qemu_cflags += ['-fno-sanitize=function']
567 endif
568 else
569 error('Your compiler does not support -fsanitize=undefined')
570 endif
571 endif
572
573 # Thread sanitizer is, for now, much noisier than the other sanitizers;
574 # keep it separate until that is not the case.
575 if get_option('tsan')
576 if get_option('asan') or get_option('ubsan')
577 error('TSAN is not supported with other sanitizers')
578 endif
579 if not cc.has_function('__tsan_create_fiber',
580 args: '-fsanitize=thread',
581 prefix: '#include <sanitizer/tsan_interface.h>')
582 error('Cannot enable TSAN due to missing fiber annotation interface')
583 endif
584 tsan_warn_suppress = []
585 # gcc (>=11) will report constructions not supported by tsan:
586 # "error: ‘atomic_thread_fence’ is not supported with ‘-fsanitize=thread’"
587 # https://gcc.gnu.org/gcc-11/changes.html
588 # However, clang does not support this warning and this triggers an error.
589 if cc.has_argument('-Wno-tsan')
590 tsan_warn_suppress = ['-Wno-tsan']
591 endif
592 qemu_cflags = ['-fsanitize=thread'] + tsan_warn_suppress + qemu_cflags
593 qemu_ldflags = ['-fsanitize=thread'] + qemu_ldflags
594 endif
595
596 # Detect support for PT_GNU_RELRO + DT_BIND_NOW.
597 # The combination is known as "full relro", because .got.plt is read-only too.
598 qemu_ldflags += cc.get_supported_link_arguments('-Wl,-z,relro', '-Wl,-z,now')
599
600 if host_os == 'windows'
601 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--no-seh', '-Wl,--nxcompat')
602 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--dynamicbase', '-Wl,--high-entropy-va')
603 endif
604 if host_os == 'linux' and get_option('werror') and get_option('prefer_static')
605 # On glibc systems, glib causes warnings about getpwuid, getpwuid_r
606 # and getpwnam_r not being supported with static linking
607 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--no-fatal-warnings')
608 endif
609
610 if get_option('fuzzing')
611 # Specify a filter to only instrument code that is directly related to
612 # virtual-devices.
613 configure_file(output: 'instrumentation-filter',
614 input: 'scripts/oss-fuzz/instrumentation-filter-template',
615 copy: true)
616
617 if cc.compiles('int main () { return 0; }',
618 name: '-fsanitize-coverage-allowlist=/dev/null',
619 args: ['-fsanitize-coverage-allowlist=/dev/null',
620 '-fsanitize-coverage=trace-pc'] )
621 qemu_common_flags += ['-fsanitize-coverage-allowlist=instrumentation-filter']
622 endif
623
624 if get_option('fuzzing_engine') == ''
625 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
626 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
627 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
628 # unable to bind the fuzzer-related callbacks added by instrumentation.
629 qemu_common_flags += ['-fsanitize=fuzzer-no-link']
630 qemu_ldflags += ['-fsanitize=fuzzer-no-link']
631 # For the actual fuzzer binaries, we need to link against the libfuzzer
632 # library. They need to be configurable, to support OSS-Fuzz
633 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
634 else
635 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
636 # the needed CFLAGS have already been provided
637 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
638 endif
639 endif
640
641 if get_option('cfi')
642 cfi_flags=[]
643 # Check for dependency on LTO
644 if not get_option('b_lto')
645 error('Selected Control-Flow Integrity but LTO is disabled')
646 endif
647 if enable_modules
648 error('Selected Control-Flow Integrity is not compatible with modules')
649 endif
650 # Check for cfi flags. CFI requires LTO so we can't use
651 # get_supported_arguments, but need a more complex "compiles" which allows
652 # custom arguments
653 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
654 args: ['-flto', '-fsanitize=cfi-icall'] )
655 cfi_flags += '-fsanitize=cfi-icall'
656 else
657 error('-fsanitize=cfi-icall is not supported by the compiler')
658 endif
659 if cc.compiles('int main () { return 0; }',
660 name: '-fsanitize-cfi-icall-generalize-pointers',
661 args: ['-flto', '-fsanitize=cfi-icall',
662 '-fsanitize-cfi-icall-generalize-pointers'] )
663 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
664 else
665 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
666 endif
667 if get_option('cfi_debug')
668 if get_option('safe_stack')
669 error('cfi_debug is not compatible with safe_stack')
670 endif
671 if cc.compiles('int main () { return 0; }',
672 name: '-fno-sanitize-trap=cfi-icall',
673 args: ['-flto', '-fsanitize=cfi-icall',
674 '-fno-sanitize-trap=cfi-icall'] )
675 cfi_flags += '-fno-sanitize-trap=cfi-icall'
676 else
677 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
678 endif
679 endif
680 add_global_arguments(cfi_flags, native: false, language: all_languages)
681 add_global_link_arguments(cfi_flags, native: false, language: all_languages)
682 endif
683
684 # Check further flags that make QEMU more robust against malicious parties
685
686 hardening_flags = [
687 # Initialize all stack variables to zero. This makes
688 # it harder to take advantage of uninitialized stack
689 # data to drive exploits
690 '-ftrivial-auto-var-init=zero',
691 # Ensure GCC zero-initializes padding bits and trailing fields in
692 # unions. This avoids potentially leaking host data into the guest
693 # when we init a struct and copy it into guest memory. GCC prior
694 # to GCC 15 and clang don't have this, but they zero the padding
695 # and trailing portions of a union by default.
696 '-fzero-init-padding-bits=all',
697 ]
698
699 # Zero out registers used during a function call
700 # upon its return. This makes it harder to assemble
701 # ROP gadgets into something usable
702 #
703 # NB: Clang 17 is broken and SEGVs
704 # https://github.com/llvm/llvm-project/issues/75168
705 if cc.compiles('extern struct { void (*cb)(void); } s; void f(void) { s.cb(); }',
706 name: '-fzero-call-used-regs=used-gpr',
707 args: ['-O2', '-fzero-call-used-regs=used-gpr'])
708 hardening_flags += '-fzero-call-used-regs=used-gpr'
709 endif
710
711 qemu_common_flags += hardening_flags
712
713 # Collect warning flags we want to set, sorted alphabetically
714 warn_flags = [
715 # First enable interesting warnings
716 '-Wempty-body',
717 '-Wendif-labels',
718 '-Wexpansion-to-defined',
719 '-Wformat-overflow=2',
720 '-Wformat-security',
721 '-Wformat-y2k',
722 '-Wignored-qualifiers',
723 '-Wimplicit-fallthrough=2',
724 '-Winit-self',
725 '-Wmissing-format-attribute',
726 '-Wmissing-prototypes',
727 '-Wnested-externs',
728 '-Wold-style-declaration',
729 '-Wold-style-definition',
730 '-Wredundant-decls',
731 '-Wshadow=local',
732 '-Wstrict-prototypes',
733 '-Wtype-limits',
734 '-Wundef',
735 '-Wvla',
736 '-Wwrite-strings',
737
738 # Then disable some undesirable warnings
739 '-Wno-gnu-variable-sized-type-not-at-end',
740 '-Wno-initializer-overrides',
741 '-Wno-missing-include-dirs',
742 '-Wno-psabi',
743 '-Wno-shift-negative-value',
744 '-Wno-string-plus-int',
745 '-Wno-tautological-type-limit-compare',
746 '-Wno-typedef-redefinition',
747 ]
748
749 if host_os != 'darwin'
750 tsa_has_cleanup = cc.compiles('''
751 struct __attribute__((capability("mutex"))) mutex {};
752 void lock(struct mutex *m) __attribute__((acquire_capability(m)));
753 void unlock(struct mutex *m) __attribute__((release_capability(m)));
754
755 void test(void) {
756 struct mutex __attribute__((cleanup(unlock))) m;
757 lock(&m);
758 }
759 ''', args: ['-Wthread-safety', '-Werror'])
760 if tsa_has_cleanup
761 warn_flags += ['-Wthread-safety']
762 endif
763 endif
764
765 # Set up C++ compiler flags
766 qemu_cxxflags = []
767 if 'cpp' in all_languages
768 qemu_cxxflags = ['-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', '-D__STDC_FORMAT_MACROS'] + qemu_cflags
769 endif
770
771 add_project_arguments(cc.get_supported_arguments(qemu_common_flags + qemu_cflags + warn_flags),
772 native: false, language: 'c')
773 add_global_link_arguments(qemu_ldflags, native: false, language: all_languages)
774 if have_rust
775 add_global_link_arguments(qemu_ldflags, native: false, language: 'rust')
776 endif
777
778 if 'cpp' in all_languages
779 add_project_arguments(cxx.get_supported_arguments(qemu_common_flags + qemu_cxxflags),
780 native: false, language: 'cpp')
781 add_project_arguments(cxx.get_supported_arguments(warn_flags), native: false, language: 'cpp')
782 endif
783 if 'objc' in all_languages
784 # Note sanitizer flags are not applied to Objective-C sources!
785 add_project_arguments(objc.get_supported_arguments(qemu_common_flags + warn_flags),
786 native: false, language: 'objc')
787 endif
788 if host_os == 'linux'
789 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
790 '-isystem', 'linux-headers',
791 language: all_languages)
792 endif
793
794 add_project_arguments('-iquote', '.',
795 '-iquote', meson.current_source_dir(),
796 '-iquote', meson.current_source_dir() / 'include',
797 language: all_languages)
798
799 # If a host-specific include directory exists, list that first...
800 host_include = meson.current_source_dir() / 'host/include/'
801 if fs.is_dir(host_include / host_arch)
802 add_project_arguments('-iquote', host_include / host_arch,
803 language: all_languages)
804 endif
805 # ... followed by the generic fallback.
806 add_project_arguments('-iquote', host_include / 'generic',
807 language: all_languages)
808
809 sparse = find_program('cgcc', required: get_option('sparse'))
810 if sparse.found()
811 run_target('sparse',
812 command: [find_program('scripts/check_sparse.py'),
813 'compile_commands.json', sparse.full_path(), '-Wbitwise',
814 '-Wno-transparent-union', '-Wno-old-initializer',
815 '-Wno-non-pointer-null'])
816 endif
817
818 #####################################
819 # Host-specific libraries and flags #
820 #####################################
821
822 libm = cc.find_library('m', required: false)
823 threads = dependency('threads')
824 util = cc.find_library('util', required: false)
825 winmm = []
826 socket = []
827 version_res = []
828 coref = []
829 iokit = []
830 pvg = not_found
831 emulator_link_args = []
832 midl = not_found
833 widl = not_found
834 pathcch = not_found
835 synchronization = not_found
836 host_dsosuf = '.so'
837 if host_os == 'windows'
838 midl = find_program('midl', required: false)
839 widl = find_program('widl', required: false)
840
841 # MinGW uses lowercase for library names
842 pathcch = cc.find_library('pathcch', required: true)
843 synchronization = cc.find_library('synchronization', required: true)
844 socket = cc.find_library('ws2_32', required: true)
845 winmm = cc.find_library('winmm', required: true)
846
847 win = import('windows')
848 version_res = win.compile_resources('version.rc',
849 depend_files: files('pc-bios/qemu-nsis.ico'),
850 include_directories: include_directories('.'))
851 host_dsosuf = '.dll'
852 elif host_os == 'darwin'
853 coref = dependency('appleframeworks', modules: 'CoreFoundation')
854 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
855 host_dsosuf = '.dylib'
856 pvg = dependency('appleframeworks', modules: ['ParavirtualizedGraphics', 'Metal'],
857 required: get_option('pvg'))
858 elif host_os == 'sunos'
859 socket = [cc.find_library('socket'),
860 cc.find_library('nsl'),
861 cc.find_library('resolv')]
862 elif host_os == 'haiku'
863 socket = [cc.find_library('posix_error_mapper'),
864 cc.find_library('network'),
865 cc.find_library('bsd')]
866 elif host_os == 'openbsd'
867 if have_tcg
868 # Disable OpenBSD W^X if available
869 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
870 endif
871 endif
872
873 ###############################################
874 # Host-specific configuration of accelerators #
875 ###############################################
876
877 accelerators = []
878 if get_option('kvm').allowed() and host_os == 'linux'
879 accelerators += 'CONFIG_KVM'
880 endif
881
882 if get_option('mshv').allowed() and host_os == 'linux'
883 if get_option('mshv').enabled() and host_machine.cpu() != 'x86_64'
884 error('mshv accelerator requires x64_64 host')
885 endif
886 accelerators += 'CONFIG_MSHV'
887 endif
888
889 if get_option('whpx').allowed() and host_os == 'windows'
890 if cpu == 'i386'
891 if get_option('whpx').enabled()
892 error('WHPX requires 64-bit host')
893 endif
894 # Leave CONFIG_WHPX disabled
895 else
896 if cc.has_header('winhvplatform.h', required: get_option('whpx'))
897 accelerators += 'CONFIG_WHPX'
898 endif
899 endif
900 endif
901
902 hvf = not_found
903 if get_option('hvf').allowed()
904 hvf = dependency('appleframeworks', modules: 'Hypervisor',
905 required: get_option('hvf'))
906 if hvf.found()
907 accelerators += 'CONFIG_HVF'
908 endif
909 endif
910
911 nitro = not_found
912 if get_option('nitro').allowed() and host_os == 'linux'
913 accelerators += 'CONFIG_NITRO'
914 endif
915
916 nvmm = not_found
917 if host_os == 'netbsd'
918 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
919 if nvmm.found()
920 accelerators += 'CONFIG_NVMM'
921 endif
922 endif
923
924 tcg_arch = host_arch
925 if have_tcg
926 if host_arch == 'unknown'
927 if not get_option('tcg_interpreter')
928 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
929 endif
930 elif host_arch == 'wasm64'
931 if not get_option('tcg_interpreter')
932 error('WebAssembly host requires --enable-tcg-interpreter')
933 endif
934 elif get_option('tcg_interpreter')
935 warning('Use of the TCG interpreter is not recommended on this host')
936 warning('architecture. There is a native TCG execution backend available')
937 warning('which provides substantially better performance and reliability.')
938 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
939 warning('configuration option on this architecture to use the native')
940 warning('backend.')
941 endif
942 if get_option('tcg_interpreter')
943 tcg_arch = 'tci'
944 endif
945 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
946 language: all_languages)
947
948 accelerators += 'CONFIG_TCG'
949 endif
950
951 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
952 error('KVM not available on this platform')
953 endif
954 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
955 error('HVF not available on this platform')
956 endif
957 if 'CONFIG_NITRO' not in accelerators and get_option('nitro').enabled()
958 error('NITRO not available on this platform')
959 endif
960 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
961 error('NVMM not available on this platform')
962 endif
963 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
964 error('WHPX not available on this platform')
965 endif
966 if 'CONFIG_MSHV' not in accelerators and get_option('mshv').enabled()
967 error('mshv not available on this platform')
968 endif
969
970 xen = not_found
971 if get_option('xen').enabled() or (get_option('xen').auto() and have_system)
972 xencontrol = dependency('xencontrol', required: false,
973 method: 'pkg-config')
974 if xencontrol.found()
975 xen_pc = declare_dependency(version: xencontrol.version(),
976 dependencies: [
977 xencontrol,
978 # disabler: true makes xen_pc.found() return false if any is not found
979 dependency('xenstore', required: false,
980 method: 'pkg-config',
981 disabler: true),
982 dependency('xenforeignmemory', required: false,
983 method: 'pkg-config',
984 disabler: true),
985 dependency('xengnttab', required: false,
986 method: 'pkg-config',
987 disabler: true),
988 dependency('xenevtchn', required: false,
989 method: 'pkg-config',
990 disabler: true),
991 dependency('xendevicemodel', required: false,
992 method: 'pkg-config',
993 disabler: true),
994 # optional, no "disabler: true"
995 dependency('xentoolcore', required: false,
996 method: 'pkg-config')])
997 if xen_pc.found()
998 xen = xen_pc
999 endif
1000 endif
1001 if not xen.found()
1002 xen_tests = [ '4.11.0', '4.10.0', '4.9.0', '4.8.0', '4.7.1' ]
1003 xen_libs = {
1004 '4.11.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
1005 '4.10.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
1006 '4.9.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
1007 '4.8.0': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
1008 '4.7.1': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
1009 }
1010 xen_deps = {}
1011 foreach ver: xen_tests
1012 # cache the various library tests to avoid polluting the logs
1013 xen_test_deps = []
1014 foreach l: xen_libs[ver]
1015 if l not in xen_deps
1016 xen_deps += { l: cc.find_library(l, required: false) }
1017 endif
1018 xen_test_deps += xen_deps[l]
1019 endforeach
1020
1021 # Use -D to pick just one of the test programs in scripts/xen-detect.c
1022 xen_version = ver.split('.')
1023 xen_ctrl_version = xen_version[0] + \
1024 ('0' + xen_version[1]).substring(-2) + \
1025 ('0' + xen_version[2]).substring(-2)
1026 if cc.links(files('scripts/xen-detect.c'),
1027 args: '-DCONFIG_XEN_CTRL_INTERFACE_VERSION=' + xen_ctrl_version,
1028 dependencies: xen_test_deps)
1029 xen = declare_dependency(version: ver, dependencies: xen_test_deps)
1030 break
1031 endif
1032 endforeach
1033 endif
1034 if xen.found()
1035 accelerators += 'CONFIG_XEN'
1036 elif get_option('xen').enabled()
1037 error('could not compile and link Xen test program')
1038 endif
1039 endif
1040 have_xen_pci_passthrough = get_option('xen_pci_passthrough') \
1041 .require(xen.found(),
1042 error_message: 'Xen PCI passthrough requested but Xen not enabled') \
1043 .require(host_os == 'linux',
1044 error_message: 'Xen PCI passthrough not available on this platform') \
1045 .require(cpu == 'x86_64',
1046 error_message: 'Xen PCI passthrough not available on this platform') \
1047 .allowed()
1048
1049 ################
1050 # Dependencies #
1051 ################
1052
1053 # When bumping glib minimum version, please check also whether to increase
1054 # the _WIN32_WINNT setting in osdep.h according to the value from glib.
1055 # You should also check if any of the glib.version() checks
1056 # below can also be removed.
1057 glib_req_ver = '>=2.66.0'
1058 glib_pc = dependency('glib-2.0', version: glib_req_ver, required: true,
1059 method: 'pkg-config')
1060 glib_cflags = []
1061 if enable_modules
1062 gmodule = dependency('gmodule-export-2.0', version: glib_req_ver, required: true,
1063 method: 'pkg-config')
1064 elif get_option('plugins')
1065 gmodule = dependency('gmodule-no-export-2.0', version: glib_req_ver, required: true,
1066 method: 'pkg-config')
1067 else
1068 gmodule = not_found
1069 endif
1070
1071 # This workaround is required due to a bug in pkg-config file for glib as it
1072 # doesn't define GLIB_STATIC_COMPILATION for pkg-config --static
1073 if host_os == 'windows' and get_option('prefer_static')
1074 glib_cflags += ['-DGLIB_STATIC_COMPILATION']
1075 endif
1076
1077 # Sanity check that the current size_t matches the
1078 # size that glib thinks it should be. This catches
1079 # problems on multi-arch where people try to build
1080 # 32-bit QEMU while pointing at 64-bit glib headers
1081
1082 if not cc.compiles('''
1083 #include <glib.h>
1084 #include <stddef.h>
1085
1086 #define QEMU_BUILD_BUG_ON(x) \
1087 typedef char qemu_build_bug_on[(x)?-1:1] __attribute__((unused));
1088
1089 int main(void) {
1090 QEMU_BUILD_BUG_ON(sizeof(size_t) != GLIB_SIZEOF_SIZE_T);
1091 return 0;
1092 }''', dependencies: glib_pc, args: glib_cflags)
1093 error('''sizeof(size_t) doesn't match GLIB_SIZEOF_SIZE_T.
1094 You probably need to set PKG_CONFIG_LIBDIR" to point
1095 to the right pkg-config files for your build target.''')
1096 endif
1097
1098 glib = declare_dependency(dependencies: [glib_pc, gmodule],
1099 compile_args: glib_cflags,
1100 version: glib_pc.version())
1101
1102 # Check whether glib has gslice, which we have to avoid for correctness.
1103 # TODO: remove this check and the corresponding workaround (qtree) when
1104 # the minimum supported glib is >= 2.75.3
1105 glib_has_gslice = glib.version().version_compare('<2.75.3')
1106
1107 # override glib dep to include the above refinements
1108 meson.override_dependency('glib-2.0', glib)
1109
1110 # The path to glib.h is added to all compilation commands.
1111 add_project_dependencies(glib.partial_dependency(compile_args: true, includes: true),
1112 native: false, language: all_languages)
1113
1114 gio = not_found
1115 gdbus_codegen = not_found
1116 gdbus_codegen_error = '@0@ requires gdbus-codegen, please install libgio'
1117 if not get_option('gio').auto() or have_system
1118 gio = dependency('gio-2.0', required: get_option('gio'),
1119 method: 'pkg-config')
1120 if gio.found() and not cc.links('''
1121 #include <gio/gio.h>
1122 int main(void)
1123 {
1124 g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0);
1125 return 0;
1126 }''', dependencies: [glib, gio])
1127 if get_option('gio').enabled()
1128 error('The installed libgio is broken for static linking')
1129 endif
1130 gio = not_found
1131 endif
1132 if gio.found()
1133 gdbus_codegen = find_program('gdbus-codegen',
1134 required: get_option('gio'))
1135 gio_unix = dependency('gio-unix-2.0', required: get_option('gio'),
1136 method: 'pkg-config')
1137 gio = declare_dependency(dependencies: [gio, gio_unix],
1138 version: gio.version())
1139 endif
1140 endif
1141 if gdbus_codegen.found() and get_option('cfi')
1142 gdbus_codegen = not_found
1143 gdbus_codegen_error = '@0@ uses gdbus-codegen, which does not support control flow integrity'
1144 endif
1145
1146 xml_pp = find_program('scripts/xml-preprocess.py')
1147
1148 lttng = not_found
1149 if 'ust' in get_option('trace_backends')
1150 lttng = dependency('lttng-ust', required: true, version: '>= 2.1',
1151 method: 'pkg-config')
1152 endif
1153 pixman = not_found
1154 if not get_option('pixman').auto() or have_system or have_tools
1155 pixman = dependency('pixman-1', required: get_option('pixman'), version:'>=0.21.8',
1156 method: 'pkg-config')
1157 endif
1158
1159 zlib = dependency('zlib', required: true)
1160
1161 libaio = not_found
1162 if not get_option('linux_aio').auto() or have_block
1163 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
1164 required: get_option('linux_aio'))
1165 endif
1166
1167 linux_io_uring_test = '''
1168 #include <liburing.h>
1169 #include <linux/errqueue.h>
1170
1171 int main(void) { return 0; }'''
1172
1173 linux_io_uring = not_found
1174 if not get_option('linux_io_uring').auto() or have_block
1175 linux_io_uring = dependency('liburing', version: '>=0.3',
1176 required: get_option('linux_io_uring'),
1177 method: 'pkg-config')
1178 if not cc.links(linux_io_uring_test)
1179 linux_io_uring = not_found
1180 endif
1181 endif
1182
1183 libnfs = not_found
1184 if not get_option('libnfs').auto() or have_block
1185 libnfs = dependency('libnfs', version: '>=1.9.3',
1186 required: get_option('libnfs'),
1187 method: 'pkg-config')
1188 endif
1189
1190 libattr_test = '''
1191 #include <stddef.h>
1192 #include <sys/types.h>
1193 #ifdef CONFIG_LIBATTR
1194 #include <attr/xattr.h>
1195 #else
1196 #include <sys/xattr.h>
1197 #endif
1198 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
1199
1200 libattr = not_found
1201 have_old_libattr = false
1202 if get_option('attr').allowed()
1203 if cc.links(libattr_test)
1204 libattr = declare_dependency()
1205 else
1206 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
1207 required: get_option('attr'))
1208 if libattr.found() and not \
1209 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
1210 libattr = not_found
1211 if get_option('attr').enabled()
1212 error('could not link libattr')
1213 else
1214 warning('could not link libattr, disabling')
1215 endif
1216 else
1217 have_old_libattr = libattr.found()
1218 endif
1219 endif
1220 endif
1221
1222 cocoa = dependency('appleframeworks',
1223 modules: ['Cocoa', 'CoreVideo', 'QuartzCore'],
1224 required: get_option('cocoa'))
1225
1226 vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
1227 if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
1228 'VMNET_BRIDGED_MODE',
1229 dependencies: vmnet)
1230 vmnet = not_found
1231 if get_option('vmnet').enabled()
1232 error('vmnet.framework API is outdated')
1233 else
1234 warning('vmnet.framework API is outdated, disabling')
1235 endif
1236 endif
1237
1238 seccomp = not_found
1239 seccomp_has_sysrawrc = false
1240 if not get_option('seccomp').auto() or have_system or have_tools
1241 seccomp = dependency('libseccomp', version: '>=2.3.0',
1242 required: get_option('seccomp'),
1243 method: 'pkg-config')
1244 if seccomp.found()
1245 seccomp_has_sysrawrc = cc.has_header_symbol('seccomp.h',
1246 'SCMP_FLTATR_API_SYSRAWRC',
1247 dependencies: seccomp)
1248 endif
1249 endif
1250
1251 libcap_ng = not_found
1252 if not get_option('cap_ng').auto() or have_system or have_tools
1253 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
1254 required: get_option('cap_ng'))
1255 endif
1256 if libcap_ng.found() and not cc.links('''
1257 #include <cap-ng.h>
1258 int main(void)
1259 {
1260 capng_capability_to_name(CAPNG_EFFECTIVE);
1261 return 0;
1262 }''', dependencies: libcap_ng)
1263 libcap_ng = not_found
1264 if get_option('cap_ng').enabled()
1265 error('could not link libcap-ng')
1266 else
1267 warning('could not link libcap-ng, disabling')
1268 endif
1269 endif
1270
1271 if get_option('xkbcommon').auto() and not have_system and not have_tools
1272 xkbcommon = not_found
1273 else
1274 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
1275 method: 'pkg-config')
1276 endif
1277
1278 slirp = not_found
1279 if not get_option('slirp').auto() or have_system
1280 slirp = dependency('slirp', required: get_option('slirp'),
1281 method: 'pkg-config')
1282 # slirp < 4.7 is incompatible with CFI support in QEMU. This is because
1283 # it passes function pointers within libslirp as callbacks for timers.
1284 # When using a system-wide shared libslirp, the type information for the
1285 # callback is missing and the timer call produces a false positive with CFI.
1286 # Do not use the "version" keyword argument to produce a better error.
1287 # with control-flow integrity.
1288 if get_option('cfi') and slirp.found() and slirp.version().version_compare('<4.7')
1289 if get_option('slirp').enabled()
1290 error('Control-Flow Integrity requires libslirp 4.7.')
1291 else
1292 warning('Cannot use libslirp since Control-Flow Integrity requires libslirp >= 4.7.')
1293 slirp = not_found
1294 endif
1295 endif
1296 endif
1297
1298 enable_passt = get_option('passt') \
1299 .require(host_os == 'linux', error_message: 'passt is supported only on Linux') \
1300 .require(gio.found(), error_message: 'passt requires gio') \
1301 .allowed()
1302
1303 vde = not_found
1304 if not get_option('vde').auto() or have_system or have_tools
1305 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
1306 required: get_option('vde'))
1307 endif
1308 if vde.found() and not cc.links('''
1309 #include <libvdeplug.h>
1310 int main(void)
1311 {
1312 struct vde_open_args a = {0, 0, 0};
1313 char s[] = "";
1314 vde_open(s, s, &a);
1315 return 0;
1316 }''', dependencies: vde)
1317 vde = not_found
1318 if get_option('cap_ng').enabled()
1319 error('could not link libvdeplug')
1320 else
1321 warning('could not link libvdeplug, disabling')
1322 endif
1323 endif
1324
1325 pulse = not_found
1326 if not get_option('pa').auto() or (host_os == 'linux' and have_system)
1327 pulse = dependency('libpulse', version: '>=0.9.13', required: get_option('pa'),
1328 method: 'pkg-config')
1329 endif
1330 alsa = not_found
1331 if not get_option('alsa').auto() or (host_os == 'linux' and have_system)
1332 alsa = dependency('alsa', required: get_option('alsa'),
1333 method: 'pkg-config')
1334 endif
1335 jack = not_found
1336 if not get_option('jack').auto() or have_system
1337 jack = dependency('jack', required: get_option('jack'),
1338 method: 'pkg-config')
1339 endif
1340 pipewire = not_found
1341 if not get_option('pipewire').auto() or (host_os == 'linux' and have_system)
1342 pipewire = dependency('libpipewire-0.3', version: '>=0.3.60',
1343 required: get_option('pipewire'),
1344 method: 'pkg-config')
1345 endif
1346 sndio = not_found
1347 if not get_option('sndio').auto() or have_system
1348 sndio = dependency('sndio', required: get_option('sndio'),
1349 method: 'pkg-config')
1350 endif
1351
1352 spice_protocol = not_found
1353 if not get_option('spice_protocol').auto() or have_system
1354 spice_protocol = dependency('spice-protocol', version: '>=0.14.3',
1355 required: get_option('spice_protocol'),
1356 method: 'pkg-config')
1357 endif
1358 spice = not_found
1359 if get_option('spice') \
1360 .disable_auto_if(not have_system) \
1361 .require(pixman.found(),
1362 error_message: 'cannot enable SPICE if pixman is not available') \
1363 .allowed()
1364 spice = dependency('spice-server', version: '>=0.15.0',
1365 required: get_option('spice'),
1366 method: 'pkg-config')
1367 endif
1368 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
1369
1370 rt = not_found
1371 if host_os != 'windows'
1372 have_shm_open = cc.has_function('shm_open')
1373 if not have_shm_open
1374 rt = cc.find_library('rt', required: true)
1375 endif
1376 endif
1377
1378 libiscsi = not_found
1379 if not get_option('libiscsi').auto() or have_block
1380 libiscsi = dependency('libiscsi', version: '>=1.9.0',
1381 required: get_option('libiscsi'),
1382 method: 'pkg-config')
1383 endif
1384 zstd = not_found
1385 if not get_option('zstd').auto() or have_block
1386 zstd = dependency('libzstd', version: '>=1.4.0',
1387 required: get_option('zstd'),
1388 method: 'pkg-config')
1389 endif
1390 qpl = not_found
1391 if not get_option('qpl').auto() or have_system
1392 qpl = dependency('qpl', version: '>=1.5.0',
1393 required: get_option('qpl'),
1394 method: 'pkg-config')
1395 endif
1396 uadk = not_found
1397 if not get_option('uadk').auto() or have_system
1398 libwd = dependency('libwd', version: '>=2.6',
1399 required: get_option('uadk'),
1400 method: 'pkg-config')
1401 libwd_comp = dependency('libwd_comp', version: '>=2.6',
1402 required: get_option('uadk'),
1403 method: 'pkg-config')
1404 if libwd.found() and libwd_comp.found()
1405 uadk = declare_dependency(dependencies: [libwd, libwd_comp])
1406 endif
1407 endif
1408
1409 qatzip = not_found
1410 if not get_option('qatzip').auto() or have_system
1411 qatzip = dependency('qatzip', version: '>=1.1.2',
1412 required: get_option('qatzip'),
1413 method: 'pkg-config')
1414 endif
1415
1416 virgl = not_found
1417
1418 have_vhost_user_gpu = have_tools and host_os == 'linux' and pixman.found()
1419 if not get_option('virglrenderer').auto() or have_system or have_vhost_user_gpu
1420 virgl = dependency('virglrenderer',
1421 method: 'pkg-config',
1422 required: get_option('virglrenderer'))
1423 endif
1424 rutabaga = not_found
1425 if not get_option('rutabaga_gfx').auto() or have_system or have_vhost_user_gpu
1426 rutabaga = dependency('rutabaga_gfx_ffi',
1427 method: 'pkg-config',
1428 required: get_option('rutabaga_gfx'))
1429 endif
1430 blkio = not_found
1431 if not get_option('blkio').auto() or have_block
1432 blkio = dependency('blkio',
1433 method: 'pkg-config',
1434 required: get_option('blkio'))
1435 endif
1436 curl = not_found
1437 if not get_option('curl').auto() or have_block
1438 curl = dependency('libcurl', version: '>=7.29.0',
1439 method: 'pkg-config',
1440 required: get_option('curl'))
1441 endif
1442 libudev = not_found
1443 if host_os == 'linux' and (have_system or have_tools)
1444 libudev = dependency('libudev',
1445 method: 'pkg-config',
1446 required: get_option('libudev'))
1447 endif
1448 igvm = not_found
1449 if not get_option('igvm').auto() or have_system
1450 igvm = dependency('igvm', version: '>= 0.3.0',
1451 method: 'pkg-config',
1452 required: get_option('igvm'))
1453 endif
1454
1455 mpathlibs = [libudev]
1456 mpathpersist = not_found
1457 if host_os == 'linux' and have_tools and get_option('mpath').allowed()
1458 mpath_test_source = '''
1459 #include <libudev.h>
1460 #include <mpath_persist.h>
1461 unsigned mpath_mx_alloc_len = 1024;
1462 int logsink;
1463 static struct config *multipath_conf;
1464 extern struct udev *udev;
1465 extern struct config *get_multipath_config(void);
1466 extern void put_multipath_config(struct config *conf);
1467 struct udev *udev;
1468 struct config *get_multipath_config(void) { return multipath_conf; }
1469 void put_multipath_config(struct config *conf) { }
1470 int main(void) {
1471 udev = udev_new();
1472 multipath_conf = mpath_lib_init();
1473 return 0;
1474 }'''
1475 libmpathpersist = cc.find_library('mpathpersist',
1476 required: get_option('mpath'))
1477 if libmpathpersist.found()
1478 mpathlibs += libmpathpersist
1479 if get_option('prefer_static')
1480 mpathlibs += cc.find_library('devmapper',
1481 required: get_option('mpath'))
1482 endif
1483 mpathlibs += cc.find_library('multipath',
1484 required: get_option('mpath'))
1485 foreach lib: mpathlibs
1486 if not lib.found()
1487 mpathlibs = []
1488 break
1489 endif
1490 endforeach
1491 if mpathlibs.length() == 0
1492 msg = 'Dependencies missing for libmpathpersist'
1493 elif cc.links(mpath_test_source, dependencies: mpathlibs)
1494 mpathpersist = declare_dependency(dependencies: mpathlibs)
1495 else
1496 msg = 'Cannot detect libmpathpersist API'
1497 endif
1498 if not mpathpersist.found()
1499 if get_option('mpath').enabled()
1500 error(msg)
1501 else
1502 warning(msg + ', disabling')
1503 endif
1504 endif
1505 endif
1506 endif
1507
1508 iconv = not_found
1509 curses = not_found
1510 if have_system and get_option('curses').allowed()
1511 curses_test = '''
1512 #ifdef __APPLE__
1513 #define _XOPEN_SOURCE_EXTENDED 1
1514 #endif
1515 #include <locale.h>
1516 #include <curses.h>
1517 #include <wchar.h>
1518 int main(void) {
1519 wchar_t wch = L'w';
1520 setlocale(LC_ALL, "");
1521 resize_term(0, 0);
1522 addwstr(L"wide chars\n");
1523 addnwstr(&wch, 1);
1524 add_wch(WACS_DEGREE);
1525 return 0;
1526 }'''
1527
1528 curses_dep_list = host_os == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
1529 curses = dependency(curses_dep_list,
1530 required: false,
1531 method: 'pkg-config')
1532 msg = get_option('curses').enabled() ? 'curses library not found' : ''
1533 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
1534 if curses.found()
1535 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
1536 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses],
1537 version: curses.version())
1538 else
1539 msg = 'curses package not usable'
1540 curses = not_found
1541 endif
1542 endif
1543 if not curses.found()
1544 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1545 if host_os != 'windows' and not has_curses_h
1546 message('Trying with /usr/include/ncursesw')
1547 curses_compile_args += ['-I/usr/include/ncursesw']
1548 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1549 endif
1550 if has_curses_h
1551 curses_libname_list = (host_os == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
1552 foreach curses_libname : curses_libname_list
1553 libcurses = cc.find_library(curses_libname,
1554 required: false)
1555 if libcurses.found()
1556 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
1557 curses = declare_dependency(compile_args: curses_compile_args,
1558 dependencies: [libcurses])
1559 break
1560 else
1561 msg = 'curses library not usable'
1562 endif
1563 endif
1564 endforeach
1565 endif
1566 endif
1567 if get_option('iconv').allowed()
1568 foreach link_args : [ ['-liconv'], [] ]
1569 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
1570 # We need to use libiconv if available because mixing libiconv's headers with
1571 # the system libc does not work.
1572 # However, without adding glib to the dependencies -L/usr/local/lib will not be
1573 # included in the command line and libiconv will not be found.
1574 if cc.links('''
1575 #include <iconv.h>
1576 int main(void) {
1577 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
1578 return conv != (iconv_t) -1;
1579 }''', args: link_args, dependencies: glib)
1580 iconv = declare_dependency(link_args: link_args, dependencies: glib)
1581 break
1582 endif
1583 endforeach
1584 endif
1585 if curses.found() and not iconv.found()
1586 if get_option('iconv').enabled()
1587 error('iconv not available')
1588 endif
1589 msg = 'iconv required for curses UI but not available'
1590 curses = not_found
1591 endif
1592 if not curses.found() and msg != ''
1593 if get_option('curses').enabled()
1594 error(msg)
1595 else
1596 warning(msg + ', disabling')
1597 endif
1598 endif
1599 endif
1600
1601 brlapi = not_found
1602 if not get_option('brlapi').auto() or have_system
1603 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
1604 required: get_option('brlapi'))
1605 if brlapi.found() and not cc.links('''
1606 #include <brlapi.h>
1607 #include <stddef.h>
1608 int main(void) {
1609 return brlapi__openConnection(NULL, NULL, NULL) == BRLAPI_INVALID_FILE_DESCRIPTOR;
1610 }''', dependencies: brlapi)
1611 brlapi = not_found
1612 if get_option('brlapi').enabled()
1613 error('could not link brlapi')
1614 else
1615 warning('could not link brlapi, disabling')
1616 endif
1617 endif
1618 endif
1619
1620 sdl = not_found
1621 if not get_option('sdl').auto() or have_system
1622 sdl = dependency('sdl2', required: get_option('sdl'))
1623 sdl_image = not_found
1624 endif
1625 if sdl.found()
1626 # Some versions of SDL have problems with -Wundef
1627 if not cc.compiles('''
1628 #include <SDL.h>
1629 #include <SDL_syswm.h>
1630 int main(int argc, char *argv[]) { return 0; }
1631 ''', dependencies: sdl, args: '-Werror=undef')
1632 sdl = declare_dependency(compile_args: '-Wno-undef',
1633 dependencies: sdl,
1634 version: sdl.version())
1635 endif
1636 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
1637 method: 'pkg-config')
1638 else
1639 if get_option('sdl_image').enabled()
1640 error('sdl-image required, but SDL was @0@'.format(
1641 get_option('sdl').disabled() ? 'disabled' : 'not found'))
1642 endif
1643 sdl_image = not_found
1644 endif
1645
1646 rbd = not_found
1647 if not get_option('rbd').auto() or have_block
1648 librados = cc.find_library('rados', required: get_option('rbd'))
1649 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
1650 required: get_option('rbd'))
1651 if librados.found() and librbd.found()
1652 if cc.links('''
1653 #include <stdio.h>
1654 #include <rbd/librbd.h>
1655 int main(void) {
1656 rados_t cluster;
1657 rados_create(&cluster, NULL);
1658 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
1659 #error
1660 #endif
1661 return 0;
1662 }''', dependencies: [librbd, librados])
1663 rbd = declare_dependency(dependencies: [librbd, librados])
1664 elif get_option('rbd').enabled()
1665 error('librbd >= 1.12.0 required')
1666 else
1667 warning('librbd >= 1.12.0 not found, disabling')
1668 endif
1669 endif
1670 endif
1671
1672 hv_balloon = false
1673 if get_option('hv_balloon').allowed() and have_system
1674 if cc.links('''
1675 #include <string.h>
1676 #include <gmodule.h>
1677 int main(void) {
1678 GTree *tree;
1679
1680 tree = g_tree_new((GCompareFunc)strcmp);
1681 (void)g_tree_node_first(tree);
1682 g_tree_destroy(tree);
1683 return 0;
1684 }
1685 ''', dependencies: glib)
1686 hv_balloon = true
1687 else
1688 if get_option('hv_balloon').enabled()
1689 error('could not enable hv-balloon, update your glib')
1690 else
1691 warning('could not find glib support for hv-balloon, disabling')
1692 endif
1693 endif
1694 endif
1695
1696 libssh = not_found
1697 if not get_option('libssh').auto() or have_block
1698 libssh = dependency('libssh', version: '>=0.8.7',
1699 method: 'pkg-config',
1700 required: get_option('libssh'))
1701 endif
1702
1703 libbzip2 = not_found
1704 if not get_option('bzip2').auto() or have_block
1705 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
1706 required: get_option('bzip2'))
1707 if libbzip2.found() and not cc.links('''
1708 #include <bzlib.h>
1709 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
1710 libbzip2 = not_found
1711 if get_option('bzip2').enabled()
1712 error('could not link libbzip2')
1713 else
1714 warning('could not link libbzip2, disabling')
1715 endif
1716 endif
1717 endif
1718
1719 liblzfse = not_found
1720 if not get_option('lzfse').auto() or have_block
1721 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
1722 required: get_option('lzfse'))
1723 endif
1724 if liblzfse.found() and not cc.links('''
1725 #include <lzfse.h>
1726 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
1727 liblzfse = not_found
1728 if get_option('lzfse').enabled()
1729 error('could not link liblzfse')
1730 else
1731 warning('could not link liblzfse, disabling')
1732 endif
1733 endif
1734
1735 oss = not_found
1736 if get_option('oss').allowed() and have_system
1737 if not cc.has_header('sys/soundcard.h')
1738 # not found
1739 elif host_os == 'netbsd'
1740 oss = cc.find_library('ossaudio', required: get_option('oss'))
1741 else
1742 oss = declare_dependency()
1743 endif
1744
1745 if not oss.found()
1746 if get_option('oss').enabled()
1747 error('OSS not found')
1748 endif
1749 endif
1750 endif
1751 dsound = not_found
1752 if not get_option('dsound').auto() or (host_os == 'windows' and have_system)
1753 if cc.has_header('dsound.h')
1754 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
1755 endif
1756
1757 if not dsound.found()
1758 if get_option('dsound').enabled()
1759 error('DirectSound not found')
1760 endif
1761 endif
1762 endif
1763
1764 coreaudio = not_found
1765 if not get_option('coreaudio').auto() or (host_os == 'darwin' and have_system)
1766 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
1767 required: get_option('coreaudio'))
1768 endif
1769
1770 opengl = not_found
1771 if not get_option('opengl').auto() or have_system or have_vhost_user_gpu
1772 epoxy = dependency('epoxy', method: 'pkg-config',
1773 required: get_option('opengl'))
1774 if cc.has_header('epoxy/egl.h', dependencies: epoxy)
1775 opengl = epoxy
1776 elif get_option('opengl').enabled()
1777 error('epoxy/egl.h not found')
1778 endif
1779 endif
1780 gbm = not_found
1781 if (have_system or have_tools) and (virgl.found() or opengl.found())
1782 gbm = dependency('gbm', method: 'pkg-config', required: false)
1783 endif
1784 have_vhost_user_gpu = have_vhost_user_gpu and virgl.found() and opengl.found() and gbm.found()
1785
1786 libcbor = not_found
1787 if not get_option('libcbor').auto() or have_system
1788 libcbor = dependency('libcbor', version: '>=0.7.0',
1789 required: get_option('libcbor'))
1790 endif
1791
1792 gnutls = not_found
1793 gnutls_crypto = not_found
1794 gnutls_bug1717_workaround = false
1795 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
1796 gnutls = dependency('gnutls', version: '>=3.7.5',
1797 method: 'pkg-config',
1798 required: get_option('gnutls'))
1799 gnutls_crypto = gnutls
1800
1801 #if gnutls.found() and not get_option('gnutls-bug1717-workaround').disabled()
1802 # XXX: when bug 1717 is resolved, add logic to probe for
1803 # the GNUTLS fixed version number to handle the 'auto' case
1804 # gnutls_bug1717_workaround = true
1805 #endif
1806 endif
1807
1808 # We prefer use of gnutls for crypto, unless the options
1809 # explicitly asked for nettle or gcrypt.
1810 #
1811 # If gnutls isn't available for crypto, then we'll prefer
1812 # gcrypt over nettle for performance reasons.
1813 gcrypt = not_found
1814 nettle = not_found
1815 hogweed = not_found
1816 crypto_sm4 = not_found
1817 crypto_sm3 = not_found
1818
1819 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1820 error('Only one of gcrypt & nettle can be enabled')
1821 endif
1822
1823 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1824 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1825 gnutls_crypto = not_found
1826 endif
1827
1828 if not gnutls_crypto.found()
1829 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1830 gcrypt = dependency('libgcrypt', version: '>=1.9.4',
1831 required: get_option('gcrypt'))
1832 # Debian has removed -lgpg-error from libgcrypt-config
1833 # as it "spreads unnecessary dependencies" which in
1834 # turn breaks static builds...
1835 if gcrypt.found() and get_option('prefer_static')
1836 gcrypt = declare_dependency(dependencies:
1837 [gcrypt,
1838 cc.find_library('gpg-error', required: true)],
1839 version: gcrypt.version())
1840 endif
1841 crypto_sm4 = gcrypt
1842 crypto_sm3 = gcrypt
1843 endif
1844 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1845 nettle = dependency('nettle', version: '>=3.7.3',
1846 method: 'pkg-config',
1847 required: get_option('nettle'))
1848 crypto_sm4 = nettle
1849 # SM4 ALG is available in nettle >= 3.9
1850 if nettle.found() and not cc.links('''
1851 #include <nettle/sm4.h>
1852 int main(void) {
1853 struct sm4_ctx ctx;
1854 unsigned char key[16] = {0};
1855 sm4_set_encrypt_key(&ctx, key);
1856 return 0;
1857 }''', dependencies: nettle)
1858 crypto_sm4 = not_found
1859 endif
1860 crypto_sm3 = nettle
1861 # SM3 ALG is available in nettle >= 3.8
1862 if nettle.found() and not cc.links('''
1863 #include <nettle/sm3.h>
1864 #include <nettle/hmac.h>
1865 int main(void) {
1866 struct sm3_ctx ctx;
1867 struct hmac_sm3_ctx hmac_ctx;
1868 unsigned char data[64] = {0};
1869 unsigned char output[32];
1870
1871 // SM3 hash function test
1872 sm3_init(&ctx);
1873 sm3_update(&ctx, 64, data);
1874 sm3_digest(&ctx, 32, data);
1875
1876 // HMAC-SM3 test
1877 hmac_sm3_set_key(&hmac_ctx, 32, data);
1878 hmac_sm3_update(&hmac_ctx, 64, data);
1879 hmac_sm3_digest(&hmac_ctx, 32, output);
1880
1881 return 0;
1882 }''', dependencies: nettle)
1883 crypto_sm3 = not_found
1884 endif
1885 endif
1886 endif
1887
1888 capstone = not_found
1889 if not get_option('capstone').auto() or have_system or have_user
1890 capstone = dependency('capstone', version: '>=3.0.5',
1891 method: 'pkg-config',
1892 required: get_option('capstone'))
1893
1894 # Some versions of capstone have broken pkg-config file
1895 # that reports a wrong -I path, causing the #include to
1896 # fail later. If the system has such a broken version
1897 # do not use it.
1898 if capstone.found() and not cc.compiles('#include <capstone.h>',
1899 dependencies: [capstone])
1900 capstone = not_found
1901 if get_option('capstone').enabled()
1902 error('capstone requested, but it does not appear to work')
1903 endif
1904 endif
1905 endif
1906
1907 gmp = dependency('gmp', required: false, method: 'pkg-config')
1908 if nettle.found() and gmp.found()
1909 hogweed = dependency('hogweed', version: '>=3.4',
1910 method: 'pkg-config',
1911 required: get_option('nettle'))
1912 endif
1913
1914
1915 gtk = not_found
1916 gtkx11 = not_found
1917 vte = not_found
1918
1919 if get_option('gtk') \
1920 .disable_auto_if(not have_system) \
1921 .require(pixman.found(),
1922 error_message: 'cannot enable GTK if pixman is not available') \
1923 .allowed()
1924 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1925 method: 'pkg-config',
1926 required: get_option('gtk'))
1927 if gtk.found()
1928 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1929 method: 'pkg-config',
1930 required: false)
1931 gtk = declare_dependency(dependencies: [gtk, gtkx11],
1932 version: gtk.version())
1933
1934 if not get_option('vte').auto() or have_system
1935 vte = dependency('vte-2.91',
1936 method: 'pkg-config',
1937 required: get_option('vte'))
1938 endif
1939 endif
1940 endif
1941
1942 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found())
1943
1944 png = not_found
1945 if get_option('png').allowed() and have_system
1946 png = dependency('libpng', version: '>=1.6.34', required: get_option('png'),
1947 method: 'pkg-config')
1948 endif
1949 vnc = not_found
1950 jpeg = not_found
1951 sasl = not_found
1952 if get_option('vnc') \
1953 .disable_auto_if(not have_system) \
1954 .require(pixman.found(),
1955 error_message: 'cannot enable VNC if pixman is not available') \
1956 .allowed()
1957 vnc = declare_dependency() # dummy dependency
1958 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1959 method: 'pkg-config')
1960 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1961 required: get_option('vnc_sasl'))
1962 if sasl.found()
1963 sasl = declare_dependency(dependencies: sasl,
1964 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1965 endif
1966 endif
1967
1968 pam = not_found
1969 if not get_option('auth_pam').auto() or have_system
1970 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1971 required: get_option('auth_pam'))
1972 endif
1973 if pam.found() and not cc.links('''
1974 #include <stddef.h>
1975 #include <security/pam_appl.h>
1976 int main(void) {
1977 const char *service_name = "qemu";
1978 const char *user = "frank";
1979 const struct pam_conv pam_conv = { 0 };
1980 pam_handle_t *pamh = NULL;
1981 pam_start(service_name, user, &pam_conv, &pamh);
1982 return 0;
1983 }''', dependencies: pam)
1984 pam = not_found
1985 if get_option('auth_pam').enabled()
1986 error('could not link libpam')
1987 else
1988 warning('could not link libpam, disabling')
1989 endif
1990 endif
1991
1992 snappy = not_found
1993 if not get_option('snappy').auto() or have_system
1994 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1995 required: get_option('snappy'))
1996 endif
1997 if snappy.found() and not cc.links('''
1998 #include <snappy-c.h>
1999 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
2000 snappy = not_found
2001 if get_option('snappy').enabled()
2002 error('could not link libsnappy')
2003 else
2004 warning('could not link libsnappy, disabling')
2005 endif
2006 endif
2007
2008 lzo = not_found
2009 if not get_option('lzo').auto() or have_system
2010 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
2011 required: get_option('lzo'))
2012 endif
2013 if lzo.found() and not cc.links('''
2014 #include <lzo/lzo1x.h>
2015 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
2016 lzo = not_found
2017 if get_option('lzo').enabled()
2018 error('could not link liblzo2')
2019 else
2020 warning('could not link liblzo2, disabling')
2021 endif
2022 endif
2023
2024 numa = not_found
2025 if not get_option('numa').auto() or have_system or have_tools
2026 numa = cc.find_library('numa', has_headers: ['numa.h'],
2027 required: get_option('numa'))
2028 endif
2029 if numa.found() and not cc.links('''
2030 #include <numa.h>
2031 int main(void) { return numa_available(); }
2032 ''', dependencies: numa)
2033 numa = not_found
2034 if get_option('numa').enabled()
2035 error('could not link numa')
2036 else
2037 warning('could not link numa, disabling')
2038 endif
2039 endif
2040
2041 fdt = not_found
2042 fdt_opt = get_option('fdt')
2043 if fdt_opt == 'enabled' and get_option('wrap_mode') == 'nodownload'
2044 fdt_opt = 'system'
2045 endif
2046 if fdt_opt in ['enabled', 'system'] or (fdt_opt == 'auto' and have_system)
2047 fdt = cc.find_library('fdt', required: fdt_opt == 'system')
2048 if fdt.found() and cc.links('''
2049 #include <libfdt.h>
2050 #include <libfdt_env.h>
2051 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
2052 dependencies: fdt)
2053 fdt_opt = 'system'
2054 elif fdt_opt != 'system'
2055 fdt_opt = get_option('wrap_mode') == 'nodownload' ? 'disabled' : 'internal'
2056 fdt = not_found
2057 else
2058 error('system libfdt is too old (1.5.1 or newer required)')
2059 endif
2060 endif
2061 if fdt_opt == 'internal'
2062 assert(not fdt.found())
2063 libfdt_proj = subproject('dtc', required: true,
2064 default_options: ['tools=false', 'yaml=disabled',
2065 'python=disabled', 'default_library=static'])
2066 fdt = libfdt_proj.get_variable('libfdt_dep')
2067 endif
2068
2069 rdma = not_found
2070 if not get_option('rdma').auto() or have_system
2071 rdma_libs = [cc.find_library('rdmacm', has_headers: ['rdma/rdma_cma.h'],
2072 required: get_option('rdma')),
2073 cc.find_library('ibverbs', required: get_option('rdma'))]
2074 rdma = declare_dependency(dependencies: rdma_libs)
2075 foreach lib: rdma_libs
2076 if not lib.found()
2077 rdma = not_found
2078 endif
2079 endforeach
2080 endif
2081
2082 cacard = not_found
2083 if not get_option('smartcard').auto() or have_system
2084 cacard = dependency('libcacard', required: get_option('smartcard'),
2085 version: '>=2.5.1', method: 'pkg-config')
2086 endif
2087 u2f = not_found
2088 if not get_option('u2f').auto() or have_system
2089 u2f = dependency('u2f-emu', required: get_option('u2f'),
2090 method: 'pkg-config')
2091 endif
2092 canokey = not_found
2093 if not get_option('canokey').auto() or have_system
2094 canokey = dependency('canokey-qemu', required: get_option('canokey'),
2095 method: 'pkg-config')
2096 endif
2097 usbredir = not_found
2098 if not get_option('usb_redir').auto() or have_system
2099 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
2100 version: '>=0.6', method: 'pkg-config')
2101 endif
2102 libusb = not_found
2103 if not get_option('libusb').auto() or have_system
2104 libusb = dependency('libusb-1.0', required: get_option('libusb'),
2105 version: '>=1.0.13', method: 'pkg-config')
2106 endif
2107
2108 libpmem = not_found
2109 if not get_option('libpmem').auto() or have_system
2110 libpmem = dependency('libpmem', required: get_option('libpmem'),
2111 method: 'pkg-config')
2112 endif
2113 libdaxctl = not_found
2114 if not get_option('libdaxctl').auto() or have_system
2115 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
2116 version: '>=57', method: 'pkg-config')
2117 endif
2118 tasn1 = not_found
2119 if gnutls.found()
2120 tasn1 = dependency('libtasn1',
2121 required: false,
2122 method: 'pkg-config')
2123 endif
2124 keyutils = not_found
2125 if not get_option('libkeyutils').auto() or have_block
2126 keyutils = dependency('libkeyutils', required: get_option('libkeyutils'),
2127 method: 'pkg-config')
2128 endif
2129
2130 has_gettid = cc.has_function('gettid')
2131
2132 # libselinux
2133 selinux = dependency('libselinux',
2134 required: get_option('selinux'),
2135 method: 'pkg-config')
2136
2137 # Malloc tests
2138
2139 malloc = []
2140 if get_option('malloc') == 'system'
2141 has_malloc_trim = \
2142 get_option('malloc_trim').allowed() and \
2143 cc.has_function('malloc_trim', prefix: '#include <malloc.h>')
2144 else
2145 has_malloc_trim = false
2146 malloc = cc.find_library(get_option('malloc'), required: true)
2147 endif
2148 if not has_malloc_trim and get_option('malloc_trim').enabled()
2149 if get_option('malloc') == 'system'
2150 error('malloc_trim not available on this platform.')
2151 else
2152 error('malloc_trim not available with non-libc memory allocator')
2153 endif
2154 endif
2155
2156 osdep_prefix = '''
2157 #ifndef _GNU_SOURCE
2158 #define _GNU_SOURCE
2159 #endif
2160
2161 #include <stddef.h>
2162 #include <sys/types.h>
2163
2164 #include <string.h>
2165 #include <limits.h>
2166 /* Put unistd.h before time.h as that triggers localtime_r/gmtime_r
2167 * function availability on recentish Mingw-w64 platforms. */
2168 #include <unistd.h>
2169 #include <time.h>
2170 #include <errno.h>
2171 #include <fcntl.h>
2172 '''
2173
2174 have_vhost_user_blk_server = get_option('vhost_user_blk_server') \
2175 .require(host_os == 'linux',
2176 error_message: 'vhost_user_blk_server requires linux') \
2177 .require(have_vhost_user,
2178 error_message: 'vhost_user_blk_server requires vhost-user support') \
2179 .disable_auto_if(not have_tools and not have_system) \
2180 .allowed()
2181
2182 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
2183 error('Cannot enable fuse-lseek while fuse is disabled')
2184 endif
2185
2186 fuse = dependency('fuse3', required: get_option('fuse'),
2187 version: '>=3.1', method: 'pkg-config')
2188
2189 fuse_lseek = not_found
2190 if get_option('fuse_lseek').allowed()
2191 if fuse.version().version_compare('>=3.8')
2192 # Dummy dependency
2193 fuse_lseek = declare_dependency()
2194 elif get_option('fuse_lseek').enabled()
2195 if fuse.found()
2196 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
2197 else
2198 error('fuse-lseek requires libfuse, which was not found')
2199 endif
2200 endif
2201 endif
2202
2203 have_libvduse = (host_os == 'linux')
2204 if get_option('libvduse').enabled()
2205 if host_os != 'linux'
2206 error('libvduse requires linux')
2207 endif
2208 elif get_option('libvduse').disabled()
2209 have_libvduse = false
2210 endif
2211
2212 have_vduse_blk_export = (have_libvduse and host_os == 'linux')
2213 if get_option('vduse_blk_export').enabled()
2214 if host_os != 'linux'
2215 error('vduse_blk_export requires linux')
2216 elif not have_libvduse
2217 error('vduse_blk_export requires libvduse support')
2218 endif
2219 elif get_option('vduse_blk_export').disabled()
2220 have_vduse_blk_export = false
2221 endif
2222
2223 # libbpf
2224 bpf_version = '1.1.0'
2225 libbpf = dependency('libbpf', version: '>=' + bpf_version, required: get_option('bpf'), method: 'pkg-config')
2226 if libbpf.found() and not cc.links('''
2227 #include <bpf/libbpf.h>
2228 #include <linux/bpf.h>
2229 int main(void)
2230 {
2231 // check flag availability
2232 int flag = BPF_F_MMAPABLE;
2233 bpf_object__destroy_skeleton(NULL);
2234 return 0;
2235 }''', dependencies: libbpf)
2236 libbpf = not_found
2237 if get_option('bpf').enabled()
2238 error('libbpf skeleton/mmaping test failed')
2239 else
2240 warning('libbpf skeleton/mmaping test failed, disabling')
2241 endif
2242 endif
2243
2244 # libxdp
2245 libxdp = not_found
2246 if not get_option('af_xdp').auto() or have_system
2247 if libbpf.found()
2248 libxdp = dependency('libxdp', required: get_option('af_xdp'),
2249 version: '>=1.4.0', method: 'pkg-config')
2250 else
2251 if get_option('af_xdp').enabled()
2252 error('libxdp requested, but libbpf is not available')
2253 endif
2254 endif
2255 endif
2256
2257 # libdw
2258 libdw = not_found
2259 if not get_option('libdw').auto() or \
2260 (not get_option('prefer_static') and (have_system or have_user))
2261 libdw = dependency('libdw',
2262 method: 'pkg-config',
2263 required: get_option('libdw'))
2264 endif
2265
2266 #################
2267 # config-host.h #
2268 #################
2269
2270 config_host_data = configuration_data()
2271
2272 config_host_data.set('CONFIG_HMP', have_hmp)
2273 config_host_data.set('CONFIG_HAVE_RUST', have_rust)
2274 audio_drivers_selected = []
2275 if have_system
2276 audio_drivers_available = {
2277 'alsa': alsa.found(),
2278 'coreaudio': coreaudio.found(),
2279 'dsound': dsound.found(),
2280 'jack': jack.found(),
2281 'oss': oss.found(),
2282 'pa': pulse.found(),
2283 'pipewire': pipewire.found(),
2284 'sdl': sdl.found(),
2285 'sndio': sndio.found(),
2286 }
2287 foreach k, v: audio_drivers_available
2288 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
2289 endforeach
2290
2291 # Default to native drivers first, OSS second, SDL third
2292 audio_drivers_priority = \
2293 [ 'pa', 'coreaudio', 'dsound', 'sndio', 'oss' ] + \
2294 (host_os == 'linux' ? [] : [ 'sdl' ])
2295 audio_drivers_default = []
2296 foreach k: audio_drivers_priority
2297 if audio_drivers_available[k]
2298 audio_drivers_default += k
2299 endif
2300 endforeach
2301
2302 foreach k: get_option('audio_drv_list')
2303 if k == 'default'
2304 audio_drivers_selected += audio_drivers_default
2305 elif not audio_drivers_available[k]
2306 error('Audio driver "@0@" not available.'.format(k))
2307 else
2308 audio_drivers_selected += k
2309 endif
2310 endforeach
2311 endif
2312 config_host_data.set('CONFIG_AUDIO_DRIVERS',
2313 '"' + '", "'.join(audio_drivers_selected) + '", ')
2314
2315 have_host_block_device = (host_os != 'darwin' or
2316 cc.has_header('IOKit/storage/IOMedia.h'))
2317
2318 dbus_display = get_option('dbus_display') \
2319 .require(gio.version().version_compare('>=2.64'),
2320 error_message: '-display dbus requires glib>=2.64') \
2321 .require(gdbus_codegen.found(),
2322 error_message: gdbus_codegen_error.format('-display dbus')) \
2323 .allowed()
2324
2325 have_qemu_vnc = get_option('qemu_vnc') \
2326 .require(have_tools,
2327 error_message: 'qemu-vnc requires tools support') \
2328 .require(dbus_display,
2329 error_message: 'qemu-vnc requires dbus-display support') \
2330 .require(vnc.found(),
2331 error_message: 'qemu-vnc requires vnc support') \
2332 .require(host_os != 'windows',
2333 error_message: 'qemu-vnc is not currently supported on Windows') \
2334 .allowed()
2335
2336 have_virtfs = get_option('virtfs') \
2337 .require(host_os == 'linux' or host_os == 'darwin' or host_os == 'freebsd',
2338 error_message: 'virtio-9p (virtfs) requires Linux or macOS or FreeBSD') \
2339 .require(host_os != 'darwin' or cc.has_function('pthread_fchdir_np'),
2340 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
2341 .require(host_os != 'linux' or libattr.found(),
2342 error_message: 'virtio-9p (virtfs) on Linux requires libattr-devel') \
2343 .disable_auto_if(not have_tools and not have_system) \
2344 .allowed()
2345
2346 qga_fsfreeze = false
2347 qga_fstrim = false
2348 if host_os == 'linux'
2349 if cc.has_header_symbol('linux/fs.h', 'FIFREEZE')
2350 qga_fsfreeze = true
2351 endif
2352 if cc.has_header_symbol('linux/fs.h', 'FITRIM')
2353 qga_fstrim = true
2354 endif
2355 elif host_os == 'freebsd' and cc.has_header_symbol('ufs/ffs/fs.h', 'UFSSUSPEND')
2356 qga_fsfreeze = true
2357 endif
2358
2359 if get_option('block_drv_ro_whitelist') == ''
2360 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', '')
2361 else
2362 config_host_data.set('CONFIG_BDRV_RO_WHITELIST',
2363 '"' + get_option('block_drv_ro_whitelist').replace(',', '", "') + '", ')
2364 endif
2365 if get_option('block_drv_rw_whitelist') == ''
2366 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', '')
2367 else
2368 config_host_data.set('CONFIG_BDRV_RW_WHITELIST',
2369 '"' + get_option('block_drv_rw_whitelist').replace(',', '", "') + '", ')
2370 endif
2371
2372 foreach k : get_option('trace_backends')
2373 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
2374 endforeach
2375 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
2376 config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority'))
2377 if iasl.found()
2378 config_host_data.set_quoted('CONFIG_IASL', iasl.full_path())
2379 endif
2380 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
2381 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
2382 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
2383 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
2384 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
2385
2386 qemu_firmwarepath = ''
2387 foreach k : get_option('qemu_firmwarepath')
2388 qemu_firmwarepath += '"' + get_option('prefix') / k + '", '
2389 endforeach
2390 config_host_data.set('CONFIG_QEMU_FIRMWAREPATH', qemu_firmwarepath)
2391
2392 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
2393 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
2394 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
2395 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
2396 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
2397 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
2398
2399 if enable_modules
2400 config_host_data.set('CONFIG_STAMP', run_command(
2401 meson.current_source_dir() / 'scripts/qemu-stamp.py',
2402 meson.project_version(), get_option('pkgversion'), '--',
2403 meson.current_source_dir() / 'configure',
2404 capture: true, check: true).stdout().strip())
2405 endif
2406
2407 have_slirp_smbd = get_option('slirp_smbd') \
2408 .require(host_os != 'windows', error_message: 'Host smbd not supported on this platform.') \
2409 .allowed()
2410 if have_slirp_smbd
2411 smbd_path = get_option('smbd')
2412 if smbd_path == ''
2413 smbd_path = (host_os == 'sunos' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
2414 endif
2415 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
2416 endif
2417
2418 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
2419
2420 kvm_targets_c = '""'
2421 if get_option('kvm').allowed() and host_os == 'linux'
2422 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
2423 endif
2424 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
2425
2426 if get_option('module_upgrades') and not enable_modules
2427 error('Cannot enable module-upgrades as modules are not enabled')
2428 endif
2429 config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades'))
2430
2431 config_host_data.set('CONFIG_ATTR', libattr.found())
2432 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
2433 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
2434 config_host_data.set('CONFIG_BSD', host_os in bsd_oses)
2435 config_host_data.set('CONFIG_FREEBSD', host_os == 'freebsd')
2436 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2437 config_host_data.set('CONFIG_COCOA', cocoa.found())
2438 config_host_data.set('CONFIG_DARWIN', host_os == 'darwin')
2439 config_host_data.set('CONFIG_FDT', fdt.found())
2440 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
2441 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
2442 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
2443 config_host_data.set('CONFIG_LINUX', host_os == 'linux')
2444 config_host_data.set('CONFIG_POSIX', host_os != 'windows')
2445 config_host_data.set('CONFIG_WIN32', host_os == 'windows')
2446 config_host_data.set('CONFIG_LZO', lzo.found())
2447 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
2448 config_host_data.set('CONFIG_BLKIO', blkio.found())
2449 if blkio.found()
2450 config_host_data.set('CONFIG_BLKIO_VHOST_VDPA_FD',
2451 blkio.version().version_compare('>=1.3.0'))
2452 config_host_data.set('CONFIG_BLKIO_WRITE_ZEROS_FUA',
2453 blkio.version().version_compare('>=1.4.0'))
2454 endif
2455 config_host_data.set('CONFIG_CURL', curl.found())
2456 config_host_data.set('CONFIG_CURSES', curses.found())
2457 config_host_data.set('CONFIG_GBM', gbm.found())
2458 config_host_data.set('CONFIG_GIO', gio.found())
2459 config_host_data.set('CONFIG_GTK', gtk.found())
2460 config_host_data.set('CONFIG_VTE', vte.found())
2461 config_host_data.set('CONFIG_HEXAGON_IDEF_PARSER', get_option('hexagon_idef_parser'))
2462 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
2463 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
2464 config_host_data.set('CONFIG_EBPF', libbpf.found())
2465 config_host_data.set('CONFIG_AF_XDP', libxdp.found())
2466 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
2467 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
2468 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
2469 config_host_data.set('CONFIG_LIBSSH', libssh.found())
2470 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
2471 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
2472 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
2473 config_host_data.set('CONFIG_MODULES', enable_modules)
2474 config_host_data.set('CONFIG_NUMA', numa.found())
2475 if numa.found()
2476 config_host_data.set('HAVE_NUMA_HAS_PREFERRED_MANY',
2477 cc.has_function('numa_has_preferred_many',
2478 dependencies: numa))
2479 endif
2480 config_host_data.set('CONFIG_OPENGL', opengl.found())
2481 config_host_data.set('CONFIG_PLUGIN', get_option('plugins'))
2482 config_host_data.set('CONFIG_RBD', rbd.found())
2483 config_host_data.set('CONFIG_RDMA', rdma.found())
2484 config_host_data.set('CONFIG_RELOCATABLE', get_option('relocatable'))
2485 config_host_data.set('CONFIG_SAFESTACK', get_option('safe_stack'))
2486 config_host_data.set('CONFIG_SDL', sdl.found())
2487 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
2488 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
2489 if seccomp.found()
2490 config_host_data.set('CONFIG_SECCOMP_SYSRAWRC', seccomp_has_sysrawrc)
2491 endif
2492 config_host_data.set('CONFIG_PIXMAN', pixman.found())
2493 config_host_data.set('CONFIG_PASST', enable_passt)
2494 config_host_data.set('CONFIG_SLIRP', slirp.found())
2495 config_host_data.set('CONFIG_SNAPPY', snappy.found())
2496 config_host_data.set('CONFIG_SOLARIS', host_os == 'sunos')
2497 if have_tcg
2498 config_host_data.set('CONFIG_TCG', 1)
2499 config_host_data.set('CONFIG_TCG_INTERPRETER', tcg_arch == 'tci')
2500 endif
2501 config_host_data.set('CONFIG_TPM', have_tpm)
2502 config_host_data.set('CONFIG_TSAN', get_option('tsan'))
2503 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
2504 config_host_data.set('CONFIG_VDE', vde.found())
2505 config_host_data.set('CONFIG_VHOST', have_vhost)
2506 config_host_data.set('CONFIG_VHOST_NET', have_vhost_net)
2507 config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user)
2508 config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa)
2509 config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel)
2510 config_host_data.set('CONFIG_VHOST_USER', have_vhost_user)
2511 config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto)
2512 config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa)
2513 config_host_data.set('CONFIG_VMNET', vmnet.found())
2514 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
2515 config_host_data.set('CONFIG_VDUSE_BLK_EXPORT', have_vduse_blk_export)
2516 config_host_data.set('CONFIG_PNG', png.found())
2517 config_host_data.set('CONFIG_VNC', vnc.found())
2518 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
2519 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
2520 if virgl.found()
2521 config_host_data.set('VIRGL_VERSION_MAJOR', virgl.version().split('.')[0])
2522 config_host_data.set('VIRGL_VERSION_MINOR', virgl.version().split('.')[1])
2523 config_host_data.set('VIRGL_VERSION_MICRO', virgl.version().split('.')[2])
2524 endif
2525 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
2526 config_host_data.set('CONFIG_VTE', vte.found())
2527 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
2528 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
2529 config_host_data.set('CONFIG_GETTID', has_gettid)
2530 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
2531 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
2532 config_host_data.set('CONFIG_GNUTLS_BUG1717_WORKAROUND', gnutls_bug1717_workaround)
2533 config_host_data.set('CONFIG_TASN1', tasn1.found())
2534 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
2535 config_host_data.set('CONFIG_NETTLE', nettle.found())
2536 config_host_data.set('CONFIG_CRYPTO_SM4', crypto_sm4.found())
2537 config_host_data.set('CONFIG_CRYPTO_SM3', crypto_sm3.found())
2538 config_host_data.set('CONFIG_HOGWEED', hogweed.found())
2539 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
2540 config_host_data.set('CONFIG_ZSTD', zstd.found())
2541 config_host_data.set('CONFIG_QPL', qpl.found())
2542 config_host_data.set('CONFIG_UADK', uadk.found())
2543 config_host_data.set('CONFIG_QATZIP', qatzip.found())
2544 config_host_data.set('CONFIG_FUSE', fuse.found())
2545 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
2546 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
2547 if spice_protocol.found()
2548 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
2549 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
2550 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
2551 endif
2552 config_host_data.set('CONFIG_SPICE', spice.found())
2553 config_host_data.set('CONFIG_X11', x11.found())
2554 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
2555 config_host_data.set('CONFIG_CFI', get_option('cfi'))
2556 config_host_data.set('CONFIG_SELINUX', selinux.found())
2557 config_host_data.set('CONFIG_XEN_BACKEND', xen.found())
2558 config_host_data.set('CONFIG_LIBDW', libdw.found())
2559 config_host_data.set('CONFIG_IGVM', igvm.found())
2560 if xen.found()
2561 # protect from xen.version() having less than three components
2562 xen_version = xen.version().split('.') + ['0', '0']
2563 xen_ctrl_version = xen_version[0] + \
2564 ('0' + xen_version[1]).substring(-2) + \
2565 ('0' + xen_version[2]).substring(-2)
2566 config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version)
2567 endif
2568 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
2569 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
2570 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
2571 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
2572
2573 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
2574 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
2575
2576 have_coroutine_pool = get_option('coroutine_pool')
2577 if get_option('debug_stack_usage') and have_coroutine_pool
2578 message('Disabling coroutine pool to measure stack usage')
2579 have_coroutine_pool = false
2580 endif
2581 config_host_data.set('CONFIG_COROUTINE_POOL', have_coroutine_pool)
2582 config_host_data.set('CONFIG_DEBUG_GRAPH_LOCK', get_option('debug_graph_lock'))
2583 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
2584 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
2585 config_host_data.set('CONFIG_DEBUG_TCG', get_option('debug_tcg'))
2586 config_host_data.set('CONFIG_DEBUG_REMAP', get_option('debug_remap'))
2587 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
2588 config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed())
2589 config_host_data.set('CONFIG_FSFREEZE', qga_fsfreeze)
2590 config_host_data.set('CONFIG_FSTRIM', qga_fstrim)
2591
2592 # has_header
2593 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
2594 valgrind = false
2595 if get_option('valgrind').allowed()
2596 if cc.has_header('valgrind/valgrind.h')
2597 valgrind = true
2598 else
2599 if get_option('valgrind').enabled()
2600 error('valgrind requested but valgrind.h not found')
2601 endif
2602 endif
2603 endif
2604 config_host_data.set('CONFIG_VALGRIND_H', valgrind)
2605 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
2606 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
2607 config_host_data.set('HAVE_OPENAT2_H', cc.has_header('linux/openat2.h'))
2608 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
2609 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
2610 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
2611 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
2612 if host_os == 'windows'
2613 config_host_data.set('HAVE_AFUNIX_H', cc.has_header('afunix.h'))
2614 endif
2615
2616 # has_function
2617 config_host_data.set('CONFIG_CLOSE_RANGE', cc.has_function('close_range', prefix: '#include <unistd.h>'))
2618 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
2619 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
2620 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
2621 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
2622 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
2623 config_host_data.set('CONFIG_SCHED_GETCPU', cc.has_function('sched_getcpu', prefix: '#include <sched.h>'))
2624 # Note that we need to specify prefix: here to avoid incorrectly
2625 # thinking that Windows has posix_memalign()
2626 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
2627 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
2628 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
2629 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
2630 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
2631 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
2632 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
2633 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
2634 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
2635 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
2636 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
2637 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
2638 config_host_data.set('CONFIG_GETLOADAVG', cc.has_function('getloadavg'))
2639 config_host_data.set('CONFIG_ARPA_INET_64', cc.has_function('htonll'))
2640 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
2641 config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
2642 config_host_data.set('HAVE_GLIB_WITH_SLICE_ALLOCATOR', glib_has_gslice)
2643 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
2644 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul', prefix: osdep_prefix))
2645 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
2646 if rbd.found()
2647 config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS',
2648 cc.has_function('rbd_namespace_exists',
2649 dependencies: rbd,
2650 prefix: '#include <rbd/librbd.h>'))
2651 endif
2652 if rdma.found()
2653 config_host_data.set('HAVE_IBV_ADVISE_MR',
2654 cc.has_function('ibv_advise_mr',
2655 dependencies: rdma,
2656 prefix: '#include <infiniband/verbs.h>'))
2657 endif
2658
2659 have_asan_fiber = false
2660 if get_option('asan') and \
2661 not cc.has_function('__sanitizer_start_switch_fiber',
2662 args: '-fsanitize=address',
2663 prefix: '#include <sanitizer/asan_interface.h>')
2664 warning('Missing ASAN due to missing fiber annotation interface')
2665 warning('Without code annotation, the report may be inferior.')
2666 else
2667 have_asan_fiber = true
2668 endif
2669 config_host_data.set('CONFIG_ASAN_IFACE_FIBER', have_asan_fiber)
2670
2671 inotify = not_found
2672 have_inotify_init1 = cc.has_header_symbol('sys/inotify.h', 'inotify_init1')
2673 if have_inotify_init1 and not cc.has_function('inotify_init1')
2674 # FreeBSD 14 and older need libinotify-kqueue wrapper
2675 inotify = cc.find_library('inotify')
2676 have_inotify_init1 = inotify.found()
2677 endif
2678 config_host_data.set('CONFIG_INOTIFY1', have_inotify_init1)
2679
2680 # has_header_symbol
2681 config_host_data.set('CONFIG_BLKZONED',
2682 cc.has_header_symbol('linux/blkzoned.h', 'BLKOPENZONE'))
2683 config_host_data.set('CONFIG_EPOLL', host_os == 'linux')
2684 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
2685 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
2686 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
2687 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
2688 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
2689 config_host_data.set('CONFIG_FIEMAP',
2690 cc.has_header('linux/fiemap.h') and
2691 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
2692 config_host_data.set('CONFIG_GETCPU',
2693 cc.has_header_symbol('sched.h', 'getcpu', prefix: osdep_prefix))
2694 config_host_data.set('CONFIG_GETRANDOM',
2695 cc.has_function('getrandom') and
2696 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
2697 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
2698 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
2699 config_host_data.set('CONFIG_RTNETLINK',
2700 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
2701 config_host_data.set('CONFIG_SYSMACROS',
2702 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
2703 config_host_data.set('HAVE_OPTRESET',
2704 cc.has_header_symbol('getopt.h', 'optreset'))
2705 config_host_data.set('HAVE_IPPROTO_MPTCP',
2706 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
2707 if libaio.found()
2708 config_host_data.set('HAVE_IO_PREP_PWRITEV2',
2709 cc.has_header_symbol('libaio.h', 'io_prep_pwritev2'))
2710 endif
2711 if linux_io_uring.found()
2712 config_host_data.set('HAVE_IO_URING_PREP_WRITEV2',
2713 cc.has_header_symbol('liburing.h', 'io_uring_prep_writev2'))
2714 config_host_data.set('HAVE_IO_URING_CQ_HAS_OVERFLOW',
2715 cc.has_header_symbol('liburing.h', 'io_uring_cq_has_overflow'))
2716 endif
2717 config_host_data.set('HAVE_TCP_KEEPCNT',
2718 cc.has_header_symbol('netinet/tcp.h', 'TCP_KEEPCNT') or
2719 cc.compiles('''
2720 #include <ws2tcpip.h>
2721 #ifndef TCP_KEEPCNT
2722 #error
2723 #endif
2724 int main(void) { return 0; }''',
2725 name: 'Win32 TCP_KEEPCNT'))
2726 # On Darwin TCP_KEEPIDLE is available under different name, TCP_KEEPALIVE.
2727 # https://github.com/apple/darwin-xnu/blob/xnu-4570.1.46/bsd/man/man4/tcp.4#L172
2728 config_host_data.set('HAVE_TCP_KEEPIDLE',
2729 cc.has_header_symbol('netinet/tcp.h', 'TCP_KEEPIDLE') or
2730 cc.has_header_symbol('netinet/tcp.h', 'TCP_KEEPALIVE') or
2731 cc.compiles('''
2732 #include <ws2tcpip.h>
2733 #ifndef TCP_KEEPIDLE
2734 #error
2735 #endif
2736 int main(void) { return 0; }''',
2737 name: 'Win32 TCP_KEEPIDLE'))
2738 config_host_data.set('HAVE_TCP_KEEPINTVL',
2739 cc.has_header_symbol('netinet/tcp.h', 'TCP_KEEPINTVL') or
2740 cc.compiles('''
2741 #include <ws2tcpip.h>
2742 #ifndef TCP_KEEPINTVL
2743 #error
2744 #endif
2745 int main(void) { return 0; }''',
2746 name: 'Win32 TCP_KEEPINTVL'))
2747
2748 # has_member
2749 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
2750 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
2751 prefix: '#include <signal.h>'))
2752 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
2753 cc.has_member('struct stat', 'st_atim',
2754 prefix: '#include <sys/stat.h>'))
2755 config_host_data.set('HAVE_BLK_ZONE_REP_CAPACITY',
2756 cc.has_member('struct blk_zone', 'capacity',
2757 prefix: '#include <linux/blkzoned.h>'))
2758
2759 # has_type
2760 config_host_data.set('CONFIG_IOVEC',
2761 cc.has_type('struct iovec',
2762 prefix: '#include <sys/uio.h>'))
2763 config_host_data.set('HAVE_UTMPX',
2764 cc.has_type('struct utmpx',
2765 prefix: '#include <utmpx.h>'))
2766
2767 config_host_data.set('CONFIG_EVENTFD', cc.links('''
2768 #include <sys/eventfd.h>
2769 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
2770 config_host_data.set('CONFIG_FDATASYNC', cc.links(osdep_prefix + '''
2771 int main(void) {
2772 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
2773 return fdatasync(0);
2774 #else
2775 #error Not supported
2776 #endif
2777 }'''))
2778
2779 has_madvise = cc.links(osdep_prefix + '''
2780 #include <sys/mman.h>
2781 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
2782 missing_madvise_proto = false
2783 if has_madvise
2784 # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
2785 # but forget to prototype it. In this case, has_madvise will be true (the
2786 # test program links despite a compile warning). To detect the
2787 # missing-prototype case, we try again with a definitely-bogus prototype.
2788 # This will only compile if the system headers don't provide the prototype;
2789 # otherwise the conflicting prototypes will cause a compiler error.
2790 missing_madvise_proto = cc.links(osdep_prefix + '''>
2791 #include <sys/mman.h>
2792 extern int madvise(int);
2793 int main(void) { return madvise(0); }''')
2794 endif
2795 config_host_data.set('CONFIG_MADVISE', has_madvise)
2796 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
2797
2798 config_host_data.set('CONFIG_MEMFD', cc.links(osdep_prefix + '''
2799 #include <sys/mman.h>
2800 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
2801 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(osdep_prefix + '''
2802 #if !defined(AT_EMPTY_PATH)
2803 # error missing definition
2804 #else
2805 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
2806 #endif'''))
2807
2808 # On Darwin posix_madvise() has the same return semantics as plain madvise(),
2809 # i.e. errno is set and -1 is returned. That's not really how POSIX defines the
2810 # function. On the flip side, it has madvise() which is preferred anyways.
2811 if host_os != 'darwin'
2812 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(osdep_prefix + '''
2813 #include <sys/mman.h>
2814 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
2815 endif
2816
2817 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(osdep_prefix + '''
2818 #include <pthread.h>
2819
2820 static void *f(void *p) { return NULL; }
2821 int main(void)
2822 {
2823 pthread_t thread;
2824 pthread_create(&thread, 0, f, 0);
2825 pthread_setname_np(thread, "QEMU");
2826 return 0;
2827 }''', dependencies: threads))
2828 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(osdep_prefix + '''
2829 #include <pthread.h>
2830
2831 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
2832 int main(void)
2833 {
2834 pthread_t thread;
2835 pthread_create(&thread, 0, f, 0);
2836 return 0;
2837 }''', dependencies: threads))
2838 config_host_data.set('CONFIG_PTHREAD_SET_NAME_NP', cc.links(osdep_prefix + '''
2839 #include <pthread.h>
2840 #include <pthread_np.h>
2841
2842 static void *f(void *p) { return NULL; }
2843 int main(void)
2844 {
2845 pthread_t thread;
2846 pthread_create(&thread, 0, f, 0);
2847 pthread_set_name_np(thread, "QEMU");
2848 return 0;
2849 }''', dependencies: threads))
2850
2851 config_host_data.set('CONFIG_PTHREAD_GETNAME_NP', cc.links(osdep_prefix + '''
2852 #include <pthread.h>
2853
2854 int main(void)
2855 {
2856 char buf[16];
2857 pthread_getname_np(pthread_self(), buf, sizeof(buf));
2858 return 0;
2859 }''', dependencies: threads))
2860 config_host_data.set('CONFIG_PTHREAD_GET_NAME_NP', cc.links(osdep_prefix + '''
2861 #include <pthread.h>
2862 #include <pthread_np.h>
2863
2864 int main(void)
2865 {
2866 char buf[16];
2867 pthread_get_name_np(pthread_self(), buf, sizeof(buf));
2868 return 0;
2869 }''', dependencies: threads))
2870
2871 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(osdep_prefix + '''
2872 #include <pthread.h>
2873
2874 int main(void)
2875 {
2876 pthread_condattr_t attr;
2877 pthread_condattr_init(&attr);
2878 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
2879 return 0;
2880 }''', dependencies: threads))
2881 config_host_data.set('CONFIG_PTHREAD_AFFINITY_NP', cc.links(osdep_prefix + '''
2882 #include <pthread.h>
2883
2884 static void *f(void *p) { return NULL; }
2885 int main(void)
2886 {
2887 int setsize = CPU_ALLOC_SIZE(64);
2888 pthread_t thread;
2889 cpu_set_t *cpuset;
2890 pthread_create(&thread, 0, f, 0);
2891 cpuset = CPU_ALLOC(64);
2892 CPU_ZERO_S(setsize, cpuset);
2893 pthread_setaffinity_np(thread, setsize, cpuset);
2894 pthread_getaffinity_np(thread, setsize, cpuset);
2895 CPU_FREE(cpuset);
2896 return 0;
2897 }''', dependencies: threads))
2898 config_host_data.set('CONFIG_SIGNALFD', cc.links(osdep_prefix + '''
2899 #include <sys/signalfd.h>
2900 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
2901
2902 config_host_data.set('HAVE_MLOCKALL', cc.links(osdep_prefix + '''
2903 #include <sys/mman.h>
2904 int main(void) {
2905 return mlockall(MCL_FUTURE);
2906 }'''))
2907
2908 config_host_data.set('HAVE_MLOCK_ONFAULT', cc.links(osdep_prefix + '''
2909 #include <sys/mman.h>
2910 int main(void) {
2911 return mlockall(MCL_FUTURE | MCL_ONFAULT);
2912 }'''))
2913
2914 have_l2tpv3 = false
2915 if get_option('l2tpv3').allowed() and have_system
2916 have_l2tpv3 = cc.has_type('struct mmsghdr',
2917 prefix: osdep_prefix + '''
2918 #include <sys/socket.h>
2919 #include <linux/ip.h>''')
2920 endif
2921 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
2922
2923 have_netmap = false
2924 if get_option('netmap').allowed() and have_system
2925 have_netmap = cc.compiles('''
2926 #include <inttypes.h>
2927 #include <net/if.h>
2928 #include <net/netmap.h>
2929 #include <net/netmap_user.h>
2930 #if (NETMAP_API < 11) || (NETMAP_API > 15)
2931 #error
2932 #endif
2933 int main(void) { return 0; }''')
2934 if not have_netmap and get_option('netmap').enabled()
2935 error('Netmap headers not available')
2936 endif
2937 endif
2938 config_host_data.set('CONFIG_NETMAP', have_netmap)
2939
2940 # Work around a system header bug with some kernel/XFS header
2941 # versions where they both try to define 'struct fsxattr':
2942 # xfs headers will not try to redefine structs from linux headers
2943 # if this macro is set.
2944 config_host_data.set('HAVE_FSXATTR', cc.links('''
2945 #include <linux/fs.h>
2946 struct fsxattr foo;
2947 int main(void) {
2948 return 0;
2949 }'''))
2950
2951 # Some versions of Mac OS X incorrectly define SIZE_MAX
2952 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
2953 #include <stdint.h>
2954 #include <stdio.h>
2955 int main(void) {
2956 return printf("%zu", SIZE_MAX);
2957 }''', args: ['-Werror']))
2958
2959 # has_int128_type is set to false on Emscripten to avoid errors by libffi
2960 # during runtime.
2961 has_int128_type = host_os != 'emscripten' and cc.compiles('''
2962 __int128_t a;
2963 __uint128_t b;
2964 int main(void) { b = a; }''')
2965 config_host_data.set('CONFIG_INT128_TYPE', has_int128_type)
2966
2967 has_int128 = has_int128_type and cc.links('''
2968 __int128_t a;
2969 __uint128_t b;
2970 int main (void) {
2971 a = a + b;
2972 b = a * b;
2973 a = a * a;
2974 return 0;
2975 }''')
2976 config_host_data.set('CONFIG_INT128', has_int128)
2977
2978 if has_int128_type
2979 # "do we have 128-bit atomics which are handled inline and specifically not
2980 # via libatomic". The reason we can't use libatomic is documented in the
2981 # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
2982 # We only care about these operations on 16-byte aligned pointers, so
2983 # force 16-byte alignment of the pointer, which may be greater than
2984 # __alignof(unsigned __int128) for the host.
2985 atomic_test_128 = '''
2986 int main(int ac, char **av) {
2987 __uint128_t *p = __builtin_assume_aligned(av[ac - 1], 16);
2988 p[1] = __atomic_load_n(&p[0], __ATOMIC_RELAXED);
2989 __atomic_store_n(&p[2], p[3], __ATOMIC_RELAXED);
2990 __atomic_compare_exchange_n(&p[4], &p[5], p[6], 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2991 return 0;
2992 }'''
2993 has_atomic128 = cc.links(atomic_test_128, args: qemu_isa_flags)
2994
2995 config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
2996
2997 if not has_atomic128
2998 # Even with __builtin_assume_aligned, the above test may have failed
2999 # without optimization enabled. Try again with optimizations locally
3000 # enabled for the function. See
3001 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107389
3002 has_atomic128_opt = cc.links('__attribute__((optimize("O1")))' + atomic_test_128,
3003 args: qemu_isa_flags)
3004 config_host_data.set('CONFIG_ATOMIC128_OPT', has_atomic128_opt)
3005
3006 if not has_atomic128_opt
3007 config_host_data.set('CONFIG_CMPXCHG128', cc.links('''
3008 int main(void)
3009 {
3010 __uint128_t x = 0, y = 0;
3011 __sync_val_compare_and_swap_16(&x, y, x);
3012 return 0;
3013 }
3014 ''', args: qemu_isa_flags))
3015 endif
3016 endif
3017 endif
3018
3019 config_host_data.set('CONFIG_GETAUXVAL', cc.links(osdep_prefix + '''
3020 #include <sys/auxv.h>
3021 int main(void) {
3022 return getauxval(AT_HWCAP) == 0;
3023 }'''))
3024
3025 config_host_data.set('CONFIG_ELF_AUX_INFO', cc.links(osdep_prefix + '''
3026 #include <sys/auxv.h>
3027 int main(void) {
3028 unsigned long hwcap = 0;
3029 elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap));
3030 return hwcap;
3031 }'''))
3032
3033 config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
3034 #include <linux/usbdevice_fs.h>
3035
3036 #ifndef USBDEVFS_GET_CAPABILITIES
3037 #error "USBDEVFS_GET_CAPABILITIES undefined"
3038 #endif
3039
3040 #ifndef USBDEVFS_DISCONNECT_CLAIM
3041 #error "USBDEVFS_DISCONNECT_CLAIM undefined"
3042 #endif
3043
3044 int main(void) { return 0; }'''))
3045
3046 have_keyring = get_option('keyring') \
3047 .require(host_os == 'linux', error_message: 'keyring is only available on Linux') \
3048 .require(cc.compiles('''
3049 #include <errno.h>
3050 #include <asm/unistd.h>
3051 #include <linux/keyctl.h>
3052 #include <sys/syscall.h>
3053 #include <unistd.h>
3054 int main(void) {
3055 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
3056 }'''), error_message: 'keyctl syscall not available on this system').allowed()
3057 config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring)
3058
3059 have_cpuid_h = cc.links('''
3060 #include <cpuid.h>
3061 int main(void) {
3062 unsigned a, b, c, d;
3063 unsigned max = __get_cpuid_max(0, 0);
3064
3065 if (max >= 1) {
3066 __cpuid(1, a, b, c, d);
3067 }
3068
3069 if (max >= 7) {
3070 __cpuid_count(7, 0, a, b, c, d);
3071 }
3072
3073 return 0;
3074 }''')
3075 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
3076
3077 # Don't bother to advertise asm/hwprobe.h for old versions that do
3078 # not contain RISCV_HWPROBE_EXT_ZBA.
3079 config_host_data.set('CONFIG_ASM_HWPROBE_H',
3080 cc.has_header_symbol('asm/hwprobe.h',
3081 'RISCV_HWPROBE_EXT_ZBA'))
3082
3083 if have_cpuid_h
3084 have_avx2 = cc.links('''
3085 #include <immintrin.h>
3086 static int __attribute__((target("avx2"))) bar(void *a) {
3087 __m256i x = *(__m256i *)a;
3088 return _mm256_testz_si256(x, x);
3089 }
3090 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
3091 ''')
3092 have_avx512bw = cc.links('''
3093 #include <immintrin.h>
3094 static int __attribute__((target("avx512bw"))) bar(void *a) {
3095 __m512i *x = a;
3096 __m512i res= _mm512_abs_epi8(*x);
3097 return res[1];
3098 }
3099 int main(int argc, char *argv[]) { return bar(argv[0]); }
3100 ''')
3101 if get_option('x86_version') >= '3' and not have_avx2
3102 error('Cannot enable AVX optimizations due to missing intrinsics')
3103 elif get_option('x86_version') >= '4' and not have_avx512bw
3104 error('Cannot enable AVX512 optimizations due to missing intrinsics')
3105 endif
3106 else
3107 have_avx2 = false
3108 have_avx512bw = false
3109 if get_option('x86_version') >= '3'
3110 error('Cannot enable AVX optimizations due to missing cpuid.h')
3111 endif
3112 endif
3113 config_host_data.set('CONFIG_AVX2_OPT', have_avx2)
3114 config_host_data.set('CONFIG_AVX512BW_OPT', have_avx512bw)
3115
3116 # For AArch64, detect if builtins are available.
3117 config_host_data.set('CONFIG_ARM_AES_BUILTIN', cc.compiles('''
3118 #include <arm_neon.h>
3119 #ifndef __ARM_FEATURE_AES
3120 __attribute__((target("+crypto")))
3121 #endif
3122 void foo(uint8x16_t *p) { *p = vaesmcq_u8(*p); }
3123 '''))
3124
3125 if get_option('membarrier').disabled()
3126 have_membarrier = false
3127 elif host_os == 'windows'
3128 have_membarrier = true
3129 elif host_os == 'linux'
3130 have_membarrier = cc.compiles('''
3131 #include <linux/membarrier.h>
3132 #include <sys/syscall.h>
3133 #include <unistd.h>
3134 #include <stdlib.h>
3135 int main(void) {
3136 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
3137 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
3138 exit(0);
3139 }''')
3140 endif
3141 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
3142 .require(have_membarrier, error_message: 'membarrier system call not available') \
3143 .allowed())
3144
3145 have_afalg = get_option('crypto_afalg') \
3146 .require(cc.compiles(osdep_prefix + '''
3147 #include <sys/socket.h>
3148 #include <linux/if_alg.h>
3149 int main(void) {
3150 int sock;
3151 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
3152 return sock;
3153 }
3154 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
3155 config_host_data.set('CONFIG_AF_ALG', have_afalg)
3156
3157 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
3158 'linux/vm_sockets.h', 'AF_VSOCK',
3159 prefix: '#include <sys/socket.h>',
3160 ))
3161
3162 have_vss = false
3163 have_vss_sdk = false # old xp/2003 SDK
3164 if host_os == 'windows' and 'cpp' in all_languages
3165 have_vss = cxx.compiles('''
3166 #define __MIDL_user_allocate_free_DEFINED__
3167 #include <vss.h>
3168 int main(void) { return VSS_CTX_BACKUP; }''')
3169 have_vss_sdk = cxx.has_header('vscoordint.h')
3170 endif
3171 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
3172
3173 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
3174 # This was fixed for v6.0.0 with commit b48e3ac8969d.
3175 if host_os == 'windows'
3176 config_host_data.set('HAVE__LOCK_FILE', cc.links('''
3177 #include <stdio.h>
3178 int main(void) {
3179 _lock_file(NULL);
3180 _unlock_file(NULL);
3181 return 0;
3182 }''', name: '_lock_file and _unlock_file'))
3183 endif
3184
3185 if spice.found()
3186 config_host_data.set('HAVE_SPICE_QXL_GL_SCANOUT2',
3187 cc.has_function('spice_qxl_gl_scanout2', dependencies: spice))
3188 endif
3189
3190 if host_os == 'windows'
3191 mingw_has_setjmp_longjmp = cc.links('''
3192 #include <setjmp.h>
3193 int main(void) {
3194 /*
3195 * These functions are not available in setjmp header, but may be
3196 * available at link time, from libmingwex.a.
3197 */
3198 extern int __mingw_setjmp(jmp_buf);
3199 extern void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int);
3200 jmp_buf env;
3201 __mingw_setjmp(env);
3202 __mingw_longjmp(env, 0);
3203 }
3204 ''', name: 'mingw setjmp and longjmp')
3205
3206 if cpu == 'aarch64' and not mingw_has_setjmp_longjmp
3207 error('mingw must provide setjmp/longjmp for windows-arm64')
3208 endif
3209 endif
3210
3211 # Detect if ConvertStringToBSTR has been defined in _com_util namespace
3212 if host_os == 'windows' and 'cpp' in all_languages
3213 has_convert_string_to_bstr = cxx.links('''
3214 #include <comutil.h>
3215 int main() {
3216 BSTR b = _com_util::ConvertStringToBSTR("test");
3217 return b ? 0 : 1;
3218 }
3219 ''')
3220 config_host_data.set('CONFIG_CONVERT_STRING_TO_BSTR', has_convert_string_to_bstr)
3221 endif
3222
3223 ########################
3224 # Target configuration #
3225 ########################
3226
3227 minikconf = find_program('scripts/minikconf.py')
3228
3229 config_all_accel = {}
3230 config_all_devices = {}
3231 config_devices_mak_list = []
3232 config_devices_h = {}
3233 config_target_h = {}
3234 config_target_mak = {}
3235 config_base_arch_mak = {}
3236 config_target_info = {}
3237
3238 disassemblers = {
3239 'alpha' : ['CONFIG_ALPHA_DIS'],
3240 'avr' : ['CONFIG_AVR_DIS'],
3241 'hexagon' : ['CONFIG_HEXAGON_DIS'],
3242 'hppa' : ['CONFIG_HPPA_DIS'],
3243 'i386' : ['CONFIG_I386_DIS'],
3244 'x86_64' : ['CONFIG_I386_DIS'],
3245 'm68k' : ['CONFIG_M68K_DIS'],
3246 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
3247 'mips' : ['CONFIG_MIPS_DIS'],
3248 'or1k' : ['CONFIG_OPENRISC_DIS'],
3249 'ppc' : ['CONFIG_PPC_DIS'],
3250 'riscv' : ['CONFIG_RISCV_DIS'],
3251 'rx' : ['CONFIG_RX_DIS'],
3252 's390' : ['CONFIG_S390_DIS'],
3253 'sh4' : ['CONFIG_SH4_DIS'],
3254 'sparc' : ['CONFIG_SPARC_DIS'],
3255 'xtensa' : ['CONFIG_XTENSA_DIS'],
3256 'loongarch' : ['CONFIG_LOONGARCH_DIS'],
3257 }
3258
3259 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
3260 host_kconfig = \
3261 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
3262 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
3263 (pixman.found() ? ['CONFIG_PIXMAN=y'] : []) + \
3264 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
3265 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
3266 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
3267 (libcbor.found() ? ['CONFIG_LIBCBOR=y'] : []) + \
3268 (gnutls.found() ? ['CONFIG_GNUTLS=y'] : []) + \
3269 (x11.found() ? ['CONFIG_X11=y'] : []) + \
3270 (fdt.found() ? ['CONFIG_FDT=y'] : []) + \
3271 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \
3272 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \
3273 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
3274 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
3275 (host_os == 'linux' ? ['CONFIG_LINUX=y'] : []) + \
3276 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \
3277 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : []) + \
3278 (hv_balloon ? ['CONFIG_HV_BALLOON_POSSIBLE=y'] : []) + \
3279 (have_rust ? ['CONFIG_HAVE_RUST=y'] : [])
3280
3281 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR' ]
3282
3283 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
3284 actual_target_dirs = []
3285 fdt_required = []
3286 foreach target : target_dirs
3287 config_target = { 'TARGET_NAME': target.split('-')[0] }
3288 if target.endswith('linux-user')
3289 if host_os != 'linux'
3290 if default_targets
3291 continue
3292 endif
3293 error('Target @0@ is only available on a Linux host'.format(target))
3294 endif
3295 config_target += { 'CONFIG_LINUX_USER': 'y' }
3296 elif target.endswith('bsd-user')
3297 if host_os not in bsd_oses
3298 if default_targets
3299 continue
3300 endif
3301 error('Target @0@ is only available on a BSD host'.format(target))
3302 endif
3303 config_target += { 'CONFIG_BSD_USER': 'y' }
3304 elif target.endswith('softmmu')
3305 config_target += { 'CONFIG_SYSTEM_ONLY': 'y' }
3306 config_target += { 'CONFIG_SOFTMMU': 'y' }
3307 endif
3308 if target.endswith('-user')
3309 config_target += {
3310 'CONFIG_USER_ONLY': 'y',
3311 'CONFIG_QEMU_INTERP_PREFIX':
3312 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME']),
3313 'CONFIG_QEMU_RTSIG_MAP': get_option('rtsig_map'),
3314 }
3315 endif
3316
3317 config_target += keyval.load('configs/targets' / target + '.mak')
3318
3319 target_kconfig = []
3320 foreach sym: accelerators
3321 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
3322 config_target += { sym: 'y' }
3323 config_all_accel += { sym: 'y' }
3324 target_kconfig += [ sym + '=y' ]
3325 endif
3326 endforeach
3327 if target_kconfig.length() == 0
3328 if default_targets
3329 continue
3330 endif
3331 error('No accelerator available for target @0@'.format(target))
3332 endif
3333
3334 if 'TARGET_NEED_FDT' in config_target and not fdt.found()
3335 if default_targets
3336 warning('Disabling ' + target + ' due to missing libfdt')
3337 else
3338 fdt_required += target
3339 endif
3340 continue
3341 endif
3342
3343 actual_target_dirs += target
3344
3345 # Add default keys
3346 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
3347 if 'TARGET_BASE_ARCH' not in config_target
3348 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
3349 endif
3350 if 'TARGET_ABI_DIR' not in config_target
3351 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
3352 endif
3353 if 'TARGET_BIG_ENDIAN' not in config_target
3354 config_target += {'TARGET_BIG_ENDIAN': 'n'}
3355 endif
3356
3357 foreach k, v: disassemblers
3358 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
3359 foreach sym: v
3360 config_target += { sym: 'y' }
3361 endforeach
3362 endif
3363 endforeach
3364
3365 config_target_data = configuration_data()
3366 foreach k, v: config_target
3367 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
3368 # do nothing
3369 elif ignored.contains(k)
3370 # do nothing
3371 elif k == 'TARGET_ARCH'
3372 config_target_data.set(k, v.to_upper())
3373 elif k == 'TARGET_BASE_ARCH'
3374 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
3375 # not used to select files from sourcesets.
3376 config_target_data.set('TARGET_' + v.to_upper(), 1)
3377 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
3378 config_target_data.set_quoted(k, v)
3379 elif v == 'y'
3380 config_target_data.set(k, 1)
3381 elif v == 'n'
3382 config_target_data.set(k, 0)
3383 else
3384 config_target_data.set(k, v)
3385 endif
3386 endforeach
3387 config_target_h += {target: configure_file(output: target + '-config-target.h',
3388 configuration: config_target_data)}
3389
3390 if target.endswith('-softmmu')
3391 target_kconfig += 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'
3392 target_kconfig += 'CONFIG_TARGET_BIG_ENDIAN=' + config_target['TARGET_BIG_ENDIAN']
3393
3394 # PVG is not cross-architecture. Use accelerator_targets as a proxy to
3395 # figure out which target can support PVG on this host
3396 if pvg.found() and target in accelerator_targets.get('CONFIG_HVF', [])
3397 target_kconfig += 'CONFIG_MAC_PVG=y'
3398 endif
3399
3400 config_input = meson.get_external_property(target, 'default')
3401 config_devices_mak = target + '-config-devices.mak'
3402 config_devices_mak = configure_file(
3403 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
3404 output: config_devices_mak,
3405 depfile: config_devices_mak + '.d',
3406 capture: true,
3407 command: [minikconf,
3408 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
3409 config_devices_mak, '@DEPFILE@', '@INPUT@',
3410 host_kconfig, target_kconfig])
3411
3412 config_devices_data = configuration_data()
3413 config_devices = keyval.load(config_devices_mak)
3414 foreach k, v: config_devices
3415 config_devices_data.set(k, 1)
3416 endforeach
3417 config_devices_mak_list += config_devices_mak
3418 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
3419 configuration: config_devices_data)}
3420 config_target += config_devices
3421 config_all_devices += config_devices
3422 endif
3423 config_target_mak += {target: config_target}
3424
3425 # build a merged config for all targets with the same TARGET_BASE_ARCH
3426 target_base_arch = config_target['TARGET_BASE_ARCH']
3427 config_base_arch = config_base_arch_mak.get(target_base_arch, {}) + config_target
3428 config_base_arch_mak += {target_base_arch: config_base_arch}
3429 endforeach
3430 target_dirs = actual_target_dirs
3431
3432 target_configs_h = []
3433 foreach target: target_dirs
3434 target_configs_h += config_target_h[target]
3435 target_configs_h += config_devices_h.get(target, [])
3436 endforeach
3437 genh += custom_target('config-poison.h',
3438 input: [target_configs_h],
3439 output: 'config-poison.h',
3440 capture: true,
3441 command: [find_program('scripts/make-config-poison.sh'),
3442 target_configs_h])
3443
3444 if fdt_required.length() > 0
3445 error('fdt disabled but required by targets ' + ', '.join(fdt_required))
3446 endif
3447
3448 ###############
3449 # Subprojects #
3450 ###############
3451
3452 libvfio_user_dep = not_found
3453 if have_system and vfio_user_server_allowed
3454 libvfio_user_proj = subproject('libvfio-user', required: true)
3455 libvfio_user_dep = libvfio_user_proj.get_variable('libvfio_user_dep')
3456 endif
3457
3458 vhost_user = not_found
3459 if host_os == 'linux' and have_vhost_user
3460 libvhost_user = subproject('libvhost-user')
3461 vhost_user = libvhost_user.get_variable('vhost_user_dep')
3462 endif
3463
3464 libvduse = not_found
3465 if have_libvduse
3466 libvduse_proj = subproject('libvduse')
3467 libvduse = libvduse_proj.get_variable('libvduse_dep')
3468 endif
3469
3470 #####################
3471 # Generated sources #
3472 #####################
3473
3474 config_host_h = configure_file(output: 'config-host.h', configuration: config_host_data)
3475 genh += config_host_h
3476
3477 devenv = environment()
3478 devenv.set('MESON_BUILD_ROOT', meson.project_build_root())
3479 devenv.set('VIRTUAL_ENV', meson.project_build_root() / 'pyvenv')
3480 devenv.prepend('PATH', meson.project_build_root() / 'pyvenv'/ 'bin')
3481 devenv.prepend('PYTHONPATH', meson.current_source_dir() / 'tests' / 'functional')
3482 devenv.prepend('PYTHONPATH', meson.current_source_dir() / 'python')
3483 meson.add_devenv(devenv)
3484
3485 run_config = configuration_data({'build_dir': meson.current_build_dir()})
3486 run = configure_file(input: 'run.in',
3487 output: 'run',
3488 configuration: run_config)
3489 run_command('chmod', 'a+x', run, check: true)
3490
3491 hxtool = find_program('scripts/hxtool')
3492 shaderinclude = find_program('scripts/shaderinclude.py')
3493 qapi_gen = find_program('scripts/qapi-gen.py')
3494 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
3495 meson.current_source_dir() / 'scripts/qapi/backend.py',
3496 meson.current_source_dir() / 'scripts/qapi/commands.py',
3497 meson.current_source_dir() / 'scripts/qapi/common.py',
3498 meson.current_source_dir() / 'scripts/qapi/error.py',
3499 meson.current_source_dir() / 'scripts/qapi/events.py',
3500 meson.current_source_dir() / 'scripts/qapi/expr.py',
3501 meson.current_source_dir() / 'scripts/qapi/features.py',
3502 meson.current_source_dir() / 'scripts/qapi/gen.py',
3503 meson.current_source_dir() / 'scripts/qapi/introspect.py',
3504 meson.current_source_dir() / 'scripts/qapi/main.py',
3505 meson.current_source_dir() / 'scripts/qapi/parser.py',
3506 meson.current_source_dir() / 'scripts/qapi/schema.py',
3507 meson.current_source_dir() / 'scripts/qapi/source.py',
3508 meson.current_source_dir() / 'scripts/qapi/types.py',
3509 meson.current_source_dir() / 'scripts/qapi/visit.py',
3510 meson.current_source_dir() / 'scripts/qapi-gen.py'
3511 ]
3512
3513 tracetool = [
3514 python, files('scripts/tracetool.py'),
3515 '--backend=' + ','.join(get_option('trace_backends'))
3516 ]
3517 tracetool_depends = files(
3518 'scripts/tracetool/backend/log.py',
3519 'scripts/tracetool/backend/__init__.py',
3520 'scripts/tracetool/backend/dtrace.py',
3521 'scripts/tracetool/backend/ftrace.py',
3522 'scripts/tracetool/backend/simple.py',
3523 'scripts/tracetool/backend/syslog.py',
3524 'scripts/tracetool/backend/ust.py',
3525 'scripts/tracetool/format/ust_events_c.py',
3526 'scripts/tracetool/format/ust_events_h.py',
3527 'scripts/tracetool/format/__init__.py',
3528 'scripts/tracetool/format/d.py',
3529 'scripts/tracetool/format/simpletrace_stap.py',
3530 'scripts/tracetool/format/c.py',
3531 'scripts/tracetool/format/h.py',
3532 'scripts/tracetool/format/log_stap.py',
3533 'scripts/tracetool/format/stap.py',
3534 'scripts/tracetool/__init__.py',
3535 )
3536
3537 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
3538 meson.current_source_dir(),
3539 get_option('pkgversion'), meson.project_version()]
3540 qemu_version = custom_target('qemu-version.h',
3541 output: 'qemu-version.h',
3542 command: qemu_version_cmd,
3543 capture: true,
3544 build_by_default: true,
3545 build_always_stale: true)
3546 genh += qemu_version
3547
3548 hxdep = []
3549 hx_headers = [
3550 ['qemu-options.hx', 'qemu-options.def'],
3551 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
3552 ]
3553 if have_system and have_hmp
3554 hx_headers += [
3555 ['hmp-commands.hx', 'hmp-commands.h'],
3556 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
3557 ]
3558 endif
3559 foreach d : hx_headers
3560 hxdep += custom_target(d[1],
3561 input: files(d[0]),
3562 output: d[1],
3563 capture: true,
3564 command: [hxtool, '-h', '@INPUT0@'])
3565 endforeach
3566 genh += hxdep
3567
3568 ###############
3569 # Trace files #
3570 ###############
3571
3572 # TODO: add each directory to the subdirs from its own meson.build, once
3573 # we have those
3574 trace_events_subdirs = [
3575 'crypto',
3576 'qapi',
3577 'qom',
3578 'monitor',
3579 'util',
3580 'gdbstub',
3581 'tools/qemu-vnc',
3582 ]
3583 if have_linux_user
3584 trace_events_subdirs += [ 'linux-user' ]
3585 endif
3586 if have_bsd_user
3587 trace_events_subdirs += [ 'bsd-user' ]
3588 endif
3589 if have_block
3590 trace_events_subdirs += [
3591 'authz',
3592 'block',
3593 'chardev',
3594 'io',
3595 'nbd',
3596 'scsi',
3597 ]
3598 endif
3599 if have_system
3600 trace_events_subdirs += [
3601 'accel/hvf',
3602 'accel/kvm',
3603 'accel/mshv',
3604 'accel/nitro',
3605 'audio',
3606 'backends',
3607 'backends/tpm',
3608 'ebpf',
3609 'hw/9pfs',
3610 'hw/acpi',
3611 'hw/adc',
3612 'hw/alpha',
3613 'hw/arm',
3614 'hw/audio',
3615 'hw/block',
3616 'hw/char',
3617 'hw/display',
3618 'hw/dma',
3619 'hw/fsi',
3620 'hw/hexagon',
3621 'hw/hyperv',
3622 'hw/i2c',
3623 'hw/i3c',
3624 'hw/i386',
3625 'hw/i386/xen',
3626 'hw/i386/kvm',
3627 'hw/ide',
3628 'hw/input',
3629 'hw/intc',
3630 'hw/isa',
3631 'hw/mem',
3632 'hw/mips',
3633 'hw/misc',
3634 'hw/misc/macio',
3635 'hw/net',
3636 'hw/net/can',
3637 'hw/nitro',
3638 'hw/nubus',
3639 'hw/nvme',
3640 'hw/nvram',
3641 'hw/pci',
3642 'hw/pci-host',
3643 'hw/ppc',
3644 'hw/rtc',
3645 'hw/riscv',
3646 'hw/s390x',
3647 'hw/scsi',
3648 'hw/sd',
3649 'hw/sensor',
3650 'hw/sh4',
3651 'hw/sparc',
3652 'hw/sparc64',
3653 'hw/ssi',
3654 'hw/timer',
3655 'hw/tpm',
3656 'hw/uefi',
3657 'hw/ufs',
3658 'hw/usb',
3659 'hw/vfio',
3660 'hw/vfio-user',
3661 'hw/virtio',
3662 'hw/vmapple',
3663 'hw/watchdog',
3664 'hw/xen',
3665 'hw/gpio',
3666 'migration',
3667 'net',
3668 'replay',
3669 'system',
3670 'ui',
3671 'hw/remote',
3672 ]
3673 endif
3674 if have_system or have_user
3675 trace_events_subdirs += [
3676 'accel/tcg',
3677 'hw/core',
3678 'target/arm',
3679 'target/arm/hvf',
3680 'target/arm/tcg',
3681 'target/hppa',
3682 'target/i386',
3683 'target/i386/kvm',
3684 'target/i386/whpx',
3685 'target/loongarch',
3686 'target/mips/tcg',
3687 'target/ppc',
3688 'target/riscv',
3689 'target/s390x',
3690 'target/s390x/kvm',
3691 'target/sparc',
3692 ]
3693 endif
3694
3695 ###################
3696 # Collect sources #
3697 ###################
3698
3699 authz_ss = ss.source_set()
3700 blockdev_ss = ss.source_set()
3701 block_ss = ss.source_set()
3702 chardev_ss = ss.source_set()
3703 common_ss = ss.source_set()
3704 crypto_ss = ss.source_set()
3705 hwcore_ss = ss.source_set()
3706 io_ss = ss.source_set()
3707 qmp_ss = ss.source_set()
3708 qom_ss = ss.source_set()
3709 system_ss = ss.source_set()
3710 specific_fuzz_ss = ss.source_set()
3711 specific_ss = ss.source_set()
3712 rust_devices_ss = ss.source_set()
3713 stub_ss = ss.source_set()
3714 trace_ss = ss.source_set()
3715 user_ss = ss.source_set()
3716 util_ss = ss.source_set()
3717
3718 # accel modules
3719 qtest_module_ss = ss.source_set()
3720
3721 modules = {}
3722 target_modules = {}
3723 plugin_modules = []
3724 hw_arch = {}
3725 target_arch = {}
3726 target_system_arch = {}
3727 target_user_arch = {}
3728 hw_common_arch = {}
3729 target_common_arch = {}
3730 target_common_system_arch = {}
3731 target_stubs_arch = {}
3732
3733 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
3734 # that is filled in by qapi/.
3735 subdir('qapi')
3736 subdir('qobject')
3737 subdir('stubs')
3738 subdir('trace')
3739 subdir('util')
3740 subdir('qom')
3741 subdir('authz')
3742 subdir('crypto')
3743 subdir('ui')
3744 subdir('semihosting')
3745 subdir('audio')
3746 subdir('io')
3747 subdir('chardev')
3748 subdir('fsdev')
3749 subdir('dump')
3750 subdir('accel')
3751
3752 subdir('backends')
3753 subdir('configs/targets')
3754 subdir('disas')
3755 subdir('migration')
3756 subdir('monitor')
3757 subdir('net')
3758 subdir('replay')
3759 subdir('stats')
3760 subdir('tcg')
3761 subdir('fpu')
3762 subdir('plugins')
3763 subdir('ebpf')
3764
3765 if have_system
3766 subdir('hw')
3767 else
3768 subdir('hw/core')
3769 endif
3770
3771 if enable_modules
3772 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
3773 modulecommon = declare_dependency(objects: libmodulecommon.extract_all_objects(recursive: false), compile_args: '-DBUILD_DSO')
3774 endif
3775
3776 qom_ss = qom_ss.apply({})
3777 libqom = static_library('qom', qom_ss.sources() + genh,
3778 dependencies: [qom_ss.dependencies()],
3779 build_by_default: false)
3780 qom = declare_dependency(objects: libqom.extract_all_objects(recursive: false),
3781 dependencies: qom_ss.dependencies())
3782
3783 event_loop_base = files('event-loop-base.c')
3784 event_loop_base = static_library('event-loop-base',
3785 sources: event_loop_base + genh,
3786 build_by_default: false)
3787 event_loop_base = declare_dependency(objects: event_loop_base.extract_all_objects(recursive: false),
3788 dependencies: [qom])
3789
3790 stub_ss = stub_ss.apply({})
3791
3792 util_ss.add_all(trace_ss)
3793 util_ss = util_ss.apply({})
3794 libqemuutil = static_library('qemuutil',
3795 build_by_default: false,
3796 sources: util_ss.sources() + stub_ss.sources() + genh,
3797 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, rt, pixman, opengl])
3798 qemuutil = declare_dependency(link_with: libqemuutil,
3799 sources: genh + version_res,
3800 dependencies: [event_loop_base])
3801
3802 if have_system or have_user
3803 decodetree = generator(find_program('scripts/decodetree.py'),
3804 output: 'decode-@BASENAME@.c.inc',
3805 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
3806 subdir('libdecnumber')
3807 subdir('gdbstub')
3808 subdir('target')
3809 endif
3810
3811 if have_block
3812 block_ss.add(files(
3813 'block.c',
3814 'blockjob.c',
3815 'job.c',
3816 'qemu-io-cmds.c',
3817 ))
3818 if config_host_data.get('CONFIG_REPLICATION')
3819 block_ss.add(files('replication.c'))
3820 endif
3821
3822 subdir('nbd')
3823 subdir('scsi')
3824 subdir('block')
3825
3826 blockdev_ss.add(files(
3827 'blockdev.c',
3828 'blockdev-nbd.c',
3829 'iothread.c',
3830 'job-qmp.c',
3831 ))
3832
3833 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
3834 # os-win32.c does not
3835 if host_os == 'windows'
3836 system_ss.add(files('os-win32.c'))
3837 elif host_os == 'emscripten'
3838 blockdev_ss.add(files('os-wasm.c'))
3839 else
3840 blockdev_ss.add(files('os-posix.c'))
3841 endif
3842 endif
3843
3844 common_ss.add(files('cpu-common.c'))
3845 user_ss.add(files('cpu-target.c'))
3846 system_ss.add(files('cpu-target.c'))
3847
3848 subdir('system')
3849
3850 # Work around a gcc bug/misfeature wherein constant propagation looks
3851 # through an alias:
3852 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
3853 # to guess that a const variable is always zero. Without lto, this is
3854 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
3855 # without lto, not even the alias is required -- we simply use different
3856 # declarations in different compilation units.
3857 pagevary = files('page-vary-common.c')
3858 if get_option('b_lto')
3859 pagevary_flags = ['-fno-lto']
3860 if get_option('cfi')
3861 pagevary_flags += '-fno-sanitize=cfi-icall'
3862 endif
3863 pagevary = static_library('page-vary-common', sources: pagevary + genh,
3864 c_args: pagevary_flags)
3865 pagevary = declare_dependency(link_with: pagevary)
3866 endif
3867 common_ss.add(pagevary)
3868 system_ss.add(files('page-vary-system.c'))
3869
3870 common_ss.add(files('target-info.c'))
3871 system_ss.add(files('target-info-qom.c'))
3872
3873 if 'CONFIG_TCG' in config_all_accel
3874 subdir('contrib/plugins')
3875 endif
3876
3877 common_user_inc = []
3878
3879 subdir('common-user')
3880 subdir('bsd-user')
3881 subdir('linux-user')
3882
3883 # needed for fuzzing binaries
3884 subdir('tests/qtest/libqos')
3885 subdir('tests/qtest/fuzz')
3886
3887 ##############################################
3888 # Internal static_libraries and dependencies #
3889 ##############################################
3890
3891 modinfo_collect = find_program('scripts/modinfo-collect.py')
3892 modinfo_generate = find_program('scripts/modinfo-generate.py')
3893 modinfo_files = []
3894 audio_modinfo_files = []
3895
3896 block_syms = []
3897 qemu_syms = []
3898
3899 block_mods = []
3900 system_mods = []
3901 emulator_modules = []
3902 foreach d, list : modules
3903 if not (d == 'block' ? have_block : have_system)
3904 continue
3905 endif
3906
3907 foreach m, module_ss : list
3908 if enable_modules
3909 module_ss.add(modulecommon)
3910 module_ss = module_ss.apply(config_all_devices, strict: false)
3911 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3912 dependencies: module_ss.dependencies(), pic: true)
3913 if d == 'block'
3914 block_mods += sl
3915 else
3916 system_mods += sl
3917 endif
3918 emulator_modules += shared_module(sl.name(),
3919 name_prefix: '',
3920 objects: sl.extract_all_objects(recursive: false),
3921 dependencies: module_ss.dependencies(),
3922 install: true,
3923 install_dir: qemu_moddir)
3924 if module_ss.sources() != []
3925 modinfo = custom_target(d + '-' + m + '.modinfo',
3926 output: d + '-' + m + '.modinfo',
3927 input: sl.extract_all_objects(recursive: true),
3928 capture: true,
3929 command: [modinfo_collect, '@INPUT@'])
3930 modinfo_files += modinfo
3931 if d == 'audio'
3932 audio_modinfo_files += modinfo
3933 endif
3934 endif
3935 else
3936 if d == 'block'
3937 block_ss.add_all(module_ss)
3938 elif d == 'audio'
3939 audio_ss.add_all(module_ss)
3940 else
3941 system_ss.add_all(module_ss)
3942 endif
3943 endif
3944 endforeach
3945 endforeach
3946
3947 foreach d, list : target_modules
3948 foreach m, module_ss : list
3949 if enable_modules
3950 module_ss.add(modulecommon)
3951 foreach target : target_dirs
3952 if target.endswith('-softmmu')
3953 config_target = config_target_mak[target]
3954 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3955 c_args = ['-DCOMPILING_PER_TARGET',
3956 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3957 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3958 target_module_ss = module_ss.apply(config_target, strict: false)
3959 if target_module_ss.sources() != []
3960 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3961 sl = static_library(module_name,
3962 [genh, target_module_ss.sources()],
3963 dependencies: target_module_ss.dependencies(),
3964 include_directories: target_inc,
3965 c_args: c_args,
3966 pic: true)
3967 system_mods += sl
3968 emulator_modules += shared_module(sl.name(),
3969 name_prefix: '',
3970 objects: sl.extract_all_objects(recursive: false),
3971 dependencies: target_module_ss.dependencies(),
3972 install: true,
3973 install_dir: qemu_moddir)
3974 modinfo_files += custom_target(module_name + '.modinfo',
3975 output: module_name + '.modinfo',
3976 input: sl.extract_all_objects(recursive: true),
3977 capture: true,
3978 command: [modinfo_collect, '--target', target, '@INPUT@'])
3979 endif
3980 endif
3981 endforeach
3982 else
3983 specific_ss.add_all(module_ss)
3984 endif
3985 endforeach
3986 endforeach
3987
3988 if enable_modules
3989 foreach target : target_dirs
3990 if target.endswith('-softmmu')
3991 config_target = config_target_mak[target]
3992 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH']
3993 config_devices_mak = target + '-config-devices.mak'
3994 modinfo_src = custom_target('modinfo-' + target + '.c',
3995 output: 'modinfo-' + target + '.c',
3996 input: modinfo_files,
3997 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'],
3998 capture: true)
3999
4000 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src)
4001 modinfo_dep = declare_dependency(link_with: modinfo_lib)
4002
4003 if not hw_arch.has_key(arch)
4004 hw_arch += {arch: ss.source_set()}
4005 endif
4006
4007 hw_arch[arch].add(modinfo_dep)
4008 endif
4009 endforeach
4010
4011 if emulator_modules.length() > 0
4012 alias_target('modules', emulator_modules)
4013 endif
4014
4015 nm = find_program('nm')
4016 undefsym = find_program('scripts/undefsym.py')
4017 block_syms = custom_target('block.syms', output: 'block.syms',
4018 input: [libqemuutil, block_mods],
4019 capture: true,
4020 command: [undefsym, nm, '@INPUT@'])
4021 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
4022 input: [libqemuutil, system_mods],
4023 capture: true,
4024 command: [undefsym, nm, '@INPUT@'])
4025 endif
4026
4027 authz_ss = authz_ss.apply({})
4028 libauthz = static_library('authz', authz_ss.sources() + genh,
4029 dependencies: [authz_ss.dependencies()],
4030 build_by_default: false)
4031
4032 authz = declare_dependency(objects: libauthz.extract_all_objects(recursive: false),
4033 dependencies: [authz_ss.dependencies(), qom])
4034
4035 crypto_ss = crypto_ss.apply({})
4036 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
4037 dependencies: [crypto_ss.dependencies()],
4038 build_by_default: false)
4039
4040 crypto = declare_dependency(objects: libcrypto.extract_all_objects(recursive: false),
4041 dependencies: [crypto_ss.dependencies(), authz, qom])
4042
4043 io_ss = io_ss.apply({})
4044 libio = static_library('io', io_ss.sources() + genh,
4045 dependencies: [io_ss.dependencies()],
4046 link_with: libqemuutil,
4047 build_by_default: false)
4048
4049 io = declare_dependency(objects: libio.extract_all_objects(recursive: false),
4050 dependencies: [io_ss.dependencies(), crypto, qom])
4051
4052 libmigration = static_library('migration', sources: migration_files + genh,
4053 build_by_default: false)
4054 migration = declare_dependency(objects: libmigration.extract_all_objects(recursive: false),
4055 dependencies: [qom, io])
4056 system_ss.add(migration)
4057
4058 block_ss = block_ss.apply({})
4059 libblock = static_library('block', block_ss.sources() + genh,
4060 dependencies: block_ss.dependencies(),
4061 build_by_default: false)
4062
4063 block = declare_dependency(objects: libblock.extract_all_objects(recursive: false),
4064 dependencies: [block_ss.dependencies(), crypto, io])
4065
4066 blockdev_ss = blockdev_ss.apply({})
4067 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
4068 dependencies: blockdev_ss.dependencies(),
4069 build_by_default: false)
4070
4071 blockdev = declare_dependency(objects: libblockdev.extract_all_objects(recursive: false),
4072 dependencies: [blockdev_ss.dependencies(), block, event_loop_base])
4073
4074 qmp_ss = qmp_ss.apply({})
4075 libqmp = static_library('qmp', qmp_ss.sources() + genh,
4076 dependencies: qmp_ss.dependencies(),
4077 build_by_default: false)
4078
4079 qmp = declare_dependency(objects: libqmp.extract_all_objects(recursive: false),
4080 dependencies: qmp_ss.dependencies())
4081
4082 libchardev = static_library('chardev', chardev_ss.sources() + genh,
4083 dependencies: chardev_ss.dependencies(),
4084 build_by_default: false)
4085
4086 chardev = declare_dependency(objects: libchardev.extract_all_objects(recursive: false),
4087 dependencies: [chardev_ss.dependencies(), io])
4088
4089 hwcore_ss = hwcore_ss.apply({})
4090 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
4091 build_by_default: false)
4092 hwcore = declare_dependency(objects: libhwcore.extract_all_objects(recursive: false))
4093 common_ss.add(hwcore)
4094
4095 audio_ss = audio_ss.apply({})
4096 libaudio = static_library('qemuaudio', audio_ss.sources() + genh,
4097 dependencies: [audio_ss.dependencies()],
4098 build_by_default: false)
4099
4100 audio = declare_dependency(objects: libaudio.extract_all_objects(recursive: false),
4101 dependencies: [audio_ss.dependencies(), qom])
4102
4103 ###########
4104 # Targets #
4105 ###########
4106
4107 system_ss.add(authz, blockdev, chardev, crypto, io, qmp, audio)
4108 common_ss.add(qom, qemuutil)
4109
4110 libuser = static_library('user',
4111 user_ss.all_sources() + genh,
4112 c_args: ['-DCONFIG_USER_ONLY',
4113 '-DCOMPILING_SYSTEM_VS_USER'],
4114 include_directories: common_user_inc,
4115 dependencies: user_ss.all_dependencies(),
4116 build_by_default: false)
4117
4118 libsystem = static_library('system',
4119 system_ss.all_sources() + genh,
4120 c_args: ['-DCONFIG_SOFTMMU',
4121 '-DCOMPILING_SYSTEM_VS_USER'],
4122 dependencies: system_ss.all_dependencies(),
4123 build_by_default: false)
4124
4125 # Note that this library is never used directly (only through extract_objects)
4126 # and is not built by default; therefore, source files not used by the build
4127 # configuration will be in build.ninja, but are never built by default.
4128 common_all = static_library('common',
4129 build_by_default: false,
4130 sources: common_ss.all_sources() + genh,
4131 implicit_include_directories: false,
4132 dependencies: common_ss.all_dependencies())
4133
4134 # construct common libraries per base architecture
4135 target_common_arch_libs = {}
4136 target_common_system_arch_libs = {}
4137 target_stubs_arch_libs = {}
4138 foreach target_base_arch, config_base_arch : config_base_arch_mak
4139 target_inc = [include_directories('target' / target_base_arch)]
4140 inc = [common_user_inc + target_inc]
4141
4142 target_common = common_ss.apply(config_base_arch, strict: false)
4143 target_system = system_ss.apply(config_base_arch, strict: false)
4144 target_user = user_ss.apply(config_base_arch, strict: false)
4145 common_deps = []
4146 system_deps = []
4147 user_deps = []
4148 foreach dep: target_common.dependencies()
4149 common_deps += dep.partial_dependency(compile_args: true, includes: true)
4150 endforeach
4151 foreach dep: target_system.dependencies()
4152 system_deps += dep.partial_dependency(compile_args: true, includes: true)
4153 endforeach
4154 foreach dep: target_user.dependencies()
4155 user_deps += dep.partial_dependency(compile_args: true, includes: true)
4156 endforeach
4157
4158 # prevent common code to access cpu compile time definition,
4159 # but still allow access to cpu.h
4160 target_c_args = ['-DCPU_DEFS_H']
4161 target_system_c_args = target_c_args + ['-DCOMPILING_SYSTEM_VS_USER', '-DCONFIG_SOFTMMU']
4162
4163 if target_base_arch in target_common_arch
4164 src = target_common_arch[target_base_arch]
4165 lib = static_library(
4166 'common_' + target_base_arch,
4167 build_by_default: false,
4168 sources: src.all_sources() + genh,
4169 include_directories: inc,
4170 c_args: target_c_args,
4171 dependencies: src.all_dependencies() + common_deps +
4172 system_deps + user_deps)
4173 target_common_arch_libs += {target_base_arch: lib}
4174 endif
4175
4176 # merge hw_common_arch in target_common_system_arch
4177 if target_base_arch in hw_common_arch
4178 hw_src = hw_common_arch[target_base_arch]
4179 if target_base_arch in target_common_system_arch
4180 target_common_system_arch[target_base_arch].add_all(hw_src)
4181 else
4182 target_common_system_arch += {target_base_arch: hw_src}
4183 endif
4184 endif
4185
4186 if target_base_arch in target_common_system_arch
4187 src = target_common_system_arch[target_base_arch]
4188 lib = static_library(
4189 'system_' + target_base_arch,
4190 build_by_default: false,
4191 sources: src.all_sources() + genh,
4192 include_directories: inc,
4193 c_args: target_system_c_args,
4194 dependencies: src.all_dependencies() + common_deps + system_deps)
4195 target_common_system_arch_libs += {target_base_arch: lib}
4196 endif
4197
4198 if target_base_arch in target_stubs_arch
4199 src = target_stubs_arch[target_base_arch]
4200 lib = static_library('stubs_' + target_base_arch,
4201 sources: src.all_sources() + genh,
4202 include_directories: inc,
4203 c_args: target_system_c_args)
4204 target_stubs_arch_libs += {target_base_arch: lib}
4205 endif
4206 endforeach
4207
4208 if have_rust
4209 bindings_incdir = include_directories('.', 'include')
4210 # We would like to use --generate-cstr, but it is only available
4211 # starting with bindgen 0.66.0. The oldest supported versions
4212 # is 0.60.x (Debian 12 has 0.60.1) which introduces --allowlist-file.
4213 bindgen_args_common = [
4214 '--disable-header-comment',
4215 '--raw-line', '// @generated',
4216 '--ctypes-prefix', 'std::os::raw',
4217 '--generate-block',
4218 '--impl-debug',
4219 '--no-doc-comments',
4220 '--with-derive-default',
4221 '--no-layout-tests',
4222 '--no-prepend-enum-name',
4223 '--blocklist-file', glib_pc.get_variable('includedir') + '/glib-2.0/.*',
4224 '--blocklist-file', meson.project_source_root() + '/include/qemu/typedefs.h',
4225 '--blocklist-type', '.*_([a-z]*autoptr)$',
4226 ]
4227 if not rustfmt.found()
4228 if bindgen.version().version_compare('<0.65.0')
4229 bindgen_args_common += ['--no-rustfmt-bindings']
4230 else
4231 bindgen_args_common += ['--formatter', 'none']
4232 endif
4233 endif
4234 if bindgen.version().version_compare('>=0.66.0')
4235 bindgen_args_common += ['--rust-target', '1.59']
4236 endif
4237 if bindgen.version().version_compare('<0.61.0')
4238 # default in 0.61+
4239 bindgen_args_common += ['--size_t-is-usize']
4240 else
4241 bindgen_args_common += ['--merge-extern-blocks']
4242 endif
4243 bindgen_c_args = []
4244 if host_arch == 'wasm64'
4245 bindgen_c_args += ['-fvisibility=default']
4246 endif
4247 subdir('rust')
4248 endif
4249
4250
4251 rust_root_crate = find_program('scripts/rust/rust_root_crate.sh')
4252
4253 if host_os == 'darwin'
4254 entitlement = find_program('scripts/entitlement.sh')
4255 endif
4256
4257 traceable = []
4258 emulators = {}
4259 foreach target : target_dirs
4260 config_target = config_target_mak[target]
4261 target_name = config_target['TARGET_NAME']
4262 target_base_arch = config_target['TARGET_BASE_ARCH']
4263 arch_srcs = [config_target_h[target]]
4264 arch_deps = []
4265 c_args = ['-DCOMPILING_PER_TARGET',
4266 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
4267 ]
4268 link_args = emulator_link_args
4269
4270 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
4271 if host_os == 'linux'
4272 target_inc += include_directories('linux-headers', is_system: true)
4273 endif
4274 if target.endswith('-softmmu')
4275 target_type='system'
4276 if target_base_arch in target_system_arch
4277 t = target_system_arch[target_base_arch].apply(config_target, strict: false)
4278 arch_srcs += t.sources()
4279 arch_deps += t.dependencies()
4280 endif
4281
4282 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
4283 if hw_arch.has_key(hw_dir)
4284 hw = hw_arch[hw_dir].apply(config_target, strict: false)
4285 arch_srcs += hw.sources()
4286 arch_deps += hw.dependencies()
4287 endif
4288
4289 c_args += ['-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
4290 arch_srcs += config_devices_h[target]
4291 link_args += enable_modules ? ['@block.syms', '@qemu.syms'] : []
4292 else
4293 abi = config_target['TARGET_ABI_DIR']
4294 target_type='user'
4295 target_inc += common_user_inc
4296 if target_base_arch in target_user_arch
4297 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
4298 arch_srcs += t.sources()
4299 arch_deps += t.dependencies()
4300 endif
4301 if 'CONFIG_LINUX_USER' in config_target
4302 base_dir = 'linux-user'
4303 endif
4304 if 'CONFIG_BSD_USER' in config_target
4305 base_dir = 'bsd-user'
4306 target_inc += include_directories('bsd-user/' / host_os)
4307 target_inc += include_directories('bsd-user/host/' / host_arch)
4308 dir = base_dir / abi
4309 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
4310 endif
4311 target_inc += include_directories(
4312 base_dir,
4313 base_dir / abi,
4314 )
4315 if 'CONFIG_LINUX_USER' in config_target
4316 dir = base_dir / abi
4317 arch_srcs += files(
4318 dir / 'cpu_loop.c',
4319 dir / 'elfload.c',
4320 dir / 'signal.c',
4321 )
4322 if config_target.has_key('TARGET_SYSTBL_ABI')
4323 arch_srcs += \
4324 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
4325 extra_args : config_target['TARGET_SYSTBL_ABI'])
4326 endif
4327 endif
4328 endif
4329
4330 if target in config_target_info
4331 arch_srcs += config_target_info[target]
4332 else
4333 arch_srcs += files('target-info-stub.c')
4334 endif
4335
4336 if target_base_arch in target_arch
4337 t = target_arch[target_base_arch].apply(config_target, strict: false)
4338 arch_srcs += t.sources()
4339 arch_deps += t.dependencies()
4340 endif
4341
4342 target_common = common_ss.apply(config_target, strict: false)
4343 objects = [common_all.extract_objects(target_common.sources())]
4344 arch_deps += target_common.dependencies()
4345 if target_base_arch in target_common_arch_libs
4346 src = target_common_arch[target_base_arch].apply(config_target, strict: false)
4347 lib = target_common_arch_libs[target_base_arch]
4348 objects += lib.extract_objects(src.sources())
4349 arch_deps += src.dependencies()
4350 endif
4351 if target_type == 'system'
4352 src = system_ss.apply(config_target, strict: false)
4353 objects += libsystem.extract_objects(src.sources())
4354 arch_deps += src.dependencies()
4355 endif
4356 if target_type == 'user'
4357 src = user_ss.apply(config_target, strict: false)
4358 objects += libuser.extract_objects(src.sources())
4359 arch_deps += src.dependencies()
4360 endif
4361 if target_type == 'system' and target_base_arch in target_common_system_arch_libs
4362 src = target_common_system_arch[target_base_arch].apply(config_target, strict: false)
4363 lib = target_common_system_arch_libs[target_base_arch]
4364 objects += lib.extract_objects(src.sources())
4365 arch_deps += src.dependencies()
4366 endif
4367 lib_target_stubs = []
4368 if target_base_arch in target_stubs_arch_libs
4369 lib_target_stubs = [target_stubs_arch_libs[target_base_arch]]
4370 endif
4371 target_stubs = declare_dependency(link_with: lib_target_stubs)
4372
4373 target_specific = specific_ss.apply(config_target, strict: false)
4374 arch_srcs += target_specific.sources()
4375 arch_deps += target_specific.dependencies()
4376
4377 main_rs = []
4378 crates = []
4379 if have_rust and target_type == 'system'
4380 target_rust = rust_devices_ss.apply(config_target, strict: false)
4381 arch_deps += target_rust.dependencies()
4382 foreach dep : target_rust.dependencies()
4383 crates += dep.get_variable('crate')
4384 endforeach
4385 if crates.length() > 0
4386 main_rs = custom_target('rust_' + target.underscorify() + '.rs',
4387 output: 'rust_' + target.underscorify() + '.rs',
4388 command: [rust_root_crate, crates],
4389 capture: true,
4390 build_by_default: true,
4391 build_always_stale: true)
4392 main_rs = structured_sources(main_rs)
4393 endif
4394 endif
4395
4396 # allow using headers from the dependencies but do not include the sources,
4397 # because this emulator only needs those in "objects". For external
4398 # dependencies, the full dependency is included below in the executable.
4399 lib_deps = []
4400 foreach dep : arch_deps
4401 lib_deps += dep.partial_dependency(compile_args: true, includes: true)
4402 endforeach
4403
4404 lib = static_library('qemu-' + target,
4405 sources: arch_srcs + genh,
4406 dependencies: lib_deps,
4407 objects: objects,
4408 include_directories: target_inc,
4409 c_args: c_args,
4410 build_by_default: false)
4411
4412 if target.endswith('-softmmu')
4413 execs = [{
4414 'name': 'qemu-system-' + target_name,
4415 'win_subsystem': 'console',
4416 'sources': [main_rs, files('system/main.c')],
4417 'dependencies': [sdl, target_stubs],
4418 }]
4419 if host_os == 'windows' and (sdl.found() or gtk.found())
4420 execs += [{
4421 'name': 'qemu-system-' + target_name + 'w',
4422 'win_subsystem': 'windows',
4423 'sources': [main_rs, files('system/main.c')],
4424 'dependencies': [sdl, target_stubs],
4425 }]
4426 endif
4427 if get_option('fuzzing')
4428 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
4429 execs += [{
4430 'name': 'qemu-fuzz-' + target_name,
4431 'win_subsystem': 'console',
4432 'sources': [main_rs, specific_fuzz.sources()],
4433 'dependencies': specific_fuzz.dependencies(),
4434 }]
4435 endif
4436 else
4437 execs = [{
4438 'name': 'qemu-' + target_name,
4439 'win_subsystem': 'console',
4440 'sources': [],
4441 'dependencies': [target_stubs]
4442 }]
4443 endif
4444 foreach exe: execs
4445 exe_name = exe['name']
4446 if host_os == 'darwin'
4447 exe_name += '-unsigned'
4448 endif
4449
4450 emulator = executable(exe_name, exe['sources'],
4451 install: true,
4452 c_args: c_args,
4453 dependencies: arch_deps + exe['dependencies'],
4454 objects: lib.extract_all_objects(recursive: true),
4455 link_depends: [block_syms, qemu_syms],
4456 link_args: link_args,
4457 win_subsystem: exe['win_subsystem'])
4458
4459 if host_os == 'darwin'
4460 icon = 'pc-bios/qemu.rsrc'
4461 build_input = [emulator, files(icon)]
4462 install_input = [
4463 get_option('bindir') / exe_name,
4464 meson.current_source_dir() / icon
4465 ]
4466 if 'CONFIG_HVF' in config_target
4467 entitlements = 'accel/hvf/entitlements.plist'
4468 build_input += files(entitlements)
4469 install_input += meson.current_source_dir() / entitlements
4470 endif
4471
4472 emulators += {exe['name'] : custom_target(exe['name'],
4473 input: build_input,
4474 output: exe['name'],
4475 build_by_default: true,
4476 command: [entitlement, '@OUTPUT@', '@INPUT@'])
4477 }
4478
4479 meson.add_install_script(entitlement, '--install',
4480 get_option('bindir') / exe['name'],
4481 install_input)
4482 else
4483 emulators += {exe['name']: emulator}
4484 endif
4485
4486 traceable += [{
4487 'exe': exe['name'],
4488 'probe-prefix': 'qemu.' + target_type + '.' + target_name,
4489 }]
4490
4491 endforeach
4492 endforeach
4493
4494 # Other build targets
4495
4496 if get_option('plugins')
4497 install_headers('include/plugins/qemu-plugin.h')
4498 if host_os == 'windows'
4499 # On windows, we want to deliver the qemu_plugin_api.lib file in the qemu installer,
4500 # so that plugin authors can compile against it.
4501 install_data(win32_qemu_plugin_api, install_dir: 'lib')
4502 endif
4503 endif
4504
4505 subdir('qga')
4506
4507 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
4508 # when we don't build tools or system
4509 if xkbcommon.found()
4510 # used for the update-keymaps target, so include rules even if !have_tools
4511 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
4512 dependencies: [qemuutil, xkbcommon], install: have_tools)
4513 endif
4514
4515 if have_tools
4516 tools_link_args = enable_modules ? ['@block.syms'] : []
4517 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
4518 link_args: tools_link_args, link_depends: block_syms,
4519 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
4520 qemu_io = executable('qemu-io', files('qemu-io.c'),
4521 link_args: tools_link_args, link_depends: block_syms,
4522 dependencies: [block, qemuutil], install: true)
4523 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
4524 link_args: tools_link_args, link_depends: block_syms,
4525 dependencies: [blockdev, qemuutil, selinux],
4526 install: true)
4527
4528 subdir('storage-daemon')
4529
4530 foreach exe: [ 'qemu-img', 'qemu-io', 'qemu-nbd', 'qemu-storage-daemon']
4531 traceable += [{
4532 'exe': exe,
4533 'probe-prefix': 'qemu.' + exe.substring(5).replace('-', '_')
4534 }]
4535 endforeach
4536
4537 subdir('contrib/elf2dmp')
4538
4539 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
4540 dependencies: [qemuutil, rt],
4541 install: true)
4542
4543 if have_vhost_user
4544 subdir('contrib/vhost-user-blk')
4545 subdir('contrib/vhost-user-bridge')
4546 subdir('contrib/vhost-user-gpu')
4547 subdir('contrib/vhost-user-input')
4548 subdir('contrib/vhost-user-scsi')
4549 endif
4550
4551 if host_os == 'linux'
4552 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
4553 dependencies: [qemuutil, libcap_ng],
4554 install: true,
4555 install_dir: get_option('libexecdir'))
4556
4557 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
4558 dependencies: [authz, crypto, io, qom, qemuutil,
4559 libcap_ng, mpathpersist],
4560 install: true)
4561
4562 if cpu == 'x86_64'
4563 executable('qemu-vmsr-helper', files('tools/i386/qemu-vmsr-helper.c'),
4564 dependencies: [authz, crypto, io, qom, qemuutil,
4565 libcap_ng, mpathpersist],
4566 install: true)
4567 endif
4568 endif
4569
4570 if have_ivshmem
4571 subdir('contrib/ivshmem-client')
4572 subdir('contrib/ivshmem-server')
4573 endif
4574
4575 if have_qemu_vnc
4576 subdir('tools/qemu-vnc')
4577 endif
4578 endif
4579
4580 if stap.found()
4581 foreach t: traceable
4582 foreach stp: [
4583 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / t['exe'], 'install': false},
4584 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / t['exe'], 'install': true},
4585 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
4586 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
4587 ]
4588 cmd = [
4589 tracetool, '--group=all', '--format=' + stp['fmt'],
4590 '--binary=' + stp['bin'],
4591 '--probe-prefix=' + t['probe-prefix'],
4592 '@INPUT@', '@OUTPUT@'
4593 ]
4594
4595 custom_target(t['exe'] + stp['ext'],
4596 input: trace_events_all,
4597 output: t['exe'] + stp['ext'],
4598 install: stp['install'],
4599 install_dir: get_option('datadir') / 'systemtap/tapset',
4600 command: cmd,
4601 depend_files: tracetool_depends)
4602 endforeach
4603 endforeach
4604 endif
4605
4606 subdir('scripts')
4607 subdir('tools')
4608 subdir('pc-bios')
4609 subdir('docs')
4610 subdir('pyvenv')
4611 # Tests are disabled on emscripten because they rely on host features that aren't
4612 # supported by emscripten (e.g. fork and unix socket).
4613 if host_os != 'emscripten'
4614 subdir('tests')
4615 endif
4616 if gtk.found()
4617 subdir('po')
4618 endif
4619
4620 if host_machine.system() == 'windows'
4621 nsis_cmd = [
4622 find_program('scripts/nsis.py'),
4623 '@OUTPUT@',
4624 get_option('prefix'),
4625 meson.current_source_dir(),
4626 glib_pc.get_variable('bindir'),
4627 host_machine.cpu(),
4628 '--',
4629 '-DDISPLAYVERSION=' + meson.project_version(),
4630 ]
4631 if build_docs
4632 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
4633 endif
4634 if gtk.found()
4635 nsis_cmd += '-DCONFIG_GTK=y'
4636 endif
4637
4638 nsis = custom_target('nsis',
4639 output: 'qemu-setup-' + meson.project_version() + '.exe',
4640 input: files('qemu.nsi'),
4641 build_always_stale: true,
4642 command: nsis_cmd + ['@INPUT@'])
4643 alias_target('installer', nsis)
4644 endif
4645
4646 #########################
4647 # Configuration summary #
4648 #########################
4649
4650 # Build environment
4651 summary_info = {}
4652 summary_info += {'Build directory': meson.current_build_dir()}
4653 summary_info += {'Source path': meson.current_source_dir()}
4654 summary_info += {'Download dependencies': get_option('wrap_mode') != 'nodownload'}
4655 summary(summary_info, bool_yn: true, section: 'Build environment')
4656
4657 # Directories
4658 summary_info = {}
4659 summary_info += {'Install prefix': get_option('prefix')}
4660 summary_info += {'BIOS directory': qemu_datadir}
4661 pathsep = host_os == 'windows' ? ';' : ':'
4662 summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))}
4663 summary_info += {'binary directory': get_option('prefix') / get_option('bindir')}
4664 summary_info += {'library directory': get_option('prefix') / get_option('libdir')}
4665 summary_info += {'module directory': qemu_moddir}
4666 summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')}
4667 summary_info += {'include directory': get_option('prefix') / get_option('includedir')}
4668 summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')}
4669 if host_os != 'windows'
4670 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')}
4671 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')}
4672 else
4673 summary_info += {'local state directory': 'queried at runtime'}
4674 endif
4675 summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')}
4676 summary(summary_info, bool_yn: true, section: 'Directories')
4677
4678 # Host binaries
4679 summary_info = {}
4680 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
4681 summary_info += {'sphinx-build': sphinx_build}
4682
4683 # FIXME: the [binaries] section of machine files, which can be probed
4684 # with find_program(), would be great for passing gdb and genisoimage
4685 # paths from configure to Meson. However, there seems to be no way to
4686 # hide a program (for example if gdb is too old).
4687 if config_host.has_key('GDB')
4688 summary_info += {'gdb': config_host['GDB']}
4689 endif
4690 summary_info += {'iasl': iasl}
4691 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
4692 if host_os == 'windows' and have_ga
4693 summary_info += {'wixl': wixl}
4694 endif
4695 if slirp.found() and have_system
4696 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false}
4697 endif
4698 summary(summary_info, bool_yn: true, section: 'Host binaries')
4699
4700 # Configurable features
4701 summary_info = {}
4702 summary_info += {'Documentation': build_docs}
4703 summary_info += {'system-mode emulation': have_system}
4704 summary_info += {'user-mode emulation': have_user}
4705 summary_info += {'block layer': have_block}
4706 summary_info += {'Install blobs': get_option('install_blobs')}
4707 summary_info += {'module support': enable_modules}
4708 if enable_modules
4709 summary_info += {'alternative module path': get_option('module_upgrades')}
4710 endif
4711 summary_info += {'fuzzing support': get_option('fuzzing')}
4712 if have_system
4713 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
4714 endif
4715 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
4716 if 'simple' in get_option('trace_backends')
4717 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
4718 endif
4719 summary_info += {'QOM debugging': get_option('qom_cast_debug')}
4720 summary_info += {'Relocatable install': get_option('relocatable')}
4721 summary_info += {'vhost-kernel support': have_vhost_kernel}
4722 summary_info += {'vhost-net support': have_vhost_net}
4723 summary_info += {'vhost-user support': have_vhost_user}
4724 summary_info += {'vhost-user-crypto support': have_vhost_user_crypto}
4725 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
4726 summary_info += {'vhost-vdpa support': have_vhost_vdpa}
4727 summary_info += {'build guest agent': have_ga}
4728 summary(summary_info, bool_yn: true, section: 'Configurable features')
4729
4730 # Compilation information
4731 summary_info = {}
4732 summary_info += {'host CPU': cpu}
4733 summary_info += {'host endianness': build_machine.endian()}
4734 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
4735 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
4736 if 'cpp' in all_languages
4737 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
4738 else
4739 summary_info += {'C++ compiler': false}
4740 endif
4741 if 'objc' in all_languages
4742 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
4743 else
4744 summary_info += {'Objective-C compiler': false}
4745 endif
4746 summary_info += {'Rust support': have_rust}
4747 if have_rust
4748 summary_info += {'Rust target': rust.compiler_target(native: false)}
4749 summary_info += {'rustc': ' '.join(rustc.cmd_array())}
4750 summary_info += {'rustc version': rustc.version()}
4751 summary_info += {'rustdoc': rustdoc}
4752 summary_info += {'bindgen': bindgen.full_path()}
4753 summary_info += {'bindgen version': bindgen.version()}
4754 endif
4755 option_cflags = (get_option('debug') ? ['-g'] : [])
4756 if get_option('optimization') != 'plain'
4757 option_cflags += ['-O' + get_option('optimization')]
4758 endif
4759 summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)}
4760 if 'cpp' in all_languages
4761 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)}
4762 endif
4763 if 'objc' in all_languages
4764 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)}
4765 endif
4766 link_args = get_option('c_link_args')
4767 if link_args.length() > 0
4768 summary_info += {'LDFLAGS': ' '.join(link_args)}
4769 endif
4770 summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)}
4771 if 'cpp' in all_languages
4772 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)}
4773 endif
4774 if 'objc' in all_languages
4775 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)}
4776 endif
4777 summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
4778 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
4779 summary_info += {'PIE': get_option('b_pie')}
4780 summary_info += {'static build': get_option('prefer_static')}
4781 summary_info += {'malloc trim support': has_malloc_trim}
4782 summary_info += {'membarrier': have_membarrier}
4783 summary_info += {'debug graph lock': get_option('debug_graph_lock')}
4784 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
4785 summary_info += {'mutex debugging': get_option('debug_mutex')}
4786 summary_info += {'memory allocator': get_option('malloc')}
4787 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
4788 summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')}
4789 summary_info += {'gcov': get_option('b_coverage')}
4790 summary_info += {'thread sanitizer': get_option('tsan')}
4791 summary_info += {'CFI support': get_option('cfi')}
4792 if get_option('cfi')
4793 summary_info += {'CFI debug support': get_option('cfi_debug')}
4794 endif
4795 summary_info += {'strip binaries': get_option('strip')}
4796 summary_info += {'sparse': sparse}
4797 summary_info += {'mingw32 support': host_os == 'windows'}
4798 summary(summary_info, bool_yn: true, section: 'Compilation')
4799
4800 # snarf the cross-compilation information for tests
4801 summary_info = {}
4802 have_cross = false
4803 foreach target: target_dirs
4804 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak'
4805 if fs.exists(tcg_mak)
4806 config_cross_tcg = keyval.load(tcg_mak)
4807 if 'CC' in config_cross_tcg
4808 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']}
4809 have_cross = true
4810 endif
4811 endif
4812 endforeach
4813 if have_cross
4814 summary(summary_info, bool_yn: true, section: 'Cross compilers')
4815 endif
4816
4817 # Targets and accelerators
4818 summary_info = {}
4819 if have_system
4820 summary_info += {'KVM support': config_all_accel.has_key('CONFIG_KVM')}
4821 summary_info += {'Nitro support': config_all_accel.has_key('CONFIG_NITRO')}
4822 summary_info += {'HVF support': config_all_accel.has_key('CONFIG_HVF')}
4823 summary_info += {'WHPX support': config_all_accel.has_key('CONFIG_WHPX')}
4824 summary_info += {'NVMM support': config_all_accel.has_key('CONFIG_NVMM')}
4825 summary_info += {'MSHV support': config_all_accel.has_key('CONFIG_MSHV')}
4826 summary_info += {'Xen support': xen.found()}
4827 if xen.found()
4828 summary_info += {'xen ctrl version': xen.version()}
4829 endif
4830 summary_info += {'Xen emulation': config_all_devices.has_key('CONFIG_XEN_EMU')}
4831 endif
4832 summary_info += {'TCG support': config_all_accel.has_key('CONFIG_TCG')}
4833 if config_all_accel.has_key('CONFIG_TCG')
4834 if get_option('tcg_interpreter')
4835 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
4836 else
4837 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
4838 endif
4839 summary_info += {'TCG plugins': get_option('plugins')}
4840 summary_info += {'TCG debug enabled': get_option('debug_tcg')}
4841 if have_linux_user or have_bsd_user
4842 summary_info += {'syscall buffer debugging support': get_option('debug_remap')}
4843 endif
4844 endif
4845 summary_info += {'target list': ' '.join(target_dirs)}
4846 if have_system
4847 summary_info += {'default devices': get_option('default_devices')}
4848 summary_info += {'out of process emulation': multiprocess_allowed}
4849 summary_info += {'vfio-user server': vfio_user_server_allowed}
4850 endif
4851 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
4852
4853 # Block layer
4854 summary_info = {}
4855 summary_info += {'coroutine backend': coroutine_backend}
4856 summary_info += {'coroutine pool': have_coroutine_pool}
4857 if have_block
4858 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')}
4859 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')}
4860 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
4861 summary_info += {'VirtFS (9P) support': have_virtfs}
4862 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
4863 summary_info += {'bochs support': get_option('bochs').allowed()}
4864 summary_info += {'cloop support': get_option('cloop').allowed()}
4865 summary_info += {'dmg support': get_option('dmg').allowed()}
4866 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
4867 summary_info += {'vdi support': get_option('vdi').allowed()}
4868 summary_info += {'vhdx support': get_option('vhdx').allowed()}
4869 summary_info += {'vmdk support': get_option('vmdk').allowed()}
4870 summary_info += {'vpc support': get_option('vpc').allowed()}
4871 summary_info += {'vvfat support': get_option('vvfat').allowed()}
4872 summary_info += {'qed support': get_option('qed').allowed()}
4873 summary_info += {'parallels support': get_option('parallels').allowed()}
4874 summary_info += {'FUSE exports': fuse}
4875 summary_info += {'VDUSE block exports': have_vduse_blk_export}
4876 endif
4877 summary(summary_info, bool_yn: true, section: 'Block layer support')
4878
4879 # Crypto
4880 summary_info = {}
4881 summary_info += {'TLS priority': get_option('tls_priority')}
4882 summary_info += {'GNUTLS support': gnutls}
4883 if gnutls.found()
4884 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
4885 summary_info += {' GNUTLS bug 1717 workaround': gnutls_bug1717_workaround }
4886 endif
4887 summary_info += {'libgcrypt': gcrypt}
4888 summary_info += {'nettle': nettle}
4889 summary_info += {'SM4 ALG support': crypto_sm4}
4890 summary_info += {'SM3 ALG support': crypto_sm3}
4891 summary_info += {'AF_ALG support': have_afalg}
4892 summary_info += {'rng-none': get_option('rng_none')}
4893 summary_info += {'Linux keyring': have_keyring}
4894 summary_info += {'Linux keyutils': keyutils}
4895 summary(summary_info, bool_yn: true, section: 'Crypto')
4896
4897 # UI
4898 summary_info = {}
4899 if host_os == 'darwin'
4900 summary_info += {'Cocoa support': cocoa}
4901 endif
4902 summary_info += {'D-Bus display': dbus_display}
4903 summary_info += {'SDL support': sdl}
4904 summary_info += {'SDL image support': sdl_image}
4905 summary_info += {'GTK support': gtk}
4906 summary_info += {'pixman': pixman}
4907 summary_info += {'VTE support': vte}
4908 summary_info += {'PNG support': png}
4909 summary_info += {'VNC support': vnc}
4910 if vnc.found()
4911 summary_info += {'VNC SASL support': sasl}
4912 summary_info += {'VNC JPEG support': jpeg}
4913 endif
4914 summary_info += {'VNC D-Bus server (qemu-vnc)': have_qemu_vnc}
4915 summary_info += {'spice protocol support': spice_protocol}
4916 if spice_protocol.found()
4917 summary_info += {' spice server support': spice}
4918 endif
4919 summary_info += {'curses support': curses}
4920 summary_info += {'brlapi support': brlapi}
4921 summary(summary_info, bool_yn: true, section: 'User interface')
4922
4923 # Graphics backends
4924 summary_info = {}
4925 summary_info += {'VirGL support': virgl}
4926 summary_info += {'Rutabaga support': rutabaga}
4927 summary(summary_info, bool_yn: true, section: 'Graphics backends')
4928
4929 # Audio backends
4930 summary_info = {}
4931 if host_os not in ['darwin', 'haiku', 'windows']
4932 summary_info += {'OSS support': oss}
4933 summary_info += {'sndio support': sndio}
4934 elif host_os == 'darwin'
4935 summary_info += {'CoreAudio support': coreaudio}
4936 elif host_os == 'windows'
4937 summary_info += {'DirectSound support': dsound}
4938 endif
4939 if host_os == 'linux'
4940 summary_info += {'ALSA support': alsa}
4941 summary_info += {'PulseAudio support': pulse}
4942 endif
4943 summary_info += {'PipeWire support': pipewire}
4944 summary_info += {'JACK support': jack}
4945 summary(summary_info, bool_yn: true, section: 'Audio backends')
4946
4947 # Network backends
4948 summary_info = {}
4949 if host_os == 'darwin'
4950 summary_info += {'vmnet.framework support': vmnet}
4951 endif
4952 summary_info += {'AF_XDP support': libxdp}
4953 summary_info += {'passt support': enable_passt}
4954 summary_info += {'slirp support': slirp}
4955 summary_info += {'vde support': vde}
4956 summary_info += {'netmap support': have_netmap}
4957 summary_info += {'l2tpv3 support': have_l2tpv3}
4958 summary(summary_info, bool_yn: true, section: 'Network backends')
4959
4960 # Libraries
4961 summary_info = {}
4962 summary_info += {'libtasn1': tasn1}
4963 summary_info += {'PAM': pam}
4964 summary_info += {'iconv support': iconv}
4965 summary_info += {'blkio support': blkio}
4966 summary_info += {'curl support': curl}
4967 summary_info += {'Multipath support': mpathpersist}
4968 summary_info += {'Linux AIO support': libaio}
4969 summary_info += {'Linux io_uring support': linux_io_uring}
4970 summary_info += {'ATTR/XATTR support': libattr}
4971 summary_info += {'RDMA support': rdma}
4972 summary_info += {'fdt support': fdt_opt == 'internal' ? 'internal' : fdt}
4973 summary_info += {'libcap-ng support': libcap_ng}
4974 summary_info += {'bpf support': libbpf}
4975 summary_info += {'rbd support': rbd}
4976 summary_info += {'smartcard support': cacard}
4977 summary_info += {'U2F support': u2f}
4978 summary_info += {'libusb': libusb}
4979 summary_info += {'usb net redir': usbredir}
4980 summary_info += {'OpenGL support (epoxy)': opengl}
4981 summary_info += {'GBM': gbm}
4982 summary_info += {'libiscsi support': libiscsi}
4983 summary_info += {'libnfs support': libnfs}
4984 if host_os == 'windows'
4985 if have_ga
4986 summary_info += {'QGA VSS support': have_qga_vss}
4987 endif
4988 endif
4989 summary_info += {'seccomp support': seccomp}
4990 summary_info += {'hv-balloon support': hv_balloon}
4991 summary_info += {'TPM support': have_tpm}
4992 summary_info += {'IGVM support': igvm}
4993 summary_info += {'libssh support': libssh}
4994 summary_info += {'lzo support': lzo}
4995 summary_info += {'snappy support': snappy}
4996 summary_info += {'bzip2 support': libbzip2}
4997 summary_info += {'lzfse support': liblzfse}
4998 summary_info += {'zstd support': zstd}
4999 summary_info += {'Query Processing Library support': qpl}
5000 summary_info += {'UADK Library support': uadk}
Showing first 5,000 of 5,072 lines. View raw