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