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