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