]> git.proxmox.com Git - mirror_qemu.git/blame - meson.build
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging
[mirror_qemu.git] / meson.build
CommitLineData
3b087f79 1project('qemu', ['c'], meson_version: '>=0.63.0',
654d6b04 2 default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto',
0a31e3a0 3 'b_staticpic=false', 'stdsplit=false', 'optimization=2', 'b_pie=true'],
654d6b04 4 version: files('VERSION'))
a5665051 5
e287072b
TH
6add_test_setup('quick', exclude_suites: ['slow', 'thorough'], is_default: true)
7add_test_setup('slow', exclude_suites: ['thorough'], env: ['G_TEST_SLOW=1', 'SPEED=slow'])
8add_test_setup('thorough', env: ['G_TEST_SLOW=1', 'SPEED=thorough'])
3d2f73ef 9
cf60ccc3
AO
10meson.add_postconf_script(find_program('scripts/symlink-install-tree.py'))
11
a5665051 12not_found = dependency('', required: false)
654d6b04 13keyval = import('keyval')
a81df1b6 14ss = import('sourceset')
8b18cdbf 15fs = import('fs')
a81df1b6 16
e5134024 17targetos = host_machine.system()
ce1c1e7a 18sh = find_program('sh')
a5665051 19config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
d7dedf42 20
e5134024
PB
21cc = meson.get_compiler('c')
22all_languages = ['c']
23if add_languages('cpp', required: false, native: false)
24 all_languages += ['cpp']
25 cxx = meson.get_compiler('cpp')
26endif
27if targetos == 'darwin' and \
28 add_languages('objc', required: get_option('cocoa'), native: false)
29 all_languages += ['objc']
30 objc = meson.get_compiler('objc')
31endif
32
e3667660
YL
33# Temporary directory used for files created while
34# configure runs. Since it is in the build directory
35# we can safely blow away any previous version of it
36# (and we need not jump through hoops to try to delete
37# it when configure exits.)
38tmpdir = meson.current_build_dir() / 'meson-private/temp'
8fe11232
MAL
39
40if get_option('qemu_suffix').startswith('/')
41 error('qemu_suffix cannot start with a /')
42endif
43
16bf7a33 44qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
ab4c0996 45qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
491e74c1 46qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
16bf7a33
PB
47qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
48
49qemu_desktopdir = get_option('datadir') / 'applications'
50qemu_icondir = get_option('datadir') / 'icons'
51
859aef02
PB
52config_host_data = configuration_data()
53genh = []
b83a80e8 54qapi_trace_events = []
a5665051 55
20cf5cb4
PB
56bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin']
57supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
58supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
6d0b52ed 59 'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc64']
20cf5cb4
PB
60
61cpu = host_machine.cpu_family()
62
63# Unify riscv* to a single family.
64if cpu in ['riscv32', 'riscv64']
65 cpu = 'riscv'
66endif
67
760e4327 68target_dirs = config_host['TARGET_DIRS'].split()
dda2da6c
WL
69have_linux_user = false
70have_bsd_user = false
760e4327
PB
71have_system = false
72foreach target : target_dirs
dda2da6c
WL
73 have_linux_user = have_linux_user or target.endswith('linux-user')
74 have_bsd_user = have_bsd_user or target.endswith('bsd-user')
760e4327
PB
75 have_system = have_system or target.endswith('-softmmu')
76endforeach
dda2da6c 77have_user = have_linux_user or have_bsd_user
20cf5cb4
PB
78have_tools = get_option('tools') \
79 .disable_auto_if(not have_system) \
80 .allowed()
81have_ga = get_option('guest_agent') \
82 .disable_auto_if(not have_system and not have_tools) \
28236ad8 83 .require(targetos in ['sunos', 'linux', 'windows', 'freebsd', 'netbsd', 'openbsd'],
20cf5cb4
PB
84 error_message: 'unsupported OS for QEMU guest agent') \
85 .allowed()
6002711c
PB
86enable_modules = get_option('modules') \
87 .require(targetos != 'windows',
88 error_message: 'Modules are not available for Windows') \
89 .require(not get_option('prefer_static'),
90 error_message: 'Modules are incompatible with static linking') \
91 .allowed()
760e4327
PB
92have_block = have_system or have_tools
93
201e8ed7
PB
94python = import('python').find_installation()
95
823eb013
PB
96if cpu not in supported_cpus
97 host_arch = 'unknown'
98elif cpu == 'x86'
99 host_arch = 'i386'
0e3ed77d
RH
100elif cpu == 'mips64'
101 host_arch = 'mips'
823eb013
PB
102else
103 host_arch = cpu
104endif
105
8a19980e
PB
106if cpu in ['x86', 'x86_64']
107 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
108elif cpu == 'aarch64'
109 kvm_targets = ['aarch64-softmmu']
110elif cpu == 's390x'
111 kvm_targets = ['s390x-softmmu']
112elif cpu in ['ppc', 'ppc64']
113 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
fbc5884c
HC
114elif cpu in ['mips', 'mips64']
115 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
fbf43c7d
YJ
116elif cpu in ['riscv']
117 kvm_targets = ['riscv32-softmmu', 'riscv64-softmmu']
8a19980e
PB
118else
119 kvm_targets = []
120endif
121
44d3d898 122kvm_targets_c = '""'
43a363ae 123if get_option('kvm').allowed() and targetos == 'linux'
e741aff0
IM
124 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
125endif
126config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
127
8a19980e 128accelerator_targets = { 'CONFIG_KVM': kvm_targets }
844a06bb
AG
129
130if cpu in ['aarch64']
131 accelerator_targets += {
132 'CONFIG_HVF': ['aarch64-softmmu']
133 }
134endif
135
0c3e41d4 136if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
2a2d51bc 137 # i386 emulator provides xenpv machine type for multiple architectures
0c3e41d4
AB
138 accelerator_targets += {
139 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
140 }
141endif
8a19980e
PB
142if cpu in ['x86', 'x86_64']
143 accelerator_targets += {
144 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
8a19980e 145 'CONFIG_HVF': ['x86_64-softmmu'],
74a414a1 146 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
8a19980e
PB
147 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
148 }
149endif
150
a1b176f9
PB
151modular_tcg = []
152# Darwin does not support references to thread-local variables in modules
153if targetos != 'darwin'
154 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
155endif
dae0ec15 156
eae9a1d1 157edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
e49c0ef6
PB
158unpack_edk2_blobs = false
159foreach target : edk2_targets
160 if target in target_dirs
161 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
162 unpack_edk2_blobs = bzip2.found()
163 break
164 endif
165endforeach
45b545dd 166
9c29b741
PB
167dtrace = not_found
168stap = not_found
169if 'dtrace' in get_option('trace_backends')
170 dtrace = find_program('dtrace', required: true)
171 stap = find_program('stap', required: false)
172 if stap.found()
173 # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
174 # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
175 # instead. QEMU --enable-modules depends on this because the SystemTap
176 # semaphores are linked into the main binary and not the module's shared
177 # object.
178 add_global_arguments('-DSTAP_SDT_V2',
e5134024 179 native: false, language: all_languages)
9c29b741
PB
180 endif
181endif
182
40c909f5
PB
183if get_option('iasl') == ''
184 iasl = find_program('iasl', required: false)
185else
186 iasl = find_program(get_option('iasl'), required: true)
187endif
188
201e8ed7
PB
189##################
190# Compiler flags #
191##################
192
13f60de8
PB
193foreach lang : all_languages
194 compiler = meson.get_compiler(lang)
195 if compiler.get_id() == 'gcc' and compiler.version().version_compare('>=7.4')
196 # ok
197 elif compiler.get_id() == 'clang' and compiler.compiles('''
198 #ifdef __apple_build_version__
199 # if __clang_major__ < 12 || (__clang_major__ == 12 && __clang_minor__ < 0)
200 # error You need at least XCode Clang v12.0 to compile QEMU
201 # endif
202 #else
203 # if __clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 0)
204 # error You need at least Clang v10.0 to compile QEMU
205 # endif
206 #endif''')
207 # ok
208 else
209 error('You either need GCC v7.4 or Clang v10.0 (or XCode Clang v12.0) to compile QEMU')
210 endif
211endforeach
212
a988b4c5
PB
213# default flags for all hosts
214# We use -fwrapv to tell the compiler that we require a C dialect where
215# left shift of signed integers is well defined and has the expected
216# 2s-complement style results. (Both clang and gcc agree that it
217# provides these semantics.)
218
219qemu_common_flags = [
220 '-D_GNU_SOURCE', '-D_FILE_OFFSET_BITS=64', '-D_LARGEFILE_SOURCE',
221 '-fno-strict-aliasing', '-fno-common', '-fwrapv' ]
d67212d4 222qemu_cflags = []
911d4caa 223qemu_ldflags = []
8cc2d231 224
a988b4c5
PB
225if targetos == 'darwin'
226 # Disable attempts to use ObjectiveC features in os/object.h since they
227 # won't work when we're compiling with gcc as a C compiler.
228 qemu_common_flags += '-DOS_OBJECT_USE_OBJC=0'
229elif targetos == 'solaris'
230 # needed for CMSG_ macros in sys/socket.h
231 qemu_common_flags += '-D_XOPEN_SOURCE=600'
232 # needed for TIOCWIN* defines in termios.h
233 qemu_common_flags += '-D__EXTENSIONS__'
234elif targetos == 'haiku'
235 qemu_common_flags += ['-DB_USE_POSITIVE_POSIX_ERRORS', '-D_BSD_SOURCE', '-fPIC']
236endif
237
238# __sync_fetch_and_and requires at least -march=i486. Many toolchains
239# use i686 as default anyway, but for those that don't, an explicit
240# specification is necessary
241if host_arch == 'i386' and not cc.links('''
242 static int sfaa(int *ptr)
243 {
244 return __sync_fetch_and_and(ptr, 0);
245 }
246
247 int main(void)
248 {
249 int val = 42;
250 val = __sync_val_compare_and_swap(&val, 0, 1);
251 sfaa(&val);
252 return val;
253 }''')
254 qemu_common_flags = ['-march=i486'] + qemu_common_flags
255endif
256
d67212d4
PB
257if get_option('gprof')
258 qemu_common_flags += ['-p']
259 qemu_ldflags += ['-p']
260endif
261
a0cbd2e8 262if get_option('prefer_static')
e4333d14
PB
263 qemu_ldflags += get_option('b_pie') ? '-static-pie' : '-static'
264endif
265
a988b4c5
PB
266# Meson currently only handles pie as a boolean for now, so if the user
267# has explicitly disabled PIE we need to extend our cflags.
268if not get_option('b_pie')
269 qemu_common_flags += cc.get_supported_arguments('-fno-pie')
270 if not get_option('prefer_static')
271 # No PIE is implied by -static which we added above.
272 qemu_ldflags += cc.get_supported_link_arguments('-no-pie')
273 endif
274endif
275
911d4caa
PB
276if not get_option('stack_protector').disabled()
277 stack_protector_probe = '''
278 int main(int argc, char *argv[])
279 {
280 char arr[64], *p = arr, *c = argv[argc - 1];
281 while (*c) {
282 *p++ = *c++;
283 }
284 return 0;
285 }'''
286 have_stack_protector = false
287 foreach arg : ['-fstack-protector-strong', '-fstack-protector-all']
288 # We need to check both a compile and a link, since some compiler
289 # setups fail only on a .c->.o compile and some only at link time
290 if cc.compiles(stack_protector_probe, args: ['-Werror', arg]) and \
291 cc.links(stack_protector_probe, args: ['-Werror', arg])
292 have_stack_protector = true
293 qemu_cflags += arg
294 qemu_ldflags += arg
295 break
296 endif
297 endforeach
298 get_option('stack_protector') \
299 .require(have_stack_protector, error_message: 'Stack protector not supported')
300endif
301
6739825a
PB
302coroutine_backend = get_option('coroutine_backend')
303ucontext_probe = '''
304 #include <ucontext.h>
305 #ifdef __stub_makecontext
306 #error Ignoring glibc stub makecontext which will always fail
307 #endif
308 int main(void) { makecontext(0, 0, 0); return 0; }'''
309
310# On Windows the only valid backend is the Windows specific one.
311# For POSIX prefer ucontext, but it's not always possible. The fallback
312# is sigcontext.
313supported_backends = []
314if targetos == 'windows'
315 supported_backends += ['windows']
316else
317 if targetos != 'darwin' and cc.links(ucontext_probe)
318 supported_backends += ['ucontext']
319 endif
320 supported_backends += ['sigaltstack']
321endif
322
323if coroutine_backend == 'auto'
324 coroutine_backend = supported_backends[0]
325elif coroutine_backend not in supported_backends
326 error('"@0@" backend requested but not available. Available backends: @1@' \
327 .format(coroutine_backend, ', '.join(supported_backends)))
328endif
329
721fa5e5
PB
330# Compiles if SafeStack *not* enabled
331safe_stack_probe = '''
332 int main(void)
333 {
334 #if defined(__has_feature)
335 #if __has_feature(safe_stack)
336 #error SafeStack Enabled
337 #endif
338 #endif
339 return 0;
340 }'''
341if get_option('safe_stack') != not cc.compiles(safe_stack_probe)
342 safe_stack_arg = get_option('safe_stack') ? '-fsanitize=safe-stack' : '-fno-sanitize=safe-stack'
343 if get_option('safe_stack') != not cc.compiles(safe_stack_probe, args: safe_stack_arg)
344 error(get_option('safe_stack') \
345 ? 'SafeStack not supported by your compiler' \
346 : 'Cannot disable SafeStack')
347 endif
348 qemu_cflags += safe_stack_arg
349 qemu_ldflags += safe_stack_arg
350endif
6739825a 351if get_option('safe_stack') and coroutine_backend != 'ucontext'
721fa5e5
PB
352 error('SafeStack is only supported with the ucontext coroutine backend')
353endif
354
34f983d8
PB
355if get_option('sanitizers')
356 if cc.has_argument('-fsanitize=address')
357 qemu_cflags = ['-fsanitize=address'] + qemu_cflags
358 qemu_ldflags = ['-fsanitize=address'] + qemu_ldflags
359 endif
360
361 # Detect static linking issue with ubsan - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84285
362 if cc.links('int main(int argc, char **argv) { return argc + 1; }',
363 args: [qemu_ldflags, '-fsanitize=undefined'])
364 qemu_cflags = ['-fsanitize=undefined'] + qemu_cflags
365 qemu_ldflags = ['-fsanitize=undefined'] + qemu_ldflags
366 endif
367endif
368
369# Thread sanitizer is, for now, much noisier than the other sanitizers;
370# keep it separate until that is not the case.
371if get_option('tsan')
372 if get_option('sanitizers')
373 error('TSAN is not supported with other sanitizers')
374 endif
375 if not cc.has_function('__tsan_create_fiber',
376 args: '-fsanitize=thread',
377 prefix: '#include <sanitizer/tsan_interface.h>')
378 error('Cannot enable TSAN due to missing fiber annotation interface')
379 endif
380 qemu_cflags = ['-fsanitize=thread'] + qemu_cflags
381 qemu_ldflags = ['-fsanitize=thread'] + qemu_ldflags
382endif
383
e4333d14
PB
384# Detect support for PT_GNU_RELRO + DT_BIND_NOW.
385# The combination is known as "full relro", because .got.plt is read-only too.
386qemu_ldflags += cc.get_supported_link_arguments('-Wl,-z,relro', '-Wl,-z,now')
387
d2147e04
PB
388if targetos == 'windows'
389 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--no-seh', '-Wl,--nxcompat')
2d73fa74 390 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--dynamicbase', '-Wl,--high-entropy-va')
d2147e04
PB
391endif
392
d67212d4 393# Exclude --warn-common with TSan to suppress warnings from the TSan libraries.
34f983d8 394if targetos != 'sunos' and not get_option('tsan')
d67212d4 395 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--warn-common')
c55cf6ab
PB
396endif
397
ff9ed62b
AB
398# Specify linker-script with add_project_link_arguments so that it is not placed
399# within a linker --start-group/--end-group pair
537b7248 400if get_option('fuzzing')
537b7248
PB
401 # Specify a filter to only instrument code that is directly related to
402 # virtual-devices.
403 configure_file(output: 'instrumentation-filter',
404 input: 'scripts/oss-fuzz/instrumentation-filter-template',
405 copy: true)
aa4f3a3b
AB
406
407 if cc.compiles('int main () { return 0; }',
408 name: '-fsanitize-coverage-allowlist=/dev/null',
e56d0970
AB
409 args: ['-fsanitize-coverage-allowlist=/dev/null',
410 '-fsanitize-coverage=trace-pc'] )
d67212d4 411 qemu_common_flags += ['-fsanitize-coverage-allowlist=instrumentation-filter']
aa4f3a3b 412 endif
537b7248
PB
413
414 if get_option('fuzzing_engine') == ''
415 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
416 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
417 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
418 # unable to bind the fuzzer-related callbacks added by instrumentation.
d67212d4
PB
419 qemu_common_flags += ['-fsanitize=fuzzer-no-link']
420 qemu_ldflags += ['-fsanitize=fuzzer-no-link']
537b7248
PB
421 # For the actual fuzzer binaries, we need to link against the libfuzzer
422 # library. They need to be configurable, to support OSS-Fuzz
423 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
424 else
425 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
426 # the needed CFLAGS have already been provided
427 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
428 endif
ff9ed62b
AB
429endif
430
d67212d4
PB
431add_global_arguments(qemu_common_flags, native: false, language: all_languages)
432add_global_link_arguments(qemu_ldflags, native: false, language: all_languages)
433
95caf1fb
PB
434# Collect warnings that we want to enable
435
436warn_flags = [
437 '-Wundef',
438 '-Wwrite-strings',
439 '-Wmissing-prototypes',
440 '-Wstrict-prototypes',
441 '-Wredundant-decls',
442 '-Wold-style-declaration',
443 '-Wold-style-definition',
444 '-Wtype-limits',
445 '-Wformat-security',
446 '-Wformat-y2k',
447 '-Winit-self',
448 '-Wignored-qualifiers',
449 '-Wempty-body',
450 '-Wnested-externs',
451 '-Wendif-labels',
452 '-Wexpansion-to-defined',
453 '-Wimplicit-fallthrough=2',
454 '-Wmissing-format-attribute',
455 '-Wno-initializer-overrides',
456 '-Wno-missing-include-dirs',
457 '-Wno-shift-negative-value',
458 '-Wno-string-plus-int',
459 '-Wno-typedef-redefinition',
460 '-Wno-tautological-type-limit-compare',
461 '-Wno-psabi',
462 '-Wno-gnu-variable-sized-type-not-at-end',
463]
464
465if targetos != 'darwin'
466 warn_flags += ['-Wthread-safety']
467endif
468
b485458e
PB
469# Check that the C++ compiler exists and works with the C compiler.
470link_language = 'c'
471linker = cc
472qemu_cxxflags = []
e5134024 473if 'cpp' in all_languages
95caf1fb 474 qemu_cxxflags = ['-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', '-D__STDC_FORMAT_MACROS'] + qemu_cflags
b485458e
PB
475 if cxx.links(files('scripts/main.c'), args: qemu_cflags)
476 link_language = 'cpp'
477 linker = cxx
478 else
479 message('C++ compiler does not work with C compiler')
480 message('Disabling C++-specific optional code')
481 endif
482endif
483
34f983d8
PB
484# clang does not support glibc + FORTIFY_SOURCE (is it still true?)
485if get_option('optimization') != '0' and targetos == 'linux'
486 if cc.get_id() == 'gcc'
487 qemu_cflags += ['-U_FORTIFY_SOURCE', '-D_FORTIFY_SOURCE=2']
488 endif
489 if 'cpp' in all_languages and cxx.get_id() == 'gcc'
490 qemu_cxxflags += ['-U_FORTIFY_SOURCE', '-D_FORTIFY_SOURCE=2']
491 endif
492endif
493
d67212d4 494add_project_arguments(qemu_cflags, native: false, language: 'c')
95caf1fb
PB
495add_project_arguments(cc.get_supported_arguments(warn_flags), native: false, language: 'c')
496if 'cpp' in all_languages
497 add_project_arguments(qemu_cxxflags, native: false, language: 'cpp')
498 add_project_arguments(cxx.get_supported_arguments(warn_flags), native: false, language: 'cpp')
499endif
500if 'objc' in all_languages
501 # Note sanitizer flags are not applied to Objective-C sources!
502 add_project_arguments(objc.get_supported_arguments(warn_flags), native: false, language: 'objc')
503endif
1e6e616d
PB
504if targetos == 'linux'
505 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
506 '-isystem', 'linux-headers',
e5134024 507 language: all_languages)
1e6e616d
PB
508endif
509
23a77b2d 510add_project_arguments('-iquote', '.',
1e6e616d 511 '-iquote', meson.current_source_dir(),
1e6e616d 512 '-iquote', meson.current_source_dir() / 'include',
e5134024 513 language: all_languages)
a5665051 514
deb62371
PB
515sparse = find_program('cgcc', required: get_option('sparse'))
516if sparse.found()
968b4db3
PB
517 run_target('sparse',
518 command: [find_program('scripts/check_sparse.py'),
deb62371
PB
519 'compile_commands.json', sparse.full_path(), '-Wbitwise',
520 '-Wno-transparent-union', '-Wno-old-initializer',
521 '-Wno-non-pointer-null'])
968b4db3
PB
522endif
523
6ec0e15d
PB
524###########################################
525# Target-specific checks and dependencies #
526###########################################
527
b7a75c8c 528# Fuzzing
537b7248
PB
529if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
530 not cc.links('''
531 #include <stdint.h>
532 #include <sys/types.h>
533 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
534 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
535 ''',
536 args: ['-Werror', '-fsanitize=fuzzer'])
537 error('Your compiler does not support -fsanitize=fuzzer')
538endif
539
b7a75c8c 540# Tracing backends
9c29b741
PB
541if 'ftrace' in get_option('trace_backends') and targetos != 'linux'
542 error('ftrace is supported only on Linux')
543endif
544if 'syslog' in get_option('trace_backends') and not cc.compiles('''
545 #include <syslog.h>
546 int main(void) {
547 openlog("qemu", LOG_PID, LOG_DAEMON);
548 syslog(LOG_INFO, "configure");
549 return 0;
550 }''')
551 error('syslog is not supported on this system')
552endif
553
b7a75c8c 554# Miscellaneous Linux-only features
a436d6d4
PB
555get_option('mpath') \
556 .require(targetos == 'linux', error_message: 'Multipath is supported only on Linux')
6ec0e15d 557
a436d6d4
PB
558multiprocess_allowed = get_option('multiprocess') \
559 .require(targetos == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \
560 .allowed()
106ad1f9 561
55116968
JR
562vfio_user_server_allowed = get_option('vfio_user_server') \
563 .require(targetos == 'linux', error_message: 'vfio-user server is supported only on Linux') \
564 .allowed()
565
0d04c4c9
PB
566have_tpm = get_option('tpm') \
567 .require(targetos != 'windows', error_message: 'TPM emulation only available on POSIX systems') \
568 .allowed()
569
2a3129a3 570# vhost
2df89d54
PB
571have_vhost_user = get_option('vhost_user') \
572 .disable_auto_if(targetos != 'linux') \
573 .require(targetos != 'windows',
574 error_message: 'vhost-user is not available on Windows').allowed()
575have_vhost_vdpa = get_option('vhost_vdpa') \
576 .require(targetos == 'linux',
577 error_message: 'vhost-vdpa is only available on Linux').allowed()
578have_vhost_kernel = get_option('vhost_kernel') \
579 .require(targetos == 'linux',
580 error_message: 'vhost-kernel is only available on Linux').allowed()
581have_vhost_user_crypto = get_option('vhost_crypto') \
582 .require(have_vhost_user,
583 error_message: 'vhost-crypto requires vhost-user to be enabled').allowed()
584
43b6d7ee 585have_vhost = have_vhost_user or have_vhost_vdpa or have_vhost_kernel
2df89d54
PB
586
587have_vhost_net_user = have_vhost_user and get_option('vhost_net').allowed()
588have_vhost_net_vdpa = have_vhost_vdpa and get_option('vhost_net').allowed()
589have_vhost_net_kernel = have_vhost_kernel and get_option('vhost_net').allowed()
590have_vhost_net = have_vhost_net_kernel or have_vhost_net_user or have_vhost_net_vdpa
2a3129a3 591
b7a75c8c 592# Target-specific libraries and flags
7fa1c635 593libm = cc.find_library('m', required: false)
6d7c7c2d 594threads = dependency('threads')
a81df1b6 595util = cc.find_library('util', required: false)
4a96337d 596winmm = []
a81df1b6 597socket = []
04c6f1e7 598version_res = []
d92989aa
MAL
599coref = []
600iokit = []
b6c7cfd4 601emulator_link_args = []
74a414a1 602nvmm =not_found
8a19980e 603hvf = not_found
23011f44
MAL
604midl = not_found
605widl = not_found
cf60ccc3 606pathcch = not_found
a6305081 607host_dsosuf = '.so'
a81df1b6 608if targetos == 'windows'
23011f44
MAL
609 midl = find_program('midl', required: false)
610 widl = find_program('widl', required: false)
cf60ccc3 611 pathcch = cc.find_library('pathcch')
a81df1b6 612 socket = cc.find_library('ws2_32')
4a96337d 613 winmm = cc.find_library('winmm')
04c6f1e7
MAL
614
615 win = import('windows')
616 version_res = win.compile_resources('version.rc',
617 depend_files: files('pc-bios/qemu-nsis.ico'),
618 include_directories: include_directories('.'))
a6305081 619 host_dsosuf = '.dll'
d92989aa
MAL
620elif targetos == 'darwin'
621 coref = dependency('appleframeworks', modules: 'CoreFoundation')
14176c8d 622 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
a6305081 623 host_dsosuf = '.dylib'
cfad62f1
PB
624elif targetos == 'sunos'
625 socket = [cc.find_library('socket'),
626 cc.find_library('nsl'),
627 cc.find_library('resolv')]
628elif targetos == 'haiku'
629 socket = [cc.find_library('posix_error_mapper'),
630 cc.find_library('network'),
631 cc.find_library('bsd')]
b6c7cfd4 632elif targetos == 'openbsd'
43a363ae 633 if get_option('tcg').allowed() and target_dirs.length() > 0
b6c7cfd4
PB
634 # Disable OpenBSD W^X if available
635 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
636 endif
a81df1b6 637endif
6ec0e15d 638
b7a75c8c 639# Target-specific configuration of accelerators
8a19980e 640accelerators = []
43a363ae 641if get_option('kvm').allowed() and targetos == 'linux'
8a19980e
PB
642 accelerators += 'CONFIG_KVM'
643endif
43a363ae 644if get_option('whpx').allowed() and targetos == 'windows'
57e2a1f8 645 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
8a19980e
PB
646 error('WHPX requires 64-bit host')
647 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
648 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
649 accelerators += 'CONFIG_WHPX'
650 endif
651endif
43a363ae 652if get_option('hvf').allowed()
8a19980e
PB
653 hvf = dependency('appleframeworks', modules: 'Hypervisor',
654 required: get_option('hvf'))
655 if hvf.found()
656 accelerators += 'CONFIG_HVF'
657 endif
658endif
43a363ae 659if get_option('hax').allowed()
8a19980e
PB
660 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
661 accelerators += 'CONFIG_HAX'
662 endif
663endif
74a414a1 664if targetos == 'netbsd'
0cc49650 665 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
74a414a1
RZ
666 if nvmm.found()
667 accelerators += 'CONFIG_NVMM'
668 endif
669endif
23a77b2d 670
823eb013 671tcg_arch = host_arch
43a363ae 672if get_option('tcg').allowed()
823eb013 673 if host_arch == 'unknown'
23a77b2d 674 if get_option('tcg_interpreter')
f1f727ac 675 warning('Unsupported CPU @0@, will use TCG with TCI (slow)'.format(cpu))
8a19980e
PB
676 else
677 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
678 endif
fa2f7b0b 679 elif get_option('tcg_interpreter')
1c282da3 680 warning('Use of the TCG interpreter is not recommended on this host')
fa2f7b0b
PMD
681 warning('architecture. There is a native TCG execution backend available')
682 warning('which provides substantially better performance and reliability.')
683 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
684 warning('configuration option on this architecture to use the native')
685 warning('backend.')
8a19980e 686 endif
23a77b2d
PB
687 if get_option('tcg_interpreter')
688 tcg_arch = 'tci'
ed145144 689 config_host += { 'CONFIG_TCG_INTERPRETER': 'y' }
823eb013 690 elif host_arch == 'x86_64'
23a77b2d 691 tcg_arch = 'i386'
823eb013 692 elif host_arch == 'ppc64'
23a77b2d 693 tcg_arch = 'ppc'
23a77b2d
PB
694 endif
695 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
e5134024 696 language: all_languages)
23a77b2d 697
8a19980e
PB
698 accelerators += 'CONFIG_TCG'
699 config_host += { 'CONFIG_TCG': 'y' }
700endif
701
702if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
703 error('KVM not available on this platform')
704endif
705if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
706 error('HVF not available on this platform')
707endif
74a414a1
RZ
708if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
709 error('NVMM not available on this platform')
710endif
8a19980e
PB
711if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
712 error('WHPX not available on this platform')
713endif
b4e312e9 714
6ec0e15d
PB
715################
716# Dependencies #
717################
718
fc9a809e
PB
719# When bumping glib minimum version, please check also whether to increase
720# the _WIN32_WINNT setting in osdep.h according to the value from glib
721glib_req_ver = '>=2.56.0'
722glib_pc = dependency('glib-2.0', version: glib_req_ver, required: true,
723 method: 'pkg-config')
724glib_cflags = []
6002711c 725if enable_modules
fc9a809e
PB
726 gmodule = dependency('gmodule-export-2.0', version: glib_req_ver, required: true,
727 method: 'pkg-config')
728elif config_host.has_key('CONFIG_PLUGIN')
729 gmodule = dependency('gmodule-no-export-2.0', version: glib_req_ver, required: true,
730 method: 'pkg-config')
731else
732 gmodule = not_found
733endif
734
735# This workaround is required due to a bug in pkg-config file for glib as it
736# doesn't define GLIB_STATIC_COMPILATION for pkg-config --static
737if targetos == 'windows' and get_option('prefer_static')
738 glib_cflags += ['-DGLIB_STATIC_COMPILATION']
739endif
740
741# Sanity check that the current size_t matches the
742# size that glib thinks it should be. This catches
743# problems on multi-arch where people try to build
744# 32-bit QEMU while pointing at 64-bit glib headers
745
746if not cc.compiles('''
747 #include <glib.h>
748 #include <unistd.h>
749
750 #define QEMU_BUILD_BUG_ON(x) \
751 typedef char qemu_build_bug_on[(x)?-1:1] __attribute__((unused));
752
753 int main(void) {
754 QEMU_BUILD_BUG_ON(sizeof(size_t) != GLIB_SIZEOF_SIZE_T);
755 return 0;
756 }''', dependencies: glib_pc, args: glib_cflags)
757 error('''sizeof(size_t) doesn't match GLIB_SIZEOF_SIZE_T.
758 You probably need to set PKG_CONFIG_LIBDIR" to point
759 to the right pkg-config files for your build target.''')
760endif
761
762# Silence clang warnings triggered by glib < 2.57.2
763if not cc.compiles('''
764 #include <glib.h>
765 typedef struct Foo {
766 int i;
767 } Foo;
768 static void foo_free(Foo *f)
769 {
770 g_free(f);
771 }
772 G_DEFINE_AUTOPTR_CLEANUP_FUNC(Foo, foo_free)
773 int main(void) { return 0; }''', dependencies: glib_pc, args: ['-Werror'])
774 glib_cflags += cc.get_supported_arguments('-Wno-unused-function')
e3feb2cc 775endif
fc9a809e
PB
776glib = declare_dependency(dependencies: [glib_pc, gmodule],
777 compile_args: glib_cflags,
778 version: glib_pc.version())
779
780# Check whether glib has gslice, which we have to avoid for correctness.
781# TODO: remove this check and the corresponding workaround (qtree) when
782# the minimum supported glib is >= 2.75.3
783glib_has_gslice = glib.version().version_compare('<2.75.3')
784
785# override glib dep to include the above refinements
786meson.override_dependency('glib-2.0', glib)
787
788# The path to glib.h is added to all compilation commands.
789add_project_dependencies(glib.partial_dependency(compile_args: true, includes: true),
790 native: false, language: all_languages)
953d5a9e 791
a81df1b6 792gio = not_found
7544060e 793gdbus_codegen = not_found
bb2dc4b7 794gdbus_codegen_error = '@0@ requires gdbus-codegen, please install libgio'
7544060e
PB
795if not get_option('gio').auto() or have_system
796 gio = dependency('gio-2.0', required: get_option('gio'),
063d5119 797 method: 'pkg-config')
7544060e
PB
798 if gio.found() and not cc.links('''
799 #include <gio/gio.h>
800 int main(void)
801 {
802 g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0);
803 return 0;
804 }''', dependencies: [glib, gio])
805 if get_option('gio').enabled()
806 error('The installed libgio is broken for static linking')
807 endif
808 gio = not_found
809 endif
810 if gio.found()
811 gdbus_codegen = find_program(gio.get_variable('gdbus_codegen'),
812 required: get_option('gio'))
813 gio_unix = dependency('gio-unix-2.0', required: get_option('gio'),
063d5119 814 method: 'pkg-config')
7544060e
PB
815 gio = declare_dependency(dependencies: [gio, gio_unix],
816 version: gio.version())
817 endif
a81df1b6 818endif
bb2dc4b7
PB
819if gdbus_codegen.found() and get_option('cfi')
820 gdbus_codegen = not_found
821 gdbus_codegen_error = '@0@ uses gdbus-codegen, which does not support control flow integrity'
822endif
7544060e 823
a81df1b6 824lttng = not_found
9c29b741 825if 'ust' in get_option('trace_backends')
e32aaa5a 826 lttng = dependency('lttng-ust', required: true, version: '>= 2.1',
063d5119 827 method: 'pkg-config')
a81df1b6 828endif
b7612f45
PB
829pixman = not_found
830if have_system or have_tools
831 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
063d5119 832 method: 'pkg-config')
b7612f45 833endif
063d5119 834zlib = dependency('zlib', required: true)
53c22b68 835
ff66f3e5
PB
836libaio = not_found
837if not get_option('linux_aio').auto() or have_block
838 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
063d5119 839 required: get_option('linux_aio'))
ff66f3e5 840endif
354081d4
LB
841
842linux_io_uring_test = '''
843 #include <liburing.h>
844 #include <linux/errqueue.h>
845
846 int main(void) { return 0; }'''
847
5e5733e5 848linux_io_uring = not_found
53c22b68 849if not get_option('linux_io_uring').auto() or have_block
a41b4fdc
DB
850 linux_io_uring = dependency('liburing', version: '>=0.3',
851 required: get_option('linux_io_uring'),
063d5119 852 method: 'pkg-config')
354081d4
LB
853 if not cc.links(linux_io_uring_test)
854 linux_io_uring = not_found
855 endif
5e5733e5 856endif
354081d4 857
5e5733e5 858libnfs = not_found
30045c05
PB
859if not get_option('libnfs').auto() or have_block
860 libnfs = dependency('libnfs', version: '>=1.9.3',
861 required: get_option('libnfs'),
063d5119 862 method: 'pkg-config')
5e5733e5 863endif
f7f2d651
PB
864
865libattr_test = '''
866 #include <stddef.h>
867 #include <sys/types.h>
868 #ifdef CONFIG_LIBATTR
869 #include <attr/xattr.h>
870 #else
871 #include <sys/xattr.h>
872 #endif
873 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
874
ec0d5893 875libattr = not_found
f7f2d651 876have_old_libattr = false
43a363ae 877if get_option('attr').allowed()
f7f2d651
PB
878 if cc.links(libattr_test)
879 libattr = declare_dependency()
880 else
881 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
063d5119 882 required: get_option('attr'))
f7f2d651
PB
883 if libattr.found() and not \
884 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
885 libattr = not_found
886 if get_option('attr').enabled()
887 error('could not link libattr')
888 else
889 warning('could not link libattr, disabling')
890 endif
891 else
892 have_old_libattr = libattr.found()
893 endif
894 endif
ec0d5893 895endif
f7f2d651 896
52eaefd3
AO
897cocoa = dependency('appleframeworks', modules: ['Cocoa', 'CoreVideo'],
898 required: get_option('cocoa'))
c1ec4941 899
e2c1d78d
VY
900vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
901if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
902 'VMNET_BRIDGED_MODE',
903 dependencies: vmnet)
904 vmnet = not_found
905 if get_option('vmnet').enabled()
906 error('vmnet.framework API is outdated')
907 else
908 warning('vmnet.framework API is outdated, disabling')
909 endif
910endif
911
3f99cf57 912seccomp = not_found
73422d95 913seccomp_has_sysrawrc = false
90835c2b
PB
914if not get_option('seccomp').auto() or have_system or have_tools
915 seccomp = dependency('libseccomp', version: '>=2.3.0',
916 required: get_option('seccomp'),
063d5119 917 method: 'pkg-config')
73422d95
MP
918 if seccomp.found()
919 seccomp_has_sysrawrc = cc.has_header_symbol('seccomp.h',
920 'SCMP_FLTATR_API_SYSRAWRC',
921 dependencies: seccomp)
922 endif
3f99cf57 923endif
727c8bb8 924
3f99cf57 925libcap_ng = not_found
727c8bb8
PB
926if not get_option('cap_ng').auto() or have_system or have_tools
927 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
063d5119 928 required: get_option('cap_ng'))
727c8bb8
PB
929endif
930if libcap_ng.found() and not cc.links('''
931 #include <cap-ng.h>
932 int main(void)
933 {
934 capng_capability_to_name(CAPNG_EFFECTIVE);
935 return 0;
936 }''', dependencies: libcap_ng)
937 libcap_ng = not_found
938 if get_option('cap_ng').enabled()
939 error('could not link libcap-ng')
940 else
941 warning('could not link libcap-ng, disabling')
942 endif
3f99cf57 943endif
727c8bb8 944
1917ec6d
PB
945if get_option('xkbcommon').auto() and not have_system and not have_tools
946 xkbcommon = not_found
947else
948 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
063d5119 949 method: 'pkg-config')
ade60d4f 950endif
e1723999 951
5890258a
TH
952slirp = not_found
953if not get_option('slirp').auto() or have_system
954 slirp = dependency('slirp', required: get_option('slirp'),
063d5119 955 method: 'pkg-config')
5890258a
TH
956 # slirp < 4.7 is incompatible with CFI support in QEMU. This is because
957 # it passes function pointers within libslirp as callbacks for timers.
958 # When using a system-wide shared libslirp, the type information for the
959 # callback is missing and the timer call produces a false positive with CFI.
960 # Do not use the "version" keyword argument to produce a better error.
961 # with control-flow integrity.
962 if get_option('cfi') and slirp.found() and slirp.version().version_compare('<4.7')
963 if get_option('slirp').enabled()
964 error('Control-Flow Integrity requires libslirp 4.7.')
965 else
966 warning('Cannot use libslirp since Control-Flow Integrity requires libslirp >= 4.7.')
967 slirp = not_found
968 endif
969 endif
970endif
971
cdaf0722 972vde = not_found
e1723999
PB
973if not get_option('vde').auto() or have_system or have_tools
974 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
063d5119 975 required: get_option('vde'))
e1723999
PB
976endif
977if vde.found() and not cc.links('''
978 #include <libvdeplug.h>
979 int main(void)
980 {
981 struct vde_open_args a = {0, 0, 0};
982 char s[] = "";
983 vde_open(s, s, &a);
984 return 0;
985 }''', dependencies: vde)
986 vde = not_found
987 if get_option('cap_ng').enabled()
988 error('could not link libvdeplug')
989 else
990 warning('could not link libvdeplug, disabling')
991 endif
cdaf0722 992endif
87430d5b 993
478e943f 994pulse = not_found
87430d5b
PB
995if not get_option('pa').auto() or (targetos == 'linux' and have_system)
996 pulse = dependency('libpulse', required: get_option('pa'),
063d5119 997 method: 'pkg-config')
478e943f
PB
998endif
999alsa = not_found
87430d5b
PB
1000if not get_option('alsa').auto() or (targetos == 'linux' and have_system)
1001 alsa = dependency('alsa', required: get_option('alsa'),
063d5119 1002 method: 'pkg-config')
478e943f
PB
1003endif
1004jack = not_found
87430d5b
PB
1005if not get_option('jack').auto() or have_system
1006 jack = dependency('jack', required: get_option('jack'),
063d5119 1007 method: 'pkg-config')
478e943f 1008endif
c2d3d1c2
DB
1009pipewire = not_found
1010if not get_option('pipewire').auto() or (targetos == 'linux' and have_system)
1011 pipewire = dependency('libpipewire-0.3', version: '>=0.3.60',
1012 required: get_option('pipewire'),
063d5119 1013 method: 'pkg-config')
c2d3d1c2 1014endif
663df1cc
AR
1015sndio = not_found
1016if not get_option('sndio').auto() or have_system
1017 sndio = dependency('sndio', required: get_option('sndio'),
063d5119 1018 method: 'pkg-config')
663df1cc 1019endif
87430d5b 1020
58d3f3ff 1021spice_protocol = not_found
3f0a5d55 1022if not get_option('spice_protocol').auto() or have_system
5c167b53 1023 spice_protocol = dependency('spice-protocol', version: '>=0.14.0',
3f0a5d55 1024 required: get_option('spice_protocol'),
063d5119 1025 method: 'pkg-config')
2634733c 1026endif
3f0a5d55
MAL
1027spice = not_found
1028if not get_option('spice').auto() or have_system
34d55725 1029 spice = dependency('spice-server', version: '>=0.14.0',
3f0a5d55 1030 required: get_option('spice'),
063d5119 1031 method: 'pkg-config')
58d3f3ff 1032endif
3f0a5d55
MAL
1033spice_headers = spice.partial_dependency(compile_args: true, includes: true)
1034
5ee24e78 1035rt = cc.find_library('rt', required: false)
a399f914 1036
99650b62 1037libiscsi = not_found
9db405a3
PB
1038if not get_option('libiscsi').auto() or have_block
1039 libiscsi = dependency('libiscsi', version: '>=1.9.0',
1040 required: get_option('libiscsi'),
063d5119 1041 method: 'pkg-config')
99650b62 1042endif
5e5733e5 1043zstd = not_found
b1def33d
PB
1044if not get_option('zstd').auto() or have_block
1045 zstd = dependency('libzstd', version: '>=1.4.0',
1046 required: get_option('zstd'),
063d5119 1047 method: 'pkg-config')
5e5733e5 1048endif
ea458960 1049virgl = not_found
0265fe9e
PB
1050
1051have_vhost_user_gpu = have_tools and targetos == 'linux' and pixman.found()
1052if not get_option('virglrenderer').auto() or have_system or have_vhost_user_gpu
587d59d6
PB
1053 virgl = dependency('virglrenderer',
1054 method: 'pkg-config',
063d5119 1055 required: get_option('virglrenderer'))
ea458960 1056endif
fd66dbd4
SH
1057blkio = not_found
1058if not get_option('blkio').auto() or have_block
1059 blkio = dependency('blkio',
1060 method: 'pkg-config',
063d5119 1061 required: get_option('blkio'))
fd66dbd4 1062endif
1d7bb6ab 1063curl = not_found
f9cd86fe
PB
1064if not get_option('curl').auto() or have_block
1065 curl = dependency('libcurl', version: '>=7.29.0',
1066 method: 'pkg-config',
063d5119 1067 required: get_option('curl'))
1d7bb6ab 1068endif
f15bff25 1069libudev = not_found
f01496a3 1070if targetos == 'linux' and (have_system or have_tools)
6ec0e15d 1071 libudev = dependency('libudev',
a0fbbb6e 1072 method: 'pkg-config',
063d5119 1073 required: get_option('libudev'))
6ec0e15d
PB
1074endif
1075
5c53015a 1076mpathlibs = [libudev]
6ec0e15d
PB
1077mpathpersist = not_found
1078mpathpersist_new_api = false
43a363ae 1079if targetos == 'linux' and have_tools and get_option('mpath').allowed()
6ec0e15d
PB
1080 mpath_test_source_new = '''
1081 #include <libudev.h>
1082 #include <mpath_persist.h>
1083 unsigned mpath_mx_alloc_len = 1024;
1084 int logsink;
1085 static struct config *multipath_conf;
1086 extern struct udev *udev;
1087 extern struct config *get_multipath_config(void);
1088 extern void put_multipath_config(struct config *conf);
1089 struct udev *udev;
1090 struct config *get_multipath_config(void) { return multipath_conf; }
1091 void put_multipath_config(struct config *conf) { }
1092 int main(void) {
1093 udev = udev_new();
1094 multipath_conf = mpath_lib_init();
1095 return 0;
1096 }'''
1097 mpath_test_source_old = '''
1098 #include <libudev.h>
1099 #include <mpath_persist.h>
1100 unsigned mpath_mx_alloc_len = 1024;
1101 int logsink;
1102 int main(void) {
1103 struct udev *udev = udev_new();
1104 mpath_lib_init(udev);
1105 return 0;
1106 }'''
5c53015a 1107 libmpathpersist = cc.find_library('mpathpersist',
063d5119 1108 required: get_option('mpath'))
5c53015a
PB
1109 if libmpathpersist.found()
1110 mpathlibs += libmpathpersist
a0cbd2e8 1111 if get_option('prefer_static')
5c53015a 1112 mpathlibs += cc.find_library('devmapper',
063d5119 1113 required: get_option('mpath'))
43b43a40 1114 endif
5c53015a 1115 mpathlibs += cc.find_library('multipath',
063d5119 1116 required: get_option('mpath'))
5c53015a
PB
1117 foreach lib: mpathlibs
1118 if not lib.found()
1119 mpathlibs = []
1120 break
1121 endif
1122 endforeach
1123 if mpathlibs.length() == 0
1124 msg = 'Dependencies missing for libmpathpersist'
1125 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
6ec0e15d
PB
1126 mpathpersist = declare_dependency(dependencies: mpathlibs)
1127 mpathpersist_new_api = true
1128 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
1129 mpathpersist = declare_dependency(dependencies: mpathlibs)
1130 else
5c53015a
PB
1131 msg = 'Cannot detect libmpathpersist API'
1132 endif
1133 if not mpathpersist.found()
6ec0e15d 1134 if get_option('mpath').enabled()
5c53015a 1135 error(msg)
6ec0e15d 1136 else
5c53015a 1137 warning(msg + ', disabling')
6ec0e15d
PB
1138 endif
1139 endif
1140 endif
f15bff25 1141endif
6ec0e15d 1142
5285e593 1143iconv = not_found
5285e593 1144curses = not_found
43a363ae 1145if have_system and get_option('curses').allowed()
925a40df 1146 curses_test = '''
fbab8cc2
SW
1147 #if defined(__APPLE__) || defined(__OpenBSD__)
1148 #define _XOPEN_SOURCE_EXTENDED 1
1149 #endif
925a40df
PB
1150 #include <locale.h>
1151 #include <curses.h>
1152 #include <wchar.h>
1153 int main(void) {
1154 wchar_t wch = L'w';
1155 setlocale(LC_ALL, "");
1156 resize_term(0, 0);
1157 addwstr(L"wide chars\n");
1158 addnwstr(&wch, 1);
1159 add_wch(WACS_DEGREE);
1160 return 0;
1161 }'''
1162
ca31e307 1163 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
6d322635
PB
1164 curses = dependency(curses_dep_list,
1165 required: false,
063d5119 1166 method: 'pkg-config')
925a40df 1167 msg = get_option('curses').enabled() ? 'curses library not found' : ''
fbab8cc2 1168 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
925a40df 1169 if curses.found()
0dbce6ef 1170 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
bd3615d6
PB
1171 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses],
1172 version: curses.version())
925a40df
PB
1173 else
1174 msg = 'curses package not usable'
1175 curses = not_found
5285e593
YL
1176 endif
1177 endif
925a40df 1178 if not curses.found()
925a40df
PB
1179 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1180 if targetos != 'windows' and not has_curses_h
1181 message('Trying with /usr/include/ncursesw')
1182 curses_compile_args += ['-I/usr/include/ncursesw']
1183 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1184 endif
1185 if has_curses_h
1186 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
1187 foreach curses_libname : curses_libname_list
5285e593 1188 libcurses = cc.find_library(curses_libname,
063d5119 1189 required: false)
925a40df
PB
1190 if libcurses.found()
1191 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
1192 curses = declare_dependency(compile_args: curses_compile_args,
1193 dependencies: [libcurses])
1194 break
1195 else
1196 msg = 'curses library not usable'
1197 endif
5285e593 1198 endif
925a40df
PB
1199 endforeach
1200 endif
1201 endif
43a363ae 1202 if get_option('iconv').allowed()
925a40df
PB
1203 foreach link_args : [ ['-liconv'], [] ]
1204 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
1205 # We need to use libiconv if available because mixing libiconv's headers with
1206 # the system libc does not work.
1207 # However, without adding glib to the dependencies -L/usr/local/lib will not be
1208 # included in the command line and libiconv will not be found.
1209 if cc.links('''
1210 #include <iconv.h>
1211 int main(void) {
1212 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
1213 return conv != (iconv_t) -1;
fc9a809e 1214 }''', args: link_args, dependencies: glib)
925a40df
PB
1215 iconv = declare_dependency(link_args: link_args, dependencies: glib)
1216 break
5285e593 1217 endif
30fe76b1
PB
1218 endforeach
1219 endif
925a40df
PB
1220 if curses.found() and not iconv.found()
1221 if get_option('iconv').enabled()
1222 error('iconv not available')
1223 endif
1224 msg = 'iconv required for curses UI but not available'
1225 curses = not_found
1226 endif
1227 if not curses.found() and msg != ''
1228 if get_option('curses').enabled()
1229 error(msg)
30fe76b1 1230 else
925a40df 1231 warning(msg + ', disabling')
30fe76b1 1232 endif
5285e593
YL
1233 endif
1234endif
1235
2634733c 1236brlapi = not_found
8c6d4ff4
PB
1237if not get_option('brlapi').auto() or have_system
1238 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
063d5119 1239 required: get_option('brlapi'))
8c6d4ff4
PB
1240 if brlapi.found() and not cc.links('''
1241 #include <brlapi.h>
1242 #include <stddef.h>
1243 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
1244 brlapi = not_found
1245 if get_option('brlapi').enabled()
1246 error('could not link brlapi')
1247 else
1248 warning('could not link brlapi, disabling')
1249 endif
1250 endif
2634733c 1251endif
35be72ba 1252
760e4327 1253sdl = not_found
64d3fec7 1254if not get_option('sdl').auto() or have_system
063d5119 1255 sdl = dependency('sdl2', required: get_option('sdl'))
760e4327
PB
1256 sdl_image = not_found
1257endif
35be72ba
PB
1258if sdl.found()
1259 # work around 2.0.8 bug
1260 sdl = declare_dependency(compile_args: '-Wno-undef',
bd3615d6
PB
1261 dependencies: sdl,
1262 version: sdl.version())
7161a433 1263 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
063d5119 1264 method: 'pkg-config')
35be72ba
PB
1265else
1266 if get_option('sdl_image').enabled()
a8dc2ace
ST
1267 error('sdl-image required, but SDL was @0@'.format(
1268 get_option('sdl').disabled() ? 'disabled' : 'not found'))
35be72ba
PB
1269 endif
1270 sdl_image = not_found
2634733c 1271endif
35be72ba 1272
5e5733e5 1273rbd = not_found
fabd1e93 1274if not get_option('rbd').auto() or have_block
063d5119 1275 librados = cc.find_library('rados', required: get_option('rbd'))
fabd1e93 1276 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
063d5119 1277 required: get_option('rbd'))
c518d6c2
PB
1278 if librados.found() and librbd.found()
1279 if cc.links('''
1280 #include <stdio.h>
1281 #include <rbd/librbd.h>
1282 int main(void) {
1283 rados_t cluster;
1284 rados_create(&cluster, NULL);
48672ac0
PL
1285 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
1286 #error
1287 #endif
c518d6c2
PB
1288 return 0;
1289 }''', dependencies: [librbd, librados])
1290 rbd = declare_dependency(dependencies: [librbd, librados])
1291 elif get_option('rbd').enabled()
48672ac0 1292 error('librbd >= 1.12.0 required')
c518d6c2 1293 else
48672ac0 1294 warning('librbd >= 1.12.0 not found, disabling')
c518d6c2 1295 endif
fabd1e93 1296 endif
5e5733e5 1297endif
fabd1e93 1298
5e5733e5 1299glusterfs = not_found
08821ca2
PB
1300glusterfs_ftruncate_has_stat = false
1301glusterfs_iocb_has_stat = false
1302if not get_option('glusterfs').auto() or have_block
1303 glusterfs = dependency('glusterfs-api', version: '>=3',
1304 required: get_option('glusterfs'),
063d5119 1305 method: 'pkg-config')
08821ca2
PB
1306 if glusterfs.found()
1307 glusterfs_ftruncate_has_stat = cc.links('''
1308 #include <glusterfs/api/glfs.h>
1309
1310 int
1311 main(void)
1312 {
1313 /* new glfs_ftruncate() passes two additional args */
1314 return glfs_ftruncate(NULL, 0, NULL, NULL);
1315 }
1316 ''', dependencies: glusterfs)
1317 glusterfs_iocb_has_stat = cc.links('''
1318 #include <glusterfs/api/glfs.h>
1319
1320 /* new glfs_io_cbk() passes two additional glfs_stat structs */
1321 static void
1322 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
1323 {}
1324
1325 int
1326 main(void)
1327 {
1328 glfs_io_cbk iocb = &glusterfs_iocb;
1329 iocb(NULL, 0 , NULL, NULL, NULL);
1330 return 0;
1331 }
1332 ''', dependencies: glusterfs)
1333 endif
5e5733e5 1334endif
e6a52b36 1335
5e5733e5 1336libssh = not_found
e6a52b36
TH
1337if not get_option('libssh').auto() or have_block
1338 libssh = dependency('libssh', version: '>=0.8.7',
1339 method: 'pkg-config',
063d5119 1340 required: get_option('libssh'))
5e5733e5 1341endif
e6a52b36 1342
5e5733e5 1343libbzip2 = not_found
29ba6116
PB
1344if not get_option('bzip2').auto() or have_block
1345 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
063d5119 1346 required: get_option('bzip2'))
29ba6116
PB
1347 if libbzip2.found() and not cc.links('''
1348 #include <bzlib.h>
1349 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
1350 libbzip2 = not_found
1351 if get_option('bzip2').enabled()
1352 error('could not link libbzip2')
1353 else
1354 warning('could not link libbzip2, disabling')
1355 endif
1356 endif
5e5733e5 1357endif
ecea3696 1358
5e5733e5 1359liblzfse = not_found
ecea3696
PB
1360if not get_option('lzfse').auto() or have_block
1361 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
063d5119 1362 required: get_option('lzfse'))
ecea3696
PB
1363endif
1364if liblzfse.found() and not cc.links('''
1365 #include <lzfse.h>
1366 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
1367 liblzfse = not_found
1368 if get_option('lzfse').enabled()
1369 error('could not link liblzfse')
1370 else
1371 warning('could not link liblzfse, disabling')
1372 endif
5e5733e5 1373endif
ecea3696 1374
478e943f 1375oss = not_found
43a363ae 1376if get_option('oss').allowed() and have_system
87430d5b
PB
1377 if not cc.has_header('sys/soundcard.h')
1378 # not found
1379 elif targetos == 'netbsd'
063d5119 1380 oss = cc.find_library('ossaudio', required: get_option('oss'))
87430d5b
PB
1381 else
1382 oss = declare_dependency()
1383 endif
1384
1385 if not oss.found()
1386 if get_option('oss').enabled()
1387 error('OSS not found')
87430d5b
PB
1388 endif
1389 endif
478e943f
PB
1390endif
1391dsound = not_found
87430d5b
PB
1392if not get_option('dsound').auto() or (targetos == 'windows' and have_system)
1393 if cc.has_header('dsound.h')
1394 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
1395 endif
1396
1397 if not dsound.found()
1398 if get_option('dsound').enabled()
1399 error('DirectSound not found')
87430d5b
PB
1400 endif
1401 endif
478e943f 1402endif
87430d5b 1403
478e943f 1404coreaudio = not_found
87430d5b
PB
1405if not get_option('coreaudio').auto() or (targetos == 'darwin' and have_system)
1406 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
1407 required: get_option('coreaudio'))
2b1ccdf4 1408endif
8bc5184d 1409
2b1ccdf4 1410opengl = not_found
88b6e618
PB
1411if not get_option('opengl').auto() or have_system or have_vhost_user_gpu
1412 epoxy = dependency('epoxy', method: 'pkg-config',
063d5119 1413 required: get_option('opengl'))
88b6e618
PB
1414 if cc.has_header('epoxy/egl.h', dependencies: epoxy)
1415 opengl = epoxy
1416 elif get_option('opengl').enabled()
1417 error('epoxy/egl.h not found')
1418 endif
2b1ccdf4 1419endif
8bc5184d
TH
1420gbm = not_found
1421if (have_system or have_tools) and (virgl.found() or opengl.found())
063d5119 1422 gbm = dependency('gbm', method: 'pkg-config', required: false)
8bc5184d 1423endif
f0caba44 1424have_vhost_user_gpu = have_vhost_user_gpu and virgl.found() and opengl.found() and gbm.found()
1b695471 1425
57612511 1426gnutls = not_found
cc4c7c73 1427gnutls_crypto = not_found
abc14fd0 1428if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
cc4c7c73
DB
1429 # For general TLS support our min gnutls matches
1430 # that implied by our platform support matrix
1431 #
1432 # For the crypto backends, we look for a newer
1433 # gnutls:
1434 #
1435 # Version 3.6.8 is needed to get XTS
1436 # Version 3.6.13 is needed to get PBKDF
1437 # Version 3.6.14 is needed to get HW accelerated XTS
1438 #
1439 # If newer enough gnutls isn't available, we can
1440 # still use a different crypto backend to satisfy
1441 # the platform support requirements
1442 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
1443 method: 'pkg-config',
063d5119 1444 required: false)
cc4c7c73
DB
1445 if gnutls_crypto.found()
1446 gnutls = gnutls_crypto
1447 else
1448 # Our min version if all we need is TLS
1449 gnutls = dependency('gnutls', version: '>=3.5.18',
1450 method: 'pkg-config',
063d5119 1451 required: get_option('gnutls'))
cc4c7c73 1452 endif
57612511
PB
1453endif
1454
8bd0931f
DB
1455# We prefer use of gnutls for crypto, unless the options
1456# explicitly asked for nettle or gcrypt.
1457#
1458# If gnutls isn't available for crypto, then we'll prefer
1459# gcrypt over nettle for performance reasons.
57612511
PB
1460gcrypt = not_found
1461nettle = not_found
4c5e512e 1462hogweed = not_found
68014044 1463xts = 'none'
8bd0931f 1464
57612511
PB
1465if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1466 error('Only one of gcrypt & nettle can be enabled')
57612511 1467endif
8bd0931f
DB
1468
1469# Explicit nettle/gcrypt request, so ignore gnutls for crypto
1470if get_option('nettle').enabled() or get_option('gcrypt').enabled()
cc4c7c73
DB
1471 gnutls_crypto = not_found
1472endif
57612511 1473
8bd0931f
DB
1474if not gnutls_crypto.found()
1475 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1476 gcrypt = dependency('libgcrypt', version: '>=1.8',
1477 method: 'config-tool',
063d5119 1478 required: get_option('gcrypt'))
8bd0931f
DB
1479 # Debian has removed -lgpg-error from libgcrypt-config
1480 # as it "spreads unnecessary dependencies" which in
1481 # turn breaks static builds...
a0cbd2e8 1482 if gcrypt.found() and get_option('prefer_static')
bd3615d6
PB
1483 gcrypt = declare_dependency(dependencies:
1484 [gcrypt,
1485 cc.find_library('gpg-error', required: true)],
1486 version: gcrypt.version())
8bd0931f 1487 endif
57612511 1488 endif
8bd0931f
DB
1489 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1490 nettle = dependency('nettle', version: '>=3.4',
1491 method: 'pkg-config',
063d5119 1492 required: get_option('nettle'))
8bd0931f
DB
1493 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1494 xts = 'private'
1495 endif
57612511
PB
1496 endif
1497endif
1498
063d5119 1499gmp = dependency('gmp', required: false, method: 'pkg-config')
4c5e512e
LH
1500if nettle.found() and gmp.found()
1501 hogweed = dependency('hogweed', version: '>=3.4',
1502 method: 'pkg-config',
063d5119 1503 required: get_option('nettle'))
4c5e512e
LH
1504endif
1505
1506
2b1ccdf4 1507gtk = not_found
1b695471 1508gtkx11 = not_found
c23d7b4e 1509vte = not_found
29e0bfff
CF
1510have_gtk_clipboard = get_option('gtk_clipboard').enabled()
1511
64d3fec7 1512if not get_option('gtk').auto() or have_system
1b695471
PB
1513 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1514 method: 'pkg-config',
063d5119 1515 required: get_option('gtk'))
1b695471
PB
1516 if gtk.found()
1517 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1518 method: 'pkg-config',
063d5119 1519 required: false)
bd3615d6
PB
1520 gtk = declare_dependency(dependencies: [gtk, gtkx11],
1521 version: gtk.version())
c23d7b4e
PB
1522
1523 if not get_option('vte').auto() or have_system
1524 vte = dependency('vte-2.91',
1525 method: 'pkg-config',
063d5119 1526 required: get_option('vte'))
c23d7b4e 1527 endif
29e0bfff
CF
1528 elif have_gtk_clipboard
1529 error('GTK clipboard requested, but GTK not found')
1b695471 1530 endif
2b1ccdf4 1531endif
1b695471 1532
2b1ccdf4 1533x11 = not_found
9d49bcf6 1534if gtkx11.found()
063d5119 1535 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found())
2b1ccdf4 1536endif
2b1ccdf4 1537png = not_found
95f8510e 1538if get_option('png').allowed() and have_system
1ec8c2c0 1539 png = dependency('libpng', version: '>=1.6.34', required: get_option('png'),
063d5119 1540 method: 'pkg-config')
95f8510e
KS
1541endif
1542vnc = not_found
2b1ccdf4 1543jpeg = not_found
2b1ccdf4 1544sasl = not_found
43a363ae 1545if get_option('vnc').allowed() and have_system
a0b93237 1546 vnc = declare_dependency() # dummy dependency
8e242b3c 1547 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
063d5119 1548 method: 'pkg-config')
a0b93237 1549 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
063d5119 1550 required: get_option('vnc_sasl'))
a0b93237
PB
1551 if sasl.found()
1552 sasl = declare_dependency(dependencies: sasl,
1553 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1554 endif
478e943f 1555endif
241611ea 1556
05e391ae
PB
1557pam = not_found
1558if not get_option('auth_pam').auto() or have_system
1559 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
063d5119 1560 required: get_option('auth_pam'))
05e391ae
PB
1561endif
1562if pam.found() and not cc.links('''
1563 #include <stddef.h>
1564 #include <security/pam_appl.h>
1565 int main(void) {
1566 const char *service_name = "qemu";
1567 const char *user = "frank";
1568 const struct pam_conv pam_conv = { 0 };
1569 pam_handle_t *pamh = NULL;
1570 pam_start(service_name, user, &pam_conv, &pamh);
1571 return 0;
1572 }''', dependencies: pam)
1573 pam = not_found
1574 if get_option('auth_pam').enabled()
1575 error('could not link libpam')
1576 else
1577 warning('could not link libpam, disabling')
1578 endif
1579endif
1580
708eab42 1581snappy = not_found
241611ea
PB
1582if not get_option('snappy').auto() or have_system
1583 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
063d5119 1584 required: get_option('snappy'))
241611ea 1585endif
565174d0 1586if snappy.found() and not linker.links('''
241611ea
PB
1587 #include <snappy-c.h>
1588 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1589 snappy = not_found
1590 if get_option('snappy').enabled()
1591 error('could not link libsnappy')
1592 else
1593 warning('could not link libsnappy, disabling')
1594 endif
708eab42 1595endif
0c32a0ae 1596
708eab42 1597lzo = not_found
0c32a0ae
PB
1598if not get_option('lzo').auto() or have_system
1599 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
063d5119 1600 required: get_option('lzo'))
0c32a0ae
PB
1601endif
1602if lzo.found() and not cc.links('''
1603 #include <lzo/lzo1x.h>
1604 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1605 lzo = not_found
1606 if get_option('lzo').enabled()
1607 error('could not link liblzo2')
1608 else
1609 warning('could not link liblzo2, disabling')
1610 endif
708eab42 1611endif
0c32a0ae 1612
488a8c73
PB
1613numa = not_found
1614if not get_option('numa').auto() or have_system or have_tools
1615 numa = cc.find_library('numa', has_headers: ['numa.h'],
063d5119 1616 required: get_option('numa'))
488a8c73
PB
1617endif
1618if numa.found() and not cc.links('''
1619 #include <numa.h>
1620 int main(void) { return numa_available(); }
1621 ''', dependencies: numa)
1622 numa = not_found
1623 if get_option('numa').enabled()
1624 error('could not link numa')
1625 else
1626 warning('could not link numa, disabling')
1627 endif
1628endif
1629
55166230 1630rdma = not_found
3730a734
PB
1631if not get_option('rdma').auto() or have_system
1632 libumad = cc.find_library('ibumad', required: get_option('rdma'))
1633 rdma_libs = [cc.find_library('rdmacm', has_headers: ['rdma/rdma_cma.h'],
063d5119
PB
1634 required: get_option('rdma')),
1635 cc.find_library('ibverbs', required: get_option('rdma')),
3730a734
PB
1636 libumad]
1637 rdma = declare_dependency(dependencies: rdma_libs)
1638 foreach lib: rdma_libs
1639 if not lib.found()
1640 rdma = not_found
1641 endif
1642 endforeach
55166230 1643endif
3730a734 1644
582ea95f 1645xen = not_found
14efd8d3
PB
1646if get_option('xen').enabled() or (get_option('xen').auto() and have_system)
1647 xencontrol = dependency('xencontrol', required: false,
063d5119 1648 method: 'pkg-config')
14efd8d3
PB
1649 if xencontrol.found()
1650 xen_pc = declare_dependency(version: xencontrol.version(),
1651 dependencies: [
1652 xencontrol,
1653 # disabler: true makes xen_pc.found() return false if any is not found
1654 dependency('xenstore', required: false,
063d5119 1655 method: 'pkg-config',
14efd8d3
PB
1656 disabler: true),
1657 dependency('xenforeignmemory', required: false,
063d5119 1658 method: 'pkg-config',
14efd8d3
PB
1659 disabler: true),
1660 dependency('xengnttab', required: false,
063d5119 1661 method: 'pkg-config',
14efd8d3
PB
1662 disabler: true),
1663 dependency('xenevtchn', required: false,
063d5119 1664 method: 'pkg-config',
14efd8d3
PB
1665 disabler: true),
1666 dependency('xendevicemodel', required: false,
063d5119 1667 method: 'pkg-config',
14efd8d3
PB
1668 disabler: true),
1669 # optional, no "disabler: true"
1670 dependency('xentoolcore', required: false,
063d5119 1671 method: 'pkg-config')])
14efd8d3
PB
1672 if xen_pc.found()
1673 xen = xen_pc
1674 endif
1675 endif
1676 if not xen.found()
1677 xen_tests = [ '4.11.0', '4.10.0', '4.9.0', '4.8.0', '4.7.1', '4.6.0', '4.5.0', '4.2.0' ]
1678 xen_libs = {
1679 '4.11.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
1680 '4.10.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
1681 '4.9.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
1682 '4.8.0': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
1683 '4.7.1': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
1684 '4.6.0': [ 'xenstore', 'xenctrl' ],
1685 '4.5.0': [ 'xenstore', 'xenctrl' ],
1686 '4.2.0': [ 'xenstore', 'xenctrl' ],
1687 }
1688 xen_deps = {}
1689 foreach ver: xen_tests
1690 # cache the various library tests to avoid polluting the logs
1691 xen_test_deps = []
1692 foreach l: xen_libs[ver]
1693 if l not in xen_deps
1694 xen_deps += { l: cc.find_library(l, required: false) }
1695 endif
1696 xen_test_deps += xen_deps[l]
1697 endforeach
1698
1699 # Use -D to pick just one of the test programs in scripts/xen-detect.c
1700 xen_version = ver.split('.')
1701 xen_ctrl_version = xen_version[0] + \
1702 ('0' + xen_version[1]).substring(-2) + \
1703 ('0' + xen_version[2]).substring(-2)
1704 if cc.links(files('scripts/xen-detect.c'),
1705 args: '-DCONFIG_XEN_CTRL_INTERFACE_VERSION=' + xen_ctrl_version,
1706 dependencies: xen_test_deps)
1707 xen = declare_dependency(version: ver, dependencies: xen_test_deps)
1708 break
1709 endif
1710 endforeach
1711 endif
1712 if xen.found()
1713 accelerators += 'CONFIG_XEN'
1714 elif get_option('xen').enabled()
1715 error('could not compile and link Xen test program')
1716 endif
582ea95f 1717endif
14efd8d3
PB
1718have_xen_pci_passthrough = get_option('xen_pci_passthrough') \
1719 .require(xen.found(),
1720 error_message: 'Xen PCI passthrough requested but Xen not enabled') \
1721 .require(targetos == 'linux',
1722 error_message: 'Xen PCI passthrough not available on this platform') \
1723 .allowed()
1724
1725
06677ce1 1726cacard = not_found
5f364c57
PB
1727if not get_option('smartcard').auto() or have_system
1728 cacard = dependency('libcacard', required: get_option('smartcard'),
063d5119 1729 version: '>=2.5.1', method: 'pkg-config')
06677ce1 1730endif
0a40bcb7
CB
1731u2f = not_found
1732if have_system
1733 u2f = dependency('u2f-emu', required: get_option('u2f'),
063d5119 1734 method: 'pkg-config')
0a40bcb7 1735endif
8caef850
HZZ
1736canokey = not_found
1737if have_system
1738 canokey = dependency('canokey-qemu', required: get_option('canokey'),
063d5119 1739 method: 'pkg-config')
8caef850 1740endif
06677ce1 1741usbredir = not_found
18f31e60
PB
1742if not get_option('usb_redir').auto() or have_system
1743 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
063d5119 1744 version: '>=0.6', method: 'pkg-config')
06677ce1
PB
1745endif
1746libusb = not_found
90540f32
PB
1747if not get_option('libusb').auto() or have_system
1748 libusb = dependency('libusb-1.0', required: get_option('libusb'),
063d5119 1749 version: '>=1.0.13', method: 'pkg-config')
06677ce1 1750endif
90540f32 1751
c9322ab5 1752libpmem = not_found
e36e8c70
PB
1753if not get_option('libpmem').auto() or have_system
1754 libpmem = dependency('libpmem', required: get_option('libpmem'),
063d5119 1755 method: 'pkg-config')
c9322ab5 1756endif
c7c91a74 1757libdaxctl = not_found
83ef1682
PB
1758if not get_option('libdaxctl').auto() or have_system
1759 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
063d5119 1760 version: '>=57', method: 'pkg-config')
c7c91a74 1761endif
8ce0a45f 1762tasn1 = not_found
ba7ed407
PB
1763if gnutls.found()
1764 tasn1 = dependency('libtasn1',
063d5119 1765 method: 'pkg-config')
8ce0a45f 1766endif
af04e89d 1767keyutils = dependency('libkeyutils', required: false,
063d5119 1768 method: 'pkg-config')
a81df1b6 1769
3909def8
MAL
1770has_gettid = cc.has_function('gettid')
1771
3d212b41
RJ
1772# libselinux
1773selinux = dependency('libselinux',
1774 required: get_option('selinux'),
063d5119 1775 method: 'pkg-config')
3d212b41 1776
aa087962
PB
1777# Malloc tests
1778
1779malloc = []
1780if get_option('malloc') == 'system'
1781 has_malloc_trim = \
43a363ae 1782 get_option('malloc_trim').allowed() and \
aa087962
PB
1783 cc.links('''#include <malloc.h>
1784 int main(void) { malloc_trim(0); return 0; }''')
1785else
1786 has_malloc_trim = false
1787 malloc = cc.find_library(get_option('malloc'), required: true)
1788endif
1789if not has_malloc_trim and get_option('malloc_trim').enabled()
1790 if get_option('malloc') == 'system'
1791 error('malloc_trim not available on this platform.')
1792 else
1793 error('malloc_trim not available with non-libc memory allocator')
1794 endif
1795endif
1796
84e319a5
HR
1797# Check whether the glibc provides statx()
1798
e66420ac 1799gnu_source_prefix = '''
84e319a5
HR
1800 #ifndef _GNU_SOURCE
1801 #define _GNU_SOURCE
1802 #endif
e66420ac
PB
1803'''
1804statx_test = gnu_source_prefix + '''
84e319a5
HR
1805 #include <sys/stat.h>
1806 int main(void) {
1807 struct statx statxbuf;
1808 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1809 return 0;
1810 }'''
1811
1812has_statx = cc.links(statx_test)
1813
4ce7a08d
HR
1814# Check whether statx() provides mount ID information
1815
1816statx_mnt_id_test = gnu_source_prefix + '''
1817 #include <sys/stat.h>
1818 int main(void) {
1819 struct statx statxbuf;
1820 statx(0, "", 0, STATX_BASIC_STATS | STATX_MNT_ID, &statxbuf);
1821 return statxbuf.stx_mnt_id;
1822 }'''
1823
1824has_statx_mnt_id = cc.links(statx_mnt_id_test)
1825
a436d6d4
PB
1826have_vhost_user_blk_server = get_option('vhost_user_blk_server') \
1827 .require(targetos == 'linux',
1828 error_message: 'vhost_user_blk_server requires linux') \
2a3129a3 1829 .require(have_vhost_user,
a436d6d4 1830 error_message: 'vhost_user_blk_server requires vhost-user support') \
26ed501b 1831 .disable_auto_if(not have_tools and not have_system) \
a436d6d4 1832 .allowed()
9e62ba48 1833
df4ea709
HR
1834if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1835 error('Cannot enable fuse-lseek while fuse is disabled')
1836endif
1837
a484a719 1838fuse = dependency('fuse3', required: get_option('fuse'),
063d5119 1839 version: '>=3.1', method: 'pkg-config')
a484a719 1840
df4ea709 1841fuse_lseek = not_found
43a363ae 1842if get_option('fuse_lseek').allowed()
df4ea709
HR
1843 if fuse.version().version_compare('>=3.8')
1844 # Dummy dependency
1845 fuse_lseek = declare_dependency()
1846 elif get_option('fuse_lseek').enabled()
1847 if fuse.found()
1848 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1849 else
1850 error('fuse-lseek requires libfuse, which was not found')
1851 endif
1852 endif
1853endif
1854
a6caeee8
XY
1855have_libvduse = (targetos == 'linux')
1856if get_option('libvduse').enabled()
1857 if targetos != 'linux'
1858 error('libvduse requires linux')
1859 endif
1860elif get_option('libvduse').disabled()
1861 have_libvduse = false
1862endif
1863
2a2359b8
XY
1864have_vduse_blk_export = (have_libvduse and targetos == 'linux')
1865if get_option('vduse_blk_export').enabled()
1866 if targetos != 'linux'
1867 error('vduse_blk_export requires linux')
1868 elif not have_libvduse
1869 error('vduse_blk_export requires libvduse support')
1870 endif
1871elif get_option('vduse_blk_export').disabled()
1872 have_vduse_blk_export = false
1873endif
1874
46627f41
AM
1875# libbpf
1876libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1877if libbpf.found() and not cc.links('''
1878 #include <bpf/libbpf.h>
1879 int main(void)
1880 {
1881 bpf_object__destroy_skeleton(NULL);
1882 return 0;
1883 }''', dependencies: libbpf)
1884 libbpf = not_found
1885 if get_option('bpf').enabled()
1886 error('libbpf skeleton test failed')
1887 else
1888 warning('libbpf skeleton test failed, disabling')
1889 endif
1890endif
1891
7c10cb38 1892# libdw
bc71d58f 1893libdw = not_found
550c6d97 1894if not get_option('libdw').auto() or \
a0cbd2e8 1895 (not get_option('prefer_static') and (have_system or have_user))
bc71d58f
IL
1896 libdw = dependency('libdw',
1897 method: 'pkg-config',
bc71d58f
IL
1898 required: get_option('libdw'))
1899endif
7c10cb38 1900
87430d5b
PB
1901#################
1902# config-host.h #
1903#################
1904
1905audio_drivers_selected = []
1906if have_system
1907 audio_drivers_available = {
1908 'alsa': alsa.found(),
1909 'coreaudio': coreaudio.found(),
1910 'dsound': dsound.found(),
1911 'jack': jack.found(),
1912 'oss': oss.found(),
1913 'pa': pulse.found(),
c2d3d1c2 1914 'pipewire': pipewire.found(),
87430d5b 1915 'sdl': sdl.found(),
663df1cc 1916 'sndio': sndio.found(),
87430d5b 1917 }
e5424a29
PB
1918 foreach k, v: audio_drivers_available
1919 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
1920 endforeach
87430d5b
PB
1921
1922 # Default to native drivers first, OSS second, SDL third
1923 audio_drivers_priority = \
663df1cc 1924 [ 'pa', 'coreaudio', 'dsound', 'sndio', 'oss' ] + \
87430d5b
PB
1925 (targetos == 'linux' ? [] : [ 'sdl' ])
1926 audio_drivers_default = []
1927 foreach k: audio_drivers_priority
1928 if audio_drivers_available[k]
1929 audio_drivers_default += k
1930 endif
1931 endforeach
1932
1933 foreach k: get_option('audio_drv_list')
1934 if k == 'default'
1935 audio_drivers_selected += audio_drivers_default
1936 elif not audio_drivers_available[k]
1937 error('Audio driver "@0@" not available.'.format(k))
1938 else
1939 audio_drivers_selected += k
1940 endif
1941 endforeach
1942endif
87430d5b
PB
1943config_host_data.set('CONFIG_AUDIO_DRIVERS',
1944 '"' + '", "'.join(audio_drivers_selected) + '", ')
1945
9e62ba48
DB
1946if get_option('cfi')
1947 cfi_flags=[]
1948 # Check for dependency on LTO
1949 if not get_option('b_lto')
1950 error('Selected Control-Flow Integrity but LTO is disabled')
1951 endif
6002711c 1952 if enable_modules
9e62ba48
DB
1953 error('Selected Control-Flow Integrity is not compatible with modules')
1954 endif
1955 # Check for cfi flags. CFI requires LTO so we can't use
1956 # get_supported_arguments, but need a more complex "compiles" which allows
1957 # custom arguments
1958 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1959 args: ['-flto', '-fsanitize=cfi-icall'] )
1960 cfi_flags += '-fsanitize=cfi-icall'
1961 else
1962 error('-fsanitize=cfi-icall is not supported by the compiler')
1963 endif
1964 if cc.compiles('int main () { return 0; }',
1965 name: '-fsanitize-cfi-icall-generalize-pointers',
1966 args: ['-flto', '-fsanitize=cfi-icall',
1967 '-fsanitize-cfi-icall-generalize-pointers'] )
1968 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1969 else
1970 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1971 endif
1972 if get_option('cfi_debug')
1973 if cc.compiles('int main () { return 0; }',
1974 name: '-fno-sanitize-trap=cfi-icall',
1975 args: ['-flto', '-fsanitize=cfi-icall',
1976 '-fno-sanitize-trap=cfi-icall'] )
1977 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1978 else
1979 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1980 endif
1981 endif
e5134024
PB
1982 add_global_arguments(cfi_flags, native: false, language: all_languages)
1983 add_global_link_arguments(cfi_flags, native: false, language: all_languages)
9e62ba48
DB
1984endif
1985
14176c8d
JD
1986have_host_block_device = (targetos != 'darwin' or
1987 cc.has_header('IOKit/storage/IOMedia.h'))
1988
a436d6d4
PB
1989dbus_display = get_option('dbus_display') \
1990 .require(gio.version().version_compare('>=2.64'),
1991 error_message: '-display dbus requires glib>=2.64') \
7544060e 1992 .require(gdbus_codegen.found(),
bb2dc4b7 1993 error_message: gdbus_codegen_error.format('-display dbus')) \
84a0a2ef
MAL
1994 .require(targetos != 'windows',
1995 error_message: '-display dbus is not available on Windows') \
a436d6d4
PB
1996 .allowed()
1997
1998have_virtfs = get_option('virtfs') \
0fb1e19d
KF
1999 .require(targetos == 'linux' or targetos == 'darwin',
2000 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \
2001 .require(targetos == 'linux' or cc.has_function('pthread_fchdir_np'),
2002 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
1a67e07f
PF
2003 .require(targetos == 'darwin' or libattr.found(),
2004 error_message: 'virtio-9p (virtfs) on Linux requires libattr-devel') \
a436d6d4
PB
2005 .disable_auto_if(not have_tools and not have_system) \
2006 .allowed()
69202b40 2007
1a67e07f
PF
2008have_virtfs_proxy_helper = get_option('virtfs_proxy_helper') \
2009 .require(targetos != 'darwin', error_message: 'the virtfs proxy helper is incompatible with macOS') \
2010 .require(have_virtfs, error_message: 'the virtfs proxy helper requires that virtfs is enabled') \
2011 .disable_auto_if(not have_tools) \
2012 .require(libcap_ng.found(), error_message: 'the virtfs proxy helper requires libcap-ng') \
2013 .allowed()
3a489d38 2014
622d64ff
PB
2015if get_option('block_drv_ro_whitelist') == ''
2016 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', '')
2017else
2018 config_host_data.set('CONFIG_BDRV_RO_WHITELIST',
2019 '"' + get_option('block_drv_ro_whitelist').replace(',', '", "') + '", ')
2020endif
2021if get_option('block_drv_rw_whitelist') == ''
2022 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', '')
2023else
2024 config_host_data.set('CONFIG_BDRV_RW_WHITELIST',
2025 '"' + get_option('block_drv_rw_whitelist').replace(',', '", "') + '", ')
2026endif
2027
9c29b741
PB
2028foreach k : get_option('trace_backends')
2029 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
2030endforeach
2031config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
41f2ae28 2032config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority'))
40c909f5
PB
2033if iasl.found()
2034 config_host_data.set_quoted('CONFIG_IASL', iasl.full_path())
5dc4618e 2035endif
16bf7a33
PB
2036config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
2037config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
2038config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
2039config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
2040config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
8154f5e6
AO
2041
2042qemu_firmwarepath = ''
2043foreach k : get_option('qemu_firmwarepath')
2044 qemu_firmwarepath += '"' + get_option('prefix') / k + '", '
2045endforeach
2046config_host_data.set('CONFIG_QEMU_FIRMWAREPATH', qemu_firmwarepath)
2047
16bf7a33
PB
2048config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
2049config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
2050config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
2051config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
2052config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
2053config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
2054
6002711c 2055if enable_modules
b0b4323e
PB
2056 config_host_data.set('CONFIG_STAMP', run_command(
2057 meson.current_source_dir() / 'scripts/qemu-stamp.py',
2058 meson.project_version(), get_option('pkgversion'), '--',
2059 meson.current_source_dir() / 'configure',
2060 capture: true, check: true).stdout().strip())
2061endif
2062
35acbb30
PB
2063have_slirp_smbd = get_option('slirp_smbd') \
2064 .require(targetos != 'windows', error_message: 'Host smbd not supported on this platform.') \
2065 .allowed()
2066if have_slirp_smbd
2067 smbd_path = get_option('smbd')
2068 if smbd_path == ''
2069 smbd_path = (targetos == 'solaris' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
2070 endif
2071 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
2072endif
2073
823eb013
PB
2074config_host_data.set('HOST_' + host_arch.to_upper(), 1)
2075
2cb2f580
PB
2076if get_option('module_upgrades') and not enable_modules
2077 error('Cannot enable module-upgrades as modules are not enabled')
2078endif
2079config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades'))
2080
f7f2d651 2081config_host_data.set('CONFIG_ATTR', libattr.found())
c55cf6ab 2082config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
8c6d4ff4 2083config_host_data.set('CONFIG_BRLAPI', brlapi.found())
b4e312e9 2084config_host_data.set('CONFIG_COCOA', cocoa.found())
537b7248 2085config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
af2bb99b 2086config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
f01496a3 2087config_host_data.set('CONFIG_LIBUDEV', libudev.found())
0c32a0ae 2088config_host_data.set('CONFIG_LZO', lzo.found())
6ec0e15d
PB
2089config_host_data.set('CONFIG_MPATH', mpathpersist.found())
2090config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
fd66dbd4 2091config_host_data.set('CONFIG_BLKIO', blkio.found())
f9cd86fe 2092config_host_data.set('CONFIG_CURL', curl.found())
5285e593 2093config_host_data.set('CONFIG_CURSES', curses.found())
8bc5184d 2094config_host_data.set('CONFIG_GBM', gbm.found())
7544060e 2095config_host_data.set('CONFIG_GIO', gio.found())
08821ca2
PB
2096config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
2097if glusterfs.found()
2098 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
2099 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
2100 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
2101 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
2102 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
2103 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
2104endif
1b695471 2105config_host_data.set('CONFIG_GTK', gtk.found())
c23d7b4e 2106config_host_data.set('CONFIG_VTE', vte.found())
29e0bfff 2107config_host_data.set('CONFIG_GTK_CLIPBOARD', have_gtk_clipboard)
f7f2d651 2108config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
727c8bb8 2109config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
46627f41 2110config_host_data.set('CONFIG_EBPF', libbpf.found())
63a7f853 2111config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
9db405a3 2112config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
30045c05 2113config_host_data.set('CONFIG_LIBNFS', libnfs.found())
e6a52b36 2114config_host_data.set('CONFIG_LIBSSH', libssh.found())
ff66f3e5 2115config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
63a7f853
PB
2116config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
2117config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
6002711c 2118config_host_data.set('CONFIG_MODULES', enable_modules)
488a8c73 2119config_host_data.set('CONFIG_NUMA', numa.found())
6bb613f0
MP
2120if numa.found()
2121 config_host_data.set('HAVE_NUMA_HAS_PREFERRED_MANY',
2122 cc.has_function('numa_has_preferred_many',
2123 dependencies: numa))
2124endif
88b6e618 2125config_host_data.set('CONFIG_OPENGL', opengl.found())
c55cf6ab 2126config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
fabd1e93 2127config_host_data.set('CONFIG_RBD', rbd.found())
3730a734 2128config_host_data.set('CONFIG_RDMA', rdma.found())
721fa5e5 2129config_host_data.set('CONFIG_SAFESTACK', get_option('safe_stack'))
35be72ba
PB
2130config_host_data.set('CONFIG_SDL', sdl.found())
2131config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
90835c2b 2132config_host_data.set('CONFIG_SECCOMP', seccomp.found())
73422d95
MP
2133if seccomp.found()
2134 config_host_data.set('CONFIG_SECCOMP_SYSRAWRC', seccomp_has_sysrawrc)
2135endif
241611ea 2136config_host_data.set('CONFIG_SNAPPY', snappy.found())
0d04c4c9 2137config_host_data.set('CONFIG_TPM', have_tpm)
34f983d8 2138config_host_data.set('CONFIG_TSAN', get_option('tsan'))
90540f32 2139config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
e1723999 2140config_host_data.set('CONFIG_VDE', vde.found())
2df89d54
PB
2141config_host_data.set('CONFIG_VHOST_NET', have_vhost_net)
2142config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user)
2143config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa)
2144config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel)
2145config_host_data.set('CONFIG_VHOST_USER', have_vhost_user)
2146config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto)
2147config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa)
e2c1d78d 2148config_host_data.set('CONFIG_VMNET', vmnet.found())
e5e856c1 2149config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
2a2359b8 2150config_host_data.set('CONFIG_VDUSE_BLK_EXPORT', have_vduse_blk_export)
95f8510e 2151config_host_data.set('CONFIG_PNG', png.found())
a0b93237
PB
2152config_host_data.set('CONFIG_VNC', vnc.found())
2153config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
a0b93237 2154config_host_data.set('CONFIG_VNC_SASL', sasl.found())
69202b40 2155config_host_data.set('CONFIG_VIRTFS', have_virtfs)
63a7f853 2156config_host_data.set('CONFIG_VTE', vte.found())
4113f4cf 2157config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
af04e89d 2158config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
3909def8 2159config_host_data.set('CONFIG_GETTID', has_gettid)
57612511 2160config_host_data.set('CONFIG_GNUTLS', gnutls.found())
cc4c7c73 2161config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
d47b83b1 2162config_host_data.set('CONFIG_TASN1', tasn1.found())
57612511
PB
2163config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
2164config_host_data.set('CONFIG_NETTLE', nettle.found())
4c5e512e 2165config_host_data.set('CONFIG_HOGWEED', hogweed.found())
57612511 2166config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
aa087962 2167config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
84e319a5 2168config_host_data.set('CONFIG_STATX', has_statx)
4ce7a08d 2169config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id)
b1def33d 2170config_host_data.set('CONFIG_ZSTD', zstd.found())
a484a719 2171config_host_data.set('CONFIG_FUSE', fuse.found())
df4ea709 2172config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
3f0a5d55 2173config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
ddece465
MAL
2174if spice_protocol.found()
2175config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
2176config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
2177config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
2178endif
3f0a5d55 2179config_host_data.set('CONFIG_SPICE', spice.found())
9d71037f 2180config_host_data.set('CONFIG_X11', x11.found())
142ca628 2181config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
9e62ba48 2182config_host_data.set('CONFIG_CFI', get_option('cfi'))
3d212b41 2183config_host_data.set('CONFIG_SELINUX', selinux.found())
14efd8d3 2184config_host_data.set('CONFIG_XEN_BACKEND', xen.found())
7c10cb38 2185config_host_data.set('CONFIG_LIBDW', libdw.found())
14efd8d3
PB
2186if xen.found()
2187 # protect from xen.version() having less than three components
2188 xen_version = xen.version().split('.') + ['0', '0']
2189 xen_ctrl_version = xen_version[0] + \
2190 ('0' + xen_version[1]).substring(-2) + \
2191 ('0' + xen_version[2]).substring(-2)
2192 config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version)
2193endif
859aef02
PB
2194config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
2195config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
2196config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
2197config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
2198
a6305081 2199config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
69d8de7a
PB
2200config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
2201
728c0a2f
PB
2202have_coroutine_pool = get_option('coroutine_pool')
2203if get_option('debug_stack_usage') and have_coroutine_pool
2204 message('Disabling coroutine pool to measure stack usage')
2205 have_coroutine_pool = false
2206endif
2207config_host_data.set10('CONFIG_COROUTINE_POOL', have_coroutine_pool)
58a2e3f5 2208config_host_data.set('CONFIG_DEBUG_GRAPH_LOCK', get_option('debug_graph_lock'))
c55cf6ab 2209config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
728c0a2f 2210config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
c55cf6ab 2211config_host_data.set('CONFIG_GPROF', get_option('gprof'))
406523f6 2212config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed())
c55cf6ab 2213config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
abad185c 2214config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed())
406523f6 2215
69d8de7a 2216# has_header
e66420ac 2217config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
d47a8b3b
PB
2218config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
2219config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
48f670ec 2220config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
2964be52 2221config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
2802d91d 2222config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
69d8de7a 2223config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
ded5d78c 2224config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
4a9d5f89 2225config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
d409373b
BM
2226if targetos == 'windows'
2227 config_host_data.set('HAVE_AFUNIX_H', cc.has_header('afunix.h'))
2228endif
ded5d78c 2229
69d8de7a 2230# has_function
c891c24b 2231config_host_data.set('CONFIG_CLOSE_RANGE', cc.has_function('close_range'))
a620fbe9 2232config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
e66420ac
PB
2233config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
2234config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
2235config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
2236config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
8698343b
PM
2237# Note that we need to specify prefix: here to avoid incorrectly
2238# thinking that Windows has posix_memalign()
2239config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
5c8c714a 2240config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
88454f84
PM
2241config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
2242config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
e66420ac 2243config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
2b9f74ef 2244config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
029ed1bd 2245config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
e66420ac
PB
2246config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
2247config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
2248config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
2249config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
2250config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
be7e89f6 2251config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
59e35c7b 2252config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
fc9a809e 2253config_host_data.set('HAVE_GLIB_WITH_SLICE_ALLOCATOR', glib_has_gslice)
e66420ac 2254config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
ed3b3f17 2255config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
69d8de7a 2256config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
66dc5f96
SG
2257if rbd.found()
2258 config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS',
2259 cc.has_function('rbd_namespace_exists',
2260 dependencies: rbd,
2261 prefix: '#include <rbd/librbd.h>'))
2262endif
911965ac
LZ
2263if rdma.found()
2264 config_host_data.set('HAVE_IBV_ADVISE_MR',
2265 cc.has_function('ibv_advise_mr',
3730a734 2266 dependencies: rdma,
911965ac
LZ
2267 prefix: '#include <infiniband/verbs.h>'))
2268endif
2b9f74ef 2269
34f983d8
PB
2270have_asan_fiber = false
2271if get_option('sanitizers') and \
2272 not cc.has_function('__sanitizer_start_switch_fiber',
2273 args: '-fsanitize=address',
2274 prefix: '#include <sanitizer/asan_interface.h>')
2275 warning('Missing ASAN due to missing fiber annotation interface')
2276 warning('Without code annotation, the report may be inferior.')
2277else
2278 have_asan_fiber = true
2279endif
2280config_host_data.set('CONFIG_ASAN_IFACE_FIBER', have_asan_fiber)
2281
e66420ac 2282# has_header_symbol
6d43eaa3
SL
2283config_host_data.set('CONFIG_BLKZONED',
2284 cc.has_header_symbol('linux/blkzoned.h', 'BLKOPENZONE'))
e66420ac
PB
2285config_host_data.set('CONFIG_EPOLL_CREATE1',
2286 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
2287config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
2288 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
2289 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
2290config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
2291 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
2292config_host_data.set('CONFIG_FIEMAP',
2293 cc.has_header('linux/fiemap.h') and
2294 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
be7e89f6
PB
2295config_host_data.set('CONFIG_GETRANDOM',
2296 cc.has_function('getrandom') and
2297 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
a620fbe9
PB
2298config_host_data.set('CONFIG_INOTIFY',
2299 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
2300config_host_data.set('CONFIG_INOTIFY1',
2301 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
e66420ac
PB
2302config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
2303 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
be7e89f6
PB
2304config_host_data.set('CONFIG_RTNETLINK',
2305 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
2306config_host_data.set('CONFIG_SYSMACROS',
2307 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
e1fbd2c4
PB
2308config_host_data.set('HAVE_OPTRESET',
2309 cc.has_header_symbol('getopt.h', 'optreset'))
653163fc
MAL
2310config_host_data.set('HAVE_IPPROTO_MPTCP',
2311 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
e66420ac
PB
2312
2313# has_member
2314config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
2315 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
2316 prefix: '#include <signal.h>'))
ed3b3f17
PB
2317config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
2318 cc.has_member('struct stat', 'st_atim',
2319 prefix: '#include <sys/stat.h>'))
6d43eaa3
SL
2320config_host_data.set('HAVE_BLK_ZONE_REP_CAPACITY',
2321 cc.has_member('struct blk_zone', 'capacity',
2322 prefix: '#include <linux/blkzoned.h>'))
e66420ac 2323
6a23f819
PB
2324# has_type
2325config_host_data.set('CONFIG_IOVEC',
2326 cc.has_type('struct iovec',
2327 prefix: '#include <sys/uio.h>'))
2328config_host_data.set('HAVE_UTMPX',
2329 cc.has_type('struct utmpx',
2330 prefix: '#include <utmpx.h>'))
2331
904ad5ec 2332config_host_data.set('CONFIG_EVENTFD', cc.links('''
e1fbd2c4
PB
2333 #include <sys/eventfd.h>
2334 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
904ad5ec 2335config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
e1fbd2c4
PB
2336 #include <unistd.h>
2337 int main(void) {
2338 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
2339 return fdatasync(0);
2340 #else
2341 #error Not supported
2342 #endif
2343 }'''))
8900c204
AD
2344
2345has_madvise = cc.links(gnu_source_prefix + '''
e1fbd2c4
PB
2346 #include <sys/types.h>
2347 #include <sys/mman.h>
2348 #include <stddef.h>
8900c204
AD
2349 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
2350missing_madvise_proto = false
2351if has_madvise
2352 # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
2353 # but forget to prototype it. In this case, has_madvise will be true (the
2354 # test program links despite a compile warning). To detect the
2355 # missing-prototype case, we try again with a definitely-bogus prototype.
2356 # This will only compile if the system headers don't provide the prototype;
2357 # otherwise the conflicting prototypes will cause a compiler error.
2358 missing_madvise_proto = cc.links(gnu_source_prefix + '''
2359 #include <sys/types.h>
2360 #include <sys/mman.h>
2361 #include <stddef.h>
2362 extern int madvise(int);
2363 int main(void) { return madvise(0); }''')
2364endif
2365config_host_data.set('CONFIG_MADVISE', has_madvise)
2366config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
2367
904ad5ec 2368config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
e1fbd2c4
PB
2369 #include <sys/mman.h>
2370 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
904ad5ec 2371config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
d47a8b3b
PB
2372 #include <fcntl.h>
2373 #if !defined(AT_EMPTY_PATH)
2374 # error missing definition
2375 #else
2376 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
2377 #endif'''))
904ad5ec 2378config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
e1fbd2c4
PB
2379 #include <sys/mman.h>
2380 #include <stddef.h>
2381 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
10f6b231 2382
6a23f819 2383config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
10f6b231
PB
2384 #include <pthread.h>
2385
2386 static void *f(void *p) { return NULL; }
2387 int main(void)
2388 {
2389 pthread_t thread;
2390 pthread_create(&thread, 0, f, 0);
2391 pthread_setname_np(thread, "QEMU");
2392 return 0;
2393 }''', dependencies: threads))
6a23f819 2394config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
10f6b231
PB
2395 #include <pthread.h>
2396
2397 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
2398 int main(void)
2399 {
2400 pthread_t thread;
2401 pthread_create(&thread, 0, f, 0);
2402 return 0;
2403 }''', dependencies: threads))
3ada67a3
BS
2404config_host_data.set('CONFIG_PTHREAD_SET_NAME_NP', cc.links(gnu_source_prefix + '''
2405 #include <pthread.h>
2406 #include <pthread_np.h>
2407
2408 static void *f(void *p) { return NULL; }
2409 int main(void)
2410 {
2411 pthread_t thread;
2412 pthread_create(&thread, 0, f, 0);
2413 pthread_set_name_np(thread, "QEMU");
2414 return 0;
2415 }''', dependencies: threads))
657ac98b
LM
2416config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + '''
2417 #include <pthread.h>
2418 #include <time.h>
2419
2420 int main(void)
2421 {
2422 pthread_condattr_t attr
2423 pthread_condattr_init(&attr);
2424 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
2425 return 0;
2426 }''', dependencies: threads))
7730f32c
DH
2427config_host_data.set('CONFIG_PTHREAD_AFFINITY_NP', cc.links(gnu_source_prefix + '''
2428 #include <pthread.h>
10f6b231 2429
7730f32c
DH
2430 static void *f(void *p) { return NULL; }
2431 int main(void)
2432 {
2433 int setsize = CPU_ALLOC_SIZE(64);
2434 pthread_t thread;
2435 cpu_set_t *cpuset;
2436 pthread_create(&thread, 0, f, 0);
2437 cpuset = CPU_ALLOC(64);
2438 CPU_ZERO_S(setsize, cpuset);
2439 pthread_setaffinity_np(thread, setsize, cpuset);
2440 pthread_getaffinity_np(thread, setsize, cpuset);
2441 CPU_FREE(cpuset);
2442 return 0;
2443 }''', dependencies: threads))
904ad5ec 2444config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
6bd17dcc
KS
2445 #include <sys/signalfd.h>
2446 #include <stddef.h>
2447 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
904ad5ec 2448config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
a620fbe9
PB
2449 #include <unistd.h>
2450 #include <fcntl.h>
2451 #include <limits.h>
2452
2453 int main(void)
2454 {
2455 int len, fd = 0;
2456 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
2457 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
2458 return 0;
2459 }'''))
e1fbd2c4 2460
96a63aeb
PB
2461config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
2462 #include <sys/mman.h>
b5d3dac1 2463 int main(void) {
96a63aeb
PB
2464 return mlockall(MCL_FUTURE);
2465 }'''))
2466
eea9453a 2467have_l2tpv3 = false
43a363ae 2468if get_option('l2tpv3').allowed() and have_system
6a23f819
PB
2469 have_l2tpv3 = cc.has_type('struct mmsghdr',
2470 prefix: gnu_source_prefix + '''
2471 #include <sys/socket.h>
2472 #include <linux/ip.h>''')
eea9453a
TH
2473endif
2474config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
2475
837b84b1 2476have_netmap = false
43a363ae 2477if get_option('netmap').allowed() and have_system
837b84b1
PB
2478 have_netmap = cc.compiles('''
2479 #include <inttypes.h>
2480 #include <net/if.h>
2481 #include <net/netmap.h>
2482 #include <net/netmap_user.h>
2483 #if (NETMAP_API < 11) || (NETMAP_API > 15)
2484 #error
2485 #endif
2486 int main(void) { return 0; }''')
2487 if not have_netmap and get_option('netmap').enabled()
2488 error('Netmap headers not available')
2489 endif
2490endif
2491config_host_data.set('CONFIG_NETMAP', have_netmap)
2492
96a63aeb
PB
2493# Work around a system header bug with some kernel/XFS header
2494# versions where they both try to define 'struct fsxattr':
2495# xfs headers will not try to redefine structs from linux headers
2496# if this macro is set.
2497config_host_data.set('HAVE_FSXATTR', cc.links('''
6a23f819 2498 #include <linux/fs.h>
96a63aeb
PB
2499 struct fsxattr foo;
2500 int main(void) {
2501 return 0;
2502 }'''))
2503
e46bd55d
PB
2504# Some versions of Mac OS X incorrectly define SIZE_MAX
2505config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
2506 #include <stdint.h>
2507 #include <stdio.h>
b5d3dac1 2508 int main(void) {
e46bd55d
PB
2509 return printf("%zu", SIZE_MAX);
2510 }''', args: ['-Werror']))
2511
e61f1efe
RH
2512# See if 64-bit atomic operations are supported.
2513# Note that without __atomic builtins, we can only
2514# assume atomic loads/stores max at pointer size.
2515config_host_data.set('CONFIG_ATOMIC64', cc.links('''
bd87a367
PB
2516 #include <stdint.h>
2517 int main(void)
2518 {
e61f1efe 2519 uint64_t x = 0, y = 0;
bd87a367
PB
2520 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
2521 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
2522 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2523 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
2524 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
2525 return 0;
e61f1efe 2526 }'''))
bd87a367 2527
848126d1
MAL
2528has_int128 = cc.links('''
2529 __int128_t a;
2530 __uint128_t b;
2531 int main (void) {
2532 a = a + b;
2533 b = a * b;
2534 a = a * a;
2535 return 0;
2536 }''')
2537
2538config_host_data.set('CONFIG_INT128', has_int128)
2539
2540if has_int128
d2958fb0
MAL
2541 # "do we have 128-bit atomics which are handled inline and specifically not
2542 # via libatomic". The reason we can't use libatomic is documented in the
2543 # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
e61f1efe
RH
2544 # We only care about these operations on 16-byte aligned pointers, so
2545 # force 16-byte alignment of the pointer, which may be greater than
2546 # __alignof(unsigned __int128) for the host.
2547 atomic_test_128 = '''
2548 int main(int ac, char **av) {
2549 unsigned __int128 *p = __builtin_assume_aligned(av[ac - 1], sizeof(16));
2550 p[1] = __atomic_load_n(&p[0], __ATOMIC_RELAXED);
2551 __atomic_store_n(&p[2], p[3], __ATOMIC_RELAXED);
2552 __atomic_compare_exchange_n(&p[4], &p[5], p[6], 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2553 return 0;
2554 }'''
2555 has_atomic128 = cc.links(atomic_test_128)
848126d1
MAL
2556
2557 config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
2558
2559 if not has_atomic128
e61f1efe
RH
2560 # Even with __builtin_assume_aligned, the above test may have failed
2561 # without optimization enabled. Try again with optimizations locally
2562 # enabled for the function. See
2563 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107389
2564 has_atomic128_opt = cc.links('__attribute__((optimize("O1")))' + atomic_test_128)
2565 config_host_data.set('CONFIG_ATOMIC128_OPT', has_atomic128_opt)
2566
2567 if not has_atomic128_opt
2568 config_host_data.set('CONFIG_CMPXCHG128', cc.links('''
2569 int main(void)
2570 {
2571 unsigned __int128 x = 0, y = 0;
2572 __sync_val_compare_and_swap_16(&x, y, x);
2573 return 0;
2574 }
2575 '''))
2576 endif
848126d1
MAL
2577 endif
2578endif
bd87a367
PB
2579
2580config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
2581 #include <sys/auxv.h>
2582 int main(void) {
2583 return getauxval(AT_HWCAP) == 0;
2584 }'''))
2585
0dae95d4
PB
2586config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
2587 #include <linux/usbdevice_fs.h>
2588
2589 #ifndef USBDEVFS_GET_CAPABILITIES
2590 #error "USBDEVFS_GET_CAPABILITIES undefined"
2591 #endif
2592
2593 #ifndef USBDEVFS_DISCONNECT_CLAIM
2594 #error "USBDEVFS_DISCONNECT_CLAIM undefined"
2595 #endif
2596
2597 int main(void) { return 0; }'''))
2598
2edd2c04
PB
2599have_keyring = get_option('keyring') \
2600 .require(targetos == 'linux', error_message: 'keyring is only available on Linux') \
2601 .require(cc.compiles('''
2602 #include <errno.h>
2603 #include <asm/unistd.h>
2604 #include <linux/keyctl.h>
2605 #include <sys/syscall.h>
2606 #include <unistd.h>
2607 int main(void) {
2608 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
2609 }'''), error_message: 'keyctl syscall not available on this system').allowed()
2610config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring)
2611
622753d2
PB
2612have_cpuid_h = cc.links('''
2613 #include <cpuid.h>
2614 int main(void) {
2615 unsigned a, b, c, d;
2616 unsigned max = __get_cpuid_max(0, 0);
2617
2618 if (max >= 1) {
2619 __cpuid(1, a, b, c, d);
2620 }
2621
2622 if (max >= 7) {
2623 __cpuid_count(7, 0, a, b, c, d);
2624 }
2625
2626 return 0;
2627 }''')
2628config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
2629
2630config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
2631 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
2632 .require(cc.links('''
622753d2
PB
2633 #include <cpuid.h>
2634 #include <immintrin.h>
701ea587 2635 static int __attribute__((target("avx2"))) bar(void *a) {
622753d2
PB
2636 __m256i x = *(__m256i *)a;
2637 return _mm256_testz_si256(x, x);
2638 }
b5d3dac1 2639 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
622753d2
PB
2640 '''), error_message: 'AVX2 not available').allowed())
2641
2642config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
2643 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
2644 .require(cc.links('''
622753d2
PB
2645 #include <cpuid.h>
2646 #include <immintrin.h>
701ea587 2647 static int __attribute__((target("avx512f"))) bar(void *a) {
622753d2
PB
2648 __m512i x = *(__m512i *)a;
2649 return _mm512_test_epi64_mask(x, x);
2650 }
b5d3dac1 2651 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
622753d2
PB
2652 '''), error_message: 'AVX512F not available').allowed())
2653
04ffce13 2654config_host_data.set('CONFIG_AVX512BW_OPT', get_option('avx512bw') \
2655 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512BW') \
2656 .require(cc.links('''
04ffce13 2657 #include <cpuid.h>
2658 #include <immintrin.h>
dc165fcd 2659 static int __attribute__((target("avx512bw"))) bar(void *a) {
04ffce13 2660 __m512i *x = a;
2661 __m512i res= _mm512_abs_epi8(*x);
2662 return res[1];
2663 }
2664 int main(int argc, char *argv[]) { return bar(argv[0]); }
2665 '''), error_message: 'AVX512BW not available').allowed())
2666
3730a734
PB
2667have_pvrdma = get_option('pvrdma') \
2668 .require(rdma.found(), error_message: 'PVRDMA requires OpenFabrics libraries') \
354d2d9b
JQ
2669 .require(cc.compiles(gnu_source_prefix + '''
2670 #include <sys/mman.h>
3730a734
PB
2671 int main(void)
2672 {
2673 char buf = 0;
2674 void *addr = &buf;
2675 addr = mremap(addr, 0, 1, MREMAP_MAYMOVE | MREMAP_FIXED);
2676
2677 return 0;
2678 }'''), error_message: 'PVRDMA requires mremap').allowed()
2679
2680if have_pvrdma
354d2d9b 2681 config_host_data.set('LEGACY_RDMA_REG_MR', not cc.links('''
3730a734
PB
2682 #include <infiniband/verbs.h>
2683 int main(void)
2684 {
2685 struct ibv_mr *mr;
2686 struct ibv_pd *pd = NULL;
2687 size_t length = 10;
2688 uint64_t iova = 0;
2689 int access = 0;
2690 void *addr = NULL;
2691
2692 mr = ibv_reg_mr_iova(pd, addr, length, iova, access);
2693 ibv_dereg_mr(mr);
2694 return 0;
2695 }'''))
2696endif
2697
b87df904
PB
2698if get_option('membarrier').disabled()
2699 have_membarrier = false
2700elif targetos == 'windows'
2701 have_membarrier = true
2702elif targetos == 'linux'
2703 have_membarrier = cc.compiles('''
2704 #include <linux/membarrier.h>
2705 #include <sys/syscall.h>
2706 #include <unistd.h>
2707 #include <stdlib.h>
2708 int main(void) {
2709 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
2710 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
2711 exit(0);
2712 }''')
2713endif
2714config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
2715 .require(have_membarrier, error_message: 'membarrier system call not available') \
2716 .allowed())
2717
34b52615
PB
2718have_afalg = get_option('crypto_afalg') \
2719 .require(cc.compiles(gnu_source_prefix + '''
2720 #include <errno.h>
2721 #include <sys/types.h>
2722 #include <sys/socket.h>
2723 #include <linux/if_alg.h>
2724 int main(void) {
2725 int sock;
2726 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
2727 return sock;
2728 }
2729 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
2730config_host_data.set('CONFIG_AF_ALG', have_afalg)
2731
9d734b85
MAL
2732config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
2733 'linux/vm_sockets.h', 'AF_VSOCK',
2734 prefix: '#include <sys/socket.h>',
2735))
bd87a367 2736
8821a389 2737have_vss = false
872b69e6 2738have_vss_sdk = false # old xp/2003 SDK
8821a389
MAL
2739if targetos == 'windows' and link_language == 'cpp'
2740 have_vss = cxx.compiles('''
2741 #define __MIDL_user_allocate_free_DEFINED__
32478cb6 2742 #include <vss.h>
8821a389 2743 int main(void) { return VSS_CTX_BACKUP; }''')
872b69e6 2744 have_vss_sdk = cxx.has_header('vscoordint.h')
8821a389 2745endif
872b69e6 2746config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
8821a389 2747
859aef02 2748foreach k, v: config_host
ce6119dc 2749 if k.startswith('CONFIG_')
859aef02
PB
2750 config_host_data.set(k, v == 'y' ? 1 : v)
2751 endif
2752endforeach
859aef02 2753
6391c772
RH
2754# Older versions of MinGW do not import _lock_file and _unlock_file properly.
2755# This was fixed for v6.0.0 with commit b48e3ac8969d.
2756if targetos == 'windows'
2757 config_host_data.set('HAVE__LOCK_FILE', cc.links('''
2758 #include <stdio.h>
2759 int main(void) {
2760 _lock_file(NULL);
2761 _unlock_file(NULL);
2762 return 0;
2763 }''', name: '_lock_file and _unlock_file'))
2764endif
2765
dbd672c8
PB
2766if targetos == 'windows'
2767 mingw_has_setjmp_longjmp = cc.links('''
2768 #include <setjmp.h>
2769 int main(void) {
2770 /*
2771 * These functions are not available in setjmp header, but may be
2772 * available at link time, from libmingwex.a.
2773 */
2774 extern int __mingw_setjmp(jmp_buf);
2775 extern void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int);
2776 jmp_buf env;
2777 __mingw_setjmp(env);
2778 __mingw_longjmp(env, 0);
2779 }
2780 ''', name: 'mingw setjmp and longjmp')
2781
2782 if cpu == 'aarch64' and not mingw_has_setjmp_longjmp
2783 error('mingw must provide setjmp/longjmp for windows-arm64')
2784 endif
2785endif
2786
a0c9162c
PB
2787########################
2788# Target configuration #
2789########################
2790
2becc36a 2791minikconf = find_program('scripts/minikconf.py')
05512f55 2792config_all = {}
a98006bc 2793config_all_devices = {}
ca0fc784 2794config_all_disas = {}
2becc36a
PB
2795config_devices_mak_list = []
2796config_devices_h = {}
859aef02 2797config_target_h = {}
2becc36a 2798config_target_mak = {}
ca0fc784
PB
2799
2800disassemblers = {
2801 'alpha' : ['CONFIG_ALPHA_DIS'],
ca0fc784
PB
2802 'avr' : ['CONFIG_AVR_DIS'],
2803 'cris' : ['CONFIG_CRIS_DIS'],
3e7a84ee 2804 'hexagon' : ['CONFIG_HEXAGON_DIS'],
ca0fc784
PB
2805 'hppa' : ['CONFIG_HPPA_DIS'],
2806 'i386' : ['CONFIG_I386_DIS'],
2807 'x86_64' : ['CONFIG_I386_DIS'],
ca0fc784
PB
2808 'm68k' : ['CONFIG_M68K_DIS'],
2809 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
2810 'mips' : ['CONFIG_MIPS_DIS'],
ca0fc784
PB
2811 'nios2' : ['CONFIG_NIOS2_DIS'],
2812 'or1k' : ['CONFIG_OPENRISC_DIS'],
2813 'ppc' : ['CONFIG_PPC_DIS'],
2814 'riscv' : ['CONFIG_RISCV_DIS'],
2815 'rx' : ['CONFIG_RX_DIS'],
2816 's390' : ['CONFIG_S390_DIS'],
2817 'sh4' : ['CONFIG_SH4_DIS'],
2818 'sparc' : ['CONFIG_SPARC_DIS'],
2819 'xtensa' : ['CONFIG_XTENSA_DIS'],
aae1746c 2820 'loongarch' : ['CONFIG_LOONGARCH_DIS'],
ca0fc784 2821}
ca0fc784 2822
e1fbd2c4 2823have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
0a189110 2824host_kconfig = \
537b7248 2825 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
0d04c4c9 2826 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
3f0a5d55 2827 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
ccd250aa 2828 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
88b6e618 2829 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
9d71037f 2830 (x11.found() ? ['CONFIG_X11=y'] : []) + \
2a3129a3
PB
2831 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \
2832 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \
2833 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
69202b40 2834 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
0a189110 2835 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
3730a734 2836 (have_pvrdma ? ['CONFIG_PVRDMA=y'] : []) + \
55116968
JR
2837 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \
2838 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : [])
0a189110 2839
a9a74907 2840ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
05512f55 2841
fdb75aef
PB
2842default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
2843actual_target_dirs = []
fbb4121d 2844fdt_required = []
a81df1b6 2845foreach target : target_dirs
765686d6
PB
2846 config_target = { 'TARGET_NAME': target.split('-')[0] }
2847 if target.endswith('linux-user')
fdb75aef
PB
2848 if targetos != 'linux'
2849 if default_targets
2850 continue
2851 endif
2852 error('Target @0@ is only available on a Linux host'.format(target))
2853 endif
765686d6
PB
2854 config_target += { 'CONFIG_LINUX_USER': 'y' }
2855 elif target.endswith('bsd-user')
fdb75aef
PB
2856 if 'CONFIG_BSD' not in config_host
2857 if default_targets
2858 continue
2859 endif
2860 error('Target @0@ is only available on a BSD host'.format(target))
2861 endif
765686d6
PB
2862 config_target += { 'CONFIG_BSD_USER': 'y' }
2863 elif target.endswith('softmmu')
2864 config_target += { 'CONFIG_SOFTMMU': 'y' }
2865 endif
2866 if target.endswith('-user')
2867 config_target += {
2868 'CONFIG_USER_ONLY': 'y',
2869 'CONFIG_QEMU_INTERP_PREFIX':
ce6119dc 2870 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME'])
765686d6
PB
2871 }
2872 endif
859aef02 2873
0a189110 2874 accel_kconfig = []
8a19980e
PB
2875 foreach sym: accelerators
2876 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
2877 config_target += { sym: 'y' }
2878 config_all += { sym: 'y' }
dae0ec15
GH
2879 if target in modular_tcg
2880 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
2881 else
2882 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
2883 endif
0a189110 2884 accel_kconfig += [ sym + '=y' ]
8a19980e
PB
2885 endif
2886 endforeach
0a189110 2887 if accel_kconfig.length() == 0
fdb75aef
PB
2888 if default_targets
2889 continue
2890 endif
2891 error('No accelerator available for target @0@'.format(target))
2892 endif
8a19980e 2893
fdb75aef 2894 actual_target_dirs += target
812b31d3 2895 config_target += keyval.load('configs/targets' / target + '.mak')
a9a74907 2896 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
765686d6 2897
fbb4121d
PB
2898 if 'TARGET_NEED_FDT' in config_target
2899 fdt_required += target
2900 endif
2901
fa73168b
PB
2902 # Add default keys
2903 if 'TARGET_BASE_ARCH' not in config_target
2904 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
2905 endif
2906 if 'TARGET_ABI_DIR' not in config_target
2907 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
2908 endif
ee3eb3a7
MAL
2909 if 'TARGET_BIG_ENDIAN' not in config_target
2910 config_target += {'TARGET_BIG_ENDIAN': 'n'}
2911 endif
859aef02 2912
ca0fc784 2913 foreach k, v: disassemblers
823eb013 2914 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
ca0fc784
PB
2915 foreach sym: v
2916 config_target += { sym: 'y' }
2917 config_all_disas += { sym: 'y' }
2918 endforeach
2919 endif
2920 endforeach
2921
859aef02
PB
2922 config_target_data = configuration_data()
2923 foreach k, v: config_target
2924 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
2925 # do nothing
2926 elif ignored.contains(k)
2927 # do nothing
2928 elif k == 'TARGET_BASE_ARCH'
a9a74907
PB
2929 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
2930 # not used to select files from sourcesets.
859aef02 2931 config_target_data.set('TARGET_' + v.to_upper(), 1)
765686d6 2932 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
859aef02
PB
2933 config_target_data.set_quoted(k, v)
2934 elif v == 'y'
2935 config_target_data.set(k, 1)
ee3eb3a7
MAL
2936 elif v == 'n'
2937 config_target_data.set(k, 0)
859aef02
PB
2938 else
2939 config_target_data.set(k, v)
2940 endif
2941 endforeach
cb2c5531
PM
2942 config_target_data.set('QEMU_ARCH',
2943 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
859aef02
PB
2944 config_target_h += {target: configure_file(output: target + '-config-target.h',
2945 configuration: config_target_data)}
2becc36a
PB
2946
2947 if target.endswith('-softmmu')
d1d5e9ee 2948 config_input = meson.get_external_property(target, 'default')
2becc36a
PB
2949 config_devices_mak = target + '-config-devices.mak'
2950 config_devices_mak = configure_file(
d1d5e9ee 2951 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
2becc36a
PB
2952 output: config_devices_mak,
2953 depfile: config_devices_mak + '.d',
2954 capture: true,
7bc3ca7f
PB
2955 command: [minikconf,
2956 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
2becc36a 2957 config_devices_mak, '@DEPFILE@', '@INPUT@',
f4063f9c
PMD
2958 host_kconfig, accel_kconfig,
2959 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
859aef02
PB
2960
2961 config_devices_data = configuration_data()
2962 config_devices = keyval.load(config_devices_mak)
2963 foreach k, v: config_devices
2964 config_devices_data.set(k, 1)
2965 endforeach
2becc36a 2966 config_devices_mak_list += config_devices_mak
859aef02
PB
2967 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
2968 configuration: config_devices_data)}
2969 config_target += config_devices
a98006bc 2970 config_all_devices += config_devices
2becc36a
PB
2971 endif
2972 config_target_mak += {target: config_target}
a81df1b6 2973endforeach
fdb75aef 2974target_dirs = actual_target_dirs
a81df1b6 2975
2becc36a
PB
2976# This configuration is used to build files that are shared by
2977# multiple binaries, and then extracted out of the "common"
2978# static_library target.
2979#
2980# We do not use all_sources()/all_dependencies(), because it would
2981# build literally all source files, including devices only used by
2982# targets that are not built for this compilation. The CONFIG_ALL
2983# pseudo symbol replaces it.
2984
05512f55 2985config_all += config_all_devices
2becc36a
PB
2986config_all += config_host
2987config_all += config_all_disas
2988config_all += {
14efd8d3 2989 'CONFIG_XEN': xen.found(),
2becc36a
PB
2990 'CONFIG_SOFTMMU': have_system,
2991 'CONFIG_USER_ONLY': have_user,
2992 'CONFIG_ALL': true,
2993}
2994
eed56e9a
PB
2995target_configs_h = []
2996foreach target: target_dirs
2997 target_configs_h += config_target_h[target]
2998 target_configs_h += config_devices_h.get(target, [])
2999endforeach
3000genh += custom_target('config-poison.h',
3001 input: [target_configs_h],
3002 output: 'config-poison.h',
3003 capture: true,
3004 command: [find_program('scripts/make-config-poison.sh'),
3005 target_configs_h])
3006
a0c9162c
PB
3007##############
3008# Submodules #
3009##############
8b18cdbf
RH
3010
3011capstone = not_found
83602083 3012if not get_option('capstone').auto() or have_system or have_user
43ecd166 3013 capstone = dependency('capstone', version: '>=3.0.5',
063d5119 3014 method: 'pkg-config',
83602083 3015 required: get_option('capstone'))
8f4aea71
DB
3016
3017 # Some versions of capstone have broken pkg-config file
3018 # that reports a wrong -I path, causing the #include to
3019 # fail later. If the system has such a broken version
3020 # do not use it.
3021 if capstone.found() and not cc.compiles('#include <capstone.h>',
3022 dependencies: [capstone])
3023 capstone = not_found
83602083
TH
3024 if get_option('capstone').enabled()
3025 error('capstone requested, but it does not appear to work')
8f4aea71
DB
3026 endif
3027 endif
8b18cdbf 3028endif
4d34a86b 3029
55116968
JR
3030libvfio_user_dep = not_found
3031if have_system and vfio_user_server_allowed
3032 have_internal = fs.exists(meson.current_source_dir() / 'subprojects/libvfio-user/meson.build')
3033
3034 if not have_internal
3035 error('libvfio-user source not found - please pull git submodule')
3036 endif
3037
3038 libvfio_user_proj = subproject('libvfio-user')
3039
5328353c 3040 libvfio_user_dep = libvfio_user_proj.get_variable('libvfio_user_dep')
55116968
JR
3041endif
3042
fbb4121d 3043fdt = not_found
fbb4121d 3044if have_system
c593d841 3045 fdt_opt = get_option('fdt')
fbb4121d
PB
3046 if fdt_opt in ['enabled', 'auto', 'system']
3047 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
063d5119 3048 fdt = cc.find_library('fdt',
fbb4121d
PB
3049 required: fdt_opt == 'system' or
3050 fdt_opt == 'enabled' and not have_internal)
3051 if fdt.found() and cc.links('''
3052 #include <libfdt.h>
3053 #include <libfdt_env.h>
de47b0ff 3054 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
fbb4121d
PB
3055 dependencies: fdt)
3056 fdt_opt = 'system'
6c22853c
TH
3057 elif fdt_opt == 'system'
3058 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
fbb4121d
PB
3059 elif have_internal
3060 fdt_opt = 'internal'
3061 else
3062 fdt_opt = 'disabled'
87daf898 3063 fdt = not_found
fbb4121d
PB
3064 endif
3065 endif
3066 if fdt_opt == 'internal'
3067 fdt_files = files(
3068 'dtc/libfdt/fdt.c',
3069 'dtc/libfdt/fdt_ro.c',
3070 'dtc/libfdt/fdt_wip.c',
3071 'dtc/libfdt/fdt_sw.c',
3072 'dtc/libfdt/fdt_rw.c',
3073 'dtc/libfdt/fdt_strerror.c',
3074 'dtc/libfdt/fdt_empty_tree.c',
3075 'dtc/libfdt/fdt_addresses.c',
3076 'dtc/libfdt/fdt_overlay.c',
3077 'dtc/libfdt/fdt_check.c',
3078 )
3079
3080 fdt_inc = include_directories('dtc/libfdt')
3081 libfdt = static_library('fdt',
610e7e0e 3082 build_by_default: false,
fbb4121d
PB
3083 sources: fdt_files,
3084 include_directories: fdt_inc)
3085 fdt = declare_dependency(link_with: libfdt,
3086 include_directories: fdt_inc)
3087 endif
c593d841
PMD
3088else
3089 fdt_opt = 'disabled'
fbb4121d
PB
3090endif
3091if not fdt.found() and fdt_required.length() > 0
3092 error('fdt not available but required by targets ' + ', '.join(fdt_required))
3093endif
3094
8b18cdbf 3095config_host_data.set('CONFIG_CAPSTONE', capstone.found())
fbb4121d 3096config_host_data.set('CONFIG_FDT', fdt.found())
4d34a86b 3097config_host_data.set('CONFIG_SLIRP', slirp.found())
8b18cdbf 3098
a0c9162c
PB
3099#####################
3100# Generated sources #
3101#####################
8b18cdbf 3102
a0c9162c 3103genh += configure_file(output: 'config-host.h', configuration: config_host_data)
a81df1b6 3104
3f885659 3105hxtool = find_program('scripts/hxtool')
e2c4012b 3106shaderinclude = find_program('scripts/shaderinclude.py')
a81df1b6 3107qapi_gen = find_program('scripts/qapi-gen.py')
654d6b04
PB
3108qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
3109 meson.current_source_dir() / 'scripts/qapi/commands.py',
3110 meson.current_source_dir() / 'scripts/qapi/common.py',
3111 meson.current_source_dir() / 'scripts/qapi/error.py',
3112 meson.current_source_dir() / 'scripts/qapi/events.py',
3113 meson.current_source_dir() / 'scripts/qapi/expr.py',
3114 meson.current_source_dir() / 'scripts/qapi/gen.py',
3115 meson.current_source_dir() / 'scripts/qapi/introspect.py',
88d357d2 3116 meson.current_source_dir() / 'scripts/qapi/main.py',
654d6b04
PB
3117 meson.current_source_dir() / 'scripts/qapi/parser.py',
3118 meson.current_source_dir() / 'scripts/qapi/schema.py',
3119 meson.current_source_dir() / 'scripts/qapi/source.py',
3120 meson.current_source_dir() / 'scripts/qapi/types.py',
3121 meson.current_source_dir() / 'scripts/qapi/visit.py',
654d6b04 3122 meson.current_source_dir() / 'scripts/qapi-gen.py'
a81df1b6
PB
3123]
3124
3125tracetool = [
3126 python, files('scripts/tracetool.py'),
9c29b741 3127 '--backend=' + ','.join(get_option('trace_backends'))
a81df1b6 3128]
0572d6cd
SH
3129tracetool_depends = files(
3130 'scripts/tracetool/backend/log.py',
3131 'scripts/tracetool/backend/__init__.py',
3132 'scripts/tracetool/backend/dtrace.py',
3133 'scripts/tracetool/backend/ftrace.py',
3134 'scripts/tracetool/backend/simple.py',
3135 'scripts/tracetool/backend/syslog.py',
3136 'scripts/tracetool/backend/ust.py',
0572d6cd
SH
3137 'scripts/tracetool/format/ust_events_c.py',
3138 'scripts/tracetool/format/ust_events_h.py',
3139 'scripts/tracetool/format/__init__.py',
3140 'scripts/tracetool/format/d.py',
0572d6cd
SH
3141 'scripts/tracetool/format/simpletrace_stap.py',
3142 'scripts/tracetool/format/c.py',
3143 'scripts/tracetool/format/h.py',
0572d6cd
SH
3144 'scripts/tracetool/format/log_stap.py',
3145 'scripts/tracetool/format/stap.py',
0572d6cd 3146 'scripts/tracetool/__init__.py',
0572d6cd
SH
3147 'scripts/tracetool/vcpu.py'
3148)
a81df1b6 3149
2c273f32
MAL
3150qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
3151 meson.current_source_dir(),
b0b4323e 3152 get_option('pkgversion'), meson.project_version()]
2c273f32
MAL
3153qemu_version = custom_target('qemu-version.h',
3154 output: 'qemu-version.h',
3155 command: qemu_version_cmd,
3156 capture: true,
3157 build_by_default: true,
3158 build_always_stale: true)
3159genh += qemu_version
3160
3f885659
MAL
3161hxdep = []
3162hx_headers = [
3163 ['qemu-options.hx', 'qemu-options.def'],
3164 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
3165]
3166if have_system
3167 hx_headers += [
3168 ['hmp-commands.hx', 'hmp-commands.h'],
3169 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
3170 ]
3171endif
3172foreach d : hx_headers
b7c70bf2 3173 hxdep += custom_target(d[1],
3f885659
MAL
3174 input: files(d[0]),
3175 output: d[1],
3176 capture: true,
3177 build_by_default: true, # to be removed when added to a target
3178 command: [hxtool, '-h', '@INPUT0@'])
3179endforeach
3180genh += hxdep
3181
a0c9162c
PB
3182###################
3183# Collect sources #
3184###################
a81df1b6 3185
55567891 3186authz_ss = ss.source_set()
4a96337d 3187blockdev_ss = ss.source_set()
7e2b888f 3188block_ss = ss.source_set()
c2306d71 3189chardev_ss = ss.source_set()
7e2b888f 3190common_ss = ss.source_set()
2389304a 3191crypto_ss = ss.source_set()
f73fb063 3192hwcore_ss = ss.source_set()
f78536b1 3193io_ss = ss.source_set()
7e2b888f 3194qmp_ss = ss.source_set()
da33fc09 3195qom_ss = ss.source_set()
7e2b888f 3196softmmu_ss = ss.source_set()
64ed6f92 3197specific_fuzz_ss = ss.source_set()
7e2b888f
PMD
3198specific_ss = ss.source_set()
3199stub_ss = ss.source_set()
3200trace_ss = ss.source_set()
3201user_ss = ss.source_set()
3202util_ss = ss.source_set()
2becc36a 3203
c94a7b88
GH
3204# accel modules
3205qtest_module_ss = ss.source_set()
dae0ec15 3206tcg_module_ss = ss.source_set()
c94a7b88 3207
3154fee4 3208modules = {}
db2e89df 3209target_modules = {}
2becc36a
PB
3210hw_arch = {}
3211target_arch = {}
3212target_softmmu_arch = {}
46369b50 3213target_user_arch = {}
a81df1b6
PB
3214
3215###############
3216# Trace files #
3217###############
3218
c9322ab5
MAL
3219# TODO: add each directory to the subdirs from its own meson.build, once
3220# we have those
a81df1b6 3221trace_events_subdirs = [
a81df1b6 3222 'crypto',
69ff4d0a
PMD
3223 'qapi',
3224 'qom',
a81df1b6 3225 'monitor',
69ff4d0a 3226 'util',
842b42df 3227 'gdbstub',
a81df1b6 3228]
6ddc1abe 3229if have_linux_user
a81df1b6
PB
3230 trace_events_subdirs += [ 'linux-user' ]
3231endif
6ddc1abe
WL
3232if have_bsd_user
3233 trace_events_subdirs += [ 'bsd-user' ]
3234endif
a81df1b6
PB
3235if have_block
3236 trace_events_subdirs += [
3237 'authz',
3238 'block',
3239 'io',
3240 'nbd',
3241 'scsi',
3242 ]
3243endif
3244if have_system
3245 trace_events_subdirs += [
8985db26 3246 'accel/kvm',
a81df1b6
PB
3247 'audio',
3248 'backends',
3249 'backends/tpm',
3250 'chardev',
46627f41 3251 'ebpf',
a81df1b6
PB
3252 'hw/9pfs',
3253 'hw/acpi',
77c05b0b 3254 'hw/adc',
a81df1b6
PB
3255 'hw/alpha',
3256 'hw/arm',
3257 'hw/audio',
3258 'hw/block',
3259 'hw/block/dataplane',
3260 'hw/char',
3261 'hw/display',
3262 'hw/dma',
a81df1b6
PB
3263 'hw/hyperv',
3264 'hw/i2c',
3265 'hw/i386',
3266 'hw/i386/xen',
aa98ee38 3267 'hw/i386/kvm',
a81df1b6
PB
3268 'hw/ide',
3269 'hw/input',
3270 'hw/intc',
3271 'hw/isa',
3272 'hw/mem',
3273 'hw/mips',
3274 'hw/misc',
3275 'hw/misc/macio',
3276 'hw/net',
98e5d7a2 3277 'hw/net/can',
ce0e6a2c 3278 'hw/nubus',
88eea45c 3279 'hw/nvme',
a81df1b6
PB
3280 'hw/nvram',
3281 'hw/pci',
3282 'hw/pci-host',
3283 'hw/ppc',
3284 'hw/rdma',
3285 'hw/rdma/vmw',
3286 'hw/rtc',
3287 'hw/s390x',
3288 'hw/scsi',
3289 'hw/sd',
ad52cfc1 3290 'hw/sh4',
a81df1b6
PB
3291 'hw/sparc',
3292 'hw/sparc64',
3293 'hw/ssi',
3294 'hw/timer',
3295 'hw/tpm',
3296 'hw/usb',
3297 'hw/vfio',
3298 'hw/virtio',
3299 'hw/watchdog',
3300 'hw/xen',
3301 'hw/gpio',
a81df1b6
PB
3302 'migration',
3303 'net',
8b7a5507 3304 'softmmu',
a81df1b6 3305 'ui',
ad22c308 3306 'hw/remote',
a81df1b6
PB
3307 ]
3308endif
8985db26
PMD
3309if have_system or have_user
3310 trace_events_subdirs += [
3311 'accel/tcg',
3312 'hw/core',
3313 'target/arm',
a1477da3 3314 'target/arm/hvf',
8985db26
PMD
3315 'target/hppa',
3316 'target/i386',
3317 'target/i386/kvm',
34b8ff25 3318 'target/mips/tcg',
6f83e277 3319 'target/nios2',
8985db26
PMD
3320 'target/ppc',
3321 'target/riscv',
3322 'target/s390x',
67043607 3323 'target/s390x/kvm',
8985db26
PMD
3324 'target/sparc',
3325 ]
3326endif
a81df1b6 3327
0df750e9 3328vhost_user = not_found
2a3129a3 3329if targetos == 'linux' and have_vhost_user
0df750e9
MAL
3330 libvhost_user = subproject('libvhost-user')
3331 vhost_user = libvhost_user.get_variable('vhost_user_dep')
3332endif
3333
a6caeee8
XY
3334libvduse = not_found
3335if have_libvduse
3336 libvduse_proj = subproject('libvduse')
3337 libvduse = libvduse_proj.get_variable('libvduse_dep')
3338endif
3339
b83a80e8
VSO
3340# NOTE: the trace/ subdirectory needs the qapi_trace_events variable
3341# that is filled in by qapi/.
a81df1b6
PB
3342subdir('qapi')
3343subdir('qobject')
3344subdir('stubs')
3345subdir('trace')
3346subdir('util')
5582c58f
MAL
3347subdir('qom')
3348subdir('authz')
a81df1b6 3349subdir('crypto')
2d78b56e 3350subdir('ui')
7d5983e3 3351subdir('hw')
842b42df 3352subdir('gdbstub')
a81df1b6 3353
3154fee4
MAL
3354if enable_modules
3355 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
3356 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
3357endif
3358
7d5983e3
NSJ
3359qom_ss = qom_ss.apply(config_host, strict: false)
3360libqom = static_library('qom', qom_ss.sources() + genh,
3361 dependencies: [qom_ss.dependencies()],
3362 name_suffix: 'fa')
3363qom = declare_dependency(link_whole: libqom)
3364
3365event_loop_base = files('event-loop-base.c')
3366event_loop_base = static_library('event-loop-base', sources: event_loop_base + genh,
3367 build_by_default: true)
3368event_loop_base = declare_dependency(link_whole: event_loop_base,
3369 dependencies: [qom])
3370
2becc36a 3371stub_ss = stub_ss.apply(config_all, strict: false)
a81df1b6
PB
3372
3373util_ss.add_all(trace_ss)
2becc36a 3374util_ss = util_ss.apply(config_all, strict: false)
a81df1b6
PB
3375libqemuutil = static_library('qemuutil',
3376 sources: util_ss.sources() + stub_ss.sources() + genh,
6d7c7c2d 3377 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
a81df1b6 3378qemuutil = declare_dependency(link_with: libqemuutil,
70ac26b9
NSJ
3379 sources: genh + version_res,
3380 dependencies: [event_loop_base])
a81df1b6 3381
957b31f6
PMD
3382if have_system or have_user
3383 decodetree = generator(find_program('scripts/decodetree.py'),
3384 output: 'decode-@BASENAME@.c.inc',
3385 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
3386 subdir('libdecnumber')
3387 subdir('target')
3388endif
abff1abf 3389
478e943f 3390subdir('audio')
7fcfd456 3391subdir('io')
848e8ff6 3392subdir('chardev')
ec0d5893 3393subdir('fsdev')
708eab42 3394subdir('dump')
ec0d5893 3395
f285bd3f
PMD
3396if have_block
3397 block_ss.add(files(
3398 'block.c',
3399 'blockjob.c',
3400 'job.c',
3401 'qemu-io-cmds.c',
3402 ))
406523f6
PB
3403 if config_host_data.get('CONFIG_REPLICATION')
3404 block_ss.add(files('replication.c'))
3405 endif
f285bd3f
PMD
3406
3407 subdir('nbd')
3408 subdir('scsi')
3409 subdir('block')
3410
3411 blockdev_ss.add(files(
3412 'blockdev.c',
3413 'blockdev-nbd.c',
3414 'iothread.c',
3415 'job-qmp.c',
3416 ), gnutls)
3417
3418 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
3419 # os-win32.c does not
3420 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
3421 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
3422endif
4a96337d
PB
3423
3424common_ss.add(files('cpus-common.c'))
31ffa2aa 3425specific_ss.add(files('cpu.c'))
4a96337d 3426
5d3ea0e1 3427subdir('softmmu')
c9322ab5 3428
44b99a6d
RH
3429# Work around a gcc bug/misfeature wherein constant propagation looks
3430# through an alias:
3431# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
3432# to guess that a const variable is always zero. Without lto, this is
3433# impossible, as the alias is restricted to page-vary-common.c. Indeed,
3434# without lto, not even the alias is required -- we simply use different
3435# declarations in different compilation units.
3436pagevary = files('page-vary-common.c')
3437if get_option('b_lto')
3438 pagevary_flags = ['-fno-lto']
3439 if get_option('cfi')
3440 pagevary_flags += '-fno-sanitize=cfi-icall'
3441 endif
54c9b194 3442 pagevary = static_library('page-vary-common', sources: pagevary + genh,
44b99a6d
RH
3443 c_args: pagevary_flags)
3444 pagevary = declare_dependency(link_with: pagevary)
3445endif
3446common_ss.add(pagevary)
6670d4d0
RH
3447specific_ss.add(files('page-vary.c'))
3448
ab318051 3449subdir('backends')
c574e161 3450subdir('disas')
55166230 3451subdir('migration')
ff219dca 3452subdir('monitor')
cdaf0722 3453subdir('net')
17ef2af6 3454subdir('replay')
8df9f0c3 3455subdir('semihosting')
aa09b3d5 3456subdir('stats')
104cc2c0 3457subdir('tcg')
c6347541 3458subdir('fpu')
1a82878a 3459subdir('accel')
f556b4a1 3460subdir('plugins')
bbf15aaf
RH
3461subdir('ebpf')
3462
3463common_user_inc = []
3464
3465subdir('common-user')
b309c321 3466subdir('bsd-user')
3a30446a 3467subdir('linux-user')
46627f41 3468
a2ce7dbd
PB
3469# needed for fuzzing binaries
3470subdir('tests/qtest/libqos')
64ed6f92 3471subdir('tests/qtest/fuzz')
a2ce7dbd 3472
c94a7b88 3473# accel modules
dae0ec15
GH
3474tcg_real_module_ss = ss.source_set()
3475tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3476specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3477target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3478 'tcg': tcg_real_module_ss }}
c94a7b88 3479
a0c9162c
PB
3480########################
3481# Library dependencies #
3482########################
3483
f5723ab6 3484modinfo_collect = find_program('scripts/modinfo-collect.py')
5ebbfecc 3485modinfo_generate = find_program('scripts/modinfo-generate.py')
f5723ab6
GH
3486modinfo_files = []
3487
3154fee4
MAL
3488block_mods = []
3489softmmu_mods = []
3490foreach d, list : modules
ef709860
PB
3491 if not (d == 'block' ? have_block : have_system)
3492 continue
3493 endif
3494
3154fee4 3495 foreach m, module_ss : list
6002711c 3496 if enable_modules
3e292c51 3497 module_ss = module_ss.apply(config_all, strict: false)
3154fee4
MAL
3498 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3499 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
3500 if d == 'block'
3501 block_mods += sl
3502 else
3503 softmmu_mods += sl
3504 endif
f5723ab6
GH
3505 if module_ss.sources() != []
3506 # FIXME: Should use sl.extract_all_objects(recursive: true) as
3507 # input. Sources can be used multiple times but objects are
3508 # unique when it comes to lookup in compile_commands.json.
3509 # Depnds on a mesion version with
3510 # https://github.com/mesonbuild/meson/pull/8900
3511 modinfo_files += custom_target(d + '-' + m + '.modinfo',
3512 output: d + '-' + m + '.modinfo',
ac347111 3513 input: module_ss.sources() + genh,
f5723ab6 3514 capture: true,
ac347111 3515 command: [modinfo_collect, module_ss.sources()])
f5723ab6 3516 endif
3154fee4
MAL
3517 else
3518 if d == 'block'
3519 block_ss.add_all(module_ss)
3520 else
3521 softmmu_ss.add_all(module_ss)
3522 endif
3523 endif
3524 endforeach
3525endforeach
3526
db2e89df
GH
3527foreach d, list : target_modules
3528 foreach m, module_ss : list
6002711c 3529 if enable_modules
db2e89df
GH
3530 foreach target : target_dirs
3531 if target.endswith('-softmmu')
3532 config_target = config_target_mak[target]
3533 config_target += config_host
3534 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3535 c_args = ['-DNEED_CPU_H',
3536 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3537 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3538 target_module_ss = module_ss.apply(config_target, strict: false)
3539 if target_module_ss.sources() != []
3540 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3541 sl = static_library(module_name,
3542 [genh, target_module_ss.sources()],
3543 dependencies: [modulecommon, target_module_ss.dependencies()],
3544 include_directories: target_inc,
3545 c_args: c_args,
3546 pic: true)
3547 softmmu_mods += sl
3548 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3549 modinfo_files += custom_target(module_name + '.modinfo',
3550 output: module_name + '.modinfo',
917ddc27 3551 input: target_module_ss.sources() + genh,
db2e89df 3552 capture: true,
917ddc27 3553 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
db2e89df
GH
3554 endif
3555 endif
3556 endforeach
3557 else
3558 specific_ss.add_all(module_ss)
3559 endif
3560 endforeach
3561endforeach
3562
5ebbfecc 3563if enable_modules
05d6814c
JZ
3564 foreach target : target_dirs
3565 if target.endswith('-softmmu')
3566 config_target = config_target_mak[target]
3567 config_devices_mak = target + '-config-devices.mak'
3568 modinfo_src = custom_target('modinfo-' + target + '.c',
3569 output: 'modinfo-' + target + '.c',
3570 input: modinfo_files,
3571 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'],
3572 capture: true)
3573
3574 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src)
3575 modinfo_dep = declare_dependency(link_with: modinfo_lib)
3576
3577 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH']
3578 hw_arch[arch].add(modinfo_dep)
3579 endif
3580 endforeach
5ebbfecc
GH
3581endif
3582
3154fee4 3583nm = find_program('nm')
604f3e4e 3584undefsym = find_program('scripts/undefsym.py')
3154fee4
MAL
3585block_syms = custom_target('block.syms', output: 'block.syms',
3586 input: [libqemuutil, block_mods],
3587 capture: true,
3588 command: [undefsym, nm, '@INPUT@'])
3589qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3590 input: [libqemuutil, softmmu_mods],
3591 capture: true,
3592 command: [undefsym, nm, '@INPUT@'])
3593
55567891
PMD
3594authz_ss = authz_ss.apply(config_host, strict: false)
3595libauthz = static_library('authz', authz_ss.sources() + genh,
3596 dependencies: [authz_ss.dependencies()],
3597 name_suffix: 'fa',
3598 build_by_default: false)
3599
3600authz = declare_dependency(link_whole: libauthz,
3601 dependencies: qom)
3602
2389304a
PMD
3603crypto_ss = crypto_ss.apply(config_host, strict: false)
3604libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3605 dependencies: [crypto_ss.dependencies()],
3606 name_suffix: 'fa',
3607 build_by_default: false)
3608
3609crypto = declare_dependency(link_whole: libcrypto,
3610 dependencies: [authz, qom])
3611
f78536b1
PMD
3612io_ss = io_ss.apply(config_host, strict: false)
3613libio = static_library('io', io_ss.sources() + genh,
3614 dependencies: [io_ss.dependencies()],
3615 link_with: libqemuutil,
3616 name_suffix: 'fa',
3617 build_by_default: false)
3618
3619io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
3620
7e6edef3
PMD
3621libmigration = static_library('migration', sources: migration_files + genh,
3622 name_suffix: 'fa',
3623 build_by_default: false)
3624migration = declare_dependency(link_with: libmigration,
3625 dependencies: [zlib, qom, io])
3626softmmu_ss.add(migration)
3627
5e5733e5
MAL
3628block_ss = block_ss.apply(config_host, strict: false)
3629libblock = static_library('block', block_ss.sources() + genh,
3630 dependencies: block_ss.dependencies(),
3631 link_depends: block_syms,
3632 name_suffix: 'fa',
3633 build_by_default: false)
3634
3635block = declare_dependency(link_whole: [libblock],
b7c70bf2
MAL
3636 link_args: '@block.syms',
3637 dependencies: [crypto, io])
5e5733e5 3638
4fb9071f
SH
3639blockdev_ss = blockdev_ss.apply(config_host, strict: false)
3640libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3641 dependencies: blockdev_ss.dependencies(),
3642 name_suffix: 'fa',
3643 build_by_default: false)
3644
3645blockdev = declare_dependency(link_whole: [libblockdev],
7d5983e3 3646 dependencies: [block, event_loop_base])
4fb9071f 3647
ff219dca
PB
3648qmp_ss = qmp_ss.apply(config_host, strict: false)
3649libqmp = static_library('qmp', qmp_ss.sources() + genh,
3650 dependencies: qmp_ss.dependencies(),
3651 name_suffix: 'fa',
3652 build_by_default: false)
3653
3654qmp = declare_dependency(link_whole: [libqmp])
3655
c2306d71
PMD
3656libchardev = static_library('chardev', chardev_ss.sources() + genh,
3657 name_suffix: 'fa',
22d1f7a8 3658 dependencies: chardev_ss.dependencies(),
c2306d71
PMD
3659 build_by_default: false)
3660
3661chardev = declare_dependency(link_whole: libchardev)
3662
f73fb063
PMD
3663hwcore_ss = hwcore_ss.apply(config_host, strict: false)
3664libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
e28ab096
PMD
3665 name_suffix: 'fa',
3666 build_by_default: false)
3667hwcore = declare_dependency(link_whole: libhwcore)
3668common_ss.add(hwcore)
3669
064f8ee7
PMD
3670###########
3671# Targets #
3672###########
3673
fb72176b 3674emulator_modules = []
3154fee4 3675foreach m : block_mods + softmmu_mods
fb72176b
PB
3676 emulator_modules += shared_module(m.name(),
3677 build_by_default: true,
3154fee4
MAL
3678 name_prefix: '',
3679 link_whole: m,
3680 install: true,
16bf7a33 3681 install_dir: qemu_moddir)
3154fee4 3682endforeach
d8f3a609
PB
3683if emulator_modules.length() > 0
3684 alias_target('modules', emulator_modules)
3685endif
3154fee4 3686
4fb9071f 3687softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
64ed6f92
PB
3688common_ss.add(qom, qemuutil)
3689
3690common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2becc36a
PB
3691common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3692
3693common_all = common_ss.apply(config_all, strict: false)
3694common_all = static_library('common',
3695 build_by_default: false,
3696 sources: common_all.sources() + genh,
9d24fb73 3697 include_directories: common_user_inc,
75eebe0b 3698 implicit_include_directories: false,
2becc36a
PB
3699 dependencies: common_all.dependencies(),
3700 name_suffix: 'fa')
3701
c9322ab5
MAL
3702feature_to_c = find_program('scripts/feature_to_c.sh')
3703
30cfa50d
PMD
3704if targetos == 'darwin'
3705 entitlement = find_program('scripts/entitlement.sh')
3706endif
3707
fd5eef85 3708emulators = {}
2becc36a
PB
3709foreach target : target_dirs
3710 config_target = config_target_mak[target]
3711 target_name = config_target['TARGET_NAME']
ffb91f68 3712 target_base_arch = config_target['TARGET_BASE_ARCH']
859aef02 3713 arch_srcs = [config_target_h[target]]
64ed6f92
PB
3714 arch_deps = []
3715 c_args = ['-DNEED_CPU_H',
3716 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3717 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
b6c7cfd4 3718 link_args = emulator_link_args
2becc36a 3719
859aef02 3720 config_target += config_host
2becc36a
PB
3721 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3722 if targetos == 'linux'
3723 target_inc += include_directories('linux-headers', is_system: true)
3724 endif
3725 if target.endswith('-softmmu')
2becc36a 3726 target_type='system'
ffb91f68 3727 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false)
abff1abf 3728 arch_srcs += t.sources()
64ed6f92 3729 arch_deps += t.dependencies()
abff1abf 3730
ffb91f68 3731 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
2c44220d
MAL
3732 hw = hw_arch[hw_dir].apply(config_target, strict: false)
3733 arch_srcs += hw.sources()
64ed6f92 3734 arch_deps += hw.dependencies()
2c44220d 3735
2becc36a 3736 arch_srcs += config_devices_h[target]
64ed6f92 3737 link_args += ['@block.syms', '@qemu.syms']
2becc36a 3738 else
3a30446a 3739 abi = config_target['TARGET_ABI_DIR']
2becc36a 3740 target_type='user'
a3a576b0 3741 target_inc += common_user_inc
ffb91f68
PB
3742 if target_base_arch in target_user_arch
3743 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
46369b50
PMD
3744 arch_srcs += t.sources()
3745 arch_deps += t.dependencies()
3746 endif
2becc36a
PB
3747 if 'CONFIG_LINUX_USER' in config_target
3748 base_dir = 'linux-user'
e2a74729
WL
3749 endif
3750 if 'CONFIG_BSD_USER' in config_target
2becc36a 3751 base_dir = 'bsd-user'
e2a74729 3752 target_inc += include_directories('bsd-user/' / targetos)
85fc1b5d 3753 target_inc += include_directories('bsd-user/host/' / host_arch)
e2a74729 3754 dir = base_dir / abi
19bf129f 3755 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
2becc36a
PB
3756 endif
3757 target_inc += include_directories(
3758 base_dir,
3a30446a 3759 base_dir / abi,
2becc36a 3760 )
3a30446a
MAL
3761 if 'CONFIG_LINUX_USER' in config_target
3762 dir = base_dir / abi
3763 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3764 if config_target.has_key('TARGET_SYSTBL_ABI')
3765 arch_srcs += \
3766 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3767 extra_args : config_target['TARGET_SYSTBL_ABI'])
3768 endif
3769 endif
2becc36a
PB
3770 endif
3771
c9322ab5
MAL
3772 if 'TARGET_XML_FILES' in config_target
3773 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3774 output: target + '-gdbstub-xml.c',
3775 input: files(config_target['TARGET_XML_FILES'].split()),
3776 command: [feature_to_c, '@INPUT@'],
3777 capture: true)
3778 arch_srcs += gdbstub_xml
3779 endif
3780
ffb91f68 3781 t = target_arch[target_base_arch].apply(config_target, strict: false)
abff1abf 3782 arch_srcs += t.sources()
64ed6f92 3783 arch_deps += t.dependencies()
abff1abf 3784
2becc36a
PB
3785 target_common = common_ss.apply(config_target, strict: false)
3786 objects = common_all.extract_objects(target_common.sources())
64ed6f92 3787 deps = target_common.dependencies()
2becc36a 3788
2becc36a
PB
3789 target_specific = specific_ss.apply(config_target, strict: false)
3790 arch_srcs += target_specific.sources()
64ed6f92 3791 arch_deps += target_specific.dependencies()
2becc36a 3792
64ed6f92 3793 lib = static_library('qemu-' + target,
859aef02 3794 sources: arch_srcs + genh,
b7612f45 3795 dependencies: arch_deps,
2becc36a
PB
3796 objects: objects,
3797 include_directories: target_inc,
64ed6f92
PB
3798 c_args: c_args,
3799 build_by_default: false,
2becc36a 3800 name_suffix: 'fa')
64ed6f92
PB
3801
3802 if target.endswith('-softmmu')
3803 execs = [{
3804 'name': 'qemu-system-' + target_name,
654d6b04 3805 'win_subsystem': 'console',
64ed6f92
PB
3806 'sources': files('softmmu/main.c'),
3807 'dependencies': []
3808 }]
35be72ba 3809 if targetos == 'windows' and (sdl.found() or gtk.found())
64ed6f92
PB
3810 execs += [{
3811 'name': 'qemu-system-' + target_name + 'w',
654d6b04 3812 'win_subsystem': 'windows',
64ed6f92
PB
3813 'sources': files('softmmu/main.c'),
3814 'dependencies': []
3815 }]
3816 endif
537b7248 3817 if get_option('fuzzing')
64ed6f92
PB
3818 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3819 execs += [{
3820 'name': 'qemu-fuzz-' + target_name,
654d6b04 3821 'win_subsystem': 'console',
64ed6f92
PB
3822 'sources': specific_fuzz.sources(),
3823 'dependencies': specific_fuzz.dependencies(),
64ed6f92
PB
3824 }]
3825 endif
3826 else
3827 execs = [{
3828 'name': 'qemu-' + target_name,
654d6b04 3829 'win_subsystem': 'console',
64ed6f92
PB
3830 'sources': [],
3831 'dependencies': []
3832 }]
3833 endif
3834 foreach exe: execs
8a74ce61 3835 exe_name = exe['name']
3983a767 3836 if targetos == 'darwin'
8a74ce61
AG
3837 exe_name += '-unsigned'
3838 endif
3839
3840 emulator = executable(exe_name, exe['sources'],
237377ac 3841 install: true,
64ed6f92
PB
3842 c_args: c_args,
3843 dependencies: arch_deps + deps + exe['dependencies'],
3844 objects: lib.extract_all_objects(recursive: true),
3845 link_language: link_language,
3846 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3847 link_args: link_args,
654d6b04 3848 win_subsystem: exe['win_subsystem'])
8a74ce61 3849
3983a767 3850 if targetos == 'darwin'
411ad8dd
AO
3851 icon = 'pc-bios/qemu.rsrc'
3852 build_input = [emulator, files(icon)]
3853 install_input = [
3854 get_option('bindir') / exe_name,
3855 meson.current_source_dir() / icon
3856 ]
3857 if 'CONFIG_HVF' in config_target
3858 entitlements = 'accel/hvf/entitlements.plist'
3859 build_input += files(entitlements)
3860 install_input += meson.current_source_dir() / entitlements
3861 endif
3862
8a74ce61 3863 emulators += {exe['name'] : custom_target(exe['name'],
411ad8dd 3864 input: build_input,
8a74ce61 3865 output: exe['name'],
235b523d 3866 command: [entitlement, '@OUTPUT@', '@INPUT@'])
8a74ce61 3867 }
237377ac 3868
235b523d 3869 meson.add_install_script(entitlement, '--install',
237377ac 3870 get_option('bindir') / exe['name'],
411ad8dd 3871 install_input)
8a74ce61
AG
3872 else
3873 emulators += {exe['name']: emulator}
3874 endif
10e1d263 3875
9c29b741 3876 if stap.found()
10e1d263 3877 foreach stp: [
bd5f973a
SH
3878 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3879 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
10e1d263
MAL
3880 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3881 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3882 ]
bd5f973a 3883 custom_target(exe['name'] + stp['ext'],
10e1d263 3884 input: trace_events_all,
bd5f973a 3885 output: exe['name'] + stp['ext'],
10e1d263 3886 install: stp['install'],
16bf7a33 3887 install_dir: get_option('datadir') / 'systemtap/tapset',
10e1d263
MAL
3888 command: [
3889 tracetool, '--group=all', '--format=' + stp['fmt'],
3890 '--binary=' + stp['bin'],
3891 '--target-name=' + target_name,
3892 '--target-type=' + target_type,
3893 '--probe-prefix=qemu.' + target_type + '.' + target_name,
c05012a3 3894 '@INPUT@', '@OUTPUT@'
0572d6cd
SH
3895 ],
3896 depend_files: tracetool_depends)
10e1d263
MAL
3897 endforeach
3898 endif
64ed6f92 3899 endforeach
2becc36a
PB
3900endforeach
3901
931049b4 3902# Other build targets
897b5afa 3903
f556b4a1
PB
3904if 'CONFIG_PLUGIN' in config_host
3905 install_headers('include/qemu/qemu-plugin.h')
3906endif
3907
20cf5cb4 3908subdir('qga')
f15bff25 3909
9755c94a
LV
3910# Don't build qemu-keymap if xkbcommon is not explicitly enabled
3911# when we don't build tools or system
4113f4cf 3912if xkbcommon.found()
28742467
MAL
3913 # used for the update-keymaps target, so include rules even if !have_tools
3914 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3915 dependencies: [qemuutil, xkbcommon], install: have_tools)
3916endif
3917
931049b4 3918if have_tools
b7c70bf2
MAL
3919 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3920 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3921 qemu_io = executable('qemu-io', files('qemu-io.c'),
3922 dependencies: [block, qemuutil], install: true)
eb705985 3923 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3d212b41
RJ
3924 dependencies: [blockdev, qemuutil, gnutls, selinux],
3925 install: true)
b7c70bf2 3926
7c58bb76 3927 subdir('storage-daemon')
a9c9727c 3928 subdir('contrib/rdmacm-mux')
1d7bb6ab 3929 subdir('contrib/elf2dmp')
a9c9727c 3930
157e7b13
MAL
3931 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3932 dependencies: qemuutil,
3933 install: true)
3934
2a3129a3 3935 if have_vhost_user
2d7ac0af 3936 subdir('contrib/vhost-user-blk')
b7612f45 3937 subdir('contrib/vhost-user-gpu')
32fcc624 3938 subdir('contrib/vhost-user-input')
99650b62 3939 subdir('contrib/vhost-user-scsi')
931049b4 3940 endif
8f51e01c
MAL
3941
3942 if targetos == 'linux'
3943 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3944 dependencies: [qemuutil, libcap_ng],
3945 install: true,
3946 install_dir: get_option('libexecdir'))
897b5afa
MAL
3947
3948 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3949 dependencies: [authz, crypto, io, qom, qemuutil,
6ec0e15d 3950 libcap_ng, mpathpersist],
897b5afa 3951 install: true)
8f51e01c
MAL
3952 endif
3953
ccd250aa 3954 if have_ivshmem
5ee24e78
MAL
3955 subdir('contrib/ivshmem-client')
3956 subdir('contrib/ivshmem-server')
3957 endif
931049b4
PB
3958endif
3959
f5aa6320 3960subdir('scripts')
3f99cf57 3961subdir('tools')
bdcbea7a 3962subdir('pc-bios')
f8aa24ea 3963subdir('docs')
e3667660 3964subdir('tests')
1b695471 3965if gtk.found()
e8f3bd71
MAL
3966 subdir('po')
3967endif
3f99cf57 3968
8adfeba9
MAL
3969if host_machine.system() == 'windows'
3970 nsis_cmd = [
3971 find_program('scripts/nsis.py'),
3972 '@OUTPUT@',
3973 get_option('prefix'),
3974 meson.current_source_dir(),
fc9a809e 3975 glib_pc.get_variable('bindir'),
24bdcc96 3976 host_machine.cpu(),
8adfeba9
MAL
3977 '--',
3978 '-DDISPLAYVERSION=' + meson.project_version(),
3979 ]
3980 if build_docs
3981 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3982 endif
1b695471 3983 if gtk.found()
8adfeba9
MAL
3984 nsis_cmd += '-DCONFIG_GTK=y'
3985 endif
3986
3987 nsis = custom_target('nsis',
3988 output: 'qemu-setup-' + meson.project_version() + '.exe',
3989 input: files('qemu.nsi'),
3990 build_always_stale: true,
3991 command: nsis_cmd + ['@INPUT@'])
3992 alias_target('installer', nsis)
3993endif
3994
a0c9162c
PB
3995#########################
3996# Configuration summary #
3997#########################
3998
983d0a75 3999# Directories
f9332757 4000summary_info = {}
16bf7a33
PB
4001summary_info += {'Install prefix': get_option('prefix')}
4002summary_info += {'BIOS directory': qemu_datadir}
8154f5e6
AO
4003pathsep = targetos == 'windows' ? ';' : ':'
4004summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))}
f7fb6c6a
PB
4005summary_info += {'binary directory': get_option('prefix') / get_option('bindir')}
4006summary_info += {'library directory': get_option('prefix') / get_option('libdir')}
16bf7a33 4007summary_info += {'module directory': qemu_moddir}
f7fb6c6a
PB
4008summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')}
4009summary_info += {'include directory': get_option('prefix') / get_option('includedir')}
4010summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')}
f9332757 4011if targetos != 'windows'
f7fb6c6a
PB
4012 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')}
4013 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')}
f9332757
PB
4014else
4015 summary_info += {'local state directory': 'queried at runtime'}
4016endif
f7fb6c6a 4017summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')}
f9332757
PB
4018summary_info += {'Build directory': meson.current_build_dir()}
4019summary_info += {'Source path': meson.current_source_dir()}
f9332757 4020summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
983d0a75
PMD
4021summary(summary_info, bool_yn: true, section: 'Directories')
4022
e11a0e17
PMD
4023# Host binaries
4024summary_info = {}
4025summary_info += {'git': config_host['GIT']}
4026summary_info += {'make': config_host['MAKE']}
4027summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
bb647c49 4028summary_info += {'sphinx-build': sphinx_build}
e11a0e17
PMD
4029if config_host.has_key('HAVE_GDB_BIN')
4030 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
4031endif
40c909f5 4032summary_info += {'iasl': iasl}
e11a0e17 4033summary_info += {'genisoimage': config_host['GENISOIMAGE']}
20cf5cb4 4034if targetos == 'windows' and have_ga
bb647c49 4035 summary_info += {'wixl': wixl}
e11a0e17 4036endif
5890258a 4037if slirp.found() and have_system
35acbb30 4038 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false}
e11a0e17
PMD
4039endif
4040summary(summary_info, bool_yn: true, section: 'Host binaries')
4041
1d718865
PMD
4042# Configurable features
4043summary_info = {}
4044summary_info += {'Documentation': build_docs}
aa3ca634
PMD
4045summary_info += {'system-mode emulation': have_system}
4046summary_info += {'user-mode emulation': have_user}
813803aa 4047summary_info += {'block layer': have_block}
1d718865 4048summary_info += {'Install blobs': get_option('install_blobs')}
6002711c
PB
4049summary_info += {'module support': enable_modules}
4050if enable_modules
2cb2f580 4051 summary_info += {'alternative module path': get_option('module_upgrades')}
1d718865 4052endif
537b7248 4053summary_info += {'fuzzing support': get_option('fuzzing')}
1d718865 4054if have_system
87430d5b 4055 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
1d718865 4056endif
9c29b741
PB
4057summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
4058if 'simple' in get_option('trace_backends')
4059 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
1d718865 4060endif
142ca628 4061summary_info += {'D-Bus display': dbus_display}
c55cf6ab 4062summary_info += {'QOM debugging': get_option('qom_cast_debug')}
2a3129a3
PB
4063summary_info += {'vhost-kernel support': have_vhost_kernel}
4064summary_info += {'vhost-net support': have_vhost_net}
4065summary_info += {'vhost-user support': have_vhost_user}
4066summary_info += {'vhost-user-crypto support': have_vhost_user_crypto}
1d718865 4067summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2a3129a3 4068summary_info += {'vhost-vdpa support': have_vhost_vdpa}
20cf5cb4 4069summary_info += {'build guest agent': have_ga}
1d718865
PMD
4070summary(summary_info, bool_yn: true, section: 'Configurable features')
4071
2e864b8b 4072# Compilation information
983d0a75 4073summary_info = {}
2e864b8b
PMD
4074summary_info += {'host CPU': cpu}
4075summary_info += {'host endianness': build_machine.endian()}
63de9353
AB
4076summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
4077summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
f9332757 4078if link_language == 'cpp'
63de9353 4079 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
f9332757
PB
4080else
4081 summary_info += {'C++ compiler': false}
4082endif
4083if targetos == 'darwin'
63de9353 4084 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
f9332757 4085endif
6a97f393
PB
4086option_cflags = (get_option('debug') ? ['-g'] : [])
4087if get_option('optimization') != 'plain'
4088 option_cflags += ['-O' + get_option('optimization')]
4089endif
4090summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)}
47b30835 4091if link_language == 'cpp'
6a97f393 4092 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)}
47b30835 4093endif
e910c7d9 4094if targetos == 'darwin'
6a97f393 4095 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)}
e910c7d9 4096endif
47b30835
PB
4097link_args = get_option(link_language + '_link_args')
4098if link_args.length() > 0
4099 summary_info += {'LDFLAGS': ' '.join(link_args)}
4100endif
d67212d4 4101summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)}
e5134024 4102if 'cpp' in all_languages
d67212d4 4103 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)}
e5134024
PB
4104endif
4105if 'objc' in all_languages
95caf1fb 4106 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)}
e5134024 4107endif
d065177e 4108summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
c55cf6ab 4109summary_info += {'profiler': get_option('profiler')}
cdad781d 4110summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2e864b8b 4111summary_info += {'PIE': get_option('b_pie')}
3e8529dd 4112summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
2e864b8b 4113summary_info += {'malloc trim support': has_malloc_trim}
b87df904 4114summary_info += {'membarrier': have_membarrier}
58a2e3f5 4115summary_info += {'debug graph lock': get_option('debug_graph_lock')}
728c0a2f 4116summary_info += {'debug stack usage': get_option('debug_stack_usage')}
c55cf6ab 4117summary_info += {'mutex debugging': get_option('debug_mutex')}
2e864b8b 4118summary_info += {'memory allocator': get_option('malloc')}
622753d2 4119summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
04ffce13 4120summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')}
622753d2 4121summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
bb9ecae7
AB
4122if get_option('gprof')
4123 gprof_info = 'YES (deprecated)'
4124else
4125 gprof_info = get_option('gprof')
4126endif
4127summary_info += {'gprof': gprof_info}
2e864b8b 4128summary_info += {'gcov': get_option('b_coverage')}
34f983d8 4129summary_info += {'thread sanitizer': get_option('tsan')}
2e864b8b
PMD
4130summary_info += {'CFI support': get_option('cfi')}
4131if get_option('cfi')
4132 summary_info += {'CFI debug support': get_option('cfi_debug')}
4133endif
4134summary_info += {'strip binaries': get_option('strip')}
bb647c49 4135summary_info += {'sparse': sparse}
2e864b8b 4136summary_info += {'mingw32 support': targetos == 'windows'}
12640f05 4137summary(summary_info, bool_yn: true, section: 'Compilation')
49e8565b
AB
4138
4139# snarf the cross-compilation information for tests
12640f05
PB
4140summary_info = {}
4141have_cross = false
49e8565b 4142foreach target: target_dirs
c7022a70 4143 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak'
49e8565b
AB
4144 if fs.exists(tcg_mak)
4145 config_cross_tcg = keyval.load(tcg_mak)
85b141ea 4146 if 'CC' in config_cross_tcg
12640f05
PB
4147 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']}
4148 have_cross = true
49e8565b 4149 endif
12640f05 4150 endif
49e8565b 4151endforeach
12640f05
PB
4152if have_cross
4153 summary(summary_info, bool_yn: true, section: 'Cross compilers')
4154endif
2e864b8b 4155
aa3ca634 4156# Targets and accelerators
2e864b8b 4157summary_info = {}
aa3ca634
PMD
4158if have_system
4159 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
4160 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
4161 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
4162 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
74a414a1 4163 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
14efd8d3
PB
4164 summary_info += {'Xen support': xen.found()}
4165 if xen.found()
4166 summary_info += {'xen ctrl version': xen.version()}
aa3ca634 4167 endif
820c1aba 4168 summary_info += {'Xen emulation': config_all.has_key('CONFIG_XEN_EMU')}
aa3ca634
PMD
4169endif
4170summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
4171if config_all.has_key('CONFIG_TCG')
39687aca 4172 if get_option('tcg_interpreter')
f1f727ac 4173 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
39687aca
PMD
4174 else
4175 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
4176 endif
029aa68f 4177 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
aa3ca634 4178 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
aa3ca634 4179endif
2e864b8b 4180summary_info += {'target list': ' '.join(target_dirs)}
aa3ca634
PMD
4181if have_system
4182 summary_info += {'default devices': get_option('default_devices')}
106ad1f9 4183 summary_info += {'out of process emulation': multiprocess_allowed}
55116968 4184 summary_info += {'vfio-user server': vfio_user_server_allowed}
aa3ca634
PMD
4185endif
4186summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
4187
813803aa
PMD
4188# Block layer
4189summary_info = {}
6739825a 4190summary_info += {'coroutine backend': coroutine_backend}
728c0a2f 4191summary_info += {'coroutine pool': have_coroutine_pool}
813803aa 4192if have_block
622d64ff
PB
4193 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')}
4194 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')}
c55cf6ab 4195 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
3887702e
CS
4196 summary_info += {'VirtFS (9P) support': have_virtfs}
4197 summary_info += {'VirtFS (9P) Proxy Helper support': have_virtfs_proxy_helper}
406523f6
PB
4198 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
4199 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
ed793c2c
PB
4200 summary_info += {'bochs support': get_option('bochs').allowed()}
4201 summary_info += {'cloop support': get_option('cloop').allowed()}
4202 summary_info += {'dmg support': get_option('dmg').allowed()}
4203 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
4204 summary_info += {'vdi support': get_option('vdi').allowed()}
11cea42e
VSO
4205 summary_info += {'vhdx support': get_option('vhdx').allowed()}
4206 summary_info += {'vmdk support': get_option('vmdk').allowed()}
4207 summary_info += {'vpc support': get_option('vpc').allowed()}
ed793c2c
PB
4208 summary_info += {'vvfat support': get_option('vvfat').allowed()}
4209 summary_info += {'qed support': get_option('qed').allowed()}
4210 summary_info += {'parallels support': get_option('parallels').allowed()}
bb647c49 4211 summary_info += {'FUSE exports': fuse}
2a2359b8 4212 summary_info += {'VDUSE block exports': have_vduse_blk_export}
813803aa
PMD
4213endif
4214summary(summary_info, bool_yn: true, section: 'Block layer support')
4215
aa58028a 4216# Crypto
aa3ca634 4217summary_info = {}
41f2ae28 4218summary_info += {'TLS priority': get_option('tls_priority')}
bb647c49
PB
4219summary_info += {'GNUTLS support': gnutls}
4220if gnutls.found()
4221 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
4222endif
4223summary_info += {'libgcrypt': gcrypt}
4224summary_info += {'nettle': nettle}
57612511
PB
4225if nettle.found()
4226 summary_info += {' XTS': xts != 'private'}
f9332757 4227endif
34b52615 4228summary_info += {'AF_ALG support': have_afalg}
c55cf6ab 4229summary_info += {'rng-none': get_option('rng_none')}
2edd2c04 4230summary_info += {'Linux keyring': have_keyring}
aa58028a
PMD
4231summary(summary_info, bool_yn: true, section: 'Crypto')
4232
69a78cce 4233# Libraries
aa58028a
PMD
4234summary_info = {}
4235if targetos == 'darwin'
e2c1d78d
VY
4236 summary_info += {'Cocoa support': cocoa}
4237 summary_info += {'vmnet.framework support': vmnet}
bb647c49
PB
4238endif
4239summary_info += {'SDL support': sdl}
4240summary_info += {'SDL image support': sdl_image}
4241summary_info += {'GTK support': gtk}
4242summary_info += {'pixman': pixman}
4243summary_info += {'VTE support': vte}
5890258a 4244summary_info += {'slirp support': slirp}
bb647c49
PB
4245summary_info += {'libtasn1': tasn1}
4246summary_info += {'PAM': pam}
4247summary_info += {'iconv support': iconv}
4248summary_info += {'curses support': curses}
4249summary_info += {'virgl support': virgl}
fd66dbd4 4250summary_info += {'blkio support': blkio}
bb647c49
PB
4251summary_info += {'curl support': curl}
4252summary_info += {'Multipath support': mpathpersist}
95f8510e 4253summary_info += {'PNG support': png}
bb647c49 4254summary_info += {'VNC support': vnc}
a0b93237 4255if vnc.found()
bb647c49
PB
4256 summary_info += {'VNC SASL support': sasl}
4257 summary_info += {'VNC JPEG support': jpeg}
f9332757 4258endif
87430d5b
PB
4259if targetos not in ['darwin', 'haiku', 'windows']
4260 summary_info += {'OSS support': oss}
663df1cc 4261 summary_info += {'sndio support': sndio}
87430d5b
PB
4262elif targetos == 'darwin'
4263 summary_info += {'CoreAudio support': coreaudio}
4264elif targetos == 'windows'
4265 summary_info += {'DirectSound support': dsound}
4266endif
4267if targetos == 'linux'
4268 summary_info += {'ALSA support': alsa}
4269 summary_info += {'PulseAudio support': pulse}
4270endif
c2d3d1c2 4271summary_info += {'Pipewire support': pipewire}
87430d5b 4272summary_info += {'JACK support': jack}
bb647c49 4273summary_info += {'brlapi support': brlapi}
e1723999 4274summary_info += {'vde support': vde}
837b84b1 4275summary_info += {'netmap support': have_netmap}
eea9453a 4276summary_info += {'l2tpv3 support': have_l2tpv3}
ff66f3e5 4277summary_info += {'Linux AIO support': libaio}
bb647c49
PB
4278summary_info += {'Linux io_uring support': linux_io_uring}
4279summary_info += {'ATTR/XATTR support': libattr}
3730a734
PB
4280summary_info += {'RDMA support': rdma}
4281summary_info += {'PVRDMA support': have_pvrdma}
fbb4121d 4282summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
bb647c49
PB
4283summary_info += {'libcap-ng support': libcap_ng}
4284summary_info += {'bpf support': libbpf}
3f0a5d55
MAL
4285summary_info += {'spice protocol support': spice_protocol}
4286if spice_protocol.found()
4287 summary_info += {' spice server support': spice}
4288endif
bb647c49 4289summary_info += {'rbd support': rbd}
bb647c49
PB
4290summary_info += {'smartcard support': cacard}
4291summary_info += {'U2F support': u2f}
4292summary_info += {'libusb': libusb}
4293summary_info += {'usb net redir': usbredir}
88b6e618 4294summary_info += {'OpenGL support (epoxy)': opengl}
bb647c49
PB
4295summary_info += {'GBM': gbm}
4296summary_info += {'libiscsi support': libiscsi}
4297summary_info += {'libnfs support': libnfs}
f9332757 4298if targetos == 'windows'
20cf5cb4 4299 if have_ga
8821a389 4300 summary_info += {'QGA VSS support': have_qga_vss}
b846ab7c 4301 endif
f9332757 4302endif
bb647c49
PB
4303summary_info += {'seccomp support': seccomp}
4304summary_info += {'GlusterFS support': glusterfs}
0d04c4c9 4305summary_info += {'TPM support': have_tpm}
e6a52b36 4306summary_info += {'libssh support': libssh}
bb647c49
PB
4307summary_info += {'lzo support': lzo}
4308summary_info += {'snappy support': snappy}
4309summary_info += {'bzip2 support': libbzip2}
4310summary_info += {'lzfse support': liblzfse}
4311summary_info += {'zstd support': zstd}
488a8c73 4312summary_info += {'NUMA host support': numa}
83602083 4313summary_info += {'capstone': capstone}
bb647c49
PB
4314summary_info += {'libpmem support': libpmem}
4315summary_info += {'libdaxctl support': libdaxctl}
4316summary_info += {'libudev': libudev}
4317# Dummy dependency, keep .found()
df4ea709 4318summary_info += {'FUSE lseek': fuse_lseek.found()}
3d212b41 4319summary_info += {'selinux': selinux}
7c10cb38 4320summary_info += {'libdw': libdw}
69a78cce 4321summary(summary_info, bool_yn: true, section: 'Dependencies')
f9332757
PB
4322
4323if not supported_cpus.contains(cpu)
4324 message()
4325 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
4326 message()
4327 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
4328 message('The QEMU project intends to remove support for this host CPU in')
4329 message('a future release if nobody volunteers to maintain it and to')
4330 message('provide a build host for our continuous integration setup.')
4331 message('configure has succeeded and you can continue to build, but')
4332 message('if you care about QEMU on this platform you should contact')
4333 message('us upstream at qemu-devel@nongnu.org.')
4334endif
4335
4336if not supported_oses.contains(targetos)
4337 message()
4338 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
4339 message()
4340 message('Host OS ' + targetos + 'support is not currently maintained.')
4341 message('The QEMU project intends to remove support for this host OS in')
4342 message('a future release if nobody volunteers to maintain it and to')
4343 message('provide a build host for our continuous integration setup.')
4344 message('configure has succeeded and you can continue to build, but')
4345 message('if you care about QEMU on this platform you should contact')
4346 message('us upstream at qemu-devel@nongnu.org.')
4347endif