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