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