1 project('qemu', ['c'], meson_version: '>=1.5.0', 2 default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto', 3 'b_staticpic=false', 'stdsplit=false', 'optimization=2', 'b_pie=true'], 4 version: files('VERSION')) 5 6 add_test_setup('quick', exclude_suites: ['slow', 'thorough'], is_default: true) 7 add_test_setup('slow', exclude_suites: ['thorough'], env: ['G_TEST_SLOW=1', 'SPEED=slow']) 8 add_test_setup('thorough', env: ['G_TEST_SLOW=1', 'SPEED=thorough']) 9 10 meson.add_postconf_script(find_program('scripts/symlink-install-tree.py')) 11 12 #################### 13 # Global variables # 14 #################### 15 16 not_found = dependency('', required: false) 17 keyval = import('keyval') 18 rust = import('rust') 19 ss = import('sourceset') 20 fs = import('fs') 21 22 host_os = host_machine.system() 23 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak') 24 25 # Temporary directory used for files created while 26 # configure runs. Since it is in the build directory 27 # we can safely blow away any previous version of it 28 # (and we need not jump through hoops to try to delete 29 # it when configure exits.) 30 tmpdir = meson.current_build_dir() / 'meson-private/temp' 31 32 if get_option('qemu_suffix').startswith('/') 33 error('qemu_suffix cannot start with a /') 34 endif 35 36 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix') 37 qemu_datadir = get_option('datadir') / get_option('qemu_suffix') 38 qemu_docdir = get_option('docdir') / get_option('qemu_suffix') 39 qemu_moddir = get_option('libdir') / get_option('qemu_suffix') 40 41 qemu_desktopdir = get_option('datadir') / 'applications' 42 qemu_icondir = get_option('datadir') / 'icons' 43 44 genh = [] 45 qapi_trace_events = [] 46 47 bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin'] 48 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux'] 49 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64', 50 'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc64'] 51 52 cpu = host_machine.cpu_family() 53 54 target_dirs = config_host['TARGET_DIRS'].split() 55 56 # type of binaries to build 57 have_linux_user = false 58 have_bsd_user = false 59 have_system = false 60 foreach target : target_dirs 61 have_linux_user = have_linux_user or target.endswith('linux-user') 62 have_bsd_user = have_bsd_user or target.endswith('bsd-user') 63 have_system = have_system or target.endswith('-softmmu') 64 endforeach 65 have_user = have_linux_user or have_bsd_user 66 67 ############ 68 # Programs # 69 ############ 70 71 sh = find_program('sh') 72 python = import('python').find_installation() 73 74 cc = meson.get_compiler('c') 75 all_languages = ['c'] 76 if host_os == 'windows' and add_languages('cpp', required: false, native: false) 77 all_languages += ['cpp'] 78 cxx = meson.get_compiler('cpp') 79 endif 80 if host_os == 'darwin' and \ 81 add_languages('objc', required: true, native: false) 82 all_languages += ['objc'] 83 objc = meson.get_compiler('objc') 84 endif 85 86 have_rust = add_languages('rust', native: false, 87 required: get_option('rust').disable_auto_if(not have_system)) 88 have_rust = have_rust and add_languages('rust', native: true, 89 required: get_option('rust').disable_auto_if(not have_system)) 90 if have_rust 91 rustc = meson.get_compiler('rust') 92 if rustc.version().version_compare('<1.63.0') 93 if get_option('rust').enabled() 94 error('rustc version ' + rustc.version() + ' is unsupported. Please upgrade to at least 1.63.0') 95 else 96 warning('rustc version ' + rustc.version() + ' is unsupported, disabling Rust compilation.') 97 message('Please upgrade to at least 1.63.0 to use Rust.') 98 have_rust = false 99 endif 100 endif 101 endif 102 103 if have_rust 104 bindgen = find_program('bindgen', required: get_option('rust')) 105 if not bindgen.found() or bindgen.version().version_compare('<0.60.0') 106 if get_option('rust').enabled() 107 error('bindgen version ' + bindgen.version() + ' is unsupported. You can install a new version with "cargo install bindgen-cli"') 108 else 109 if bindgen.found() 110 warning('bindgen version ' + bindgen.version() + ' is unsupported, disabling Rust compilation.') 111 else 112 warning('bindgen not found, disabling Rust compilation.') 113 endif 114 message('To use Rust you can install a new version with "cargo install bindgen-cli"') 115 have_rust = false 116 endif 117 endif 118 endif 119 120 if have_rust 121 rustfmt = find_program('rustfmt', required: false) 122 endif 123 124 dtrace = not_found 125 stap = not_found 126 if 'dtrace' in get_option('trace_backends') 127 dtrace = find_program('dtrace', required: true) 128 stap = find_program('stap', required: false) 129 if stap.found() 130 # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol 131 # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility 132 # instead. QEMU --enable-modules depends on this because the SystemTap 133 # semaphores are linked into the main binary and not the module's shared 134 # object. 135 add_global_arguments('-DSTAP_SDT_V2', 136 native: false, language: all_languages) 137 endif 138 endif 139 140 if get_option('iasl') == '' 141 iasl = find_program('iasl', required: false) 142 else 143 iasl = find_program(get_option('iasl'), required: true) 144 endif 145 146 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu', 'riscv64-softmmu', 'loongarch64-softmmu' ] 147 unpack_edk2_blobs = false 148 foreach target : edk2_targets 149 if target in target_dirs 150 bzip2 = find_program('bzip2', required: get_option('install_blobs')) 151 unpack_edk2_blobs = bzip2.found() 152 break 153 endif 154 endforeach 155 156 ##################### 157 # Option validation # 158 ##################### 159 160 # Fuzzing 161 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \ 162 not cc.links(''' 163 #include <stdint.h> 164 #include <sys/types.h> 165 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size); 166 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; } 167 ''', 168 args: ['-Werror', '-fsanitize=fuzzer']) 169 error('Your compiler does not support -fsanitize=fuzzer') 170 endif 171 172 # Tracing backends 173 if 'ftrace' in get_option('trace_backends') and host_os != 'linux' 174 error('ftrace is supported only on Linux') 175 endif 176 if 'syslog' in get_option('trace_backends') and not cc.compiles(''' 177 #include <syslog.h> 178 int main(void) { 179 openlog("qemu", LOG_PID, LOG_DAEMON); 180 syslog(LOG_INFO, "configure"); 181 return 0; 182 }''') 183 error('syslog is not supported on this system') 184 endif 185 186 # Miscellaneous Linux-only features 187 get_option('mpath') \ 188 .require(host_os == 'linux', error_message: 'Multipath is supported only on Linux') 189 190 multiprocess_allowed = get_option('multiprocess') \ 191 .require(host_os == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \ 192 .allowed() 193 194 vfio_user_server_allowed = get_option('vfio_user_server') \ 195 .require(host_os == 'linux', error_message: 'vfio-user server is supported only on Linux') \ 196 .allowed() 197 198 have_tpm = get_option('tpm') \ 199 .require(host_os != 'windows', error_message: 'TPM emulation only available on POSIX systems') \ 200 .allowed() 201 202 # vhost 203 have_vhost_user = get_option('vhost_user') \ 204 .disable_auto_if(host_os != 'linux') \ 205 .require(host_os != 'windows', 206 error_message: 'vhost-user is not available on Windows').allowed() 207 have_vhost_vdpa = get_option('vhost_vdpa') \ 208 .require(host_os == 'linux', 209 error_message: 'vhost-vdpa is only available on Linux').allowed() 210 have_vhost_kernel = get_option('vhost_kernel') \ 211 .require(host_os == 'linux', 212 error_message: 'vhost-kernel is only available on Linux').allowed() 213 have_vhost_user_crypto = get_option('vhost_crypto') \ 214 .require(have_vhost_user, 215 error_message: 'vhost-crypto requires vhost-user to be enabled').allowed() 216 217 have_vhost = have_vhost_user or have_vhost_vdpa or have_vhost_kernel 218 219 have_vhost_net_user = have_vhost_user and get_option('vhost_net').allowed() 220 have_vhost_net_vdpa = have_vhost_vdpa and get_option('vhost_net').allowed() 221 have_vhost_net_kernel = have_vhost_kernel and get_option('vhost_net').allowed() 222 have_vhost_net = have_vhost_net_kernel or have_vhost_net_user or have_vhost_net_vdpa 223 224 have_tools = get_option('tools') \ 225 .disable_auto_if(not have_system) \ 226 .allowed() 227 have_ga = get_option('guest_agent') \ 228 .disable_auto_if(not have_system and not have_tools) \ 229 .require(host_os in ['sunos', 'linux', 'windows', 'freebsd', 'netbsd', 'openbsd'], 230 error_message: 'unsupported OS for QEMU guest agent') \ 231 .allowed() 232 have_block = have_system or have_tools 233 234 enable_modules = get_option('modules') \ 235 .require(host_os != 'windows', 236 error_message: 'Modules are not available for Windows') \ 237 .require(not get_option('prefer_static'), 238 error_message: 'Modules are incompatible with static linking') \ 239 .allowed() 240 241 ####################################### 242 # Variables for host and accelerators # 243 ####################################### 244 245 if cpu not in supported_cpus 246 host_arch = 'unknown' 247 elif cpu == 'x86' 248 host_arch = 'i386' 249 elif cpu == 'mips64' 250 host_arch = 'mips' 251 elif cpu in ['riscv32', 'riscv64'] 252 host_arch = 'riscv' 253 else 254 host_arch = cpu 255 endif 256 257 if cpu in ['x86', 'x86_64'] 258 kvm_targets = ['i386-softmmu', 'x86_64-softmmu'] 259 elif cpu == 'aarch64' 260 kvm_targets = ['aarch64-softmmu'] 261 elif cpu == 's390x' 262 kvm_targets = ['s390x-softmmu'] 263 elif cpu in ['ppc', 'ppc64'] 264 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu'] 265 elif cpu in ['mips', 'mips64'] 266 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu'] 267 elif cpu in ['riscv32'] 268 kvm_targets = ['riscv32-softmmu'] 269 elif cpu in ['riscv64'] 270 kvm_targets = ['riscv64-softmmu'] 271 elif cpu in ['loongarch64'] 272 kvm_targets = ['loongarch64-softmmu'] 273 else 274 kvm_targets = [] 275 endif 276 accelerator_targets = { 'CONFIG_KVM': kvm_targets } 277 278 if cpu in ['x86', 'x86_64'] 279 xen_targets = ['i386-softmmu', 'x86_64-softmmu'] 280 elif cpu in ['arm', 'aarch64'] 281 # i386 emulator provides xenpv machine type for multiple architectures 282 xen_targets = ['i386-softmmu', 'x86_64-softmmu', 'aarch64-softmmu'] 283 else 284 xen_targets = [] 285 endif 286 accelerator_targets += { 'CONFIG_XEN': xen_targets } 287 288 if cpu in ['aarch64'] 289 accelerator_targets += { 290 'CONFIG_HVF': ['aarch64-softmmu'] 291 } 292 endif 293 294 if cpu in ['x86', 'x86_64'] 295 accelerator_targets += { 296 'CONFIG_HVF': ['x86_64-softmmu'], 297 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'], 298 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'], 299 } 300 endif 301 302 modular_tcg = [] 303 # Darwin does not support references to thread-local variables in modules 304 if host_os != 'darwin' 305 modular_tcg = ['i386-softmmu', 'x86_64-softmmu'] 306 endif 307 308 ################## 309 # Compiler flags # 310 ################## 311 312 foreach lang : all_languages 313 compiler = meson.get_compiler(lang) 314 if compiler.get_id() == 'gcc' and compiler.version().version_compare('>=7.4') 315 # ok 316 elif compiler.get_id() == 'clang' and compiler.compiles(''' 317 #ifdef __apple_build_version__ 318 # if __clang_major__ < 15 || (__clang_major__ == 15 && __clang_minor__ < 0) 319 # error You need at least XCode Clang v15.0 to compile QEMU 320 # endif 321 #else 322 # if __clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 0) 323 # error You need at least Clang v10.0 to compile QEMU 324 # endif 325 #endif''') 326 # ok 327 else 328 error('You either need GCC v7.4 or Clang v10.0 (or XCode Clang v15.0) to compile QEMU') 329 endif 330 endforeach 331 332 # default flags for all hosts 333 # We use -fwrapv to tell the compiler that we require a C dialect where 334 # left shift of signed integers is well defined and has the expected 335 # 2s-complement style results. (Both clang and gcc agree that it 336 # provides these semantics.) 337 338 qemu_common_flags = [ 339 '-D_GNU_SOURCE', '-D_FILE_OFFSET_BITS=64', '-D_LARGEFILE_SOURCE', 340 '-fno-strict-aliasing', '-fno-common', '-fwrapv' ] 341 qemu_cflags = [] 342 qemu_ldflags = [] 343 344 if host_os == 'darwin' 345 # Disable attempts to use ObjectiveC features in os/object.h since they 346 # won't work when we're compiling with gcc as a C compiler. 347 if compiler.get_id() == 'gcc' 348 qemu_common_flags += '-DOS_OBJECT_USE_OBJC=0' 349 endif 350 elif host_os == 'sunos' 351 # needed for CMSG_ macros in sys/socket.h 352 qemu_common_flags += '-D_XOPEN_SOURCE=600' 353 # needed for TIOCWIN* defines in termios.h 354 qemu_common_flags += '-D__EXTENSIONS__' 355 elif host_os == 'haiku' 356 qemu_common_flags += ['-DB_USE_POSITIVE_POSIX_ERRORS', '-D_BSD_SOURCE', '-fPIC'] 357 elif host_os == 'windows' 358 if not compiler.compiles('struct x { int y; } __attribute__((gcc_struct));', 359 args: '-Werror') 360 error('Your compiler does not support __attribute__((gcc_struct)) - please use GCC instead of Clang') 361 endif 362 endif 363 364 # Choose instruction set (currently x86-only) 365 366 qemu_isa_flags = [] 367 368 # __sync_fetch_and_and requires at least -march=i486. Many toolchains 369 # use i686 as default anyway, but for those that don't, an explicit 370 # specification is necessary 371 if host_arch == 'i386' and not cc.links(''' 372 static int sfaa(int *ptr) 373 { 374 return __sync_fetch_and_and(ptr, 0); 375 } 376 377 int main(void) 378 { 379 int val = 42; 380 val = __sync_val_compare_and_swap(&val, 0, 1); 381 sfaa(&val); 382 return val; 383 }''') 384 qemu_isa_flags += ['-march=i486'] 385 endif 386 387 # Pick x86-64 baseline version 388 if host_arch in ['i386', 'x86_64'] 389 if get_option('x86_version') == '0' and host_arch == 'x86_64' 390 error('x86_64-v1 required for x86-64 hosts') 391 endif 392 393 # add flags for individual instruction set extensions 394 if get_option('x86_version') >= '1' 395 if host_arch == 'i386' 396 qemu_common_flags = ['-mfpmath=sse'] + qemu_common_flags 397 else 398 # present on basically all processors but technically not part of 399 # x86-64-v1, so only include -mneeded for x86-64 version 2 and above 400 qemu_isa_flags += ['-mcx16'] 401 endif 402 endif 403 if get_option('x86_version') >= '2' 404 qemu_isa_flags += ['-mpopcnt'] 405 qemu_isa_flags += cc.get_supported_arguments('-mneeded') 406 endif 407 if get_option('x86_version') >= '3' 408 qemu_isa_flags += ['-mmovbe', '-mabm', '-mbmi', '-mbmi2', '-mfma', '-mf16c'] 409 endif 410 411 # add required vector instruction set (each level implies those below) 412 if get_option('x86_version') == '1' 413 qemu_isa_flags += ['-msse2'] 414 elif get_option('x86_version') == '2' 415 qemu_isa_flags += ['-msse4.2'] 416 elif get_option('x86_version') == '3' 417 qemu_isa_flags += ['-mavx2'] 418 elif get_option('x86_version') == '4' 419 qemu_isa_flags += ['-mavx512f', '-mavx512bw', '-mavx512cd', '-mavx512dq', '-mavx512vl'] 420 endif 421 endif 422 423 qemu_common_flags = qemu_isa_flags + qemu_common_flags 424 425 if get_option('prefer_static') 426 qemu_ldflags += get_option('b_pie') ? '-static-pie' : '-static' 427 endif 428 429 # Meson currently only handles pie as a boolean for now, so if the user 430 # has explicitly disabled PIE we need to extend our cflags. 431 # 432 # -no-pie is supposedly a linker flag that has no effect on the compiler 433 # command line, but some distros, that didn't quite know what they were 434 # doing, made local changes to gcc's specs file that turned it into 435 # a compiler command-line flag. 436 # 437 # What about linker flags? For a static build, no PIE is implied by -static 438 # which we added above (and if it's not because of the same specs patching, 439 # there's nothing we can do: compilation will fail, report a bug to your 440 # distro and do not use --disable-pie in the meanwhile). For dynamic linking, 441 # instead, we can't add -no-pie because it overrides -shared: the linker then 442 # tries to build an executable instead of a shared library and fails. So 443 # don't add -no-pie anywhere and cross fingers. :( 444 if not get_option('b_pie') 445 qemu_common_flags += cc.get_supported_arguments('-fno-pie', '-no-pie') 446 endif 447 448 if not get_option('stack_protector').disabled() 449 stack_protector_probe = ''' 450 int main(int argc, char *argv[]) 451 { 452 char arr[64], *p = arr, *c = argv[argc - 1]; 453 while (*c) { 454 *p++ = *c++; 455 } 456 return 0; 457 }''' 458 have_stack_protector = false 459 foreach arg : ['-fstack-protector-strong', '-fstack-protector-all'] 460 # We need to check both a compile and a link, since some compiler 461 # setups fail only on a .c->.o compile and some only at link time 462 if cc.compiles(stack_protector_probe, args: ['-Werror', arg]) and \ 463 cc.links(stack_protector_probe, args: ['-Werror', arg]) 464 have_stack_protector = true 465 qemu_cflags += arg 466 qemu_ldflags += arg 467 break 468 endif 469 endforeach 470 get_option('stack_protector') \ 471 .require(have_stack_protector, error_message: 'Stack protector not supported') 472 endif 473 474 coroutine_backend = get_option('coroutine_backend') 475 ucontext_probe = ''' 476 #include <ucontext.h> 477 #ifdef __stub_makecontext 478 #error Ignoring glibc stub makecontext which will always fail 479 #endif 480 int main(void) { makecontext(0, 0, 0); return 0; }''' 481 482 # On Windows the only valid backend is the Windows specific one. 483 # For POSIX prefer ucontext, but it's not always possible. The fallback 484 # is sigcontext. 485 supported_backends = [] 486 if host_os == 'windows' 487 supported_backends += ['windows'] 488 else 489 if host_os != 'darwin' and cc.links(ucontext_probe) 490 supported_backends += ['ucontext'] 491 endif 492 supported_backends += ['sigaltstack'] 493 endif 494 495 if coroutine_backend == 'auto' 496 coroutine_backend = supported_backends[0] 497 elif coroutine_backend not in supported_backends 498 error('"@0@" backend requested but not available. Available backends: @1@' \ 499 .format(coroutine_backend, ', '.join(supported_backends))) 500 endif 501 502 # Compiles if SafeStack *not* enabled 503 safe_stack_probe = ''' 504 int main(void) 505 { 506 #if defined(__has_feature) 507 #if __has_feature(safe_stack) 508 #error SafeStack Enabled 509 #endif 510 #endif 511 return 0; 512 }''' 513 if get_option('safe_stack') != not cc.compiles(safe_stack_probe) 514 safe_stack_arg = get_option('safe_stack') ? '-fsanitize=safe-stack' : '-fno-sanitize=safe-stack' 515 if get_option('safe_stack') != not cc.compiles(safe_stack_probe, args: safe_stack_arg) 516 error(get_option('safe_stack') \ 517 ? 'SafeStack not supported by your compiler' \ 518 : 'Cannot disable SafeStack') 519 endif 520 qemu_cflags += safe_stack_arg 521 qemu_ldflags += safe_stack_arg 522 endif 523 if get_option('safe_stack') and coroutine_backend != 'ucontext' 524 error('SafeStack is only supported with the ucontext coroutine backend') 525 endif 526 527 if get_option('asan') 528 if cc.has_argument('-fsanitize=address') 529 qemu_cflags = ['-fsanitize=address'] + qemu_cflags 530 qemu_ldflags = ['-fsanitize=address'] + qemu_ldflags 531 else 532 error('Your compiler does not support -fsanitize=address') 533 endif 534 endif 535 536 if get_option('ubsan') 537 # Detect static linking issue with ubsan: 538 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84285 539 if cc.links('int main(int argc, char **argv) { return argc + 1; }', 540 args: [qemu_ldflags, '-fsanitize=undefined']) 541 qemu_cflags += ['-fsanitize=undefined'] 542 qemu_ldflags += ['-fsanitize=undefined'] 543 544 # Suppress undefined behaviour from function call to mismatched type. 545 # In addition, tcg prologue does not emit function type prefix 546 # required by function call sanitizer. 547 if cc.has_argument('-fno-sanitize=function') 548 qemu_cflags += ['-fno-sanitize=function'] 549 endif 550 else 551 error('Your compiler does not support -fsanitize=undefined') 552 endif 553 endif 554 555 # Thread sanitizer is, for now, much noisier than the other sanitizers; 556 # keep it separate until that is not the case. 557 if get_option('tsan') 558 if get_option('asan') or get_option('ubsan') 559 error('TSAN is not supported with other sanitizers') 560 endif 561 if not cc.has_function('__tsan_create_fiber', 562 args: '-fsanitize=thread', 563 prefix: '#include <sanitizer/tsan_interface.h>') 564 error('Cannot enable TSAN due to missing fiber annotation interface') 565 endif 566 tsan_warn_suppress = [] 567 # gcc (>=11) will report constructions not supported by tsan: 568 # "error: ‘atomic_thread_fence’ is not supported with ‘-fsanitize=thread’" 569 # https://gcc.gnu.org/gcc-11/changes.html 570 # However, clang does not support this warning and this triggers an error. 571 if cc.has_argument('-Wno-tsan') 572 tsan_warn_suppress = ['-Wno-tsan'] 573 endif 574 qemu_cflags = ['-fsanitize=thread'] + tsan_warn_suppress + qemu_cflags 575 qemu_ldflags = ['-fsanitize=thread'] + qemu_ldflags 576 endif 577 578 # Detect support for PT_GNU_RELRO + DT_BIND_NOW. 579 # The combination is known as "full relro", because .got.plt is read-only too. 580 qemu_ldflags += cc.get_supported_link_arguments('-Wl,-z,relro', '-Wl,-z,now') 581 582 if host_os == 'windows' 583 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--no-seh', '-Wl,--nxcompat') 584 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--dynamicbase', '-Wl,--high-entropy-va') 585 endif 586 587 if get_option('fuzzing') 588 # Specify a filter to only instrument code that is directly related to 589 # virtual-devices. 590 configure_file(output: 'instrumentation-filter', 591 input: 'scripts/oss-fuzz/instrumentation-filter-template', 592 copy: true) 593 594 if cc.compiles('int main () { return 0; }', 595 name: '-fsanitize-coverage-allowlist=/dev/null', 596 args: ['-fsanitize-coverage-allowlist=/dev/null', 597 '-fsanitize-coverage=trace-pc'] ) 598 qemu_common_flags += ['-fsanitize-coverage-allowlist=instrumentation-filter'] 599 endif 600 601 if get_option('fuzzing_engine') == '' 602 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the 603 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link 604 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be 605 # unable to bind the fuzzer-related callbacks added by instrumentation. 606 qemu_common_flags += ['-fsanitize=fuzzer-no-link'] 607 qemu_ldflags += ['-fsanitize=fuzzer-no-link'] 608 # For the actual fuzzer binaries, we need to link against the libfuzzer 609 # library. They need to be configurable, to support OSS-Fuzz 610 fuzz_exe_ldflags = ['-fsanitize=fuzzer'] 611 else 612 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and 613 # the needed CFLAGS have already been provided 614 fuzz_exe_ldflags = get_option('fuzzing_engine').split() 615 endif 616 endif 617 618 if get_option('cfi') 619 cfi_flags=[] 620 # Check for dependency on LTO 621 if not get_option('b_lto') 622 error('Selected Control-Flow Integrity but LTO is disabled') 623 endif 624 if enable_modules 625 error('Selected Control-Flow Integrity is not compatible with modules') 626 endif 627 # Check for cfi flags. CFI requires LTO so we can't use 628 # get_supported_arguments, but need a more complex "compiles" which allows 629 # custom arguments 630 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall', 631 args: ['-flto', '-fsanitize=cfi-icall'] ) 632 cfi_flags += '-fsanitize=cfi-icall' 633 else 634 error('-fsanitize=cfi-icall is not supported by the compiler') 635 endif 636 if cc.compiles('int main () { return 0; }', 637 name: '-fsanitize-cfi-icall-generalize-pointers', 638 args: ['-flto', '-fsanitize=cfi-icall', 639 '-fsanitize-cfi-icall-generalize-pointers'] ) 640 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers' 641 else 642 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler') 643 endif 644 if get_option('cfi_debug') 645 if cc.compiles('int main () { return 0; }', 646 name: '-fno-sanitize-trap=cfi-icall', 647 args: ['-flto', '-fsanitize=cfi-icall', 648 '-fno-sanitize-trap=cfi-icall'] ) 649 cfi_flags += '-fno-sanitize-trap=cfi-icall' 650 else 651 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler') 652 endif 653 endif 654 add_global_arguments(cfi_flags, native: false, language: all_languages) 655 add_global_link_arguments(cfi_flags, native: false, language: all_languages) 656 endif 657 658 # Check further flags that make QEMU more robust against malicious parties 659 660 hardening_flags = [ 661 # Initialize all stack variables to zero. This makes 662 # it harder to take advantage of uninitialized stack 663 # data to drive exploits 664 '-ftrivial-auto-var-init=zero', 665 ] 666 667 # Zero out registers used during a function call 668 # upon its return. This makes it harder to assemble 669 # ROP gadgets into something usable 670 # 671 # NB: Clang 17 is broken and SEGVs 672 # https://github.com/llvm/llvm-project/issues/75168 673 # 674 # NB2: This clashes with the "retguard" extension of OpenBSD's Clang 675 # https://gitlab.com/qemu-project/qemu/-/issues/2278 676 if host_os != 'openbsd' and \ 677 cc.compiles('extern struct { void (*cb)(void); } s; void f(void) { s.cb(); }', 678 name: '-fzero-call-used-regs=used-gpr', 679 args: ['-O2', '-fzero-call-used-regs=used-gpr']) 680 hardening_flags += '-fzero-call-used-regs=used-gpr' 681 endif 682 683 qemu_common_flags += cc.get_supported_arguments(hardening_flags) 684 685 add_global_arguments(qemu_common_flags, native: false, language: all_languages) 686 add_global_link_arguments(qemu_ldflags, native: false, language: all_languages) 687 688 # Collect warning flags we want to set, sorted alphabetically 689 warn_flags = [ 690 # First enable interesting warnings 691 '-Wempty-body', 692 '-Wendif-labels', 693 '-Wexpansion-to-defined', 694 '-Wformat-security', 695 '-Wformat-y2k', 696 '-Wignored-qualifiers', 697 '-Wimplicit-fallthrough=2', 698 '-Winit-self', 699 '-Wmissing-format-attribute', 700 '-Wmissing-prototypes', 701 '-Wnested-externs', 702 '-Wold-style-declaration', 703 '-Wold-style-definition', 704 '-Wredundant-decls', 705 '-Wshadow=local', 706 '-Wstrict-prototypes', 707 '-Wtype-limits', 708 '-Wundef', 709 '-Wvla', 710 '-Wwrite-strings', 711 712 # Then disable some undesirable warnings 713 '-Wno-gnu-variable-sized-type-not-at-end', 714 '-Wno-initializer-overrides', 715 '-Wno-missing-include-dirs', 716 '-Wno-psabi', 717 '-Wno-shift-negative-value', 718 '-Wno-string-plus-int', 719 '-Wno-tautological-type-limit-compare', 720 '-Wno-typedef-redefinition', 721 ] 722 723 if host_os != 'darwin' 724 tsa_has_cleanup = cc.compiles(''' 725 struct __attribute__((capability("mutex"))) mutex {}; 726 void lock(struct mutex *m) __attribute__((acquire_capability(m))); 727 void unlock(struct mutex *m) __attribute__((release_capability(m))); 728 729 void test(void) { 730 struct mutex __attribute__((cleanup(unlock))) m; 731 lock(&m); 732 } 733 ''', args: ['-Wthread-safety', '-Werror']) 734 if tsa_has_cleanup 735 warn_flags += ['-Wthread-safety'] 736 endif 737 endif 738 739 # Set up C++ compiler flags 740 qemu_cxxflags = [] 741 if 'cpp' in all_languages 742 qemu_cxxflags = ['-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', '-D__STDC_FORMAT_MACROS'] + qemu_cflags 743 endif 744 745 add_project_arguments(qemu_cflags, native: false, language: 'c') 746 add_project_arguments(cc.get_supported_arguments(warn_flags), native: false, language: 'c') 747 if 'cpp' in all_languages 748 add_project_arguments(qemu_cxxflags, native: false, language: 'cpp') 749 add_project_arguments(cxx.get_supported_arguments(warn_flags), native: false, language: 'cpp') 750 endif 751 if 'objc' in all_languages 752 # Note sanitizer flags are not applied to Objective-C sources! 753 add_project_arguments(objc.get_supported_arguments(warn_flags), native: false, language: 'objc') 754 endif 755 if host_os == 'linux' 756 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers', 757 '-isystem', 'linux-headers', 758 language: all_languages) 759 endif 760 761 add_project_arguments('-iquote', '.', 762 '-iquote', meson.current_source_dir(), 763 '-iquote', meson.current_source_dir() / 'include', 764 language: all_languages) 765 766 # If a host-specific include directory exists, list that first... 767 host_include = meson.current_source_dir() / 'host/include/' 768 if fs.is_dir(host_include / host_arch) 769 add_project_arguments('-iquote', host_include / host_arch, 770 language: all_languages) 771 endif 772 # ... followed by the generic fallback. 773 add_project_arguments('-iquote', host_include / 'generic', 774 language: all_languages) 775 776 sparse = find_program('cgcc', required: get_option('sparse')) 777 if sparse.found() 778 run_target('sparse', 779 command: [find_program('scripts/check_sparse.py'), 780 'compile_commands.json', sparse.full_path(), '-Wbitwise', 781 '-Wno-transparent-union', '-Wno-old-initializer', 782 '-Wno-non-pointer-null']) 783 endif 784 785 ##################################### 786 # Host-specific libraries and flags # 787 ##################################### 788 789 libm = cc.find_library('m', required: false) 790 threads = dependency('threads') 791 util = cc.find_library('util', required: false) 792 winmm = [] 793 socket = [] 794 version_res = [] 795 coref = [] 796 iokit = [] 797 emulator_link_args = [] 798 midl = not_found 799 widl = not_found 800 pathcch = not_found 801 host_dsosuf = '.so' 802 if host_os == 'windows' 803 midl = find_program('midl', required: false) 804 widl = find_program('widl', required: false) 805 pathcch = cc.find_library('pathcch') 806 socket = cc.find_library('ws2_32') 807 winmm = cc.find_library('winmm') 808 809 win = import('windows') 810 version_res = win.compile_resources('version.rc', 811 depend_files: files('pc-bios/qemu-nsis.ico'), 812 include_directories: include_directories('.')) 813 host_dsosuf = '.dll' 814 elif host_os == 'darwin' 815 coref = dependency('appleframeworks', modules: 'CoreFoundation') 816 iokit = dependency('appleframeworks', modules: 'IOKit', required: false) 817 host_dsosuf = '.dylib' 818 elif host_os == 'sunos' 819 socket = [cc.find_library('socket'), 820 cc.find_library('nsl'), 821 cc.find_library('resolv')] 822 elif host_os == 'haiku' 823 socket = [cc.find_library('posix_error_mapper'), 824 cc.find_library('network'), 825 cc.find_library('bsd')] 826 elif host_os == 'openbsd' 827 if get_option('tcg').allowed() and target_dirs.length() > 0 828 # Disable OpenBSD W^X if available 829 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded') 830 endif 831 endif 832 833 ############################################### 834 # Host-specific configuration of accelerators # 835 ############################################### 836 837 accelerators = [] 838 if get_option('kvm').allowed() and host_os == 'linux' 839 accelerators += 'CONFIG_KVM' 840 endif 841 if get_option('whpx').allowed() and host_os == 'windows' 842 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64' 843 error('WHPX requires 64-bit host') 844 elif cc.has_header('winhvplatform.h', required: get_option('whpx')) and \ 845 cc.has_header('winhvemulation.h', required: get_option('whpx')) 846 accelerators += 'CONFIG_WHPX' 847 endif 848 endif 849 850 hvf = not_found 851 if get_option('hvf').allowed() 852 hvf = dependency('appleframeworks', modules: 'Hypervisor', 853 required: get_option('hvf')) 854 if hvf.found() 855 accelerators += 'CONFIG_HVF' 856 endif 857 endif 858 859 nvmm = not_found 860 if host_os == 'netbsd' 861 nvmm = cc.find_library('nvmm', required: get_option('nvmm')) 862 if nvmm.found() 863 accelerators += 'CONFIG_NVMM' 864 endif 865 endif 866 867 tcg_arch = host_arch 868 if get_option('tcg').allowed() 869 if host_arch == 'unknown' 870 if not get_option('tcg_interpreter') 871 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu)) 872 endif 873 elif get_option('tcg_interpreter') 874 warning('Use of the TCG interpreter is not recommended on this host') 875 warning('architecture. There is a native TCG execution backend available') 876 warning('which provides substantially better performance and reliability.') 877 warning('It is strongly recommended to remove the --enable-tcg-interpreter') 878 warning('configuration option on this architecture to use the native') 879 warning('backend.') 880 endif 881 if get_option('tcg_interpreter') 882 tcg_arch = 'tci' 883 elif host_arch == 'x86_64' 884 tcg_arch = 'i386' 885 elif host_arch == 'ppc64' 886 tcg_arch = 'ppc' 887 endif 888 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch, 889 language: all_languages) 890 891 accelerators += 'CONFIG_TCG' 892 endif 893 894 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled() 895 error('KVM not available on this platform') 896 endif 897 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled() 898 error('HVF not available on this platform') 899 endif 900 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled() 901 error('NVMM not available on this platform') 902 endif 903 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled() 904 error('WHPX not available on this platform') 905 endif 906 907 xen = not_found 908 if get_option('xen').enabled() or (get_option('xen').auto() and have_system) 909 xencontrol = dependency('xencontrol', required: false, 910 method: 'pkg-config') 911 if xencontrol.found() 912 xen_pc = declare_dependency(version: xencontrol.version(), 913 dependencies: [ 914 xencontrol, 915 # disabler: true makes xen_pc.found() return false if any is not found 916 dependency('xenstore', required: false, 917 method: 'pkg-config', 918 disabler: true), 919 dependency('xenforeignmemory', required: false, 920 method: 'pkg-config', 921 disabler: true), 922 dependency('xengnttab', required: false, 923 method: 'pkg-config', 924 disabler: true), 925 dependency('xenevtchn', required: false, 926 method: 'pkg-config', 927 disabler: true), 928 dependency('xendevicemodel', required: false, 929 method: 'pkg-config', 930 disabler: true), 931 # optional, no "disabler: true" 932 dependency('xentoolcore', required: false, 933 method: 'pkg-config')]) 934 if xen_pc.found() 935 xen = xen_pc 936 endif 937 endif 938 if not xen.found() 939 xen_tests = [ '4.11.0', '4.10.0', '4.9.0', '4.8.0', '4.7.1' ] 940 xen_libs = { 941 '4.11.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ], 942 '4.10.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ], 943 '4.9.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ], 944 '4.8.0': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ], 945 '4.7.1': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ], 946 } 947 xen_deps = {} 948 foreach ver: xen_tests 949 # cache the various library tests to avoid polluting the logs 950 xen_test_deps = [] 951 foreach l: xen_libs[ver] 952 if l not in xen_deps 953 xen_deps += { l: cc.find_library(l, required: false) } 954 endif 955 xen_test_deps += xen_deps[l] 956 endforeach 957 958 # Use -D to pick just one of the test programs in scripts/xen-detect.c 959 xen_version = ver.split('.') 960 xen_ctrl_version = xen_version[0] + \ 961 ('0' + xen_version[1]).substring(-2) + \ 962 ('0' + xen_version[2]).substring(-2) 963 if cc.links(files('scripts/xen-detect.c'), 964 args: '-DCONFIG_XEN_CTRL_INTERFACE_VERSION=' + xen_ctrl_version, 965 dependencies: xen_test_deps) 966 xen = declare_dependency(version: ver, dependencies: xen_test_deps) 967 break 968 endif 969 endforeach 970 endif 971 if xen.found() 972 accelerators += 'CONFIG_XEN' 973 elif get_option('xen').enabled() 974 error('could not compile and link Xen test program') 975 endif 976 endif 977 have_xen_pci_passthrough = get_option('xen_pci_passthrough') \ 978 .require(xen.found(), 979 error_message: 'Xen PCI passthrough requested but Xen not enabled') \ 980 .require(host_os == 'linux', 981 error_message: 'Xen PCI passthrough not available on this platform') \ 982 .require(cpu == 'x86' or cpu == 'x86_64', 983 error_message: 'Xen PCI passthrough not available on this platform') \ 984 .allowed() 985 986 ################ 987 # Dependencies # 988 ################ 989 990 # When bumping glib minimum version, please check also whether to increase 991 # the _WIN32_WINNT setting in osdep.h according to the value from glib. 992 # You should also check if any of the glib.version() checks 993 # below can also be removed. 994 glib_req_ver = '>=2.66.0' 995 glib_pc = dependency('glib-2.0', version: glib_req_ver, required: true, 996 method: 'pkg-config') 997 glib_cflags = [] 998 if enable_modules 999 gmodule = dependency('gmodule-export-2.0', version: glib_req_ver, required: true, 1000 method: 'pkg-config') 1001 elif get_option('plugins') 1002 gmodule = dependency('gmodule-no-export-2.0', version: glib_req_ver, required: true, 1003 method: 'pkg-config') 1004 else 1005 gmodule = not_found 1006 endif 1007 1008 # This workaround is required due to a bug in pkg-config file for glib as it 1009 # doesn't define GLIB_STATIC_COMPILATION for pkg-config --static 1010 if host_os == 'windows' and get_option('prefer_static') 1011 glib_cflags += ['-DGLIB_STATIC_COMPILATION'] 1012 endif 1013 1014 # Sanity check that the current size_t matches the 1015 # size that glib thinks it should be. This catches 1016 # problems on multi-arch where people try to build 1017 # 32-bit QEMU while pointing at 64-bit glib headers 1018 1019 if not cc.compiles(''' 1020 #include <glib.h> 1021 #include <unistd.h> 1022 1023 #define QEMU_BUILD_BUG_ON(x) \ 1024 typedef char qemu_build_bug_on[(x)?-1:1] __attribute__((unused)); 1025 1026 int main(void) { 1027 QEMU_BUILD_BUG_ON(sizeof(size_t) != GLIB_SIZEOF_SIZE_T); 1028 return 0; 1029 }''', dependencies: glib_pc, args: glib_cflags) 1030 error('''sizeof(size_t) doesn't match GLIB_SIZEOF_SIZE_T. 1031 You probably need to set PKG_CONFIG_LIBDIR" to point 1032 to the right pkg-config files for your build target.''') 1033 endif 1034 1035 glib = declare_dependency(dependencies: [glib_pc, gmodule], 1036 compile_args: glib_cflags, 1037 version: glib_pc.version()) 1038 1039 # Check whether glib has gslice, which we have to avoid for correctness. 1040 # TODO: remove this check and the corresponding workaround (qtree) when 1041 # the minimum supported glib is >= 2.75.3 1042 glib_has_gslice = glib.version().version_compare('<2.75.3') 1043 # Check whether glib has the aligned_alloc family of functions. 1044 # <https://docs.gtk.org/glib/func.aligned_alloc.html> 1045 glib_has_aligned_alloc = glib.version().version_compare('>=2.72.0') 1046 1047 # override glib dep to include the above refinements 1048 meson.override_dependency('glib-2.0', glib) 1049 1050 # The path to glib.h is added to all compilation commands. 1051 add_project_dependencies(glib.partial_dependency(compile_args: true, includes: true), 1052 native: false, language: all_languages) 1053 1054 gio = not_found 1055 gdbus_codegen = not_found 1056 gdbus_codegen_error = '@0@ requires gdbus-codegen, please install libgio' 1057 if not get_option('gio').auto() or have_system 1058 gio = dependency('gio-2.0', required: get_option('gio'), 1059 method: 'pkg-config') 1060 if gio.found() and not cc.links(''' 1061 #include <gio/gio.h> 1062 int main(void) 1063 { 1064 g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0); 1065 return 0; 1066 }''', dependencies: [glib, gio]) 1067 if get_option('gio').enabled() 1068 error('The installed libgio is broken for static linking') 1069 endif 1070 gio = not_found 1071 endif 1072 if gio.found() 1073 gdbus_codegen = find_program('gdbus-codegen', 1074 required: get_option('gio')) 1075 gio_unix = dependency('gio-unix-2.0', required: get_option('gio'), 1076 method: 'pkg-config') 1077 gio = declare_dependency(dependencies: [gio, gio_unix], 1078 version: gio.version()) 1079 endif 1080 endif 1081 if gdbus_codegen.found() and get_option('cfi') 1082 gdbus_codegen = not_found 1083 gdbus_codegen_error = '@0@ uses gdbus-codegen, which does not support control flow integrity' 1084 endif 1085 1086 xml_pp = find_program('scripts/xml-preprocess.py') 1087 1088 lttng = not_found 1089 if 'ust' in get_option('trace_backends') 1090 lttng = dependency('lttng-ust', required: true, version: '>= 2.1', 1091 method: 'pkg-config') 1092 endif 1093 pixman = not_found 1094 if not get_option('pixman').auto() or have_system or have_tools 1095 pixman = dependency('pixman-1', required: get_option('pixman'), version:'>=0.21.8', 1096 method: 'pkg-config') 1097 endif 1098 1099 zlib = dependency('zlib', required: true) 1100 1101 libaio = not_found 1102 if not get_option('linux_aio').auto() or have_block 1103 libaio = cc.find_library('aio', has_headers: ['libaio.h'], 1104 required: get_option('linux_aio')) 1105 endif 1106 1107 linux_io_uring_test = ''' 1108 #include <liburing.h> 1109 #include <linux/errqueue.h> 1110 1111 int main(void) { return 0; }''' 1112 1113 linux_io_uring = not_found 1114 if not get_option('linux_io_uring').auto() or have_block 1115 linux_io_uring = dependency('liburing', version: '>=0.3', 1116 required: get_option('linux_io_uring'), 1117 method: 'pkg-config') 1118 if not cc.links(linux_io_uring_test) 1119 linux_io_uring = not_found 1120 endif 1121 endif 1122 1123 libnfs = not_found 1124 if not get_option('libnfs').auto() or have_block 1125 libnfs = dependency('libnfs', version: ['>=1.9.3', '<6.0.0'], 1126 required: get_option('libnfs'), 1127 method: 'pkg-config') 1128 endif 1129 1130 libattr_test = ''' 1131 #include <stddef.h> 1132 #include <sys/types.h> 1133 #ifdef CONFIG_LIBATTR 1134 #include <attr/xattr.h> 1135 #else 1136 #include <sys/xattr.h> 1137 #endif 1138 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }''' 1139 1140 libattr = not_found 1141 have_old_libattr = false 1142 if get_option('attr').allowed() 1143 if cc.links(libattr_test) 1144 libattr = declare_dependency() 1145 else 1146 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'], 1147 required: get_option('attr')) 1148 if libattr.found() and not \ 1149 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR') 1150 libattr = not_found 1151 if get_option('attr').enabled() 1152 error('could not link libattr') 1153 else 1154 warning('could not link libattr, disabling') 1155 endif 1156 else 1157 have_old_libattr = libattr.found() 1158 endif 1159 endif 1160 endif 1161 1162 cocoa = dependency('appleframeworks', 1163 modules: ['Cocoa', 'CoreVideo', 'QuartzCore'], 1164 required: get_option('cocoa')) 1165 1166 vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet')) 1167 if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h', 1168 'VMNET_BRIDGED_MODE', 1169 dependencies: vmnet) 1170 vmnet = not_found 1171 if get_option('vmnet').enabled() 1172 error('vmnet.framework API is outdated') 1173 else 1174 warning('vmnet.framework API is outdated, disabling') 1175 endif 1176 endif 1177 1178 seccomp = not_found 1179 seccomp_has_sysrawrc = false 1180 if not get_option('seccomp').auto() or have_system or have_tools 1181 seccomp = dependency('libseccomp', version: '>=2.3.0', 1182 required: get_option('seccomp'), 1183 method: 'pkg-config') 1184 if seccomp.found() 1185 seccomp_has_sysrawrc = cc.has_header_symbol('seccomp.h', 1186 'SCMP_FLTATR_API_SYSRAWRC', 1187 dependencies: seccomp) 1188 endif 1189 endif 1190 1191 libcap_ng = not_found 1192 if not get_option('cap_ng').auto() or have_system or have_tools 1193 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'], 1194 required: get_option('cap_ng')) 1195 endif 1196 if libcap_ng.found() and not cc.links(''' 1197 #include <cap-ng.h> 1198 int main(void) 1199 { 1200 capng_capability_to_name(CAPNG_EFFECTIVE); 1201 return 0; 1202 }''', dependencies: libcap_ng) 1203 libcap_ng = not_found 1204 if get_option('cap_ng').enabled() 1205 error('could not link libcap-ng') 1206 else 1207 warning('could not link libcap-ng, disabling') 1208 endif 1209 endif 1210 1211 if get_option('xkbcommon').auto() and not have_system and not have_tools 1212 xkbcommon = not_found 1213 else 1214 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'), 1215 method: 'pkg-config') 1216 endif 1217 1218 slirp = not_found 1219 if not get_option('slirp').auto() or have_system 1220 slirp = dependency('slirp', required: get_option('slirp'), 1221 method: 'pkg-config') 1222 # slirp < 4.7 is incompatible with CFI support in QEMU. This is because 1223 # it passes function pointers within libslirp as callbacks for timers. 1224 # When using a system-wide shared libslirp, the type information for the 1225 # callback is missing and the timer call produces a false positive with CFI. 1226 # Do not use the "version" keyword argument to produce a better error. 1227 # with control-flow integrity. 1228 if get_option('cfi') and slirp.found() and slirp.version().version_compare('<4.7') 1229 if get_option('slirp').enabled() 1230 error('Control-Flow Integrity requires libslirp 4.7.') 1231 else 1232 warning('Cannot use libslirp since Control-Flow Integrity requires libslirp >= 4.7.') 1233 slirp = not_found 1234 endif 1235 endif 1236 endif 1237 1238 vde = not_found 1239 if not get_option('vde').auto() or have_system or have_tools 1240 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'], 1241 required: get_option('vde')) 1242 endif 1243 if vde.found() and not cc.links(''' 1244 #include <libvdeplug.h> 1245 int main(void) 1246 { 1247 struct vde_open_args a = {0, 0, 0}; 1248 char s[] = ""; 1249 vde_open(s, s, &a); 1250 return 0; 1251 }''', dependencies: vde) 1252 vde = not_found 1253 if get_option('cap_ng').enabled() 1254 error('could not link libvdeplug') 1255 else 1256 warning('could not link libvdeplug, disabling') 1257 endif 1258 endif 1259 1260 pulse = not_found 1261 if not get_option('pa').auto() or (host_os == 'linux' and have_system) 1262 pulse = dependency('libpulse', required: get_option('pa'), 1263 method: 'pkg-config') 1264 endif 1265 alsa = not_found 1266 if not get_option('alsa').auto() or (host_os == 'linux' and have_system) 1267 alsa = dependency('alsa', required: get_option('alsa'), 1268 method: 'pkg-config') 1269 endif 1270 jack = not_found 1271 if not get_option('jack').auto() or have_system 1272 jack = dependency('jack', required: get_option('jack'), 1273 method: 'pkg-config') 1274 endif 1275 pipewire = not_found 1276 if not get_option('pipewire').auto() or (host_os == 'linux' and have_system) 1277 pipewire = dependency('libpipewire-0.3', version: '>=0.3.60', 1278 required: get_option('pipewire'), 1279 method: 'pkg-config') 1280 endif 1281 sndio = not_found 1282 if not get_option('sndio').auto() or have_system 1283 sndio = dependency('sndio', required: get_option('sndio'), 1284 method: 'pkg-config') 1285 endif 1286 1287 spice_protocol = not_found 1288 if not get_option('spice_protocol').auto() or have_system 1289 spice_protocol = dependency('spice-protocol', version: '>=0.14.0', 1290 required: get_option('spice_protocol'), 1291 method: 'pkg-config') 1292 endif 1293 spice = not_found 1294 if get_option('spice') \ 1295 .disable_auto_if(not have_system) \ 1296 .require(pixman.found(), 1297 error_message: 'cannot enable SPICE if pixman is not available') \ 1298 .allowed() 1299 spice = dependency('spice-server', version: '>=0.14.0', 1300 required: get_option('spice'), 1301 method: 'pkg-config') 1302 endif 1303 spice_headers = spice.partial_dependency(compile_args: true, includes: true) 1304 1305 rt = cc.find_library('rt', required: false) 1306 1307 libiscsi = not_found 1308 if not get_option('libiscsi').auto() or have_block 1309 libiscsi = dependency('libiscsi', version: '>=1.9.0', 1310 required: get_option('libiscsi'), 1311 method: 'pkg-config') 1312 endif 1313 zstd = not_found 1314 if not get_option('zstd').auto() or have_block 1315 zstd = dependency('libzstd', version: '>=1.4.0', 1316 required: get_option('zstd'), 1317 method: 'pkg-config') 1318 endif 1319 qpl = not_found 1320 if not get_option('qpl').auto() or have_system 1321 qpl = dependency('qpl', version: '>=1.5.0', 1322 required: get_option('qpl'), 1323 method: 'pkg-config') 1324 endif 1325 uadk = not_found 1326 if not get_option('uadk').auto() or have_system 1327 libwd = dependency('libwd', version: '>=2.6', 1328 required: get_option('uadk'), 1329 method: 'pkg-config') 1330 libwd_comp = dependency('libwd_comp', version: '>=2.6', 1331 required: get_option('uadk'), 1332 method: 'pkg-config') 1333 if libwd.found() and libwd_comp.found() 1334 uadk = declare_dependency(dependencies: [libwd, libwd_comp]) 1335 endif 1336 endif 1337 1338 qatzip = not_found 1339 if not get_option('qatzip').auto() or have_system 1340 qatzip = dependency('qatzip', version: '>=1.1.2', 1341 required: get_option('qatzip'), 1342 method: 'pkg-config') 1343 endif 1344 1345 virgl = not_found 1346 1347 have_vhost_user_gpu = have_tools and host_os == 'linux' and pixman.found() 1348 if not get_option('virglrenderer').auto() or have_system or have_vhost_user_gpu 1349 virgl = dependency('virglrenderer', 1350 method: 'pkg-config', 1351 required: get_option('virglrenderer')) 1352 endif 1353 rutabaga = not_found 1354 if not get_option('rutabaga_gfx').auto() or have_system or have_vhost_user_gpu 1355 rutabaga = dependency('rutabaga_gfx_ffi', 1356 method: 'pkg-config', 1357 required: get_option('rutabaga_gfx')) 1358 endif 1359 blkio = not_found 1360 if not get_option('blkio').auto() or have_block 1361 blkio = dependency('blkio', 1362 method: 'pkg-config', 1363 required: get_option('blkio')) 1364 endif 1365 curl = not_found 1366 if not get_option('curl').auto() or have_block 1367 curl = dependency('libcurl', version: '>=7.29.0', 1368 method: 'pkg-config', 1369 required: get_option('curl')) 1370 endif 1371 libudev = not_found 1372 if host_os == 'linux' and (have_system or have_tools) 1373 libudev = dependency('libudev', 1374 method: 'pkg-config', 1375 required: get_option('libudev')) 1376 endif 1377 1378 mpathlibs = [libudev] 1379 mpathpersist = not_found 1380 if host_os == 'linux' and have_tools and get_option('mpath').allowed() 1381 mpath_test_source = ''' 1382 #include <libudev.h> 1383 #include <mpath_persist.h> 1384 unsigned mpath_mx_alloc_len = 1024; 1385 int logsink; 1386 static struct config *multipath_conf; 1387 extern struct udev *udev; 1388 extern struct config *get_multipath_config(void); 1389 extern void put_multipath_config(struct config *conf); 1390 struct udev *udev; 1391 struct config *get_multipath_config(void) { return multipath_conf; } 1392 void put_multipath_config(struct config *conf) { } 1393 int main(void) { 1394 udev = udev_new(); 1395 multipath_conf = mpath_lib_init(); 1396 return 0; 1397 }''' 1398 libmpathpersist = cc.find_library('mpathpersist', 1399 required: get_option('mpath')) 1400 if libmpathpersist.found() 1401 mpathlibs += libmpathpersist 1402 if get_option('prefer_static') 1403 mpathlibs += cc.find_library('devmapper', 1404 required: get_option('mpath')) 1405 endif 1406 mpathlibs += cc.find_library('multipath', 1407 required: get_option('mpath')) 1408 foreach lib: mpathlibs 1409 if not lib.found() 1410 mpathlibs = [] 1411 break 1412 endif 1413 endforeach 1414 if mpathlibs.length() == 0 1415 msg = 'Dependencies missing for libmpathpersist' 1416 elif cc.links(mpath_test_source, dependencies: mpathlibs) 1417 mpathpersist = declare_dependency(dependencies: mpathlibs) 1418 else 1419 msg = 'Cannot detect libmpathpersist API' 1420 endif 1421 if not mpathpersist.found() 1422 if get_option('mpath').enabled() 1423 error(msg) 1424 else 1425 warning(msg + ', disabling') 1426 endif 1427 endif 1428 endif 1429 endif 1430 1431 iconv = not_found 1432 curses = not_found 1433 if have_system and get_option('curses').allowed() 1434 curses_test = ''' 1435 #ifdef __APPLE__ 1436 #define _XOPEN_SOURCE_EXTENDED 1 1437 #endif 1438 #include <locale.h> 1439 #include <curses.h> 1440 #include <wchar.h> 1441 int main(void) { 1442 wchar_t wch = L'w'; 1443 setlocale(LC_ALL, ""); 1444 resize_term(0, 0); 1445 addwstr(L"wide chars\n"); 1446 addnwstr(&wch, 1); 1447 add_wch(WACS_DEGREE); 1448 return 0; 1449 }''' 1450 1451 curses_dep_list = host_os == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw'] 1452 curses = dependency(curses_dep_list, 1453 required: false, 1454 method: 'pkg-config') 1455 msg = get_option('curses').enabled() ? 'curses library not found' : '' 1456 curses_compile_args = ['-DNCURSES_WIDECHAR=1'] 1457 if curses.found() 1458 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses]) 1459 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses], 1460 version: curses.version()) 1461 else 1462 msg = 'curses package not usable' 1463 curses = not_found 1464 endif 1465 endif 1466 if not curses.found() 1467 has_curses_h = cc.has_header('curses.h', args: curses_compile_args) 1468 if host_os != 'windows' and not has_curses_h 1469 message('Trying with /usr/include/ncursesw') 1470 curses_compile_args += ['-I/usr/include/ncursesw'] 1471 has_curses_h = cc.has_header('curses.h', args: curses_compile_args) 1472 endif 1473 if has_curses_h 1474 curses_libname_list = (host_os == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw']) 1475 foreach curses_libname : curses_libname_list 1476 libcurses = cc.find_library(curses_libname, 1477 required: false) 1478 if libcurses.found() 1479 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses) 1480 curses = declare_dependency(compile_args: curses_compile_args, 1481 dependencies: [libcurses]) 1482 break 1483 else 1484 msg = 'curses library not usable' 1485 endif 1486 endif 1487 endforeach 1488 endif 1489 endif 1490 if get_option('iconv').allowed() 1491 foreach link_args : [ ['-liconv'], [] ] 1492 # Programs will be linked with glib and this will bring in libiconv on FreeBSD. 1493 # We need to use libiconv if available because mixing libiconv's headers with 1494 # the system libc does not work. 1495 # However, without adding glib to the dependencies -L/usr/local/lib will not be 1496 # included in the command line and libiconv will not be found. 1497 if cc.links(''' 1498 #include <iconv.h> 1499 int main(void) { 1500 iconv_t conv = iconv_open("WCHAR_T", "UCS-2"); 1501 return conv != (iconv_t) -1; 1502 }''', args: link_args, dependencies: glib) 1503 iconv = declare_dependency(link_args: link_args, dependencies: glib) 1504 break 1505 endif 1506 endforeach 1507 endif 1508 if curses.found() and not iconv.found() 1509 if get_option('iconv').enabled() 1510 error('iconv not available') 1511 endif 1512 msg = 'iconv required for curses UI but not available' 1513 curses = not_found 1514 endif 1515 if not curses.found() and msg != '' 1516 if get_option('curses').enabled() 1517 error(msg) 1518 else 1519 warning(msg + ', disabling') 1520 endif 1521 endif 1522 endif 1523 1524 brlapi = not_found 1525 if not get_option('brlapi').auto() or have_system 1526 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'], 1527 required: get_option('brlapi')) 1528 if brlapi.found() and not cc.links(''' 1529 #include <brlapi.h> 1530 #include <stddef.h> 1531 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi) 1532 brlapi = not_found 1533 if get_option('brlapi').enabled() 1534 error('could not link brlapi') 1535 else 1536 warning('could not link brlapi, disabling') 1537 endif 1538 endif 1539 endif 1540 1541 sdl = not_found 1542 if not get_option('sdl').auto() or have_system 1543 sdl = dependency('sdl2', required: get_option('sdl')) 1544 sdl_image = not_found 1545 endif 1546 if sdl.found() 1547 # Some versions of SDL have problems with -Wundef 1548 if not cc.compiles(''' 1549 #include <SDL.h> 1550 #include <SDL_syswm.h> 1551 int main(int argc, char *argv[]) { return 0; } 1552 ''', dependencies: sdl, args: '-Werror=undef') 1553 sdl = declare_dependency(compile_args: '-Wno-undef', 1554 dependencies: sdl, 1555 version: sdl.version()) 1556 endif 1557 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'), 1558 method: 'pkg-config') 1559 else 1560 if get_option('sdl_image').enabled() 1561 error('sdl-image required, but SDL was @0@'.format( 1562 get_option('sdl').disabled() ? 'disabled' : 'not found')) 1563 endif 1564 sdl_image = not_found 1565 endif 1566 1567 rbd = not_found 1568 if not get_option('rbd').auto() or have_block 1569 librados = cc.find_library('rados', required: get_option('rbd')) 1570 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'], 1571 required: get_option('rbd')) 1572 if librados.found() and librbd.found() 1573 if cc.links(''' 1574 #include <stdio.h> 1575 #include <rbd/librbd.h> 1576 int main(void) { 1577 rados_t cluster; 1578 rados_create(&cluster, NULL); 1579 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0) 1580 #error 1581 #endif 1582 return 0; 1583 }''', dependencies: [librbd, librados]) 1584 rbd = declare_dependency(dependencies: [librbd, librados]) 1585 elif get_option('rbd').enabled() 1586 error('librbd >= 1.12.0 required') 1587 else 1588 warning('librbd >= 1.12.0 not found, disabling') 1589 endif 1590 endif 1591 endif 1592 1593 glusterfs = not_found 1594 glusterfs_ftruncate_has_stat = false 1595 glusterfs_iocb_has_stat = false 1596 if not get_option('glusterfs').auto() or have_block 1597 glusterfs = dependency('glusterfs-api', version: '>=3', 1598 required: get_option('glusterfs'), 1599 method: 'pkg-config') 1600 if glusterfs.found() 1601 glusterfs_ftruncate_has_stat = cc.links(''' 1602 #include <glusterfs/api/glfs.h> 1603 1604 int 1605 main(void) 1606 { 1607 /* new glfs_ftruncate() passes two additional args */ 1608 return glfs_ftruncate(NULL, 0, NULL, NULL); 1609 } 1610 ''', dependencies: glusterfs) 1611 glusterfs_iocb_has_stat = cc.links(''' 1612 #include <glusterfs/api/glfs.h> 1613 1614 /* new glfs_io_cbk() passes two additional glfs_stat structs */ 1615 static void 1616 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data) 1617 {} 1618 1619 int 1620 main(void) 1621 { 1622 glfs_io_cbk iocb = &glusterfs_iocb; 1623 iocb(NULL, 0 , NULL, NULL, NULL); 1624 return 0; 1625 } 1626 ''', dependencies: glusterfs) 1627 endif 1628 endif 1629 1630 hv_balloon = false 1631 if get_option('hv_balloon').allowed() and have_system 1632 if cc.links(''' 1633 #include <string.h> 1634 #include <gmodule.h> 1635 int main(void) { 1636 GTree *tree; 1637 1638 tree = g_tree_new((GCompareFunc)strcmp); 1639 (void)g_tree_node_first(tree); 1640 g_tree_destroy(tree); 1641 return 0; 1642 } 1643 ''', dependencies: glib) 1644 hv_balloon = true 1645 else 1646 if get_option('hv_balloon').enabled() 1647 error('could not enable hv-balloon, update your glib') 1648 else 1649 warning('could not find glib support for hv-balloon, disabling') 1650 endif 1651 endif 1652 endif 1653 1654 libssh = not_found 1655 if not get_option('libssh').auto() or have_block 1656 libssh = dependency('libssh', version: '>=0.8.7', 1657 method: 'pkg-config', 1658 required: get_option('libssh')) 1659 endif 1660 1661 libbzip2 = not_found 1662 if not get_option('bzip2').auto() or have_block 1663 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'], 1664 required: get_option('bzip2')) 1665 if libbzip2.found() and not cc.links(''' 1666 #include <bzlib.h> 1667 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2) 1668 libbzip2 = not_found 1669 if get_option('bzip2').enabled() 1670 error('could not link libbzip2') 1671 else 1672 warning('could not link libbzip2, disabling') 1673 endif 1674 endif 1675 endif 1676 1677 liblzfse = not_found 1678 if not get_option('lzfse').auto() or have_block 1679 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'], 1680 required: get_option('lzfse')) 1681 endif 1682 if liblzfse.found() and not cc.links(''' 1683 #include <lzfse.h> 1684 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse) 1685 liblzfse = not_found 1686 if get_option('lzfse').enabled() 1687 error('could not link liblzfse') 1688 else 1689 warning('could not link liblzfse, disabling') 1690 endif 1691 endif 1692 1693 oss = not_found 1694 if get_option('oss').allowed() and have_system 1695 if not cc.has_header('sys/soundcard.h') 1696 # not found 1697 elif host_os == 'netbsd' 1698 oss = cc.find_library('ossaudio', required: get_option('oss')) 1699 else 1700 oss = declare_dependency() 1701 endif 1702 1703 if not oss.found() 1704 if get_option('oss').enabled() 1705 error('OSS not found') 1706 endif 1707 endif 1708 endif 1709 dsound = not_found 1710 if not get_option('dsound').auto() or (host_os == 'windows' and have_system) 1711 if cc.has_header('dsound.h') 1712 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid']) 1713 endif 1714 1715 if not dsound.found() 1716 if get_option('dsound').enabled() 1717 error('DirectSound not found') 1718 endif 1719 endif 1720 endif 1721 1722 coreaudio = not_found 1723 if not get_option('coreaudio').auto() or (host_os == 'darwin' and have_system) 1724 coreaudio = dependency('appleframeworks', modules: 'CoreAudio', 1725 required: get_option('coreaudio')) 1726 endif 1727 1728 opengl = not_found 1729 if not get_option('opengl').auto() or have_system or have_vhost_user_gpu 1730 epoxy = dependency('epoxy', method: 'pkg-config', 1731 required: get_option('opengl')) 1732 if cc.has_header('epoxy/egl.h', dependencies: epoxy) 1733 opengl = epoxy 1734 elif get_option('opengl').enabled() 1735 error('epoxy/egl.h not found') 1736 endif 1737 endif 1738 gbm = not_found 1739 if (have_system or have_tools) and (virgl.found() or opengl.found()) 1740 gbm = dependency('gbm', method: 'pkg-config', required: false) 1741 endif 1742 have_vhost_user_gpu = have_vhost_user_gpu and virgl.found() and opengl.found() and gbm.found() 1743 1744 libcbor = not_found 1745 if not get_option('libcbor').auto() or have_system 1746 libcbor = dependency('libcbor', version: '>=0.7.0', 1747 required: get_option('libcbor')) 1748 endif 1749 1750 gnutls = not_found 1751 gnutls_crypto = not_found 1752 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system) 1753 # For general TLS support our min gnutls matches 1754 # that implied by our platform support matrix 1755 # 1756 # For the crypto backends, we look for a newer 1757 # gnutls: 1758 # 1759 # Version 3.6.8 is needed to get XTS 1760 # Version 3.6.13 is needed to get PBKDF 1761 # Version 3.6.14 is needed to get HW accelerated XTS 1762 # 1763 # If newer enough gnutls isn't available, we can 1764 # still use a different crypto backend to satisfy 1765 # the platform support requirements 1766 gnutls_crypto = dependency('gnutls', version: '>=3.6.14', 1767 method: 'pkg-config', 1768 required: false) 1769 if gnutls_crypto.found() 1770 gnutls = gnutls_crypto 1771 else 1772 # Our min version if all we need is TLS 1773 gnutls = dependency('gnutls', version: '>=3.5.18', 1774 method: 'pkg-config', 1775 required: get_option('gnutls')) 1776 endif 1777 endif 1778 1779 # We prefer use of gnutls for crypto, unless the options 1780 # explicitly asked for nettle or gcrypt. 1781 # 1782 # If gnutls isn't available for crypto, then we'll prefer 1783 # gcrypt over nettle for performance reasons. 1784 gcrypt = not_found 1785 nettle = not_found 1786 hogweed = not_found 1787 crypto_sm4 = not_found 1788 crypto_sm3 = not_found 1789 xts = 'none' 1790 1791 if get_option('nettle').enabled() and get_option('gcrypt').enabled() 1792 error('Only one of gcrypt & nettle can be enabled') 1793 endif 1794 1795 # Explicit nettle/gcrypt request, so ignore gnutls for crypto 1796 if get_option('nettle').enabled() or get_option('gcrypt').enabled() 1797 gnutls_crypto = not_found 1798 endif 1799 1800 if not gnutls_crypto.found() 1801 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled() 1802 gcrypt = dependency('libgcrypt', version: '>=1.8', 1803 required: get_option('gcrypt')) 1804 # Debian has removed -lgpg-error from libgcrypt-config 1805 # as it "spreads unnecessary dependencies" which in 1806 # turn breaks static builds... 1807 if gcrypt.found() and get_option('prefer_static') 1808 gcrypt = declare_dependency(dependencies: 1809 [gcrypt, 1810 cc.find_library('gpg-error', required: true)], 1811 version: gcrypt.version()) 1812 endif 1813 crypto_sm4 = gcrypt 1814 # SM4 ALG is available in libgcrypt >= 1.9 1815 if gcrypt.found() and not cc.links(''' 1816 #include <gcrypt.h> 1817 int main(void) { 1818 gcry_cipher_hd_t handler; 1819 gcry_cipher_open(&handler, GCRY_CIPHER_SM4, GCRY_CIPHER_MODE_ECB, 0); 1820 return 0; 1821 }''', dependencies: gcrypt) 1822 crypto_sm4 = not_found 1823 endif 1824 crypto_sm3 = gcrypt 1825 # SM3 ALG is available in libgcrypt >= 1.9 1826 if gcrypt.found() and not cc.links(''' 1827 #include <gcrypt.h> 1828 int main(void) { 1829 gcry_md_hd_t handler; 1830 gcry_md_open(&handler, GCRY_MD_SM3, 0); 1831 return 0; 1832 }''', dependencies: gcrypt) 1833 crypto_sm3 = not_found 1834 endif 1835 endif 1836 if (not get_option('nettle').auto() or have_system) and not gcrypt.found() 1837 nettle = dependency('nettle', version: '>=3.4', 1838 method: 'pkg-config', 1839 required: get_option('nettle')) 1840 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle) 1841 xts = 'private' 1842 endif 1843 crypto_sm4 = nettle 1844 # SM4 ALG is available in nettle >= 3.9 1845 if nettle.found() and not cc.links(''' 1846 #include <nettle/sm4.h> 1847 int main(void) { 1848 struct sm4_ctx ctx; 1849 unsigned char key[16] = {0}; 1850 sm4_set_encrypt_key(&ctx, key); 1851 return 0; 1852 }''', dependencies: nettle) 1853 crypto_sm4 = not_found 1854 endif 1855 crypto_sm3 = nettle 1856 # SM3 ALG is available in nettle >= 3.8 1857 if nettle.found() and not cc.links(''' 1858 #include <nettle/sm3.h> 1859 #include <nettle/hmac.h> 1860 int main(void) { 1861 struct sm3_ctx ctx; 1862 struct hmac_sm3_ctx hmac_ctx; 1863 unsigned char data[64] = {0}; 1864 unsigned char output[32]; 1865 1866 // SM3 hash function test 1867 sm3_init(&ctx); 1868 sm3_update(&ctx, 64, data); 1869 sm3_digest(&ctx, 32, data); 1870 1871 // HMAC-SM3 test 1872 hmac_sm3_set_key(&hmac_ctx, 32, data); 1873 hmac_sm3_update(&hmac_ctx, 64, data); 1874 hmac_sm3_digest(&hmac_ctx, 32, output); 1875 1876 return 0; 1877 }''', dependencies: nettle) 1878 crypto_sm3 = not_found 1879 endif 1880 endif 1881 endif 1882 1883 capstone = not_found 1884 if not get_option('capstone').auto() or have_system or have_user 1885 capstone = dependency('capstone', version: '>=3.0.5', 1886 method: 'pkg-config', 1887 required: get_option('capstone')) 1888 1889 # Some versions of capstone have broken pkg-config file 1890 # that reports a wrong -I path, causing the #include to 1891 # fail later. If the system has such a broken version 1892 # do not use it. 1893 if capstone.found() and not cc.compiles('#include <capstone.h>', 1894 dependencies: [capstone]) 1895 capstone = not_found 1896 if get_option('capstone').enabled() 1897 error('capstone requested, but it does not appear to work') 1898 endif 1899 endif 1900 endif 1901 1902 gmp = dependency('gmp', required: false, method: 'pkg-config') 1903 if nettle.found() and gmp.found() 1904 hogweed = dependency('hogweed', version: '>=3.4', 1905 method: 'pkg-config', 1906 required: get_option('nettle')) 1907 endif 1908 1909 1910 gtk = not_found 1911 gtkx11 = not_found 1912 vte = not_found 1913 have_gtk_clipboard = get_option('gtk_clipboard').enabled() 1914 1915 if get_option('gtk') \ 1916 .disable_auto_if(not have_system) \ 1917 .require(pixman.found(), 1918 error_message: 'cannot enable GTK if pixman is not available') \ 1919 .allowed() 1920 gtk = dependency('gtk+-3.0', version: '>=3.22.0', 1921 method: 'pkg-config', 1922 required: get_option('gtk')) 1923 if gtk.found() 1924 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0', 1925 method: 'pkg-config', 1926 required: false) 1927 gtk = declare_dependency(dependencies: [gtk, gtkx11], 1928 version: gtk.version()) 1929 1930 if not get_option('vte').auto() or have_system 1931 vte = dependency('vte-2.91', 1932 method: 'pkg-config', 1933 required: get_option('vte')) 1934 endif 1935 elif have_gtk_clipboard 1936 error('GTK clipboard requested, but GTK not found') 1937 endif 1938 endif 1939 1940 x11 = not_found 1941 if gtkx11.found() 1942 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found()) 1943 endif 1944 png = not_found 1945 if get_option('png').allowed() and have_system 1946 png = dependency('libpng', version: '>=1.6.34', required: get_option('png'), 1947 method: 'pkg-config') 1948 endif 1949 vnc = not_found 1950 jpeg = not_found 1951 sasl = not_found 1952 if get_option('vnc') \ 1953 .disable_auto_if(not have_system) \ 1954 .require(pixman.found(), 1955 error_message: 'cannot enable VNC if pixman is not available') \ 1956 .allowed() 1957 vnc = declare_dependency() # dummy dependency 1958 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'), 1959 method: 'pkg-config') 1960 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'], 1961 required: get_option('vnc_sasl')) 1962 if sasl.found() 1963 sasl = declare_dependency(dependencies: sasl, 1964 compile_args: '-DSTRUCT_IOVEC_DEFINED') 1965 endif 1966 endif 1967 1968 pam = not_found 1969 if not get_option('auth_pam').auto() or have_system 1970 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'], 1971 required: get_option('auth_pam')) 1972 endif 1973 if pam.found() and not cc.links(''' 1974 #include <stddef.h> 1975 #include <security/pam_appl.h> 1976 int main(void) { 1977 const char *service_name = "qemu"; 1978 const char *user = "frank"; 1979 const struct pam_conv pam_conv = { 0 }; 1980 pam_handle_t *pamh = NULL; 1981 pam_start(service_name, user, &pam_conv, &pamh); 1982 return 0; 1983 }''', dependencies: pam) 1984 pam = not_found 1985 if get_option('auth_pam').enabled() 1986 error('could not link libpam') 1987 else 1988 warning('could not link libpam, disabling') 1989 endif 1990 endif 1991 1992 snappy = not_found 1993 if not get_option('snappy').auto() or have_system 1994 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'], 1995 required: get_option('snappy')) 1996 endif 1997 if snappy.found() and not cc.links(''' 1998 #include <snappy-c.h> 1999 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy) 2000 snappy = not_found 2001 if get_option('snappy').enabled() 2002 error('could not link libsnappy') 2003 else 2004 warning('could not link libsnappy, disabling') 2005 endif 2006 endif 2007 2008 lzo = not_found 2009 if not get_option('lzo').auto() or have_system 2010 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'], 2011 required: get_option('lzo')) 2012 endif 2013 if lzo.found() and not cc.links(''' 2014 #include <lzo/lzo1x.h> 2015 int main(void) { lzo_version(); return 0; }''', dependencies: lzo) 2016 lzo = not_found 2017 if get_option('lzo').enabled() 2018 error('could not link liblzo2') 2019 else 2020 warning('could not link liblzo2, disabling') 2021 endif 2022 endif 2023 2024 numa = not_found 2025 if not get_option('numa').auto() or have_system or have_tools 2026 numa = cc.find_library('numa', has_headers: ['numa.h'], 2027 required: get_option('numa')) 2028 endif 2029 if numa.found() and not cc.links(''' 2030 #include <numa.h> 2031 int main(void) { return numa_available(); } 2032 ''', dependencies: numa) 2033 numa = not_found 2034 if get_option('numa').enabled() 2035 error('could not link numa') 2036 else 2037 warning('could not link numa, disabling') 2038 endif 2039 endif 2040 2041 fdt = not_found 2042 fdt_opt = get_option('fdt') 2043 if fdt_opt == 'enabled' and get_option('wrap_mode') == 'nodownload' 2044 fdt_opt = 'system' 2045 endif 2046 if fdt_opt in ['enabled', 'system'] or (fdt_opt == 'auto' and have_system) 2047 fdt = cc.find_library('fdt', required: fdt_opt == 'system') 2048 if fdt.found() and cc.links(''' 2049 #include <libfdt.h> 2050 #include <libfdt_env.h> 2051 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''', 2052 dependencies: fdt) 2053 fdt_opt = 'system' 2054 elif fdt_opt != 'system' 2055 fdt_opt = get_option('wrap_mode') == 'nodownload' ? 'disabled' : 'internal' 2056 fdt = not_found 2057 else 2058 error('system libfdt is too old (1.5.1 or newer required)') 2059 endif 2060 endif 2061 if fdt_opt == 'internal' 2062 assert(not fdt.found()) 2063 libfdt_proj = subproject('dtc', required: true, 2064 default_options: ['tools=false', 'yaml=disabled', 2065 'python=disabled', 'default_library=static']) 2066 fdt = libfdt_proj.get_variable('libfdt_dep') 2067 endif 2068 2069 rdma = not_found 2070 if not get_option('rdma').auto() or have_system 2071 rdma_libs = [cc.find_library('rdmacm', has_headers: ['rdma/rdma_cma.h'], 2072 required: get_option('rdma')), 2073 cc.find_library('ibverbs', required: get_option('rdma'))] 2074 rdma = declare_dependency(dependencies: rdma_libs) 2075 foreach lib: rdma_libs 2076 if not lib.found() 2077 rdma = not_found 2078 endif 2079 endforeach 2080 endif 2081 2082 cacard = not_found 2083 if not get_option('smartcard').auto() or have_system 2084 cacard = dependency('libcacard', required: get_option('smartcard'), 2085 version: '>=2.5.1', method: 'pkg-config') 2086 endif 2087 u2f = not_found 2088 if not get_option('u2f').auto() or have_system 2089 u2f = dependency('u2f-emu', required: get_option('u2f'), 2090 method: 'pkg-config') 2091 endif 2092 canokey = not_found 2093 if not get_option('canokey').auto() or have_system 2094 canokey = dependency('canokey-qemu', required: get_option('canokey'), 2095 method: 'pkg-config') 2096 endif 2097 usbredir = not_found 2098 if not get_option('usb_redir').auto() or have_system 2099 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'), 2100 version: '>=0.6', method: 'pkg-config') 2101 endif 2102 libusb = not_found 2103 if not get_option('libusb').auto() or have_system 2104 libusb = dependency('libusb-1.0', required: get_option('libusb'), 2105 version: '>=1.0.13', method: 'pkg-config') 2106 endif 2107 2108 libpmem = not_found 2109 if not get_option('libpmem').auto() or have_system 2110 libpmem = dependency('libpmem', required: get_option('libpmem'), 2111 method: 'pkg-config') 2112 endif 2113 libdaxctl = not_found 2114 if not get_option('libdaxctl').auto() or have_system 2115 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'), 2116 version: '>=57', method: 'pkg-config') 2117 endif 2118 tasn1 = not_found 2119 if gnutls.found() 2120 tasn1 = dependency('libtasn1', 2121 required: false, 2122 method: 'pkg-config') 2123 endif 2124 keyutils = not_found 2125 if not get_option('libkeyutils').auto() or have_block 2126 keyutils = dependency('libkeyutils', required: get_option('libkeyutils'), 2127 method: 'pkg-config') 2128 endif 2129 2130 has_gettid = cc.has_function('gettid') 2131 2132 # libselinux 2133 selinux = dependency('libselinux', 2134 required: get_option('selinux'), 2135 method: 'pkg-config') 2136 2137 # Malloc tests 2138 2139 malloc = [] 2140 if get_option('malloc') == 'system' 2141 has_malloc_trim = \ 2142 get_option('malloc_trim').allowed() and \ 2143 cc.has_function('malloc_trim', prefix: '#include <malloc.h>') 2144 else 2145 has_malloc_trim = false 2146 malloc = cc.find_library(get_option('malloc'), required: true) 2147 endif 2148 if not has_malloc_trim and get_option('malloc_trim').enabled() 2149 if get_option('malloc') == 'system' 2150 error('malloc_trim not available on this platform.') 2151 else 2152 error('malloc_trim not available with non-libc memory allocator') 2153 endif 2154 endif 2155 2156 gnu_source_prefix = ''' 2157 #ifndef _GNU_SOURCE 2158 #define _GNU_SOURCE 2159 #endif 2160 ''' 2161 2162 # Check whether the glibc provides STATX_BASIC_STATS 2163 2164 has_statx = cc.has_header_symbol('sys/stat.h', 'STATX_BASIC_STATS', prefix: gnu_source_prefix) 2165 2166 # Check whether statx() provides mount ID information 2167 2168 has_statx_mnt_id = cc.has_header_symbol('sys/stat.h', 'STATX_MNT_ID', prefix: gnu_source_prefix) 2169 2170 have_vhost_user_blk_server = get_option('vhost_user_blk_server') \ 2171 .require(host_os == 'linux', 2172 error_message: 'vhost_user_blk_server requires linux') \ 2173 .require(have_vhost_user, 2174 error_message: 'vhost_user_blk_server requires vhost-user support') \ 2175 .disable_auto_if(not have_tools and not have_system) \ 2176 .allowed() 2177 2178 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled() 2179 error('Cannot enable fuse-lseek while fuse is disabled') 2180 endif 2181 2182 fuse = dependency('fuse3', required: get_option('fuse'), 2183 version: '>=3.1', method: 'pkg-config') 2184 2185 fuse_lseek = not_found 2186 if get_option('fuse_lseek').allowed() 2187 if fuse.version().version_compare('>=3.8') 2188 # Dummy dependency 2189 fuse_lseek = declare_dependency() 2190 elif get_option('fuse_lseek').enabled() 2191 if fuse.found() 2192 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version()) 2193 else 2194 error('fuse-lseek requires libfuse, which was not found') 2195 endif 2196 endif 2197 endif 2198 2199 have_libvduse = (host_os == 'linux') 2200 if get_option('libvduse').enabled() 2201 if host_os != 'linux' 2202 error('libvduse requires linux') 2203 endif 2204 elif get_option('libvduse').disabled() 2205 have_libvduse = false 2206 endif 2207 2208 have_vduse_blk_export = (have_libvduse and host_os == 'linux') 2209 if get_option('vduse_blk_export').enabled() 2210 if host_os != 'linux' 2211 error('vduse_blk_export requires linux') 2212 elif not have_libvduse 2213 error('vduse_blk_export requires libvduse support') 2214 endif 2215 elif get_option('vduse_blk_export').disabled() 2216 have_vduse_blk_export = false 2217 endif 2218 2219 # libbpf 2220 bpf_version = '1.1.0' 2221 libbpf = dependency('libbpf', version: '>=' + bpf_version, required: get_option('bpf'), method: 'pkg-config') 2222 if libbpf.found() and not cc.links(''' 2223 #include <bpf/libbpf.h> 2224 #include <linux/bpf.h> 2225 int main(void) 2226 { 2227 // check flag availability 2228 int flag = BPF_F_MMAPABLE; 2229 bpf_object__destroy_skeleton(NULL); 2230 return 0; 2231 }''', dependencies: libbpf) 2232 libbpf = not_found 2233 if get_option('bpf').enabled() 2234 error('libbpf skeleton/mmaping test failed') 2235 else 2236 warning('libbpf skeleton/mmaping test failed, disabling') 2237 endif 2238 endif 2239 2240 # libxdp 2241 libxdp = not_found 2242 if not get_option('af_xdp').auto() or have_system 2243 if libbpf.found() 2244 libxdp = dependency('libxdp', required: get_option('af_xdp'), 2245 version: '>=1.4.0', method: 'pkg-config') 2246 else 2247 if get_option('af_xdp').enabled() 2248 error('libxdp requested, but libbpf is not available') 2249 endif 2250 endif 2251 endif 2252 2253 # libdw 2254 libdw = not_found 2255 if not get_option('libdw').auto() or \ 2256 (not get_option('prefer_static') and (have_system or have_user)) 2257 libdw = dependency('libdw', 2258 method: 'pkg-config', 2259 required: get_option('libdw')) 2260 endif 2261 2262 ################# 2263 # config-host.h # 2264 ################# 2265 2266 config_host_data = configuration_data() 2267 2268 config_host_data.set('CONFIG_HAVE_RUST', have_rust) 2269 audio_drivers_selected = [] 2270 if have_system 2271 audio_drivers_available = { 2272 'alsa': alsa.found(), 2273 'coreaudio': coreaudio.found(), 2274 'dsound': dsound.found(), 2275 'jack': jack.found(), 2276 'oss': oss.found(), 2277 'pa': pulse.found(), 2278 'pipewire': pipewire.found(), 2279 'sdl': sdl.found(), 2280 'sndio': sndio.found(), 2281 } 2282 foreach k, v: audio_drivers_available 2283 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v) 2284 endforeach 2285 2286 # Default to native drivers first, OSS second, SDL third 2287 audio_drivers_priority = \ 2288 [ 'pa', 'coreaudio', 'dsound', 'sndio', 'oss' ] + \ 2289 (host_os == 'linux' ? [] : [ 'sdl' ]) 2290 audio_drivers_default = [] 2291 foreach k: audio_drivers_priority 2292 if audio_drivers_available[k] 2293 audio_drivers_default += k 2294 endif 2295 endforeach 2296 2297 foreach k: get_option('audio_drv_list') 2298 if k == 'default' 2299 audio_drivers_selected += audio_drivers_default 2300 elif not audio_drivers_available[k] 2301 error('Audio driver "@0@" not available.'.format(k)) 2302 else 2303 audio_drivers_selected += k 2304 endif 2305 endforeach 2306 endif 2307 config_host_data.set('CONFIG_AUDIO_DRIVERS', 2308 '"' + '", "'.join(audio_drivers_selected) + '", ') 2309 2310 have_host_block_device = (host_os != 'darwin' or 2311 cc.has_header('IOKit/storage/IOMedia.h')) 2312 2313 dbus_display = get_option('dbus_display') \ 2314 .require(gio.version().version_compare('>=2.64'), 2315 error_message: '-display dbus requires glib>=2.64') \ 2316 .require(gdbus_codegen.found(), 2317 error_message: gdbus_codegen_error.format('-display dbus')) \ 2318 .allowed() 2319 2320 have_virtfs = get_option('virtfs') \ 2321 .require(host_os == 'linux' or host_os == 'darwin', 2322 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \ 2323 .require(host_os == 'linux' or cc.has_function('pthread_fchdir_np'), 2324 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \ 2325 .require(host_os == 'darwin' or libattr.found(), 2326 error_message: 'virtio-9p (virtfs) on Linux requires libattr-devel') \ 2327 .disable_auto_if(not have_tools and not have_system) \ 2328 .allowed() 2329 2330 qga_fsfreeze = false 2331 qga_fstrim = false 2332 if host_os == 'linux' 2333 if cc.has_header_symbol('linux/fs.h', 'FIFREEZE') 2334 qga_fsfreeze = true 2335 endif 2336 if cc.has_header_symbol('linux/fs.h', 'FITRIM') 2337 qga_fstrim = true 2338 endif 2339 elif host_os == 'freebsd' and cc.has_header_symbol('ufs/ffs/fs.h', 'UFSSUSPEND') 2340 qga_fsfreeze = true 2341 endif 2342 2343 if get_option('block_drv_ro_whitelist') == '' 2344 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', '') 2345 else 2346 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', 2347 '"' + get_option('block_drv_ro_whitelist').replace(',', '", "') + '", ') 2348 endif 2349 if get_option('block_drv_rw_whitelist') == '' 2350 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', '') 2351 else 2352 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', 2353 '"' + get_option('block_drv_rw_whitelist').replace(',', '", "') + '", ') 2354 endif 2355 2356 foreach k : get_option('trace_backends') 2357 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true) 2358 endforeach 2359 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file')) 2360 config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority')) 2361 if iasl.found() 2362 config_host_data.set_quoted('CONFIG_IASL', iasl.full_path()) 2363 endif 2364 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir')) 2365 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix')) 2366 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir) 2367 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir) 2368 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir) 2369 2370 qemu_firmwarepath = '' 2371 foreach k : get_option('qemu_firmwarepath') 2372 qemu_firmwarepath += '"' + get_option('prefix') / k + '", ' 2373 endforeach 2374 config_host_data.set('CONFIG_QEMU_FIRMWAREPATH', qemu_firmwarepath) 2375 2376 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir')) 2377 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir) 2378 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir')) 2379 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir')) 2380 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir) 2381 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir')) 2382 2383 if enable_modules 2384 config_host_data.set('CONFIG_STAMP', run_command( 2385 meson.current_source_dir() / 'scripts/qemu-stamp.py', 2386 meson.project_version(), get_option('pkgversion'), '--', 2387 meson.current_source_dir() / 'configure', 2388 capture: true, check: true).stdout().strip()) 2389 endif 2390 2391 have_slirp_smbd = get_option('slirp_smbd') \ 2392 .require(host_os != 'windows', error_message: 'Host smbd not supported on this platform.') \ 2393 .allowed() 2394 if have_slirp_smbd 2395 smbd_path = get_option('smbd') 2396 if smbd_path == '' 2397 smbd_path = (host_os == 'sunos' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd') 2398 endif 2399 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path) 2400 endif 2401 2402 config_host_data.set('HOST_' + host_arch.to_upper(), 1) 2403 2404 kvm_targets_c = '""' 2405 if get_option('kvm').allowed() and host_os == 'linux' 2406 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"' 2407 endif 2408 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c) 2409 2410 if get_option('module_upgrades') and not enable_modules 2411 error('Cannot enable module-upgrades as modules are not enabled') 2412 endif 2413 config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades')) 2414 2415 config_host_data.set('CONFIG_ATTR', libattr.found()) 2416 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools')) 2417 config_host_data.set('CONFIG_BRLAPI', brlapi.found()) 2418 config_host_data.set('CONFIG_BSD', host_os in bsd_oses) 2419 config_host_data.set('CONFIG_FREEBSD', host_os == 'freebsd') 2420 config_host_data.set('CONFIG_CAPSTONE', capstone.found()) 2421 config_host_data.set('CONFIG_COCOA', cocoa.found()) 2422 config_host_data.set('CONFIG_DARWIN', host_os == 'darwin') 2423 config_host_data.set('CONFIG_FDT', fdt.found()) 2424 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing')) 2425 config_host_data.set('CONFIG_GCOV', get_option('b_coverage')) 2426 config_host_data.set('CONFIG_LIBUDEV', libudev.found()) 2427 config_host_data.set('CONFIG_LINUX', host_os == 'linux') 2428 config_host_data.set('CONFIG_POSIX', host_os != 'windows') 2429 config_host_data.set('CONFIG_WIN32', host_os == 'windows') 2430 config_host_data.set('CONFIG_LZO', lzo.found()) 2431 config_host_data.set('CONFIG_MPATH', mpathpersist.found()) 2432 config_host_data.set('CONFIG_BLKIO', blkio.found()) 2433 if blkio.found() 2434 config_host_data.set('CONFIG_BLKIO_VHOST_VDPA_FD', 2435 blkio.version().version_compare('>=1.3.0')) 2436 config_host_data.set('CONFIG_BLKIO_WRITE_ZEROS_FUA', 2437 blkio.version().version_compare('>=1.4.0')) 2438 endif 2439 config_host_data.set('CONFIG_CURL', curl.found()) 2440 config_host_data.set('CONFIG_CURSES', curses.found()) 2441 config_host_data.set('CONFIG_GBM', gbm.found()) 2442 config_host_data.set('CONFIG_GIO', gio.found()) 2443 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found()) 2444 if glusterfs.found() 2445 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4')) 2446 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5')) 2447 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6')) 2448 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6')) 2449 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat) 2450 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat) 2451 endif 2452 config_host_data.set('CONFIG_GTK', gtk.found()) 2453 config_host_data.set('CONFIG_VTE', vte.found()) 2454 config_host_data.set('CONFIG_GTK_CLIPBOARD', have_gtk_clipboard) 2455 config_host_data.set('CONFIG_HEXAGON_IDEF_PARSER', get_option('hexagon_idef_parser')) 2456 config_host_data.set('CONFIG_LIBATTR', have_old_libattr) 2457 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found()) 2458 config_host_data.set('CONFIG_EBPF', libbpf.found()) 2459 config_host_data.set('CONFIG_AF_XDP', libxdp.found()) 2460 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found()) 2461 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found()) 2462 config_host_data.set('CONFIG_LIBNFS', libnfs.found()) 2463 config_host_data.set('CONFIG_LIBSSH', libssh.found()) 2464 config_host_data.set('CONFIG_LINUX_AIO', libaio.found()) 2465 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found()) 2466 config_host_data.set('CONFIG_LIBPMEM', libpmem.found()) 2467 config_host_data.set('CONFIG_MODULES', enable_modules) 2468 config_host_data.set('CONFIG_NUMA', numa.found()) 2469 if numa.found() 2470 config_host_data.set('HAVE_NUMA_HAS_PREFERRED_MANY', 2471 cc.has_function('numa_has_preferred_many', 2472 dependencies: numa)) 2473 endif 2474 config_host_data.set('CONFIG_OPENGL', opengl.found()) 2475 config_host_data.set('CONFIG_PLUGIN', get_option('plugins')) 2476 config_host_data.set('CONFIG_RBD', rbd.found()) 2477 config_host_data.set('CONFIG_RDMA', rdma.found()) 2478 config_host_data.set('CONFIG_RELOCATABLE', get_option('relocatable')) 2479 config_host_data.set('CONFIG_SAFESTACK', get_option('safe_stack')) 2480 config_host_data.set('CONFIG_SDL', sdl.found()) 2481 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found()) 2482 config_host_data.set('CONFIG_SECCOMP', seccomp.found()) 2483 if seccomp.found() 2484 config_host_data.set('CONFIG_SECCOMP_SYSRAWRC', seccomp_has_sysrawrc) 2485 endif 2486 config_host_data.set('CONFIG_PIXMAN', pixman.found()) 2487 config_host_data.set('CONFIG_SLIRP', slirp.found()) 2488 config_host_data.set('CONFIG_SNAPPY', snappy.found()) 2489 config_host_data.set('CONFIG_SOLARIS', host_os == 'sunos') 2490 if get_option('tcg').allowed() 2491 config_host_data.set('CONFIG_TCG', 1) 2492 config_host_data.set('CONFIG_TCG_INTERPRETER', tcg_arch == 'tci') 2493 endif 2494 config_host_data.set('CONFIG_TPM', have_tpm) 2495 config_host_data.set('CONFIG_TSAN', get_option('tsan')) 2496 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found()) 2497 config_host_data.set('CONFIG_VDE', vde.found()) 2498 config_host_data.set('CONFIG_VHOST', have_vhost) 2499 config_host_data.set('CONFIG_VHOST_NET', have_vhost_net) 2500 config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user) 2501 config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa) 2502 config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel) 2503 config_host_data.set('CONFIG_VHOST_USER', have_vhost_user) 2504 config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto) 2505 config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa) 2506 config_host_data.set('CONFIG_VMNET', vmnet.found()) 2507 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server) 2508 config_host_data.set('CONFIG_VDUSE_BLK_EXPORT', have_vduse_blk_export) 2509 config_host_data.set('CONFIG_PNG', png.found()) 2510 config_host_data.set('CONFIG_VNC', vnc.found()) 2511 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found()) 2512 config_host_data.set('CONFIG_VNC_SASL', sasl.found()) 2513 if virgl.found() 2514 config_host_data.set('VIRGL_VERSION_MAJOR', virgl.version().split('.')[0]) 2515 endif 2516 config_host_data.set('CONFIG_VIRTFS', have_virtfs) 2517 config_host_data.set('CONFIG_VTE', vte.found()) 2518 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found()) 2519 config_host_data.set('CONFIG_KEYUTILS', keyutils.found()) 2520 config_host_data.set('CONFIG_GETTID', has_gettid) 2521 config_host_data.set('CONFIG_GNUTLS', gnutls.found()) 2522 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found()) 2523 config_host_data.set('CONFIG_TASN1', tasn1.found()) 2524 config_host_data.set('CONFIG_GCRYPT', gcrypt.found()) 2525 config_host_data.set('CONFIG_NETTLE', nettle.found()) 2526 config_host_data.set('CONFIG_CRYPTO_SM4', crypto_sm4.found()) 2527 config_host_data.set('CONFIG_CRYPTO_SM3', crypto_sm3.found()) 2528 config_host_data.set('CONFIG_HOGWEED', hogweed.found()) 2529 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private') 2530 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim) 2531 config_host_data.set('CONFIG_STATX', has_statx) 2532 config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id) 2533 config_host_data.set('CONFIG_ZSTD', zstd.found()) 2534 config_host_data.set('CONFIG_QPL', qpl.found()) 2535 config_host_data.set('CONFIG_UADK', uadk.found()) 2536 config_host_data.set('CONFIG_QATZIP', qatzip.found()) 2537 config_host_data.set('CONFIG_FUSE', fuse.found()) 2538 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found()) 2539 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found()) 2540 if spice_protocol.found() 2541 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0]) 2542 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1]) 2543 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2]) 2544 endif 2545 config_host_data.set('CONFIG_SPICE', spice.found()) 2546 config_host_data.set('CONFIG_X11', x11.found()) 2547 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display) 2548 config_host_data.set('CONFIG_CFI', get_option('cfi')) 2549 config_host_data.set('CONFIG_SELINUX', selinux.found()) 2550 config_host_data.set('CONFIG_XEN_BACKEND', xen.found()) 2551 config_host_data.set('CONFIG_LIBDW', libdw.found()) 2552 if xen.found() 2553 # protect from xen.version() having less than three components 2554 xen_version = xen.version().split('.') + ['0', '0'] 2555 xen_ctrl_version = xen_version[0] + \ 2556 ('0' + xen_version[1]).substring(-2) + \ 2557 ('0' + xen_version[2]).substring(-2) 2558 config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version) 2559 endif 2560 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version())) 2561 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0]) 2562 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1]) 2563 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2]) 2564 2565 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf) 2566 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device) 2567 2568 have_coroutine_pool = get_option('coroutine_pool') 2569 if get_option('debug_stack_usage') and have_coroutine_pool 2570 message('Disabling coroutine pool to measure stack usage') 2571 have_coroutine_pool = false 2572 endif 2573 config_host_data.set('CONFIG_COROUTINE_POOL', have_coroutine_pool) 2574 config_host_data.set('CONFIG_DEBUG_GRAPH_LOCK', get_option('debug_graph_lock')) 2575 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex')) 2576 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage')) 2577 config_host_data.set('CONFIG_DEBUG_TCG', get_option('debug_tcg')) 2578 config_host_data.set('CONFIG_DEBUG_REMAP', get_option('debug_remap')) 2579 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug')) 2580 config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed()) 2581 config_host_data.set('CONFIG_FSFREEZE', qga_fsfreeze) 2582 config_host_data.set('CONFIG_FSTRIM', qga_fstrim) 2583 2584 # has_header 2585 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h')) 2586 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h')) 2587 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h')) 2588 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h')) 2589 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h')) 2590 config_host_data.set('HAVE_OPENAT2_H', cc.has_header('linux/openat2.h')) 2591 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h')) 2592 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h')) 2593 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h')) 2594 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h')) 2595 if host_os == 'windows' 2596 config_host_data.set('HAVE_AFUNIX_H', cc.has_header('afunix.h')) 2597 endif 2598 2599 # has_function 2600 config_host_data.set('CONFIG_CLOSE_RANGE', cc.has_function('close_range')) 2601 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4')) 2602 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime')) 2603 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3')) 2604 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate')) 2605 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate')) 2606 config_host_data.set('CONFIG_GETCPU', cc.has_function('getcpu', prefix: gnu_source_prefix)) 2607 config_host_data.set('CONFIG_SCHED_GETCPU', cc.has_function('sched_getcpu', prefix: '#include <sched.h>')) 2608 # Note that we need to specify prefix: here to avoid incorrectly 2609 # thinking that Windows has posix_memalign() 2610 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>')) 2611 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc')) 2612 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc')) 2613 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign')) 2614 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll')) 2615 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>')) 2616 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np')) 2617 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile')) 2618 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare')) 2619 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs')) 2620 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range')) 2621 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create')) 2622 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range')) 2623 config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs')) 2624 config_host_data.set('HAVE_GLIB_WITH_SLICE_ALLOCATOR', glib_has_gslice) 2625 config_host_data.set('HAVE_GLIB_WITH_ALIGNED_ALLOC', glib_has_aligned_alloc) 2626 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util)) 2627 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul')) 2628 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>')) 2629 if rbd.found() 2630 config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS', 2631 cc.has_function('rbd_namespace_exists', 2632 dependencies: rbd, 2633 prefix: '#include <rbd/librbd.h>')) 2634 endif 2635 if rdma.found() 2636 config_host_data.set('HAVE_IBV_ADVISE_MR', 2637 cc.has_function('ibv_advise_mr', 2638 dependencies: rdma, 2639 prefix: '#include <infiniband/verbs.h>')) 2640 endif 2641 2642 have_asan_fiber = false 2643 if get_option('asan') and \ 2644 not cc.has_function('__sanitizer_start_switch_fiber', 2645 args: '-fsanitize=address', 2646 prefix: '#include <sanitizer/asan_interface.h>') 2647 warning('Missing ASAN due to missing fiber annotation interface') 2648 warning('Without code annotation, the report may be inferior.') 2649 else 2650 have_asan_fiber = true 2651 endif 2652 config_host_data.set('CONFIG_ASAN_IFACE_FIBER', have_asan_fiber) 2653 2654 have_inotify_init = cc.has_header_symbol('sys/inotify.h', 'inotify_init') 2655 have_inotify_init1 = cc.has_header_symbol('sys/inotify.h', 'inotify_init1') 2656 inotify = not_found 2657 if (have_inotify_init or have_inotify_init1) and host_os == 'freebsd' 2658 # libinotify-kqueue 2659 inotify = cc.find_library('inotify') 2660 if have_inotify_init 2661 have_inotify_init = inotify.found() 2662 endif 2663 if have_inotify_init1 2664 have_inotify_init1 = inotify.found() 2665 endif 2666 endif 2667 config_host_data.set('CONFIG_INOTIFY', have_inotify_init) 2668 config_host_data.set('CONFIG_INOTIFY1', have_inotify_init1) 2669 2670 # has_header_symbol 2671 config_host_data.set('CONFIG_BLKZONED', 2672 cc.has_header_symbol('linux/blkzoned.h', 'BLKOPENZONE')) 2673 config_host_data.set('CONFIG_EPOLL_CREATE1', 2674 cc.has_header_symbol('sys/epoll.h', 'epoll_create1')) 2675 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE', 2676 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and 2677 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE')) 2678 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE', 2679 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE')) 2680 config_host_data.set('CONFIG_FIEMAP', 2681 cc.has_header('linux/fiemap.h') and 2682 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP')) 2683 config_host_data.set('CONFIG_GETRANDOM', 2684 cc.has_function('getrandom') and 2685 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK')) 2686 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK', 2687 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK')) 2688 config_host_data.set('CONFIG_RTNETLINK', 2689 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN')) 2690 config_host_data.set('CONFIG_SYSMACROS', 2691 cc.has_header_symbol('sys/sysmacros.h', 'makedev')) 2692 config_host_data.set('HAVE_OPTRESET', 2693 cc.has_header_symbol('getopt.h', 'optreset')) 2694 config_host_data.set('HAVE_IPPROTO_MPTCP', 2695 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP')) 2696 2697 # has_member 2698 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID', 2699 cc.has_member('struct sigevent', 'sigev_notify_thread_id', 2700 prefix: '#include <signal.h>')) 2701 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM', 2702 cc.has_member('struct stat', 'st_atim', 2703 prefix: '#include <sys/stat.h>')) 2704 config_host_data.set('HAVE_BLK_ZONE_REP_CAPACITY', 2705 cc.has_member('struct blk_zone', 'capacity', 2706 prefix: '#include <linux/blkzoned.h>')) 2707 2708 # has_type 2709 config_host_data.set('CONFIG_IOVEC', 2710 cc.has_type('struct iovec', 2711 prefix: '#include <sys/uio.h>')) 2712 config_host_data.set('HAVE_UTMPX', 2713 cc.has_type('struct utmpx', 2714 prefix: '#include <utmpx.h>')) 2715 2716 config_host_data.set('CONFIG_EVENTFD', cc.links(''' 2717 #include <sys/eventfd.h> 2718 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }''')) 2719 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + ''' 2720 #include <unistd.h> 2721 int main(void) { 2722 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0 2723 return fdatasync(0); 2724 #else 2725 #error Not supported 2726 #endif 2727 }''')) 2728 2729 has_madvise = cc.links(gnu_source_prefix + ''' 2730 #include <sys/types.h> 2731 #include <sys/mman.h> 2732 #include <stddef.h> 2733 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''') 2734 missing_madvise_proto = false 2735 if has_madvise 2736 # Some platforms (illumos and Solaris before Solaris 11) provide madvise() 2737 # but forget to prototype it. In this case, has_madvise will be true (the 2738 # test program links despite a compile warning). To detect the 2739 # missing-prototype case, we try again with a definitely-bogus prototype. 2740 # This will only compile if the system headers don't provide the prototype; 2741 # otherwise the conflicting prototypes will cause a compiler error. 2742 missing_madvise_proto = cc.links(gnu_source_prefix + ''' 2743 #include <sys/types.h> 2744 #include <sys/mman.h> 2745 #include <stddef.h> 2746 extern int madvise(int); 2747 int main(void) { return madvise(0); }''') 2748 endif 2749 config_host_data.set('CONFIG_MADVISE', has_madvise) 2750 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto) 2751 2752 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + ''' 2753 #include <sys/mman.h> 2754 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }''')) 2755 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + ''' 2756 #include <fcntl.h> 2757 #if !defined(AT_EMPTY_PATH) 2758 # error missing definition 2759 #else 2760 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); } 2761 #endif''')) 2762 2763 # On Darwin posix_madvise() has the same return semantics as plain madvise(), 2764 # i.e. errno is set and -1 is returned. That's not really how POSIX defines the 2765 # function. On the flip side, it has madvise() which is preferred anyways. 2766 if host_os != 'darwin' 2767 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + ''' 2768 #include <sys/mman.h> 2769 #include <stddef.h> 2770 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }''')) 2771 endif 2772 2773 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + ''' 2774 #include <pthread.h> 2775 2776 static void *f(void *p) { return NULL; } 2777 int main(void) 2778 { 2779 pthread_t thread; 2780 pthread_create(&thread, 0, f, 0); 2781 pthread_setname_np(thread, "QEMU"); 2782 return 0; 2783 }''', dependencies: threads)) 2784 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + ''' 2785 #include <pthread.h> 2786 2787 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; } 2788 int main(void) 2789 { 2790 pthread_t thread; 2791 pthread_create(&thread, 0, f, 0); 2792 return 0; 2793 }''', dependencies: threads)) 2794 config_host_data.set('CONFIG_PTHREAD_SET_NAME_NP', cc.links(gnu_source_prefix + ''' 2795 #include <pthread.h> 2796 #include <pthread_np.h> 2797 2798 static void *f(void *p) { return NULL; } 2799 int main(void) 2800 { 2801 pthread_t thread; 2802 pthread_create(&thread, 0, f, 0); 2803 pthread_set_name_np(thread, "QEMU"); 2804 return 0; 2805 }''', dependencies: threads)) 2806 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + ''' 2807 #include <pthread.h> 2808 #include <time.h> 2809 2810 int main(void) 2811 { 2812 pthread_condattr_t attr 2813 pthread_condattr_init(&attr); 2814 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); 2815 return 0; 2816 }''', dependencies: threads)) 2817 config_host_data.set('CONFIG_PTHREAD_AFFINITY_NP', cc.links(gnu_source_prefix + ''' 2818 #include <pthread.h> 2819 2820 static void *f(void *p) { return NULL; } 2821 int main(void) 2822 { 2823 int setsize = CPU_ALLOC_SIZE(64); 2824 pthread_t thread; 2825 cpu_set_t *cpuset; 2826 pthread_create(&thread, 0, f, 0); 2827 cpuset = CPU_ALLOC(64); 2828 CPU_ZERO_S(setsize, cpuset); 2829 pthread_setaffinity_np(thread, setsize, cpuset); 2830 pthread_getaffinity_np(thread, setsize, cpuset); 2831 CPU_FREE(cpuset); 2832 return 0; 2833 }''', dependencies: threads)) 2834 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + ''' 2835 #include <sys/signalfd.h> 2836 #include <stddef.h> 2837 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }''')) 2838 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + ''' 2839 #include <unistd.h> 2840 #include <fcntl.h> 2841 #include <limits.h> 2842 2843 int main(void) 2844 { 2845 int len, fd = 0; 2846 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK); 2847 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE); 2848 return 0; 2849 }''')) 2850 2851 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + ''' 2852 #include <sys/mman.h> 2853 int main(void) { 2854 return mlockall(MCL_FUTURE); 2855 }''')) 2856 2857 have_l2tpv3 = false 2858 if get_option('l2tpv3').allowed() and have_system 2859 have_l2tpv3 = cc.has_type('struct mmsghdr', 2860 prefix: gnu_source_prefix + ''' 2861 #include <sys/socket.h> 2862 #include <linux/ip.h>''') 2863 endif 2864 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3) 2865 2866 have_netmap = false 2867 if get_option('netmap').allowed() and have_system 2868 have_netmap = cc.compiles(''' 2869 #include <inttypes.h> 2870 #include <net/if.h> 2871 #include <net/netmap.h> 2872 #include <net/netmap_user.h> 2873 #if (NETMAP_API < 11) || (NETMAP_API > 15) 2874 #error 2875 #endif 2876 int main(void) { return 0; }''') 2877 if not have_netmap and get_option('netmap').enabled() 2878 error('Netmap headers not available') 2879 endif 2880 endif 2881 config_host_data.set('CONFIG_NETMAP', have_netmap) 2882 2883 # Work around a system header bug with some kernel/XFS header 2884 # versions where they both try to define 'struct fsxattr': 2885 # xfs headers will not try to redefine structs from linux headers 2886 # if this macro is set. 2887 config_host_data.set('HAVE_FSXATTR', cc.links(''' 2888 #include <linux/fs.h> 2889 struct fsxattr foo; 2890 int main(void) { 2891 return 0; 2892 }''')) 2893 2894 # Some versions of Mac OS X incorrectly define SIZE_MAX 2895 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles(''' 2896 #include <stdint.h> 2897 #include <stdio.h> 2898 int main(void) { 2899 return printf("%zu", SIZE_MAX); 2900 }''', args: ['-Werror'])) 2901 2902 # See if 64-bit atomic operations are supported. 2903 # Note that without __atomic builtins, we can only 2904 # assume atomic loads/stores max at pointer size. 2905 config_host_data.set('CONFIG_ATOMIC64', cc.links(''' 2906 #include <stdint.h> 2907 int main(void) 2908 { 2909 uint64_t x = 0, y = 0; 2910 y = __atomic_load_n(&x, __ATOMIC_RELAXED); 2911 __atomic_store_n(&x, y, __ATOMIC_RELAXED); 2912 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); 2913 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED); 2914 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED); 2915 return 0; 2916 }''', args: qemu_isa_flags)) 2917 2918 has_int128_type = cc.compiles(''' 2919 __int128_t a; 2920 __uint128_t b; 2921 int main(void) { b = a; }''') 2922 config_host_data.set('CONFIG_INT128_TYPE', has_int128_type) 2923 2924 has_int128 = has_int128_type and cc.links(''' 2925 __int128_t a; 2926 __uint128_t b; 2927 int main (void) { 2928 a = a + b; 2929 b = a * b; 2930 a = a * a; 2931 return 0; 2932 }''') 2933 config_host_data.set('CONFIG_INT128', has_int128) 2934 2935 if has_int128_type 2936 # "do we have 128-bit atomics which are handled inline and specifically not 2937 # via libatomic". The reason we can't use libatomic is documented in the 2938 # comment starting "GCC is a house divided" in include/qemu/atomic128.h. 2939 # We only care about these operations on 16-byte aligned pointers, so 2940 # force 16-byte alignment of the pointer, which may be greater than 2941 # __alignof(unsigned __int128) for the host. 2942 atomic_test_128 = ''' 2943 int main(int ac, char **av) { 2944 __uint128_t *p = __builtin_assume_aligned(av[ac - 1], 16); 2945 p[1] = __atomic_load_n(&p[0], __ATOMIC_RELAXED); 2946 __atomic_store_n(&p[2], p[3], __ATOMIC_RELAXED); 2947 __atomic_compare_exchange_n(&p[4], &p[5], p[6], 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); 2948 return 0; 2949 }''' 2950 has_atomic128 = cc.links(atomic_test_128, args: qemu_isa_flags) 2951 2952 config_host_data.set('CONFIG_ATOMIC128', has_atomic128) 2953 2954 if not has_atomic128 2955 # Even with __builtin_assume_aligned, the above test may have failed 2956 # without optimization enabled. Try again with optimizations locally 2957 # enabled for the function. See 2958 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107389 2959 has_atomic128_opt = cc.links('__attribute__((optimize("O1")))' + atomic_test_128, 2960 args: qemu_isa_flags) 2961 config_host_data.set('CONFIG_ATOMIC128_OPT', has_atomic128_opt) 2962 2963 if not has_atomic128_opt 2964 config_host_data.set('CONFIG_CMPXCHG128', cc.links(''' 2965 int main(void) 2966 { 2967 __uint128_t x = 0, y = 0; 2968 __sync_val_compare_and_swap_16(&x, y, x); 2969 return 0; 2970 } 2971 ''', args: qemu_isa_flags)) 2972 endif 2973 endif 2974 endif 2975 2976 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + ''' 2977 #include <sys/auxv.h> 2978 int main(void) { 2979 return getauxval(AT_HWCAP) == 0; 2980 }''')) 2981 2982 config_host_data.set('CONFIG_ELF_AUX_INFO', cc.links(gnu_source_prefix + ''' 2983 #include <sys/auxv.h> 2984 int main(void) { 2985 unsigned long hwcap = 0; 2986 elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); 2987 return hwcap; 2988 }''')) 2989 2990 config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles(''' 2991 #include <linux/usbdevice_fs.h> 2992 2993 #ifndef USBDEVFS_GET_CAPABILITIES 2994 #error "USBDEVFS_GET_CAPABILITIES undefined" 2995 #endif 2996 2997 #ifndef USBDEVFS_DISCONNECT_CLAIM 2998 #error "USBDEVFS_DISCONNECT_CLAIM undefined" 2999 #endif 3000 3001 int main(void) { return 0; }''')) 3002 3003 have_keyring = get_option('keyring') \ 3004 .require(host_os == 'linux', error_message: 'keyring is only available on Linux') \ 3005 .require(cc.compiles(''' 3006 #include <errno.h> 3007 #include <asm/unistd.h> 3008 #include <linux/keyctl.h> 3009 #include <sys/syscall.h> 3010 #include <unistd.h> 3011 int main(void) { 3012 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0); 3013 }'''), error_message: 'keyctl syscall not available on this system').allowed() 3014 config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring) 3015 3016 have_cpuid_h = cc.links(''' 3017 #include <cpuid.h> 3018 int main(void) { 3019 unsigned a, b, c, d; 3020 unsigned max = __get_cpuid_max(0, 0); 3021 3022 if (max >= 1) { 3023 __cpuid(1, a, b, c, d); 3024 } 3025 3026 if (max >= 7) { 3027 __cpuid_count(7, 0, a, b, c, d); 3028 } 3029 3030 return 0; 3031 }''') 3032 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h) 3033 3034 # Don't bother to advertise asm/hwprobe.h for old versions that do 3035 # not contain RISCV_HWPROBE_EXT_ZBA. 3036 config_host_data.set('CONFIG_ASM_HWPROBE_H', 3037 cc.has_header_symbol('asm/hwprobe.h', 3038 'RISCV_HWPROBE_EXT_ZBA')) 3039 3040 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \ 3041 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \ 3042 .require(cc.links(''' 3043 #include <cpuid.h> 3044 #include <immintrin.h> 3045 static int __attribute__((target("avx2"))) bar(void *a) { 3046 __m256i x = *(__m256i *)a; 3047 return _mm256_testz_si256(x, x); 3048 } 3049 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); } 3050 '''), error_message: 'AVX2 not available').allowed()) 3051 3052 config_host_data.set('CONFIG_AVX512BW_OPT', get_option('avx512bw') \ 3053 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512BW') \ 3054 .require(cc.links(''' 3055 #include <cpuid.h> 3056 #include <immintrin.h> 3057 static int __attribute__((target("avx512bw"))) bar(void *a) { 3058 __m512i *x = a; 3059 __m512i res= _mm512_abs_epi8(*x); 3060 return res[1]; 3061 } 3062 int main(int argc, char *argv[]) { return bar(argv[0]); } 3063 '''), error_message: 'AVX512BW not available').allowed()) 3064 3065 # For both AArch64 and AArch32, detect if builtins are available. 3066 config_host_data.set('CONFIG_ARM_AES_BUILTIN', cc.compiles(''' 3067 #include <arm_neon.h> 3068 #ifndef __ARM_FEATURE_AES 3069 __attribute__((target("+crypto"))) 3070 #endif 3071 void foo(uint8x16_t *p) { *p = vaesmcq_u8(*p); } 3072 ''')) 3073 3074 if get_option('membarrier').disabled() 3075 have_membarrier = false 3076 elif host_os == 'windows' 3077 have_membarrier = true 3078 elif host_os == 'linux' 3079 have_membarrier = cc.compiles(''' 3080 #include <linux/membarrier.h> 3081 #include <sys/syscall.h> 3082 #include <unistd.h> 3083 #include <stdlib.h> 3084 int main(void) { 3085 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0); 3086 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0); 3087 exit(0); 3088 }''') 3089 endif 3090 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \ 3091 .require(have_membarrier, error_message: 'membarrier system call not available') \ 3092 .allowed()) 3093 3094 have_afalg = get_option('crypto_afalg') \ 3095 .require(cc.compiles(gnu_source_prefix + ''' 3096 #include <errno.h> 3097 #include <sys/types.h> 3098 #include <sys/socket.h> 3099 #include <linux/if_alg.h> 3100 int main(void) { 3101 int sock; 3102 sock = socket(AF_ALG, SOCK_SEQPACKET, 0); 3103 return sock; 3104 } 3105 '''), error_message: 'AF_ALG requested but could not be detected').allowed() 3106 config_host_data.set('CONFIG_AF_ALG', have_afalg) 3107 3108 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol( 3109 'linux/vm_sockets.h', 'AF_VSOCK', 3110 prefix: '#include <sys/socket.h>', 3111 )) 3112 3113 have_vss = false 3114 have_vss_sdk = false # old xp/2003 SDK 3115 if host_os == 'windows' and 'cpp' in all_languages 3116 have_vss = cxx.compiles(''' 3117 #define __MIDL_user_allocate_free_DEFINED__ 3118 #include <vss.h> 3119 int main(void) { return VSS_CTX_BACKUP; }''') 3120 have_vss_sdk = cxx.has_header('vscoordint.h') 3121 endif 3122 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk) 3123 3124 # Older versions of MinGW do not import _lock_file and _unlock_file properly. 3125 # This was fixed for v6.0.0 with commit b48e3ac8969d. 3126 if host_os == 'windows' 3127 config_host_data.set('HAVE__LOCK_FILE', cc.links(''' 3128 #include <stdio.h> 3129 int main(void) { 3130 _lock_file(NULL); 3131 _unlock_file(NULL); 3132 return 0; 3133 }''', name: '_lock_file and _unlock_file')) 3134 endif 3135 3136 if host_os == 'windows' 3137 mingw_has_setjmp_longjmp = cc.links(''' 3138 #include <setjmp.h> 3139 int main(void) { 3140 /* 3141 * These functions are not available in setjmp header, but may be 3142 * available at link time, from libmingwex.a. 3143 */ 3144 extern int __mingw_setjmp(jmp_buf); 3145 extern void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int); 3146 jmp_buf env; 3147 __mingw_setjmp(env); 3148 __mingw_longjmp(env, 0); 3149 } 3150 ''', name: 'mingw setjmp and longjmp') 3151 3152 if cpu == 'aarch64' and not mingw_has_setjmp_longjmp 3153 error('mingw must provide setjmp/longjmp for windows-arm64') 3154 endif 3155 endif 3156 3157 ######################## 3158 # Target configuration # 3159 ######################## 3160 3161 minikconf = find_program('scripts/minikconf.py') 3162 3163 config_all_accel = {} 3164 config_all_devices = {} 3165 config_devices_mak_list = [] 3166 config_devices_h = {} 3167 config_target_h = {} 3168 config_target_mak = {} 3169 3170 disassemblers = { 3171 'alpha' : ['CONFIG_ALPHA_DIS'], 3172 'avr' : ['CONFIG_AVR_DIS'], 3173 'hexagon' : ['CONFIG_HEXAGON_DIS'], 3174 'hppa' : ['CONFIG_HPPA_DIS'], 3175 'i386' : ['CONFIG_I386_DIS'], 3176 'x86_64' : ['CONFIG_I386_DIS'], 3177 'm68k' : ['CONFIG_M68K_DIS'], 3178 'microblaze' : ['CONFIG_MICROBLAZE_DIS'], 3179 'mips' : ['CONFIG_MIPS_DIS'], 3180 'or1k' : ['CONFIG_OPENRISC_DIS'], 3181 'ppc' : ['CONFIG_PPC_DIS'], 3182 'riscv' : ['CONFIG_RISCV_DIS'], 3183 'rx' : ['CONFIG_RX_DIS'], 3184 's390' : ['CONFIG_S390_DIS'], 3185 'sh4' : ['CONFIG_SH4_DIS'], 3186 'sparc' : ['CONFIG_SPARC_DIS'], 3187 'xtensa' : ['CONFIG_XTENSA_DIS'], 3188 'loongarch' : ['CONFIG_LOONGARCH_DIS'], 3189 } 3190 3191 have_ivshmem = config_host_data.get('CONFIG_EVENTFD') 3192 host_kconfig = \ 3193 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \ 3194 (have_tpm ? ['CONFIG_TPM=y'] : []) + \ 3195 (pixman.found() ? ['CONFIG_PIXMAN=y'] : []) + \ 3196 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \ 3197 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \ 3198 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \ 3199 (libcbor.found() ? ['CONFIG_LIBCBOR=y'] : []) + \ 3200 (gnutls.found() ? ['CONFIG_GNUTLS=y'] : []) + \ 3201 (x11.found() ? ['CONFIG_X11=y'] : []) + \ 3202 (fdt.found() ? ['CONFIG_FDT=y'] : []) + \ 3203 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \ 3204 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \ 3205 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \ 3206 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \ 3207 (host_os == 'linux' ? ['CONFIG_LINUX=y'] : []) + \ 3208 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \ 3209 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : []) + \ 3210 (hv_balloon ? ['CONFIG_HV_BALLOON_POSSIBLE=y'] : []) + \ 3211 (have_rust ? ['CONFIG_HAVE_RUST=y'] : []) 3212 3213 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ] 3214 3215 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host 3216 actual_target_dirs = [] 3217 fdt_required = [] 3218 foreach target : target_dirs 3219 config_target = { 'TARGET_NAME': target.split('-')[0] } 3220 if target.endswith('linux-user') 3221 if host_os != 'linux' 3222 if default_targets 3223 continue 3224 endif 3225 error('Target @0@ is only available on a Linux host'.format(target)) 3226 endif 3227 config_target += { 'CONFIG_LINUX_USER': 'y' } 3228 elif target.endswith('bsd-user') 3229 if host_os not in bsd_oses 3230 if default_targets 3231 continue 3232 endif 3233 error('Target @0@ is only available on a BSD host'.format(target)) 3234 endif 3235 config_target += { 'CONFIG_BSD_USER': 'y' } 3236 elif target.endswith('softmmu') 3237 config_target += { 'CONFIG_SYSTEM_ONLY': 'y' } 3238 config_target += { 'CONFIG_SOFTMMU': 'y' } 3239 endif 3240 if target.endswith('-user') 3241 config_target += { 3242 'CONFIG_USER_ONLY': 'y', 3243 'CONFIG_QEMU_INTERP_PREFIX': 3244 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME']), 3245 'CONFIG_QEMU_RTSIG_MAP': get_option('rtsig_map'), 3246 } 3247 endif 3248 3249 target_kconfig = [] 3250 foreach sym: accelerators 3251 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, []) 3252 config_target += { sym: 'y' } 3253 config_all_accel += { sym: 'y' } 3254 if target in modular_tcg 3255 config_target += { 'CONFIG_TCG_MODULAR': 'y' } 3256 else 3257 config_target += { 'CONFIG_TCG_BUILTIN': 'y' } 3258 endif 3259 target_kconfig += [ sym + '=y' ] 3260 endif 3261 endforeach 3262 if target_kconfig.length() == 0 3263 if default_targets 3264 continue 3265 endif 3266 error('No accelerator available for target @0@'.format(target)) 3267 endif 3268 3269 config_target += keyval.load('configs/targets' / target + '.mak') 3270 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' } 3271 3272 if 'TARGET_NEED_FDT' in config_target and not fdt.found() 3273 if default_targets 3274 warning('Disabling ' + target + ' due to missing libfdt') 3275 else 3276 fdt_required += target 3277 endif 3278 continue 3279 endif 3280 3281 actual_target_dirs += target 3282 3283 # Add default keys 3284 if 'TARGET_BASE_ARCH' not in config_target 3285 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']} 3286 endif 3287 if 'TARGET_ABI_DIR' not in config_target 3288 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']} 3289 endif 3290 if 'TARGET_BIG_ENDIAN' not in config_target 3291 config_target += {'TARGET_BIG_ENDIAN': 'n'} 3292 endif 3293 3294 foreach k, v: disassemblers 3295 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k) 3296 foreach sym: v 3297 config_target += { sym: 'y' } 3298 endforeach 3299 endif 3300 endforeach 3301 3302 config_target_data = configuration_data() 3303 foreach k, v: config_target 3304 if not k.startswith('TARGET_') and not k.startswith('CONFIG_') 3305 # do nothing 3306 elif ignored.contains(k) 3307 # do nothing 3308 elif k == 'TARGET_BASE_ARCH' 3309 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is 3310 # not used to select files from sourcesets. 3311 config_target_data.set('TARGET_' + v.to_upper(), 1) 3312 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX' 3313 config_target_data.set_quoted(k, v) 3314 elif v == 'y' 3315 config_target_data.set(k, 1) 3316 elif v == 'n' 3317 config_target_data.set(k, 0) 3318 else 3319 config_target_data.set(k, v) 3320 endif 3321 endforeach 3322 config_target_data.set('QEMU_ARCH', 3323 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper()) 3324 config_target_h += {target: configure_file(output: target + '-config-target.h', 3325 configuration: config_target_data)} 3326 3327 if target.endswith('-softmmu') 3328 target_kconfig += 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y' 3329 target_kconfig += 'CONFIG_TARGET_BIG_ENDIAN=' + config_target['TARGET_BIG_ENDIAN'] 3330 3331 config_input = meson.get_external_property(target, 'default') 3332 config_devices_mak = target + '-config-devices.mak' 3333 config_devices_mak = configure_file( 3334 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'], 3335 output: config_devices_mak, 3336 depfile: config_devices_mak + '.d', 3337 capture: true, 3338 command: [minikconf, 3339 get_option('default_devices') ? '--defconfig' : '--allnoconfig', 3340 config_devices_mak, '@DEPFILE@', '@INPUT@', 3341 host_kconfig, target_kconfig]) 3342 3343 config_devices_data = configuration_data() 3344 config_devices = keyval.load(config_devices_mak) 3345 foreach k, v: config_devices 3346 config_devices_data.set(k, 1) 3347 endforeach 3348 config_devices_mak_list += config_devices_mak 3349 config_devices_h += {target: configure_file(output: target + '-config-devices.h', 3350 configuration: config_devices_data)} 3351 config_target += config_devices 3352 config_all_devices += config_devices 3353 endif 3354 config_target_mak += {target: config_target} 3355 endforeach 3356 target_dirs = actual_target_dirs 3357 3358 target_configs_h = [] 3359 foreach target: target_dirs 3360 target_configs_h += config_target_h[target] 3361 target_configs_h += config_devices_h.get(target, []) 3362 endforeach 3363 genh += custom_target('config-poison.h', 3364 input: [target_configs_h], 3365 output: 'config-poison.h', 3366 capture: true, 3367 command: [find_program('scripts/make-config-poison.sh'), 3368 target_configs_h]) 3369 3370 if fdt_required.length() > 0 3371 error('fdt disabled but required by targets ' + ', '.join(fdt_required)) 3372 endif 3373 3374 ############### 3375 # Subprojects # 3376 ############### 3377 3378 libvfio_user_dep = not_found 3379 if have_system and vfio_user_server_allowed 3380 libvfio_user_proj = subproject('libvfio-user', required: true) 3381 libvfio_user_dep = libvfio_user_proj.get_variable('libvfio_user_dep') 3382 endif 3383 3384 vhost_user = not_found 3385 if host_os == 'linux' and have_vhost_user 3386 libvhost_user = subproject('libvhost-user') 3387 vhost_user = libvhost_user.get_variable('vhost_user_dep') 3388 endif 3389 3390 libvduse = not_found 3391 if have_libvduse 3392 libvduse_proj = subproject('libvduse') 3393 libvduse = libvduse_proj.get_variable('libvduse_dep') 3394 endif 3395 3396 ##################### 3397 # Generated sources # 3398 ##################### 3399 3400 genh += configure_file(output: 'config-host.h', configuration: config_host_data) 3401 3402 if have_rust 3403 rustc_args = run_command( 3404 find_program('scripts/rust/rustc_args.py'), 3405 '--config-headers', meson.project_build_root() / 'config-host.h', 3406 capture : true, 3407 check: true).stdout().strip().split() 3408 3409 # Prohibit code that is forbidden in Rust 2024 3410 rustc_args += ['-D', 'unsafe_op_in_unsafe_fn'] 3411 3412 # Occasionally, we may need to silence warnings and clippy lints that 3413 # were only introduced in newer Rust compiler versions. Do not croak 3414 # in that case; a CI job with rust_strict_lints == true ensures that 3415 # we do not have misspelled allow() attributes. 3416 if not get_option('strict_rust_lints') 3417 rustc_args += ['-A', 'unknown_lints'] 3418 endif 3419 3420 # Apart from procedural macros, our Rust executables will often link 3421 # with C code, so include all the libraries that C code needs. This 3422 # is safe; https://github.com/rust-lang/rust/pull/54675 says that 3423 # passing -nodefaultlibs to the linker "was more ideological to 3424 # start with than anything". 3425 add_project_arguments(rustc_args + ['-C', 'default-linker-libraries'], 3426 native: false, language: 'rust') 3427 3428 add_project_arguments(rustc_args, native: true, language: 'rust') 3429 endif 3430 3431 hxtool = find_program('scripts/hxtool') 3432 shaderinclude = find_program('scripts/shaderinclude.py') 3433 qapi_gen = find_program('scripts/qapi-gen.py') 3434 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py', 3435 meson.current_source_dir() / 'scripts/qapi/commands.py', 3436 meson.current_source_dir() / 'scripts/qapi/common.py', 3437 meson.current_source_dir() / 'scripts/qapi/error.py', 3438 meson.current_source_dir() / 'scripts/qapi/events.py', 3439 meson.current_source_dir() / 'scripts/qapi/expr.py', 3440 meson.current_source_dir() / 'scripts/qapi/gen.py', 3441 meson.current_source_dir() / 'scripts/qapi/introspect.py', 3442 meson.current_source_dir() / 'scripts/qapi/main.py', 3443 meson.current_source_dir() / 'scripts/qapi/parser.py', 3444 meson.current_source_dir() / 'scripts/qapi/schema.py', 3445 meson.current_source_dir() / 'scripts/qapi/source.py', 3446 meson.current_source_dir() / 'scripts/qapi/types.py', 3447 meson.current_source_dir() / 'scripts/qapi/visit.py', 3448 meson.current_source_dir() / 'scripts/qapi-gen.py' 3449 ] 3450 3451 tracetool = [ 3452 python, files('scripts/tracetool.py'), 3453 '--backend=' + ','.join(get_option('trace_backends')) 3454 ] 3455 tracetool_depends = files( 3456 'scripts/tracetool/backend/log.py', 3457 'scripts/tracetool/backend/__init__.py', 3458 'scripts/tracetool/backend/dtrace.py', 3459 'scripts/tracetool/backend/ftrace.py', 3460 'scripts/tracetool/backend/simple.py', 3461 'scripts/tracetool/backend/syslog.py', 3462 'scripts/tracetool/backend/ust.py', 3463 'scripts/tracetool/format/ust_events_c.py', 3464 'scripts/tracetool/format/ust_events_h.py', 3465 'scripts/tracetool/format/__init__.py', 3466 'scripts/tracetool/format/d.py', 3467 'scripts/tracetool/format/simpletrace_stap.py', 3468 'scripts/tracetool/format/c.py', 3469 'scripts/tracetool/format/h.py', 3470 'scripts/tracetool/format/log_stap.py', 3471 'scripts/tracetool/format/stap.py', 3472 'scripts/tracetool/__init__.py', 3473 ) 3474 3475 qemu_version_cmd = [find_program('scripts/qemu-version.sh'), 3476 meson.current_source_dir(), 3477 get_option('pkgversion'), meson.project_version()] 3478 qemu_version = custom_target('qemu-version.h', 3479 output: 'qemu-version.h', 3480 command: qemu_version_cmd, 3481 capture: true, 3482 build_by_default: true, 3483 build_always_stale: true) 3484 genh += qemu_version 3485 3486 hxdep = [] 3487 hx_headers = [ 3488 ['qemu-options.hx', 'qemu-options.def'], 3489 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'], 3490 ] 3491 if have_system 3492 hx_headers += [ 3493 ['hmp-commands.hx', 'hmp-commands.h'], 3494 ['hmp-commands-info.hx', 'hmp-commands-info.h'], 3495 ] 3496 endif 3497 foreach d : hx_headers 3498 hxdep += custom_target(d[1], 3499 input: files(d[0]), 3500 output: d[1], 3501 capture: true, 3502 command: [hxtool, '-h', '@INPUT0@']) 3503 endforeach 3504 genh += hxdep 3505 3506 ############### 3507 # Trace files # 3508 ############### 3509 3510 # TODO: add each directory to the subdirs from its own meson.build, once 3511 # we have those 3512 trace_events_subdirs = [ 3513 'crypto', 3514 'qapi', 3515 'qom', 3516 'monitor', 3517 'util', 3518 'gdbstub', 3519 ] 3520 if have_linux_user 3521 trace_events_subdirs += [ 'linux-user' ] 3522 endif 3523 if have_bsd_user 3524 trace_events_subdirs += [ 'bsd-user' ] 3525 endif 3526 if have_block 3527 trace_events_subdirs += [ 3528 'authz', 3529 'block', 3530 'chardev', 3531 'io', 3532 'nbd', 3533 'scsi', 3534 ] 3535 endif 3536 if have_system 3537 trace_events_subdirs += [ 3538 'accel/kvm', 3539 'audio', 3540 'backends', 3541 'backends/tpm', 3542 'ebpf', 3543 'hw/9pfs', 3544 'hw/acpi', 3545 'hw/adc', 3546 'hw/alpha', 3547 'hw/arm', 3548 'hw/audio', 3549 'hw/block', 3550 'hw/char', 3551 'hw/display', 3552 'hw/dma', 3553 'hw/fsi', 3554 'hw/hyperv', 3555 'hw/i2c', 3556 'hw/i3c', 3557 'hw/i386', 3558 'hw/i386/xen', 3559 'hw/i386/kvm', 3560 'hw/ide', 3561 'hw/input', 3562 'hw/intc', 3563 'hw/isa', 3564 'hw/mem', 3565 'hw/mips', 3566 'hw/misc', 3567 'hw/misc/macio', 3568 'hw/net', 3569 'hw/net/can', 3570 'hw/nubus', 3571 'hw/nvme', 3572 'hw/nvram', 3573 'hw/pci', 3574 'hw/pci-host', 3575 'hw/ppc', 3576 'hw/rtc', 3577 'hw/riscv', 3578 'hw/s390x', 3579 'hw/scsi', 3580 'hw/sd', 3581 'hw/sensor', 3582 'hw/sh4', 3583 'hw/sparc', 3584 'hw/sparc64', 3585 'hw/ssi', 3586 'hw/timer', 3587 'hw/tpm', 3588 'hw/ufs', 3589 'hw/usb', 3590 'hw/vfio', 3591 'hw/virtio', 3592 'hw/watchdog', 3593 'hw/xen', 3594 'hw/gpio', 3595 'migration', 3596 'net', 3597 'system', 3598 'ui', 3599 'hw/remote', 3600 ] 3601 endif 3602 if have_system or have_user 3603 trace_events_subdirs += [ 3604 'accel/tcg', 3605 'hw/core', 3606 'target/arm', 3607 'target/arm/hvf', 3608 'target/hppa', 3609 'target/i386', 3610 'target/i386/kvm', 3611 'target/loongarch', 3612 'target/mips/tcg', 3613 'target/ppc', 3614 'target/riscv', 3615 'target/s390x', 3616 'target/s390x/kvm', 3617 'target/sparc', 3618 ] 3619 endif 3620 3621 ################### 3622 # Collect sources # 3623 ################### 3624 3625 authz_ss = ss.source_set() 3626 blockdev_ss = ss.source_set() 3627 block_ss = ss.source_set() 3628 chardev_ss = ss.source_set() 3629 common_ss = ss.source_set() 3630 crypto_ss = ss.source_set() 3631 hwcore_ss = ss.source_set() 3632 io_ss = ss.source_set() 3633 qmp_ss = ss.source_set() 3634 qom_ss = ss.source_set() 3635 system_ss = ss.source_set() 3636 specific_fuzz_ss = ss.source_set() 3637 specific_ss = ss.source_set() 3638 rust_devices_ss = ss.source_set() 3639 stub_ss = ss.source_set() 3640 trace_ss = ss.source_set() 3641 user_ss = ss.source_set() 3642 util_ss = ss.source_set() 3643 3644 # accel modules 3645 qtest_module_ss = ss.source_set() 3646 tcg_module_ss = ss.source_set() 3647 3648 modules = {} 3649 target_modules = {} 3650 hw_arch = {} 3651 target_arch = {} 3652 target_system_arch = {} 3653 target_user_arch = {} 3654 3655 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable 3656 # that is filled in by qapi/. 3657 subdir('qapi') 3658 subdir('qobject') 3659 subdir('stubs') 3660 subdir('trace') 3661 subdir('util') 3662 subdir('qom') 3663 subdir('authz') 3664 subdir('crypto') 3665 subdir('ui') 3666 subdir('gdbstub') 3667 if have_system 3668 subdir('hw') 3669 else 3670 subdir('hw/core') 3671 endif 3672 3673 if enable_modules 3674 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO') 3675 modulecommon = declare_dependency(objects: libmodulecommon.extract_all_objects(recursive: false), compile_args: '-DBUILD_DSO') 3676 endif 3677 3678 qom_ss = qom_ss.apply({}) 3679 libqom = static_library('qom', qom_ss.sources() + genh, 3680 dependencies: [qom_ss.dependencies()], 3681 build_by_default: false) 3682 qom = declare_dependency(objects: libqom.extract_all_objects(recursive: false), 3683 dependencies: qom_ss.dependencies()) 3684 3685 event_loop_base = files('event-loop-base.c') 3686 event_loop_base = static_library('event-loop-base', 3687 sources: event_loop_base + genh, 3688 build_by_default: false) 3689 event_loop_base = declare_dependency(objects: event_loop_base.extract_all_objects(recursive: false), 3690 dependencies: [qom]) 3691 3692 stub_ss = stub_ss.apply({}) 3693 3694 util_ss.add_all(trace_ss) 3695 util_ss = util_ss.apply({}) 3696 libqemuutil = static_library('qemuutil', 3697 build_by_default: false, 3698 sources: util_ss.sources() + stub_ss.sources() + genh, 3699 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc]) 3700 qemuutil = declare_dependency(link_with: libqemuutil, 3701 sources: genh + version_res, 3702 dependencies: [event_loop_base]) 3703 3704 if have_system or have_user 3705 decodetree = generator(find_program('scripts/decodetree.py'), 3706 output: 'decode-@BASENAME@.c.inc', 3707 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@']) 3708 subdir('libdecnumber') 3709 subdir('target') 3710 endif 3711 3712 subdir('audio') 3713 subdir('io') 3714 subdir('chardev') 3715 subdir('fsdev') 3716 subdir('dump') 3717 3718 if have_block 3719 block_ss.add(files( 3720 'block.c', 3721 'blockjob.c', 3722 'job.c', 3723 'qemu-io-cmds.c', 3724 )) 3725 if config_host_data.get('CONFIG_REPLICATION') 3726 block_ss.add(files('replication.c')) 3727 endif 3728 3729 subdir('nbd') 3730 subdir('scsi') 3731 subdir('block') 3732 3733 blockdev_ss.add(files( 3734 'blockdev.c', 3735 'blockdev-nbd.c', 3736 'iothread.c', 3737 'job-qmp.c', 3738 )) 3739 3740 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon, 3741 # os-win32.c does not 3742 if host_os == 'windows' 3743 system_ss.add(files('os-win32.c')) 3744 else 3745 blockdev_ss.add(files('os-posix.c')) 3746 endif 3747 endif 3748 3749 common_ss.add(files('cpu-common.c')) 3750 specific_ss.add(files('cpu-target.c')) 3751 3752 subdir('system') 3753 3754 # Work around a gcc bug/misfeature wherein constant propagation looks 3755 # through an alias: 3756 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696 3757 # to guess that a const variable is always zero. Without lto, this is 3758 # impossible, as the alias is restricted to page-vary-common.c. Indeed, 3759 # without lto, not even the alias is required -- we simply use different 3760 # declarations in different compilation units. 3761 pagevary = files('page-vary-common.c') 3762 if get_option('b_lto') 3763 pagevary_flags = ['-fno-lto'] 3764 if get_option('cfi') 3765 pagevary_flags += '-fno-sanitize=cfi-icall' 3766 endif 3767 pagevary = static_library('page-vary-common', sources: pagevary + genh, 3768 c_args: pagevary_flags) 3769 pagevary = declare_dependency(link_with: pagevary) 3770 endif 3771 common_ss.add(pagevary) 3772 specific_ss.add(files('page-target.c', 'page-vary-target.c')) 3773 3774 subdir('backends') 3775 subdir('disas') 3776 subdir('migration') 3777 subdir('monitor') 3778 subdir('net') 3779 subdir('replay') 3780 subdir('semihosting') 3781 subdir('stats') 3782 subdir('tcg') 3783 subdir('fpu') 3784 subdir('accel') 3785 subdir('plugins') 3786 subdir('ebpf') 3787 3788 if 'CONFIG_TCG' in config_all_accel 3789 subdir('contrib/plugins') 3790 endif 3791 3792 common_user_inc = [] 3793 3794 subdir('common-user') 3795 subdir('bsd-user') 3796 subdir('linux-user') 3797 3798 # needed for fuzzing binaries 3799 subdir('tests/qtest/libqos') 3800 subdir('tests/qtest/fuzz') 3801 3802 # accel modules 3803 tcg_real_module_ss = ss.source_set() 3804 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss) 3805 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss) 3806 target_modules += { 'accel' : { 'qtest': qtest_module_ss, 3807 'tcg': tcg_real_module_ss }} 3808 3809 ############################################## 3810 # Internal static_libraries and dependencies # 3811 ############################################## 3812 3813 modinfo_collect = find_program('scripts/modinfo-collect.py') 3814 modinfo_generate = find_program('scripts/modinfo-generate.py') 3815 modinfo_files = [] 3816 3817 block_mods = [] 3818 system_mods = [] 3819 emulator_modules = [] 3820 foreach d, list : modules 3821 if not (d == 'block' ? have_block : have_system) 3822 continue 3823 endif 3824 3825 foreach m, module_ss : list 3826 if enable_modules 3827 module_ss.add(modulecommon) 3828 module_ss = module_ss.apply(config_all_devices, strict: false) 3829 sl = static_library(d + '-' + m, [genh, module_ss.sources()], 3830 dependencies: module_ss.dependencies(), pic: true) 3831 if d == 'block' 3832 block_mods += sl 3833 else 3834 system_mods += sl 3835 endif 3836 emulator_modules += shared_module(sl.name(), 3837 name_prefix: '', 3838 objects: sl.extract_all_objects(recursive: false), 3839 dependencies: module_ss.dependencies(), 3840 install: true, 3841 install_dir: qemu_moddir) 3842 if module_ss.sources() != [] 3843 # FIXME: Should use sl.extract_all_objects(recursive: true) as 3844 # input. Sources can be used multiple times but objects are 3845 # unique when it comes to lookup in compile_commands.json. 3846 # Depnds on a mesion version with 3847 # https://github.com/mesonbuild/meson/pull/8900 3848 modinfo_files += custom_target(d + '-' + m + '.modinfo', 3849 output: d + '-' + m + '.modinfo', 3850 input: module_ss.sources() + genh, 3851 capture: true, 3852 command: [modinfo_collect, module_ss.sources()]) 3853 endif 3854 else 3855 if d == 'block' 3856 block_ss.add_all(module_ss) 3857 else 3858 system_ss.add_all(module_ss) 3859 endif 3860 endif 3861 endforeach 3862 endforeach 3863 3864 foreach d, list : target_modules 3865 foreach m, module_ss : list 3866 if enable_modules 3867 module_ss.add(modulecommon) 3868 foreach target : target_dirs 3869 if target.endswith('-softmmu') 3870 config_target = config_target_mak[target] 3871 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 3872 c_args = ['-DCOMPILING_PER_TARGET', 3873 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 3874 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 3875 target_module_ss = module_ss.apply(config_target, strict: false) 3876 if target_module_ss.sources() != [] 3877 module_name = d + '-' + m + '-' + config_target['TARGET_NAME'] 3878 sl = static_library(module_name, 3879 [genh, target_module_ss.sources()], 3880 dependencies: target_module_ss.dependencies(), 3881 include_directories: target_inc, 3882 c_args: c_args, 3883 pic: true) 3884 system_mods += sl 3885 emulator_modules += shared_module(sl.name(), 3886 name_prefix: '', 3887 objects: sl.extract_all_objects(recursive: false), 3888 dependencies: target_module_ss.dependencies(), 3889 install: true, 3890 install_dir: qemu_moddir) 3891 # FIXME: Should use sl.extract_all_objects(recursive: true) too. 3892 modinfo_files += custom_target(module_name + '.modinfo', 3893 output: module_name + '.modinfo', 3894 input: target_module_ss.sources() + genh, 3895 capture: true, 3896 command: [modinfo_collect, '--target', target, target_module_ss.sources()]) 3897 endif 3898 endif 3899 endforeach 3900 else 3901 specific_ss.add_all(module_ss) 3902 endif 3903 endforeach 3904 endforeach 3905 3906 if enable_modules 3907 foreach target : target_dirs 3908 if target.endswith('-softmmu') 3909 config_target = config_target_mak[target] 3910 config_devices_mak = target + '-config-devices.mak' 3911 modinfo_src = custom_target('modinfo-' + target + '.c', 3912 output: 'modinfo-' + target + '.c', 3913 input: modinfo_files, 3914 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'], 3915 capture: true) 3916 3917 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src) 3918 modinfo_dep = declare_dependency(link_with: modinfo_lib) 3919 3920 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH'] 3921 hw_arch[arch].add(modinfo_dep) 3922 endif 3923 endforeach 3924 3925 if emulator_modules.length() > 0 3926 alias_target('modules', emulator_modules) 3927 endif 3928 endif 3929 3930 nm = find_program('nm') 3931 undefsym = find_program('scripts/undefsym.py') 3932 block_syms = custom_target('block.syms', output: 'block.syms', 3933 input: [libqemuutil, block_mods], 3934 capture: true, 3935 command: [undefsym, nm, '@INPUT@']) 3936 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms', 3937 input: [libqemuutil, system_mods], 3938 capture: true, 3939 command: [undefsym, nm, '@INPUT@']) 3940 3941 authz_ss = authz_ss.apply({}) 3942 libauthz = static_library('authz', authz_ss.sources() + genh, 3943 dependencies: [authz_ss.dependencies()], 3944 build_by_default: false) 3945 3946 authz = declare_dependency(objects: libauthz.extract_all_objects(recursive: false), 3947 dependencies: [authz_ss.dependencies(), qom]) 3948 3949 crypto_ss = crypto_ss.apply({}) 3950 libcrypto = static_library('crypto', crypto_ss.sources() + genh, 3951 dependencies: [crypto_ss.dependencies()], 3952 build_by_default: false) 3953 3954 crypto = declare_dependency(objects: libcrypto.extract_all_objects(recursive: false), 3955 dependencies: [crypto_ss.dependencies(), authz, qom]) 3956 3957 io_ss = io_ss.apply({}) 3958 libio = static_library('io', io_ss.sources() + genh, 3959 dependencies: [io_ss.dependencies()], 3960 link_with: libqemuutil, 3961 build_by_default: false) 3962 3963 io = declare_dependency(objects: libio.extract_all_objects(recursive: false), 3964 dependencies: [io_ss.dependencies(), crypto, qom]) 3965 3966 libmigration = static_library('migration', sources: migration_files + genh, 3967 build_by_default: false) 3968 migration = declare_dependency(objects: libmigration.extract_all_objects(recursive: false), 3969 dependencies: [qom, io]) 3970 system_ss.add(migration) 3971 3972 block_ss = block_ss.apply({}) 3973 libblock = static_library('block', block_ss.sources() + genh, 3974 dependencies: block_ss.dependencies(), 3975 build_by_default: false) 3976 3977 block = declare_dependency(objects: libblock.extract_all_objects(recursive: false), 3978 dependencies: [block_ss.dependencies(), crypto, io]) 3979 3980 blockdev_ss = blockdev_ss.apply({}) 3981 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh, 3982 dependencies: blockdev_ss.dependencies(), 3983 build_by_default: false) 3984 3985 blockdev = declare_dependency(objects: libblockdev.extract_all_objects(recursive: false), 3986 dependencies: [blockdev_ss.dependencies(), block, event_loop_base]) 3987 3988 qmp_ss = qmp_ss.apply({}) 3989 libqmp = static_library('qmp', qmp_ss.sources() + genh, 3990 dependencies: qmp_ss.dependencies(), 3991 build_by_default: false) 3992 3993 qmp = declare_dependency(objects: libqmp.extract_all_objects(recursive: false), 3994 dependencies: qmp_ss.dependencies()) 3995 3996 libchardev = static_library('chardev', chardev_ss.sources() + genh, 3997 dependencies: chardev_ss.dependencies(), 3998 build_by_default: false) 3999 4000 chardev = declare_dependency(objects: libchardev.extract_all_objects(recursive: false), 4001 dependencies: chardev_ss.dependencies()) 4002 4003 hwcore_ss = hwcore_ss.apply({}) 4004 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh, 4005 build_by_default: false) 4006 hwcore = declare_dependency(objects: libhwcore.extract_all_objects(recursive: false)) 4007 common_ss.add(hwcore) 4008 4009 ########### 4010 # Targets # 4011 ########### 4012 4013 system_ss.add(authz, blockdev, chardev, crypto, io, qmp) 4014 common_ss.add(qom, qemuutil) 4015 4016 common_ss.add_all(when: 'CONFIG_SYSTEM_ONLY', if_true: [system_ss]) 4017 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss) 4018 4019 # Note that this library is never used directly (only through extract_objects) 4020 # and is not built by default; therefore, source files not used by the build 4021 # configuration will be in build.ninja, but are never built by default. 4022 common_all = static_library('common', 4023 build_by_default: false, 4024 sources: common_ss.all_sources() + genh, 4025 include_directories: common_user_inc, 4026 implicit_include_directories: false, 4027 dependencies: common_ss.all_dependencies()) 4028 4029 if have_rust 4030 # We would like to use --generate-cstr, but it is only available 4031 # starting with bindgen 0.66.0. The oldest supported versions 4032 # is 0.60.x (Debian 12 has 0.60.1) which introduces --allowlist-file. 4033 bindgen_args = [ 4034 '--disable-header-comment', 4035 '--raw-line', '// @generated', 4036 '--ctypes-prefix', 'std::os::raw', 4037 '--generate-block', 4038 '--impl-debug', 4039 '--no-doc-comments', 4040 '--with-derive-default', 4041 '--no-layout-tests', 4042 '--no-prepend-enum-name', 4043 '--allowlist-file', meson.project_source_root() + '/include/.*', 4044 '--allowlist-file', meson.project_source_root() + '/.*', 4045 '--allowlist-file', meson.project_build_root() + '/.*' 4046 ] 4047 if not rustfmt.found() 4048 if bindgen.version().version_compare('<0.65.0') 4049 bindgen_args += ['--no-rustfmt-bindings'] 4050 else 4051 bindgen_args += ['--formatter', 'none'] 4052 endif 4053 endif 4054 if bindgen.version().version_compare('>=0.66.0') 4055 bindgen_args += ['--rust-target', '1.59'] 4056 endif 4057 if bindgen.version().version_compare('<0.61.0') 4058 # default in 0.61+ 4059 bindgen_args += ['--size_t-is-usize'] 4060 else 4061 bindgen_args += ['--merge-extern-blocks'] 4062 endif 4063 c_enums = [ 4064 'DeviceCategory', 4065 'GpioPolarity', 4066 'MachineInitPhase', 4067 'MemoryDeviceInfoKind', 4068 'MigrationPolicy', 4069 'MigrationPriority', 4070 'QEMUChrEvent', 4071 'QEMUClockType', 4072 'device_endian', 4073 'module_init_type', 4074 ] 4075 foreach enum : c_enums 4076 bindgen_args += ['--rustified-enum', enum] 4077 endforeach 4078 c_bitfields = [ 4079 'ClockEvent', 4080 'VMStateFlags', 4081 ] 4082 foreach enum : c_bitfields 4083 bindgen_args += ['--bitfield-enum', enum] 4084 endforeach 4085 4086 # TODO: Remove this comment when the clang/libclang mismatch issue is solved. 4087 # 4088 # Rust bindings generation with `bindgen` might fail in some cases where the 4089 # detected `libclang` does not match the expected `clang` version/target. In 4090 # this case you must pass the path to `clang` and `libclang` to your build 4091 # command invocation using the environment variables CLANG_PATH and 4092 # LIBCLANG_PATH 4093 bindings_rs = rust.bindgen( 4094 input: 'rust/wrapper.h', 4095 dependencies: common_ss.all_dependencies(), 4096 output: 'bindings.rs', 4097 include_directories: include_directories('.', 'include'), 4098 bindgen_version: ['>=0.60.0'], 4099 args: bindgen_args, 4100 ) 4101 subdir('rust') 4102 endif 4103 4104 4105 feature_to_c = find_program('scripts/feature_to_c.py') 4106 rust_root_crate = find_program('scripts/rust/rust_root_crate.sh') 4107 4108 if host_os == 'darwin' 4109 entitlement = find_program('scripts/entitlement.sh') 4110 endif 4111 4112 traceable = [] 4113 emulators = {} 4114 foreach target : target_dirs 4115 config_target = config_target_mak[target] 4116 target_name = config_target['TARGET_NAME'] 4117 target_base_arch = config_target['TARGET_BASE_ARCH'] 4118 arch_srcs = [config_target_h[target]] 4119 arch_deps = [] 4120 c_args = ['-DCOMPILING_PER_TARGET', 4121 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 4122 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 4123 link_args = emulator_link_args 4124 4125 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 4126 if host_os == 'linux' 4127 target_inc += include_directories('linux-headers', is_system: true) 4128 endif 4129 if target.endswith('-softmmu') 4130 target_type='system' 4131 t = target_system_arch[target_base_arch].apply(config_target, strict: false) 4132 arch_srcs += t.sources() 4133 arch_deps += t.dependencies() 4134 4135 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch 4136 if hw_arch.has_key(hw_dir) 4137 hw = hw_arch[hw_dir].apply(config_target, strict: false) 4138 arch_srcs += hw.sources() 4139 arch_deps += hw.dependencies() 4140 endif 4141 4142 arch_srcs += config_devices_h[target] 4143 link_args += ['@block.syms', '@qemu.syms'] 4144 else 4145 abi = config_target['TARGET_ABI_DIR'] 4146 target_type='user' 4147 target_inc += common_user_inc 4148 if target_base_arch in target_user_arch 4149 t = target_user_arch[target_base_arch].apply(config_target, strict: false) 4150 arch_srcs += t.sources() 4151 arch_deps += t.dependencies() 4152 endif 4153 if 'CONFIG_LINUX_USER' in config_target 4154 base_dir = 'linux-user' 4155 endif 4156 if 'CONFIG_BSD_USER' in config_target 4157 base_dir = 'bsd-user' 4158 target_inc += include_directories('bsd-user/' / host_os) 4159 target_inc += include_directories('bsd-user/host/' / host_arch) 4160 dir = base_dir / abi 4161 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c') 4162 endif 4163 target_inc += include_directories( 4164 base_dir, 4165 base_dir / abi, 4166 ) 4167 if 'CONFIG_LINUX_USER' in config_target 4168 dir = base_dir / abi 4169 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c') 4170 if config_target.has_key('TARGET_SYSTBL_ABI') 4171 arch_srcs += \ 4172 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'], 4173 extra_args : config_target['TARGET_SYSTBL_ABI']) 4174 endif 4175 endif 4176 endif 4177 4178 if 'TARGET_XML_FILES' in config_target 4179 gdbstub_xml = custom_target(target + '-gdbstub-xml.c', 4180 output: target + '-gdbstub-xml.c', 4181 input: files(config_target['TARGET_XML_FILES'].split()), 4182 command: [feature_to_c, '@INPUT@'], 4183 capture: true) 4184 arch_srcs += gdbstub_xml 4185 endif 4186 4187 t = target_arch[target_base_arch].apply(config_target, strict: false) 4188 arch_srcs += t.sources() 4189 arch_deps += t.dependencies() 4190 4191 target_common = common_ss.apply(config_target, strict: false) 4192 objects = common_all.extract_objects(target_common.sources()) 4193 arch_deps += target_common.dependencies() 4194 4195 target_specific = specific_ss.apply(config_target, strict: false) 4196 arch_srcs += target_specific.sources() 4197 arch_deps += target_specific.dependencies() 4198 4199 if have_rust and target_type == 'system' 4200 target_rust = rust_devices_ss.apply(config_target, strict: false) 4201 crates = [] 4202 foreach dep : target_rust.dependencies() 4203 crates += dep.get_variable('crate') 4204 endforeach 4205 if crates.length() > 0 4206 rlib_rs = custom_target('rust_' + target.underscorify() + '.rs', 4207 output: 'rust_' + target.underscorify() + '.rs', 4208 command: [rust_root_crate, crates], 4209 capture: true, 4210 build_by_default: true, 4211 build_always_stale: true) 4212 rlib = static_library('rust_' + target.underscorify(), 4213 rlib_rs, 4214 dependencies: target_rust.dependencies(), 4215 override_options: ['rust_std=2021', 'build.rust_std=2021'], 4216 rust_abi: 'c') 4217 arch_deps += declare_dependency(link_whole: [rlib]) 4218 endif 4219 endif 4220 4221 # allow using headers from the dependencies but do not include the sources, 4222 # because this emulator only needs those in "objects". For external 4223 # dependencies, the full dependency is included below in the executable. 4224 lib_deps = [] 4225 foreach dep : arch_deps 4226 lib_deps += dep.partial_dependency(compile_args: true, includes: true) 4227 endforeach 4228 4229 lib = static_library('qemu-' + target, 4230 sources: arch_srcs + genh, 4231 dependencies: lib_deps, 4232 objects: objects, 4233 include_directories: target_inc, 4234 c_args: c_args, 4235 build_by_default: false) 4236 4237 if target.endswith('-softmmu') 4238 execs = [{ 4239 'name': 'qemu-system-' + target_name, 4240 'win_subsystem': 'console', 4241 'sources': files('system/main.c'), 4242 'dependencies': [sdl] 4243 }] 4244 if host_os == 'windows' and (sdl.found() or gtk.found()) 4245 execs += [{ 4246 'name': 'qemu-system-' + target_name + 'w', 4247 'win_subsystem': 'windows', 4248 'sources': files('system/main.c'), 4249 'dependencies': [sdl] 4250 }] 4251 endif 4252 if get_option('fuzzing') 4253 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false) 4254 execs += [{ 4255 'name': 'qemu-fuzz-' + target_name, 4256 'win_subsystem': 'console', 4257 'sources': specific_fuzz.sources(), 4258 'dependencies': specific_fuzz.dependencies(), 4259 }] 4260 endif 4261 else 4262 execs = [{ 4263 'name': 'qemu-' + target_name, 4264 'win_subsystem': 'console', 4265 'sources': [], 4266 'dependencies': [] 4267 }] 4268 endif 4269 foreach exe: execs 4270 exe_name = exe['name'] 4271 if host_os == 'darwin' 4272 exe_name += '-unsigned' 4273 endif 4274 4275 emulator = executable(exe_name, exe['sources'], 4276 install: true, 4277 c_args: c_args, 4278 dependencies: arch_deps + exe['dependencies'], 4279 objects: lib.extract_all_objects(recursive: true), 4280 link_depends: [block_syms, qemu_syms], 4281 link_args: link_args, 4282 win_subsystem: exe['win_subsystem']) 4283 4284 if host_os == 'darwin' 4285 icon = 'pc-bios/qemu.rsrc' 4286 build_input = [emulator, files(icon)] 4287 install_input = [ 4288 get_option('bindir') / exe_name, 4289 meson.current_source_dir() / icon 4290 ] 4291 if 'CONFIG_HVF' in config_target 4292 entitlements = 'accel/hvf/entitlements.plist' 4293 build_input += files(entitlements) 4294 install_input += meson.current_source_dir() / entitlements 4295 endif 4296 4297 emulators += {exe['name'] : custom_target(exe['name'], 4298 input: build_input, 4299 output: exe['name'], 4300 command: [entitlement, '@OUTPUT@', '@INPUT@']) 4301 } 4302 4303 meson.add_install_script(entitlement, '--install', 4304 get_option('bindir') / exe['name'], 4305 install_input) 4306 else 4307 emulators += {exe['name']: emulator} 4308 endif 4309 4310 traceable += [{ 4311 'exe': exe['name'], 4312 'probe-prefix': 'qemu.' + target_type + '.' + target_name, 4313 }] 4314 4315 endforeach 4316 endforeach 4317 4318 # Other build targets 4319 4320 if get_option('plugins') 4321 install_headers('include/qemu/qemu-plugin.h') 4322 if host_os == 'windows' 4323 # On windows, we want to deliver the qemu_plugin_api.lib file in the qemu installer, 4324 # so that plugin authors can compile against it. 4325 install_data(win32_qemu_plugin_api_lib, install_dir: 'lib') 4326 endif 4327 endif 4328 4329 subdir('qga') 4330 4331 # Don't build qemu-keymap if xkbcommon is not explicitly enabled 4332 # when we don't build tools or system 4333 if xkbcommon.found() 4334 # used for the update-keymaps target, so include rules even if !have_tools 4335 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh, 4336 dependencies: [qemuutil, xkbcommon], install: have_tools) 4337 endif 4338 4339 if have_tools 4340 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep], 4341 link_args: '@block.syms', link_depends: block_syms, 4342 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true) 4343 qemu_io = executable('qemu-io', files('qemu-io.c'), 4344 link_args: '@block.syms', link_depends: block_syms, 4345 dependencies: [block, qemuutil], install: true) 4346 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'), 4347 link_args: '@block.syms', link_depends: block_syms, 4348 dependencies: [blockdev, qemuutil, selinux], 4349 install: true) 4350 4351 subdir('storage-daemon') 4352 4353 foreach exe: [ 'qemu-img', 'qemu-io', 'qemu-nbd', 'qemu-storage-daemon'] 4354 traceable += [{ 4355 'exe': exe, 4356 'probe-prefix': 'qemu.' + exe.substring(5).replace('-', '_') 4357 }] 4358 endforeach 4359 4360 subdir('contrib/elf2dmp') 4361 4362 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'), 4363 dependencies: qemuutil, 4364 install: true) 4365 4366 if have_vhost_user 4367 subdir('contrib/vhost-user-blk') 4368 subdir('contrib/vhost-user-gpu') 4369 subdir('contrib/vhost-user-input') 4370 subdir('contrib/vhost-user-scsi') 4371 endif 4372 4373 if host_os == 'linux' 4374 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'), 4375 dependencies: [qemuutil, libcap_ng], 4376 install: true, 4377 install_dir: get_option('libexecdir')) 4378 4379 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'), 4380 dependencies: [authz, crypto, io, qom, qemuutil, 4381 libcap_ng, mpathpersist], 4382 install: true) 4383 4384 if cpu in ['x86', 'x86_64'] 4385 executable('qemu-vmsr-helper', files('tools/i386/qemu-vmsr-helper.c'), 4386 dependencies: [authz, crypto, io, qom, qemuutil, 4387 libcap_ng, mpathpersist], 4388 install: true) 4389 endif 4390 endif 4391 4392 if have_ivshmem 4393 subdir('contrib/ivshmem-client') 4394 subdir('contrib/ivshmem-server') 4395 endif 4396 endif 4397 4398 if stap.found() 4399 foreach t: traceable 4400 foreach stp: [ 4401 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / t['exe'], 'install': false}, 4402 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / t['exe'], 'install': true}, 4403 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true}, 4404 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true}, 4405 ] 4406 cmd = [ 4407 tracetool, '--group=all', '--format=' + stp['fmt'], 4408 '--binary=' + stp['bin'], 4409 '--probe-prefix=' + t['probe-prefix'], 4410 '@INPUT@', '@OUTPUT@' 4411 ] 4412 4413 custom_target(t['exe'] + stp['ext'], 4414 input: trace_events_all, 4415 output: t['exe'] + stp['ext'], 4416 install: stp['install'], 4417 install_dir: get_option('datadir') / 'systemtap/tapset', 4418 command: cmd, 4419 depend_files: tracetool_depends) 4420 endforeach 4421 endforeach 4422 endif 4423 4424 subdir('scripts') 4425 subdir('tools') 4426 subdir('pc-bios') 4427 subdir('docs') 4428 subdir('tests') 4429 if gtk.found() 4430 subdir('po') 4431 endif 4432 4433 if host_machine.system() == 'windows' 4434 nsis_cmd = [ 4435 find_program('scripts/nsis.py'), 4436 '@OUTPUT@', 4437 get_option('prefix'), 4438 meson.current_source_dir(), 4439 glib_pc.get_variable('bindir'), 4440 host_machine.cpu(), 4441 '--', 4442 '-DDISPLAYVERSION=' + meson.project_version(), 4443 ] 4444 if build_docs 4445 nsis_cmd += '-DCONFIG_DOCUMENTATION=y' 4446 endif 4447 if gtk.found() 4448 nsis_cmd += '-DCONFIG_GTK=y' 4449 endif 4450 4451 nsis = custom_target('nsis', 4452 output: 'qemu-setup-' + meson.project_version() + '.exe', 4453 input: files('qemu.nsi'), 4454 build_always_stale: true, 4455 command: nsis_cmd + ['@INPUT@']) 4456 alias_target('installer', nsis) 4457 endif 4458 4459 ######################### 4460 # Configuration summary # 4461 ######################### 4462 4463 # Build environment 4464 summary_info = {} 4465 summary_info += {'Build directory': meson.current_build_dir()} 4466 summary_info += {'Source path': meson.current_source_dir()} 4467 summary_info += {'Download dependencies': get_option('wrap_mode') != 'nodownload'} 4468 summary(summary_info, bool_yn: true, section: 'Build environment') 4469 4470 # Directories 4471 summary_info += {'Install prefix': get_option('prefix')} 4472 summary_info += {'BIOS directory': qemu_datadir} 4473 pathsep = host_os == 'windows' ? ';' : ':' 4474 summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))} 4475 summary_info += {'binary directory': get_option('prefix') / get_option('bindir')} 4476 summary_info += {'library directory': get_option('prefix') / get_option('libdir')} 4477 summary_info += {'module directory': qemu_moddir} 4478 summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')} 4479 summary_info += {'include directory': get_option('prefix') / get_option('includedir')} 4480 summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')} 4481 if host_os != 'windows' 4482 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')} 4483 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')} 4484 else 4485 summary_info += {'local state directory': 'queried at runtime'} 4486 endif 4487 summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')} 4488 summary(summary_info, bool_yn: true, section: 'Directories') 4489 4490 # Host binaries 4491 summary_info = {} 4492 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())} 4493 summary_info += {'sphinx-build': sphinx_build} 4494 4495 # FIXME: the [binaries] section of machine files, which can be probed 4496 # with find_program(), would be great for passing gdb and genisoimage 4497 # paths from configure to Meson. However, there seems to be no way to 4498 # hide a program (for example if gdb is too old). 4499 if config_host.has_key('GDB') 4500 summary_info += {'gdb': config_host['GDB']} 4501 endif 4502 summary_info += {'iasl': iasl} 4503 summary_info += {'genisoimage': config_host['GENISOIMAGE']} 4504 if host_os == 'windows' and have_ga 4505 summary_info += {'wixl': wixl} 4506 endif 4507 if slirp.found() and have_system 4508 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false} 4509 endif 4510 summary(summary_info, bool_yn: true, section: 'Host binaries') 4511 4512 # Configurable features 4513 summary_info = {} 4514 summary_info += {'Documentation': build_docs} 4515 summary_info += {'system-mode emulation': have_system} 4516 summary_info += {'user-mode emulation': have_user} 4517 summary_info += {'block layer': have_block} 4518 summary_info += {'Install blobs': get_option('install_blobs')} 4519 summary_info += {'module support': enable_modules} 4520 if enable_modules 4521 summary_info += {'alternative module path': get_option('module_upgrades')} 4522 endif 4523 summary_info += {'fuzzing support': get_option('fuzzing')} 4524 if have_system 4525 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)} 4526 endif 4527 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))} 4528 if 'simple' in get_option('trace_backends') 4529 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'} 4530 endif 4531 summary_info += {'D-Bus display': dbus_display} 4532 summary_info += {'QOM debugging': get_option('qom_cast_debug')} 4533 summary_info += {'Relocatable install': get_option('relocatable')} 4534 summary_info += {'vhost-kernel support': have_vhost_kernel} 4535 summary_info += {'vhost-net support': have_vhost_net} 4536 summary_info += {'vhost-user support': have_vhost_user} 4537 summary_info += {'vhost-user-crypto support': have_vhost_user_crypto} 4538 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server} 4539 summary_info += {'vhost-vdpa support': have_vhost_vdpa} 4540 summary_info += {'build guest agent': have_ga} 4541 summary(summary_info, bool_yn: true, section: 'Configurable features') 4542 4543 # Compilation information 4544 summary_info = {} 4545 summary_info += {'host CPU': cpu} 4546 summary_info += {'host endianness': build_machine.endian()} 4547 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())} 4548 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())} 4549 if 'cpp' in all_languages 4550 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())} 4551 else 4552 summary_info += {'C++ compiler': false} 4553 endif 4554 if 'objc' in all_languages 4555 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())} 4556 else 4557 summary_info += {'Objective-C compiler': false} 4558 endif 4559 summary_info += {'Rust support': have_rust} 4560 if have_rust 4561 summary_info += {'Rust target': config_host['RUST_TARGET_TRIPLE']} 4562 summary_info += {'rustc': ' '.join(rustc.cmd_array())} 4563 summary_info += {'rustc version': rustc.version()} 4564 summary_info += {'bindgen': bindgen.full_path()} 4565 summary_info += {'bindgen version': bindgen.version()} 4566 endif 4567 option_cflags = (get_option('debug') ? ['-g'] : []) 4568 if get_option('optimization') != 'plain' 4569 option_cflags += ['-O' + get_option('optimization')] 4570 endif 4571 summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)} 4572 if 'cpp' in all_languages 4573 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)} 4574 endif 4575 if 'objc' in all_languages 4576 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)} 4577 endif 4578 link_args = get_option('c_link_args') 4579 if link_args.length() > 0 4580 summary_info += {'LDFLAGS': ' '.join(link_args)} 4581 endif 4582 summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)} 4583 if 'cpp' in all_languages 4584 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)} 4585 endif 4586 if 'objc' in all_languages 4587 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)} 4588 endif 4589 summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)} 4590 summary_info += {'link-time optimization (LTO)': get_option('b_lto')} 4591 summary_info += {'PIE': get_option('b_pie')} 4592 summary_info += {'static build': get_option('prefer_static')} 4593 summary_info += {'malloc trim support': has_malloc_trim} 4594 summary_info += {'membarrier': have_membarrier} 4595 summary_info += {'debug graph lock': get_option('debug_graph_lock')} 4596 summary_info += {'debug stack usage': get_option('debug_stack_usage')} 4597 summary_info += {'mutex debugging': get_option('debug_mutex')} 4598 summary_info += {'memory allocator': get_option('malloc')} 4599 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')} 4600 summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')} 4601 summary_info += {'gcov': get_option('b_coverage')} 4602 summary_info += {'thread sanitizer': get_option('tsan')} 4603 summary_info += {'CFI support': get_option('cfi')} 4604 if get_option('cfi') 4605 summary_info += {'CFI debug support': get_option('cfi_debug')} 4606 endif 4607 summary_info += {'strip binaries': get_option('strip')} 4608 summary_info += {'sparse': sparse} 4609 summary_info += {'mingw32 support': host_os == 'windows'} 4610 summary(summary_info, bool_yn: true, section: 'Compilation') 4611 4612 # snarf the cross-compilation information for tests 4613 summary_info = {} 4614 have_cross = false 4615 foreach target: target_dirs 4616 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak' 4617 if fs.exists(tcg_mak) 4618 config_cross_tcg = keyval.load(tcg_mak) 4619 if 'CC' in config_cross_tcg 4620 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']} 4621 have_cross = true 4622 endif 4623 endif 4624 endforeach 4625 if have_cross 4626 summary(summary_info, bool_yn: true, section: 'Cross compilers') 4627 endif 4628 4629 # Targets and accelerators 4630 summary_info = {} 4631 if have_system 4632 summary_info += {'KVM support': config_all_accel.has_key('CONFIG_KVM')} 4633 summary_info += {'HVF support': config_all_accel.has_key('CONFIG_HVF')} 4634 summary_info += {'WHPX support': config_all_accel.has_key('CONFIG_WHPX')} 4635 summary_info += {'NVMM support': config_all_accel.has_key('CONFIG_NVMM')} 4636 summary_info += {'Xen support': xen.found()} 4637 if xen.found() 4638 summary_info += {'xen ctrl version': xen.version()} 4639 endif 4640 summary_info += {'Xen emulation': config_all_devices.has_key('CONFIG_XEN_EMU')} 4641 endif 4642 summary_info += {'TCG support': config_all_accel.has_key('CONFIG_TCG')} 4643 if config_all_accel.has_key('CONFIG_TCG') 4644 if get_option('tcg_interpreter') 4645 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'} 4646 else 4647 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)} 4648 endif 4649 summary_info += {'TCG plugins': get_option('plugins')} 4650 summary_info += {'TCG debug enabled': get_option('debug_tcg')} 4651 if have_linux_user or have_bsd_user 4652 summary_info += {'syscall buffer debugging support': get_option('debug_remap')} 4653 endif 4654 endif 4655 summary_info += {'target list': ' '.join(target_dirs)} 4656 if have_system 4657 summary_info += {'default devices': get_option('default_devices')} 4658 summary_info += {'out of process emulation': multiprocess_allowed} 4659 summary_info += {'vfio-user server': vfio_user_server_allowed} 4660 endif 4661 summary(summary_info, bool_yn: true, section: 'Targets and accelerators') 4662 4663 # Block layer 4664 summary_info = {} 4665 summary_info += {'coroutine backend': coroutine_backend} 4666 summary_info += {'coroutine pool': have_coroutine_pool} 4667 if have_block 4668 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')} 4669 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')} 4670 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')} 4671 summary_info += {'VirtFS (9P) support': have_virtfs} 4672 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')} 4673 summary_info += {'bochs support': get_option('bochs').allowed()} 4674 summary_info += {'cloop support': get_option('cloop').allowed()} 4675 summary_info += {'dmg support': get_option('dmg').allowed()} 4676 summary_info += {'qcow v1 support': get_option('qcow1').allowed()} 4677 summary_info += {'vdi support': get_option('vdi').allowed()} 4678 summary_info += {'vhdx support': get_option('vhdx').allowed()} 4679 summary_info += {'vmdk support': get_option('vmdk').allowed()} 4680 summary_info += {'vpc support': get_option('vpc').allowed()} 4681 summary_info += {'vvfat support': get_option('vvfat').allowed()} 4682 summary_info += {'qed support': get_option('qed').allowed()} 4683 summary_info += {'parallels support': get_option('parallels').allowed()} 4684 summary_info += {'FUSE exports': fuse} 4685 summary_info += {'VDUSE block exports': have_vduse_blk_export} 4686 endif 4687 summary(summary_info, bool_yn: true, section: 'Block layer support') 4688 4689 # Crypto 4690 summary_info = {} 4691 summary_info += {'TLS priority': get_option('tls_priority')} 4692 summary_info += {'GNUTLS support': gnutls} 4693 if gnutls.found() 4694 summary_info += {' GNUTLS crypto': gnutls_crypto.found()} 4695 endif 4696 summary_info += {'libgcrypt': gcrypt} 4697 summary_info += {'nettle': nettle} 4698 if nettle.found() 4699 summary_info += {' XTS': xts != 'private'} 4700 endif 4701 summary_info += {'SM4 ALG support': crypto_sm4} 4702 summary_info += {'SM3 ALG support': crypto_sm3} 4703 summary_info += {'AF_ALG support': have_afalg} 4704 summary_info += {'rng-none': get_option('rng_none')} 4705 summary_info += {'Linux keyring': have_keyring} 4706 summary_info += {'Linux keyutils': keyutils} 4707 summary(summary_info, bool_yn: true, section: 'Crypto') 4708 4709 # UI 4710 summary_info = {} 4711 if host_os == 'darwin' 4712 summary_info += {'Cocoa support': cocoa} 4713 endif 4714 summary_info += {'SDL support': sdl} 4715 summary_info += {'SDL image support': sdl_image} 4716 summary_info += {'GTK support': gtk} 4717 summary_info += {'pixman': pixman} 4718 summary_info += {'VTE support': vte} 4719 summary_info += {'PNG support': png} 4720 summary_info += {'VNC support': vnc} 4721 if vnc.found() 4722 summary_info += {'VNC SASL support': sasl} 4723 summary_info += {'VNC JPEG support': jpeg} 4724 endif 4725 summary_info += {'spice protocol support': spice_protocol} 4726 if spice_protocol.found() 4727 summary_info += {' spice server support': spice} 4728 endif 4729 summary_info += {'curses support': curses} 4730 summary_info += {'brlapi support': brlapi} 4731 summary(summary_info, bool_yn: true, section: 'User interface') 4732 4733 # Graphics backends 4734 summary_info = {} 4735 summary_info += {'VirGL support': virgl} 4736 summary_info += {'Rutabaga support': rutabaga} 4737 summary(summary_info, bool_yn: true, section: 'Graphics backends') 4738 4739 # Audio backends 4740 summary_info = {} 4741 if host_os not in ['darwin', 'haiku', 'windows'] 4742 summary_info += {'OSS support': oss} 4743 summary_info += {'sndio support': sndio} 4744 elif host_os == 'darwin' 4745 summary_info += {'CoreAudio support': coreaudio} 4746 elif host_os == 'windows' 4747 summary_info += {'DirectSound support': dsound} 4748 endif 4749 if host_os == 'linux' 4750 summary_info += {'ALSA support': alsa} 4751 summary_info += {'PulseAudio support': pulse} 4752 endif 4753 summary_info += {'PipeWire support': pipewire} 4754 summary_info += {'JACK support': jack} 4755 summary(summary_info, bool_yn: true, section: 'Audio backends') 4756 4757 # Network backends 4758 summary_info = {} 4759 if host_os == 'darwin' 4760 summary_info += {'vmnet.framework support': vmnet} 4761 endif 4762 summary_info += {'AF_XDP support': libxdp} 4763 summary_info += {'slirp support': slirp} 4764 summary_info += {'vde support': vde} 4765 summary_info += {'netmap support': have_netmap} 4766 summary_info += {'l2tpv3 support': have_l2tpv3} 4767 summary(summary_info, bool_yn: true, section: 'Network backends') 4768 4769 # Libraries 4770 summary_info = {} 4771 summary_info += {'libtasn1': tasn1} 4772 summary_info += {'PAM': pam} 4773 summary_info += {'iconv support': iconv} 4774 summary_info += {'blkio support': blkio} 4775 summary_info += {'curl support': curl} 4776 summary_info += {'Multipath support': mpathpersist} 4777 summary_info += {'Linux AIO support': libaio} 4778 summary_info += {'Linux io_uring support': linux_io_uring} 4779 summary_info += {'ATTR/XATTR support': libattr} 4780 summary_info += {'RDMA support': rdma} 4781 summary_info += {'fdt support': fdt_opt == 'internal' ? 'internal' : fdt} 4782 summary_info += {'libcap-ng support': libcap_ng} 4783 summary_info += {'bpf support': libbpf} 4784 summary_info += {'rbd support': rbd} 4785 summary_info += {'smartcard support': cacard} 4786 summary_info += {'U2F support': u2f} 4787 summary_info += {'libusb': libusb} 4788 summary_info += {'usb net redir': usbredir} 4789 summary_info += {'OpenGL support (epoxy)': opengl} 4790 summary_info += {'GBM': gbm} 4791 summary_info += {'libiscsi support': libiscsi} 4792 summary_info += {'libnfs support': libnfs} 4793 if host_os == 'windows' 4794 if have_ga 4795 summary_info += {'QGA VSS support': have_qga_vss} 4796 endif 4797 endif 4798 summary_info += {'seccomp support': seccomp} 4799 summary_info += {'GlusterFS support': glusterfs} 4800 summary_info += {'hv-balloon support': hv_balloon} 4801 summary_info += {'TPM support': have_tpm} 4802 summary_info += {'libssh support': libssh} 4803 summary_info += {'lzo support': lzo} 4804 summary_info += {'snappy support': snappy} 4805 summary_info += {'bzip2 support': libbzip2} 4806 summary_info += {'lzfse support': liblzfse} 4807 summary_info += {'zstd support': zstd} 4808 summary_info += {'Query Processing Library support': qpl} 4809 summary_info += {'UADK Library support': uadk} 4810 summary_info += {'qatzip support': qatzip} 4811 summary_info += {'NUMA host support': numa} 4812 summary_info += {'capstone': capstone} 4813 summary_info += {'libpmem support': libpmem} 4814 summary_info += {'libdaxctl support': libdaxctl} 4815 summary_info += {'libcbor support': libcbor} 4816 summary_info += {'libudev': libudev} 4817 # Dummy dependency, keep .found() 4818 summary_info += {'FUSE lseek': fuse_lseek.found()} 4819 summary_info += {'selinux': selinux} 4820 summary_info += {'libdw': libdw} 4821 if host_os == 'freebsd' 4822 summary_info += {'libinotify-kqueue': inotify} 4823 endif 4824 summary(summary_info, bool_yn: true, section: 'Dependencies') 4825 4826 if host_arch == 'unknown' 4827 message() 4828 warning('UNSUPPORTED HOST CPU') 4829 message() 4830 message('Support for CPU host architecture ' + cpu + ' is not currently') 4831 message('maintained. The QEMU project does not guarantee that QEMU will') 4832 message('compile or work on this host CPU. You can help by volunteering') 4833 message('to maintain it and providing a build host for our continuous') 4834 message('integration setup.') 4835 if get_option('tcg').allowed() and target_dirs.length() > 0 4836 message() 4837 message('configure has succeeded and you can continue to build, but') 4838 message('QEMU will use a slow interpreter to emulate the target CPU.') 4839 endif 4840 elif host_arch == 'mips' 4841 message() 4842 warning('DEPRECATED HOST CPU') 4843 message() 4844 message('Support for CPU host architecture ' + cpu + ' is going to be') 4845 message('dropped as soon as the QEMU project stops supporting Debian 12') 4846 message('("Bookworm"). Going forward, the QEMU project will not guarantee') 4847 message('that QEMU will compile or work on this host CPU.') 4848 endif 4849 4850 if not supported_oses.contains(host_os) 4851 message() 4852 warning('UNSUPPORTED HOST OS') 4853 message() 4854 message('Support for host OS ' + host_os + 'is not currently maintained.') 4855 message('configure has succeeded and you can continue to build, but') 4856 message('the QEMU project does not guarantee that QEMU will compile or') 4857 message('work on this operating system. You can help by volunteering') 4858 message('to maintain it and providing a build host for our continuous') 4859 message('integration setup. This will ensure that future versions of QEMU') 4860 message('will keep working on ' + host_os + '.') 4861 endif 4862 4863 if host_arch == 'unknown' or not supported_oses.contains(host_os) 4864 message() 4865 message('If you want to help supporting QEMU on this platform, please') 4866 message('contact the developers at qemu-devel@nongnu.org.') 4867 endif 4868 4869 actually_reloc = get_option('relocatable') 4870 # check if get_relocated_path() is actually able to relocate paths 4871 if get_option('relocatable') and \ 4872 not (get_option('prefix') / get_option('bindir')).startswith(get_option('prefix') / '') 4873 message() 4874 warning('bindir not included within prefix, the installation will not be relocatable.') 4875 actually_reloc = false 4876 endif 4877 if not actually_reloc and (host_os == 'windows' or get_option('relocatable')) 4878 if host_os == 'windows' 4879 message() 4880 warning('Windows installs should usually be relocatable.') 4881 endif 4882 message() 4883 message('QEMU will have to be installed under ' + get_option('prefix') + '.') 4884 message('Use --disable-relocatable to remove this warning.') 4885 endif 4886