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