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