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