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