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