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