1project('qemu', ['c'], meson_version: '>=0.55.0', 2 default_options: ['warning_level=1', 'c_std=gnu99', 'cpp_std=gnu++11', 3 'b_colorout=auto'], 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 20build_docs = 'BUILD_DOCS' in config_host 21 22if get_option('qemu_suffix').startswith('/') 23 error('qemu_suffix cannot start with a /') 24endif 25 26qemu_datadir = get_option('datadir') / get_option('qemu_suffix') 27qemu_docdir = get_option('docdir') / get_option('qemu_suffix') 28config_host_data = configuration_data() 29genh = [] 30 31target_dirs = config_host['TARGET_DIRS'].split() 32have_user = false 33have_system = false 34foreach target : target_dirs 35 have_user = have_user or target.endswith('-user') 36 have_system = have_system or target.endswith('-softmmu') 37endforeach 38have_tools = 'CONFIG_TOOLS' in config_host 39have_block = have_system or have_tools 40 41python = import('python').find_installation() 42 43supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux'] 44supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64', 45 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64'] 46 47cpu = host_machine.cpu_family() 48targetos = host_machine.system() 49 50if cpu in ['x86', 'x86_64'] 51 kvm_targets = ['i386-softmmu', 'x86_64-softmmu'] 52elif cpu == 'aarch64' 53 kvm_targets = ['aarch64-softmmu'] 54elif cpu == 's390x' 55 kvm_targets = ['s390x-softmmu'] 56elif cpu in ['ppc', 'ppc64'] 57 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu'] 58elif cpu in ['mips', 'mips64'] 59 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu'] 60else 61 kvm_targets = [] 62endif 63 64accelerator_targets = { 'CONFIG_KVM': kvm_targets } 65if cpu in ['x86', 'x86_64'] 66 accelerator_targets += { 67 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'], 68 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'], 69 'CONFIG_HVF': ['x86_64-softmmu'], 70 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'], 71 } 72endif 73 74################## 75# Compiler flags # 76################## 77 78# Specify linker-script with add_project_link_arguments so that it is not placed 79# within a linker --start-group/--end-group pair 80if 'CONFIG_FUZZ' in config_host 81 add_project_link_arguments(['-Wl,-T,', 82 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')], 83 native: false, language: ['c', 'cpp', 'objc']) 84endif 85 86add_project_arguments(config_host['QEMU_CFLAGS'].split(), 87 native: false, language: ['c', 'objc']) 88add_project_arguments(config_host['QEMU_CXXFLAGS'].split(), 89 native: false, language: 'cpp') 90add_project_link_arguments(config_host['QEMU_LDFLAGS'].split(), 91 native: false, language: ['c', 'cpp', 'objc']) 92 93if targetos == 'linux' 94 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers', 95 '-isystem', 'linux-headers', 96 language: ['c', 'cpp']) 97endif 98 99if 'CONFIG_TCG_INTERPRETER' in config_host 100 tcg_arch = 'tci' 101elif config_host['ARCH'] == 'sparc64' 102 tcg_arch = 'sparc' 103elif config_host['ARCH'] == 's390x' 104 tcg_arch = 's390' 105elif config_host['ARCH'] in ['x86_64', 'x32'] 106 tcg_arch = 'i386' 107elif config_host['ARCH'] == 'ppc64' 108 tcg_arch = 'ppc' 109elif config_host['ARCH'] in ['riscv32', 'riscv64'] 110 tcg_arch = 'riscv' 111else 112 tcg_arch = config_host['ARCH'] 113endif 114add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch, 115 '-iquote', '.', 116 '-iquote', meson.current_source_dir(), 117 '-iquote', meson.current_source_dir() / 'accel/tcg', 118 '-iquote', meson.current_source_dir() / 'include', 119 '-iquote', meson.current_source_dir() / 'disas/libvixl', 120 language: ['c', 'cpp', 'objc']) 121 122link_language = meson.get_external_property('link_language', 'cpp') 123if link_language == 'cpp' 124 add_languages('cpp', required: true, native: false) 125endif 126if host_machine.system() == 'darwin' 127 add_languages('objc', required: false, native: false) 128endif 129 130sparse = find_program('cgcc', required: get_option('sparse')) 131if sparse.found() 132 run_target('sparse', 133 command: [find_program('scripts/check_sparse.py'), 134 'compile_commands.json', sparse.full_path(), '-Wbitwise', 135 '-Wno-transparent-union', '-Wno-old-initializer', 136 '-Wno-non-pointer-null']) 137endif 138 139########################################### 140# Target-specific checks and dependencies # 141########################################### 142 143if targetos != 'linux' and get_option('mpath').enabled() 144 error('Multipath is supported only on Linux') 145endif 146 147m = cc.find_library('m', required: false) 148util = cc.find_library('util', required: false) 149winmm = [] 150socket = [] 151version_res = [] 152coref = [] 153iokit = [] 154emulator_link_args = [] 155cocoa = not_found 156hvf = not_found 157if targetos == 'windows' 158 socket = cc.find_library('ws2_32') 159 winmm = cc.find_library('winmm') 160 161 win = import('windows') 162 version_res = win.compile_resources('version.rc', 163 depend_files: files('pc-bios/qemu-nsis.ico'), 164 include_directories: include_directories('.')) 165elif targetos == 'darwin' 166 coref = dependency('appleframeworks', modules: 'CoreFoundation') 167 iokit = dependency('appleframeworks', modules: 'IOKit') 168 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa')) 169elif targetos == 'sunos' 170 socket = [cc.find_library('socket'), 171 cc.find_library('nsl'), 172 cc.find_library('resolv')] 173elif targetos == 'haiku' 174 socket = [cc.find_library('posix_error_mapper'), 175 cc.find_library('network'), 176 cc.find_library('bsd')] 177elif targetos == 'openbsd' 178 if not get_option('tcg').disabled() and target_dirs.length() > 0 179 # Disable OpenBSD W^X if available 180 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded') 181 endif 182endif 183 184accelerators = [] 185if not get_option('kvm').disabled() and targetos == 'linux' 186 accelerators += 'CONFIG_KVM' 187endif 188if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host 189 accelerators += 'CONFIG_XEN' 190 have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux' 191else 192 have_xen_pci_passthrough = false 193endif 194if not get_option('whpx').disabled() and targetos == 'windows' 195 if get_option('whpx').enabled() and cpu != 'x86_64' 196 error('WHPX requires 64-bit host') 197 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \ 198 cc.has_header('WinHvEmulation.h', required: get_option('whpx')) 199 accelerators += 'CONFIG_WHPX' 200 endif 201endif 202if not get_option('hvf').disabled() 203 hvf = dependency('appleframeworks', modules: 'Hypervisor', 204 required: get_option('hvf')) 205 if hvf.found() 206 accelerators += 'CONFIG_HVF' 207 endif 208endif 209if not get_option('hax').disabled() 210 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd'] 211 accelerators += 'CONFIG_HAX' 212 endif 213endif 214if not get_option('tcg').disabled() 215 if cpu not in supported_cpus 216 if 'CONFIG_TCG_INTERPRETER' in config_host 217 warning('Unsupported CPU @0@, will use TCG with TCI (experimental)'.format(cpu)) 218 else 219 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu)) 220 endif 221 endif 222 accelerators += 'CONFIG_TCG' 223 config_host += { 'CONFIG_TCG': 'y' } 224endif 225 226if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled() 227 error('KVM not available on this platform') 228endif 229if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled() 230 error('HVF not available on this platform') 231endif 232if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled() 233 error('WHPX not available on this platform') 234endif 235if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled() 236 if 'CONFIG_XEN' in accelerators 237 error('Xen PCI passthrough not available on this platform') 238 else 239 error('Xen PCI passthrough requested but Xen not enabled') 240 endif 241endif 242if not cocoa.found() and get_option('cocoa').enabled() 243 error('Cocoa not available on this platform') 244endif 245 246################ 247# Dependencies # 248################ 249 250# The path to glib.h is added to all compilation commands. This was 251# grandfathered in from the QEMU Makefiles. 252add_project_arguments(config_host['GLIB_CFLAGS'].split(), 253 native: false, language: ['c', 'cpp', 'objc']) 254glib = declare_dependency(link_args: config_host['GLIB_LIBS'].split()) 255gio = not_found 256if 'CONFIG_GIO' in config_host 257 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(), 258 link_args: config_host['GIO_LIBS'].split()) 259endif 260lttng = not_found 261if 'CONFIG_TRACE_UST' in config_host 262 lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split()) 263endif 264urcubp = not_found 265if 'CONFIG_TRACE_UST' in config_host 266 urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split()) 267endif 268gcrypt = not_found 269if 'CONFIG_GCRYPT' in config_host 270 gcrypt = declare_dependency(compile_args: config_host['GCRYPT_CFLAGS'].split(), 271 link_args: config_host['GCRYPT_LIBS'].split()) 272endif 273nettle = not_found 274if 'CONFIG_NETTLE' in config_host 275 nettle = declare_dependency(compile_args: config_host['NETTLE_CFLAGS'].split(), 276 link_args: config_host['NETTLE_LIBS'].split()) 277endif 278gnutls = not_found 279if 'CONFIG_GNUTLS' in config_host 280 gnutls = declare_dependency(compile_args: config_host['GNUTLS_CFLAGS'].split(), 281 link_args: config_host['GNUTLS_LIBS'].split()) 282endif 283pixman = not_found 284if have_system or have_tools 285 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8', 286 method: 'pkg-config', static: enable_static) 287endif 288pam = not_found 289if 'CONFIG_AUTH_PAM' in config_host 290 pam = cc.find_library('pam') 291endif 292libaio = cc.find_library('aio', required: false) 293zlib = dependency('zlib', required: true, static: enable_static) 294linux_io_uring = not_found 295if 'CONFIG_LINUX_IO_URING' in config_host 296 linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(), 297 link_args: config_host['LINUX_IO_URING_LIBS'].split()) 298endif 299libxml2 = not_found 300if 'CONFIG_LIBXML2' in config_host 301 libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(), 302 link_args: config_host['LIBXML2_LIBS'].split()) 303endif 304libnfs = not_found 305if 'CONFIG_LIBNFS' in config_host 306 libnfs = declare_dependency(link_args: config_host['LIBNFS_LIBS'].split()) 307endif 308libattr = not_found 309if 'CONFIG_ATTR' in config_host 310 libattr = declare_dependency(link_args: config_host['LIBATTR_LIBS'].split()) 311endif 312seccomp = not_found 313if 'CONFIG_SECCOMP' in config_host 314 seccomp = declare_dependency(compile_args: config_host['SECCOMP_CFLAGS'].split(), 315 link_args: config_host['SECCOMP_LIBS'].split()) 316endif 317libcap_ng = not_found 318if 'CONFIG_LIBCAP_NG' in config_host 319 libcap_ng = declare_dependency(link_args: config_host['LIBCAP_NG_LIBS'].split()) 320endif 321if get_option('xkbcommon').auto() and not have_system and not have_tools 322 xkbcommon = not_found 323else 324 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'), 325 method: 'pkg-config', static: enable_static) 326endif 327vde = not_found 328if config_host.has_key('CONFIG_VDE') 329 vde = declare_dependency(link_args: config_host['VDE_LIBS'].split()) 330endif 331pulse = not_found 332if 'CONFIG_LIBPULSE' in config_host 333 pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(), 334 link_args: config_host['PULSE_LIBS'].split()) 335endif 336alsa = not_found 337if 'CONFIG_ALSA' in config_host 338 alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(), 339 link_args: config_host['ALSA_LIBS'].split()) 340endif 341jack = not_found 342if 'CONFIG_LIBJACK' in config_host 343 jack = declare_dependency(link_args: config_host['JACK_LIBS'].split()) 344endif 345spice = not_found 346if 'CONFIG_SPICE' in config_host 347 spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(), 348 link_args: config_host['SPICE_LIBS'].split()) 349endif 350rt = cc.find_library('rt', required: false) 351libdl = not_found 352if 'CONFIG_PLUGIN' in config_host 353 libdl = cc.find_library('dl', required: true) 354endif 355libiscsi = not_found 356if 'CONFIG_LIBISCSI' in config_host 357 libiscsi = declare_dependency(compile_args: config_host['LIBISCSI_CFLAGS'].split(), 358 link_args: config_host['LIBISCSI_LIBS'].split()) 359endif 360zstd = not_found 361if 'CONFIG_ZSTD' in config_host 362 zstd = declare_dependency(compile_args: config_host['ZSTD_CFLAGS'].split(), 363 link_args: config_host['ZSTD_LIBS'].split()) 364endif 365gbm = not_found 366if 'CONFIG_GBM' in config_host 367 gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(), 368 link_args: config_host['GBM_LIBS'].split()) 369endif 370virgl = not_found 371if 'CONFIG_VIRGL' in config_host 372 virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(), 373 link_args: config_host['VIRGL_LIBS'].split()) 374endif 375curl = not_found 376if 'CONFIG_CURL' in config_host 377 curl = declare_dependency(compile_args: config_host['CURL_CFLAGS'].split(), 378 link_args: config_host['CURL_LIBS'].split()) 379endif 380libudev = not_found 381if targetos == 'linux' and (have_system or have_tools) 382 libudev = dependency('libudev', 383 required: get_option('libudev'), 384 static: enable_static) 385endif 386 387mpathlibs = [libudev] 388mpathpersist = not_found 389mpathpersist_new_api = false 390if targetos == 'linux' and have_tools and not get_option('mpath').disabled() 391 mpath_test_source_new = ''' 392 #include <libudev.h> 393 #include <mpath_persist.h> 394 unsigned mpath_mx_alloc_len = 1024; 395 int logsink; 396 static struct config *multipath_conf; 397 extern struct udev *udev; 398 extern struct config *get_multipath_config(void); 399 extern void put_multipath_config(struct config *conf); 400 struct udev *udev; 401 struct config *get_multipath_config(void) { return multipath_conf; } 402 void put_multipath_config(struct config *conf) { } 403 int main(void) { 404 udev = udev_new(); 405 multipath_conf = mpath_lib_init(); 406 return 0; 407 }''' 408 mpath_test_source_old = ''' 409 #include <libudev.h> 410 #include <mpath_persist.h> 411 unsigned mpath_mx_alloc_len = 1024; 412 int logsink; 413 int main(void) { 414 struct udev *udev = udev_new(); 415 mpath_lib_init(udev); 416 return 0; 417 }''' 418 libmpathpersist = cc.find_library('mpathpersist', 419 required: get_option('mpath'), 420 static: enable_static) 421 if libmpathpersist.found() 422 mpathlibs += libmpathpersist 423 if enable_static 424 mpathlibs += cc.find_library('devmapper', 425 required: get_option('mpath'), 426 static: enable_static) 427 endif 428 mpathlibs += cc.find_library('multipath', 429 required: get_option('mpath'), 430 static: enable_static) 431 foreach lib: mpathlibs 432 if not lib.found() 433 mpathlibs = [] 434 break 435 endif 436 endforeach 437 if mpathlibs.length() == 0 438 msg = 'Dependencies missing for libmpathpersist' 439 elif cc.links(mpath_test_source_new, dependencies: mpathlibs) 440 mpathpersist = declare_dependency(dependencies: mpathlibs) 441 mpathpersist_new_api = true 442 elif cc.links(mpath_test_source_old, dependencies: mpathlibs) 443 mpathpersist = declare_dependency(dependencies: mpathlibs) 444 else 445 msg = 'Cannot detect libmpathpersist API' 446 endif 447 if not mpathpersist.found() 448 if get_option('mpath').enabled() 449 error(msg) 450 else 451 warning(msg + ', disabling') 452 endif 453 endif 454 endif 455endif 456 457iconv = not_found 458curses = not_found 459if have_system and not get_option('curses').disabled() 460 if not get_option('iconv').disabled() 461 libiconv = cc.find_library('iconv', 462 required: false, 463 static: enable_static) 464 if cc.links(''' 465 #include <iconv.h> 466 int main(void) { 467 iconv_t conv = iconv_open("WCHAR_T", "UCS-2"); 468 return conv != (iconv_t) -1; 469 }''', dependencies: [libiconv]) 470 iconv = declare_dependency(dependencies: [libiconv]) 471 endif 472 endif 473 if get_option('iconv').enabled() and not iconv.found() 474 error('Cannot detect iconv API') 475 endif 476 if iconv.found() 477 curses_libname_list = ['ncursesw', 'ncurses', 'cursesw', 'pdcurses'] 478 curses_test = ''' 479 #include <locale.h> 480 #include <curses.h> 481 #include <wchar.h> 482 int main(void) { 483 wchar_t wch = L'w'; 484 setlocale(LC_ALL, ""); 485 resize_term(0, 0); 486 addwstr(L"wide chars\n"); 487 addnwstr(&wch, 1); 488 add_wch(WACS_DEGREE); 489 return 0; 490 }''' 491 foreach curses_libname : curses_libname_list 492 libcurses = dependency(curses_libname, 493 required: false, 494 method: 'pkg-config', 495 static: enable_static) 496 497 if not libcurses.found() 498 dirs = ['/usr/include/ncursesw'] 499 if targetos == 'windows' 500 dirs = [] 501 endif 502 libcurses = cc.find_library(curses_libname, 503 required: false, 504 dirs: dirs, 505 static: enable_static) 506 endif 507 if libcurses.found() 508 if cc.links(curses_test, dependencies: [libcurses]) 509 curses = declare_dependency(compile_args: '-DNCURSES_WIDECHAR', dependencies: [libcurses]) 510 break 511 endif 512 endif 513 endforeach 514 endif 515 if not curses.found() 516 if iconv.found() 517 if get_option('curses').enabled() 518 error('Cannot find curses') 519 endif 520 elif get_option('curses').enabled() 521 error('iconv required for curses UI but not available') 522 else 523 warning('iconv required for curses UI but not available, disabling') 524 endif 525 endif 526endif 527 528brlapi = not_found 529if 'CONFIG_BRLAPI' in config_host 530 brlapi = declare_dependency(link_args: config_host['BRLAPI_LIBS'].split()) 531endif 532 533sdl = not_found 534if have_system 535 sdl = dependency('sdl2', required: get_option('sdl'), static: enable_static) 536 sdl_image = not_found 537endif 538if sdl.found() 539 # work around 2.0.8 bug 540 sdl = declare_dependency(compile_args: '-Wno-undef', 541 dependencies: sdl) 542 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'), 543 method: 'pkg-config', static: enable_static) 544else 545 if get_option('sdl_image').enabled() 546 error('sdl-image required, but SDL was @0@'.format( 547 get_option('sdl').disabled() ? 'disabled' : 'not found')) 548 endif 549 sdl_image = not_found 550endif 551 552rbd = not_found 553if 'CONFIG_RBD' in config_host 554 rbd = declare_dependency(link_args: config_host['RBD_LIBS'].split()) 555endif 556glusterfs = not_found 557if 'CONFIG_GLUSTERFS' in config_host 558 glusterfs = declare_dependency(compile_args: config_host['GLUSTERFS_CFLAGS'].split(), 559 link_args: config_host['GLUSTERFS_LIBS'].split()) 560endif 561libssh = not_found 562if 'CONFIG_LIBSSH' in config_host 563 libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(), 564 link_args: config_host['LIBSSH_LIBS'].split()) 565endif 566libbzip2 = not_found 567if 'CONFIG_BZIP2' in config_host 568 libbzip2 = declare_dependency(link_args: config_host['BZIP2_LIBS'].split()) 569endif 570liblzfse = not_found 571if 'CONFIG_LZFSE' in config_host 572 liblzfse = declare_dependency(link_args: config_host['LZFSE_LIBS'].split()) 573endif 574oss = not_found 575if 'CONFIG_AUDIO_OSS' in config_host 576 oss = declare_dependency(link_args: config_host['OSS_LIBS'].split()) 577endif 578dsound = not_found 579if 'CONFIG_AUDIO_DSOUND' in config_host 580 dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split()) 581endif 582coreaudio = not_found 583if 'CONFIG_AUDIO_COREAUDIO' in config_host 584 coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split()) 585endif 586opengl = not_found 587if 'CONFIG_OPENGL' in config_host 588 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(), 589 link_args: config_host['OPENGL_LIBS'].split()) 590endif 591gtk = not_found 592if 'CONFIG_GTK' in config_host 593 gtk = declare_dependency(compile_args: config_host['GTK_CFLAGS'].split(), 594 link_args: config_host['GTK_LIBS'].split()) 595endif 596vte = not_found 597if 'CONFIG_VTE' in config_host 598 vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(), 599 link_args: config_host['VTE_LIBS'].split()) 600endif 601x11 = not_found 602if 'CONFIG_X11' in config_host 603 x11 = declare_dependency(compile_args: config_host['X11_CFLAGS'].split(), 604 link_args: config_host['X11_LIBS'].split()) 605endif 606vnc = not_found 607png = not_found 608jpeg = not_found 609sasl = not_found 610if get_option('vnc').enabled() 611 vnc = declare_dependency() # dummy dependency 612 png = dependency('libpng', required: get_option('vnc_png'), 613 method: 'pkg-config', static: enable_static) 614 jpeg = cc.find_library('jpeg', has_headers: ['jpeglib.h'], 615 required: get_option('vnc_jpeg'), 616 static: enable_static) 617 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'], 618 required: get_option('vnc_sasl'), 619 static: enable_static) 620 if sasl.found() 621 sasl = declare_dependency(dependencies: sasl, 622 compile_args: '-DSTRUCT_IOVEC_DEFINED') 623 endif 624endif 625snappy = not_found 626if 'CONFIG_SNAPPY' in config_host 627 snappy = declare_dependency(link_args: config_host['SNAPPY_LIBS'].split()) 628endif 629lzo = not_found 630if 'CONFIG_LZO' in config_host 631 lzo = declare_dependency(link_args: config_host['LZO_LIBS'].split()) 632endif 633rdma = not_found 634if 'CONFIG_RDMA' in config_host 635 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split()) 636endif 637numa = not_found 638if 'CONFIG_NUMA' in config_host 639 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split()) 640endif 641xen = not_found 642if 'CONFIG_XEN_BACKEND' in config_host 643 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(), 644 link_args: config_host['XEN_LIBS'].split()) 645endif 646cacard = not_found 647if 'CONFIG_SMARTCARD' in config_host 648 cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(), 649 link_args: config_host['SMARTCARD_LIBS'].split()) 650endif 651u2f = not_found 652if have_system 653 u2f = dependency('u2f-emu', required: get_option('u2f'), 654 method: 'pkg-config', 655 static: enable_static) 656endif 657usbredir = not_found 658if 'CONFIG_USB_REDIR' in config_host 659 usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(), 660 link_args: config_host['USB_REDIR_LIBS'].split()) 661endif 662libusb = not_found 663if 'CONFIG_USB_LIBUSB' in config_host 664 libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(), 665 link_args: config_host['LIBUSB_LIBS'].split()) 666endif 667libpmem = not_found 668if 'CONFIG_LIBPMEM' in config_host 669 libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(), 670 link_args: config_host['LIBPMEM_LIBS'].split()) 671endif 672libdaxctl = not_found 673if 'CONFIG_LIBDAXCTL' in config_host 674 libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split()) 675endif 676tasn1 = not_found 677if 'CONFIG_TASN1' in config_host 678 tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(), 679 link_args: config_host['TASN1_LIBS'].split()) 680endif 681keyutils = dependency('libkeyutils', required: false, 682 method: 'pkg-config', static: enable_static) 683 684has_gettid = cc.has_function('gettid') 685 686# Malloc tests 687 688malloc = [] 689if get_option('malloc') == 'system' 690 has_malloc_trim = \ 691 not get_option('malloc_trim').disabled() and \ 692 cc.links('''#include <malloc.h> 693 int main(void) { malloc_trim(0); return 0; }''') 694else 695 has_malloc_trim = false 696 malloc = cc.find_library(get_option('malloc'), required: true) 697endif 698if not has_malloc_trim and get_option('malloc_trim').enabled() 699 if get_option('malloc') == 'system' 700 error('malloc_trim not available on this platform.') 701 else 702 error('malloc_trim not available with non-libc memory allocator') 703 endif 704endif 705 706################# 707# config-host.h # 708################# 709 710config_host_data.set('CONFIG_COCOA', cocoa.found()) 711config_host_data.set('CONFIG_LIBUDEV', libudev.found()) 712config_host_data.set('CONFIG_MPATH', mpathpersist.found()) 713config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api) 714config_host_data.set('CONFIG_CURSES', curses.found()) 715config_host_data.set('CONFIG_SDL', sdl.found()) 716config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found()) 717config_host_data.set('CONFIG_VNC', vnc.found()) 718config_host_data.set('CONFIG_VNC_JPEG', jpeg.found()) 719config_host_data.set('CONFIG_VNC_PNG', png.found()) 720config_host_data.set('CONFIG_VNC_SASL', sasl.found()) 721config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found()) 722config_host_data.set('CONFIG_KEYUTILS', keyutils.found()) 723config_host_data.set('CONFIG_GETTID', has_gettid) 724config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim) 725config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version())) 726config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0]) 727config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1]) 728config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2]) 729 730ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target 731arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST'] 732strings = ['HOST_DSOSUF', 'CONFIG_IASL', 'bindir', 'prefix', 'qemu_confdir', 'qemu_datadir', 733 'qemu_moddir', 'qemu_localstatedir', 'qemu_helperdir', 'qemu_localedir', 734 'qemu_icondir', 'qemu_desktopdir', 'qemu_firmwarepath', 'sysconfdir'] 735foreach k, v: config_host 736 if ignored.contains(k) 737 # do nothing 738 elif arrays.contains(k) 739 if v != '' 740 v = '"' + '", "'.join(v.split()) + '", ' 741 endif 742 config_host_data.set(k, v) 743 elif k == 'ARCH' 744 config_host_data.set('HOST_' + v.to_upper(), 1) 745 elif strings.contains(k) 746 if not k.startswith('CONFIG_') 747 k = 'CONFIG_' + k.to_upper() 748 endif 749 config_host_data.set_quoted(k, v) 750 elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_') 751 config_host_data.set(k, v == 'y' ? 1 : v) 752 endif 753endforeach 754 755######################## 756# Target configuration # 757######################## 758 759minikconf = find_program('scripts/minikconf.py') 760config_all = {} 761config_all_devices = {} 762config_all_disas = {} 763config_devices_mak_list = [] 764config_devices_h = {} 765config_target_h = {} 766config_target_mak = {} 767 768disassemblers = { 769 'alpha' : ['CONFIG_ALPHA_DIS'], 770 'arm' : ['CONFIG_ARM_DIS'], 771 'avr' : ['CONFIG_AVR_DIS'], 772 'cris' : ['CONFIG_CRIS_DIS'], 773 'hppa' : ['CONFIG_HPPA_DIS'], 774 'i386' : ['CONFIG_I386_DIS'], 775 'x86_64' : ['CONFIG_I386_DIS'], 776 'x32' : ['CONFIG_I386_DIS'], 777 'lm32' : ['CONFIG_LM32_DIS'], 778 'm68k' : ['CONFIG_M68K_DIS'], 779 'microblaze' : ['CONFIG_MICROBLAZE_DIS'], 780 'mips' : ['CONFIG_MIPS_DIS'], 781 'moxie' : ['CONFIG_MOXIE_DIS'], 782 'nios2' : ['CONFIG_NIOS2_DIS'], 783 'or1k' : ['CONFIG_OPENRISC_DIS'], 784 'ppc' : ['CONFIG_PPC_DIS'], 785 'riscv' : ['CONFIG_RISCV_DIS'], 786 'rx' : ['CONFIG_RX_DIS'], 787 's390' : ['CONFIG_S390_DIS'], 788 'sh4' : ['CONFIG_SH4_DIS'], 789 'sparc' : ['CONFIG_SPARC_DIS'], 790 'xtensa' : ['CONFIG_XTENSA_DIS'], 791} 792if link_language == 'cpp' 793 disassemblers += { 794 'aarch64' : [ 'CONFIG_ARM_A64_DIS'], 795 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'], 796 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'], 797 } 798endif 799 800kconfig_external_symbols = [ 801 'CONFIG_KVM', 802 'CONFIG_XEN', 803 'CONFIG_TPM', 804 'CONFIG_SPICE', 805 'CONFIG_IVSHMEM', 806 'CONFIG_OPENGL', 807 'CONFIG_X11', 808 'CONFIG_VHOST_USER', 809 'CONFIG_VHOST_VDPA', 810 'CONFIG_VHOST_KERNEL', 811 'CONFIG_VIRTFS', 812 'CONFIG_LINUX', 813 'CONFIG_PVRDMA', 814] 815ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ] 816 817default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host 818actual_target_dirs = [] 819fdt_required = [] 820foreach target : target_dirs 821 config_target = { 'TARGET_NAME': target.split('-')[0] } 822 if target.endswith('linux-user') 823 if targetos != 'linux' 824 if default_targets 825 continue 826 endif 827 error('Target @0@ is only available on a Linux host'.format(target)) 828 endif 829 config_target += { 'CONFIG_LINUX_USER': 'y' } 830 elif target.endswith('bsd-user') 831 if 'CONFIG_BSD' not in config_host 832 if default_targets 833 continue 834 endif 835 error('Target @0@ is only available on a BSD host'.format(target)) 836 endif 837 config_target += { 'CONFIG_BSD_USER': 'y' } 838 elif target.endswith('softmmu') 839 config_target += { 'CONFIG_SOFTMMU': 'y' } 840 endif 841 if target.endswith('-user') 842 config_target += { 843 'CONFIG_USER_ONLY': 'y', 844 'CONFIG_QEMU_INTERP_PREFIX': 845 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME']) 846 } 847 endif 848 849 have_accel = false 850 foreach sym: accelerators 851 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, []) 852 config_target += { sym: 'y' } 853 config_all += { sym: 'y' } 854 if sym == 'CONFIG_XEN' and have_xen_pci_passthrough 855 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' } 856 endif 857 have_accel = true 858 endif 859 endforeach 860 if not have_accel 861 if default_targets 862 continue 863 endif 864 error('No accelerator available for target @0@'.format(target)) 865 endif 866 867 actual_target_dirs += target 868 config_target += keyval.load('default-configs/targets' / target + '.mak') 869 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' } 870 871 if 'TARGET_NEED_FDT' in config_target 872 fdt_required += target 873 endif 874 875 # Add default keys 876 if 'TARGET_BASE_ARCH' not in config_target 877 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']} 878 endif 879 if 'TARGET_ABI_DIR' not in config_target 880 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']} 881 endif 882 883 foreach k, v: disassemblers 884 if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k) 885 foreach sym: v 886 config_target += { sym: 'y' } 887 config_all_disas += { sym: 'y' } 888 endforeach 889 endif 890 endforeach 891 892 config_target_data = configuration_data() 893 foreach k, v: config_target 894 if not k.startswith('TARGET_') and not k.startswith('CONFIG_') 895 # do nothing 896 elif ignored.contains(k) 897 # do nothing 898 elif k == 'TARGET_BASE_ARCH' 899 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is 900 # not used to select files from sourcesets. 901 config_target_data.set('TARGET_' + v.to_upper(), 1) 902 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX' 903 config_target_data.set_quoted(k, v) 904 elif v == 'y' 905 config_target_data.set(k, 1) 906 else 907 config_target_data.set(k, v) 908 endif 909 endforeach 910 config_target_h += {target: configure_file(output: target + '-config-target.h', 911 configuration: config_target_data)} 912 913 if target.endswith('-softmmu') 914 base_kconfig = [] 915 foreach sym : kconfig_external_symbols 916 if sym in config_target or sym in config_host 917 base_kconfig += '@0@=y'.format(sym) 918 endif 919 endforeach 920 921 config_devices_mak = target + '-config-devices.mak' 922 config_devices_mak = configure_file( 923 input: ['default-configs/devices' / target + '.mak', 'Kconfig'], 924 output: config_devices_mak, 925 depfile: config_devices_mak + '.d', 926 capture: true, 927 command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'], 928 config_devices_mak, '@DEPFILE@', '@INPUT@', 929 base_kconfig]) 930 931 config_devices_data = configuration_data() 932 config_devices = keyval.load(config_devices_mak) 933 foreach k, v: config_devices 934 config_devices_data.set(k, 1) 935 endforeach 936 config_devices_mak_list += config_devices_mak 937 config_devices_h += {target: configure_file(output: target + '-config-devices.h', 938 configuration: config_devices_data)} 939 config_target += config_devices 940 config_all_devices += config_devices 941 endif 942 config_target_mak += {target: config_target} 943endforeach 944target_dirs = actual_target_dirs 945 946# This configuration is used to build files that are shared by 947# multiple binaries, and then extracted out of the "common" 948# static_library target. 949# 950# We do not use all_sources()/all_dependencies(), because it would 951# build literally all source files, including devices only used by 952# targets that are not built for this compilation. The CONFIG_ALL 953# pseudo symbol replaces it. 954 955config_all += config_all_devices 956config_all += config_host 957config_all += config_all_disas 958config_all += { 959 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'), 960 'CONFIG_SOFTMMU': have_system, 961 'CONFIG_USER_ONLY': have_user, 962 'CONFIG_ALL': true, 963} 964 965############## 966# Submodules # 967############## 968 969capstone = not_found 970capstone_opt = get_option('capstone') 971if capstone_opt in ['enabled', 'auto', 'system'] 972 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile') 973 capstone = dependency('capstone', version: '>=4.0', 974 static: enable_static, method: 'pkg-config', 975 required: capstone_opt == 'system' or 976 capstone_opt == 'enabled' and not have_internal) 977 if capstone.found() 978 capstone_opt = 'system' 979 elif have_internal 980 capstone_opt = 'internal' 981 else 982 capstone_opt = 'disabled' 983 endif 984endif 985if capstone_opt == 'internal' 986 capstone_data = configuration_data() 987 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1') 988 989 capstone_files = files( 990 'capstone/cs.c', 991 'capstone/MCInst.c', 992 'capstone/MCInstrDesc.c', 993 'capstone/MCRegisterInfo.c', 994 'capstone/SStream.c', 995 'capstone/utils.c' 996 ) 997 998 if 'CONFIG_ARM_DIS' in config_all_disas 999 capstone_data.set('CAPSTONE_HAS_ARM', '1') 1000 capstone_files += files( 1001 'capstone/arch/ARM/ARMDisassembler.c', 1002 'capstone/arch/ARM/ARMInstPrinter.c', 1003 'capstone/arch/ARM/ARMMapping.c', 1004 'capstone/arch/ARM/ARMModule.c' 1005 ) 1006 endif 1007 1008 # FIXME: This config entry currently depends on a c++ compiler. 1009 # Which is needed for building libvixl, but not for capstone. 1010 if 'CONFIG_ARM_A64_DIS' in config_all_disas 1011 capstone_data.set('CAPSTONE_HAS_ARM64', '1') 1012 capstone_files += files( 1013 'capstone/arch/AArch64/AArch64BaseInfo.c', 1014 'capstone/arch/AArch64/AArch64Disassembler.c', 1015 'capstone/arch/AArch64/AArch64InstPrinter.c', 1016 'capstone/arch/AArch64/AArch64Mapping.c', 1017 'capstone/arch/AArch64/AArch64Module.c' 1018 ) 1019 endif 1020 1021 if 'CONFIG_PPC_DIS' in config_all_disas 1022 capstone_data.set('CAPSTONE_HAS_POWERPC', '1') 1023 capstone_files += files( 1024 'capstone/arch/PowerPC/PPCDisassembler.c', 1025 'capstone/arch/PowerPC/PPCInstPrinter.c', 1026 'capstone/arch/PowerPC/PPCMapping.c', 1027 'capstone/arch/PowerPC/PPCModule.c' 1028 ) 1029 endif 1030 1031 if 'CONFIG_S390_DIS' in config_all_disas 1032 capstone_data.set('CAPSTONE_HAS_SYSZ', '1') 1033 capstone_files += files( 1034 'capstone/arch/SystemZ/SystemZDisassembler.c', 1035 'capstone/arch/SystemZ/SystemZInstPrinter.c', 1036 'capstone/arch/SystemZ/SystemZMapping.c', 1037 'capstone/arch/SystemZ/SystemZModule.c', 1038 'capstone/arch/SystemZ/SystemZMCTargetDesc.c' 1039 ) 1040 endif 1041 1042 if 'CONFIG_I386_DIS' in config_all_disas 1043 capstone_data.set('CAPSTONE_HAS_X86', 1) 1044 capstone_files += files( 1045 'capstone/arch/X86/X86Disassembler.c', 1046 'capstone/arch/X86/X86DisassemblerDecoder.c', 1047 'capstone/arch/X86/X86ATTInstPrinter.c', 1048 'capstone/arch/X86/X86IntelInstPrinter.c', 1049 'capstone/arch/X86/X86InstPrinterCommon.c', 1050 'capstone/arch/X86/X86Mapping.c', 1051 'capstone/arch/X86/X86Module.c' 1052 ) 1053 endif 1054 1055 configure_file(output: 'capstone-defs.h', configuration: capstone_data) 1056 1057 capstone_cargs = [ 1058 # FIXME: There does not seem to be a way to completely replace the c_args 1059 # that come from add_project_arguments() -- we can only add to them. 1060 # So: disable all warnings with a big hammer. 1061 '-Wno-error', '-w', 1062 1063 # Include all configuration defines via a header file, which will wind up 1064 # as a dependency on the object file, and thus changes here will result 1065 # in a rebuild. 1066 '-include', 'capstone-defs.h' 1067 ] 1068 1069 libcapstone = static_library('capstone', 1070 sources: capstone_files, 1071 c_args: capstone_cargs, 1072 include_directories: 'capstone/include') 1073 capstone = declare_dependency(link_with: libcapstone, 1074 include_directories: 'capstone/include/capstone') 1075endif 1076 1077slirp = not_found 1078slirp_opt = 'disabled' 1079if have_system 1080 slirp_opt = get_option('slirp') 1081 if slirp_opt in ['enabled', 'auto', 'system'] 1082 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build') 1083 slirp = dependency('slirp', static: enable_static, 1084 method: 'pkg-config', 1085 required: slirp_opt == 'system' or 1086 slirp_opt == 'enabled' and not have_internal) 1087 if slirp.found() 1088 slirp_opt = 'system' 1089 elif have_internal 1090 slirp_opt = 'internal' 1091 else 1092 slirp_opt = 'disabled' 1093 endif 1094 endif 1095 if slirp_opt == 'internal' 1096 slirp_deps = [] 1097 if targetos == 'windows' 1098 slirp_deps = cc.find_library('iphlpapi') 1099 endif 1100 slirp_conf = configuration_data() 1101 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0]) 1102 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1]) 1103 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2]) 1104 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version()) 1105 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"'] 1106 slirp_files = [ 1107 'slirp/src/arp_table.c', 1108 'slirp/src/bootp.c', 1109 'slirp/src/cksum.c', 1110 'slirp/src/dhcpv6.c', 1111 'slirp/src/dnssearch.c', 1112 'slirp/src/if.c', 1113 'slirp/src/ip6_icmp.c', 1114 'slirp/src/ip6_input.c', 1115 'slirp/src/ip6_output.c', 1116 'slirp/src/ip_icmp.c', 1117 'slirp/src/ip_input.c', 1118 'slirp/src/ip_output.c', 1119 'slirp/src/mbuf.c', 1120 'slirp/src/misc.c', 1121 'slirp/src/ncsi.c', 1122 'slirp/src/ndp_table.c', 1123 'slirp/src/sbuf.c', 1124 'slirp/src/slirp.c', 1125 'slirp/src/socket.c', 1126 'slirp/src/state.c', 1127 'slirp/src/stream.c', 1128 'slirp/src/tcp_input.c', 1129 'slirp/src/tcp_output.c', 1130 'slirp/src/tcp_subr.c', 1131 'slirp/src/tcp_timer.c', 1132 'slirp/src/tftp.c', 1133 'slirp/src/udp.c', 1134 'slirp/src/udp6.c', 1135 'slirp/src/util.c', 1136 'slirp/src/version.c', 1137 'slirp/src/vmstate.c', 1138 ] 1139 1140 configure_file( 1141 input : 'slirp/src/libslirp-version.h.in', 1142 output : 'libslirp-version.h', 1143 configuration: slirp_conf) 1144 1145 slirp_inc = include_directories('slirp', 'slirp/src') 1146 libslirp = static_library('slirp', 1147 sources: slirp_files, 1148 c_args: slirp_cargs, 1149 include_directories: slirp_inc) 1150 slirp = declare_dependency(link_with: libslirp, 1151 dependencies: slirp_deps, 1152 include_directories: slirp_inc) 1153 endif 1154endif 1155 1156fdt = not_found 1157fdt_opt = get_option('fdt') 1158if have_system 1159 if fdt_opt in ['enabled', 'auto', 'system'] 1160 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt') 1161 fdt = cc.find_library('fdt', static: enable_static, 1162 required: fdt_opt == 'system' or 1163 fdt_opt == 'enabled' and not have_internal) 1164 if fdt.found() and cc.links(''' 1165 #include <libfdt.h> 1166 #include <libfdt_env.h> 1167 int main(void) { fdt_check_full(NULL, 0); return 0; }''', 1168 dependencies: fdt) 1169 fdt_opt = 'system' 1170 elif have_internal 1171 fdt_opt = 'internal' 1172 else 1173 fdt_opt = 'disabled' 1174 endif 1175 endif 1176 if fdt_opt == 'internal' 1177 fdt_files = files( 1178 'dtc/libfdt/fdt.c', 1179 'dtc/libfdt/fdt_ro.c', 1180 'dtc/libfdt/fdt_wip.c', 1181 'dtc/libfdt/fdt_sw.c', 1182 'dtc/libfdt/fdt_rw.c', 1183 'dtc/libfdt/fdt_strerror.c', 1184 'dtc/libfdt/fdt_empty_tree.c', 1185 'dtc/libfdt/fdt_addresses.c', 1186 'dtc/libfdt/fdt_overlay.c', 1187 'dtc/libfdt/fdt_check.c', 1188 ) 1189 1190 fdt_inc = include_directories('dtc/libfdt') 1191 libfdt = static_library('fdt', 1192 sources: fdt_files, 1193 include_directories: fdt_inc) 1194 fdt = declare_dependency(link_with: libfdt, 1195 include_directories: fdt_inc) 1196 endif 1197endif 1198if not fdt.found() and fdt_required.length() > 0 1199 error('fdt not available but required by targets ' + ', '.join(fdt_required)) 1200endif 1201 1202config_host_data.set('CONFIG_CAPSTONE', capstone.found()) 1203config_host_data.set('CONFIG_FDT', fdt.found()) 1204config_host_data.set('CONFIG_SLIRP', slirp.found()) 1205 1206##################### 1207# Generated sources # 1208##################### 1209 1210genh += configure_file(output: 'config-host.h', configuration: config_host_data) 1211 1212hxtool = find_program('scripts/hxtool') 1213shaderinclude = find_program('scripts/shaderinclude.pl') 1214qapi_gen = find_program('scripts/qapi-gen.py') 1215qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py', 1216 meson.source_root() / 'scripts/qapi/commands.py', 1217 meson.source_root() / 'scripts/qapi/common.py', 1218 meson.source_root() / 'scripts/qapi/error.py', 1219 meson.source_root() / 'scripts/qapi/events.py', 1220 meson.source_root() / 'scripts/qapi/expr.py', 1221 meson.source_root() / 'scripts/qapi/gen.py', 1222 meson.source_root() / 'scripts/qapi/introspect.py', 1223 meson.source_root() / 'scripts/qapi/parser.py', 1224 meson.source_root() / 'scripts/qapi/schema.py', 1225 meson.source_root() / 'scripts/qapi/source.py', 1226 meson.source_root() / 'scripts/qapi/types.py', 1227 meson.source_root() / 'scripts/qapi/visit.py', 1228 meson.source_root() / 'scripts/qapi/common.py', 1229 meson.source_root() / 'scripts/qapi-gen.py' 1230] 1231 1232tracetool = [ 1233 python, files('scripts/tracetool.py'), 1234 '--backend=' + config_host['TRACE_BACKENDS'] 1235] 1236 1237qemu_version_cmd = [find_program('scripts/qemu-version.sh'), 1238 meson.current_source_dir(), 1239 config_host['PKGVERSION'], meson.project_version()] 1240qemu_version = custom_target('qemu-version.h', 1241 output: 'qemu-version.h', 1242 command: qemu_version_cmd, 1243 capture: true, 1244 build_by_default: true, 1245 build_always_stale: true) 1246genh += qemu_version 1247 1248hxdep = [] 1249hx_headers = [ 1250 ['qemu-options.hx', 'qemu-options.def'], 1251 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'], 1252] 1253if have_system 1254 hx_headers += [ 1255 ['hmp-commands.hx', 'hmp-commands.h'], 1256 ['hmp-commands-info.hx', 'hmp-commands-info.h'], 1257 ] 1258endif 1259foreach d : hx_headers 1260 hxdep += custom_target(d[1], 1261 input: files(d[0]), 1262 output: d[1], 1263 capture: true, 1264 build_by_default: true, # to be removed when added to a target 1265 command: [hxtool, '-h', '@INPUT0@']) 1266endforeach 1267genh += hxdep 1268 1269SPHINX_ARGS = [config_host['SPHINX_BUILD'], 1270 '-Dversion=' + meson.project_version(), 1271 '-Drelease=' + config_host['PKGVERSION']] 1272 1273if get_option('werror') 1274 SPHINX_ARGS += [ '-W' ] 1275endif 1276 1277sphinx_extn_depends = [ meson.source_root() / 'docs/sphinx/depfile.py', 1278 meson.source_root() / 'docs/sphinx/hxtool.py', 1279 meson.source_root() / 'docs/sphinx/kerneldoc.py', 1280 meson.source_root() / 'docs/sphinx/kernellog.py', 1281 meson.source_root() / 'docs/sphinx/qapidoc.py', 1282 meson.source_root() / 'docs/sphinx/qmp_lexer.py', 1283 qapi_gen_depends ] 1284 1285################### 1286# Collect sources # 1287################### 1288 1289authz_ss = ss.source_set() 1290blockdev_ss = ss.source_set() 1291block_ss = ss.source_set() 1292bsd_user_ss = ss.source_set() 1293chardev_ss = ss.source_set() 1294common_ss = ss.source_set() 1295crypto_ss = ss.source_set() 1296io_ss = ss.source_set() 1297linux_user_ss = ss.source_set() 1298qmp_ss = ss.source_set() 1299qom_ss = ss.source_set() 1300softmmu_ss = ss.source_set() 1301specific_fuzz_ss = ss.source_set() 1302specific_ss = ss.source_set() 1303stub_ss = ss.source_set() 1304trace_ss = ss.source_set() 1305user_ss = ss.source_set() 1306util_ss = ss.source_set() 1307 1308modules = {} 1309hw_arch = {} 1310target_arch = {} 1311target_softmmu_arch = {} 1312 1313############### 1314# Trace files # 1315############### 1316 1317# TODO: add each directory to the subdirs from its own meson.build, once 1318# we have those 1319trace_events_subdirs = [ 1320 'accel/kvm', 1321 'accel/tcg', 1322 'crypto', 1323 'monitor', 1324] 1325if have_user 1326 trace_events_subdirs += [ 'linux-user' ] 1327endif 1328if have_block 1329 trace_events_subdirs += [ 1330 'authz', 1331 'block', 1332 'io', 1333 'nbd', 1334 'scsi', 1335 ] 1336endif 1337if have_system 1338 trace_events_subdirs += [ 1339 'audio', 1340 'backends', 1341 'backends/tpm', 1342 'chardev', 1343 'hw/9pfs', 1344 'hw/acpi', 1345 'hw/alpha', 1346 'hw/arm', 1347 'hw/audio', 1348 'hw/block', 1349 'hw/block/dataplane', 1350 'hw/char', 1351 'hw/display', 1352 'hw/dma', 1353 'hw/hppa', 1354 'hw/hyperv', 1355 'hw/i2c', 1356 'hw/i386', 1357 'hw/i386/xen', 1358 'hw/ide', 1359 'hw/input', 1360 'hw/intc', 1361 'hw/isa', 1362 'hw/mem', 1363 'hw/mips', 1364 'hw/misc', 1365 'hw/misc/macio', 1366 'hw/net', 1367 'hw/nvram', 1368 'hw/pci', 1369 'hw/pci-host', 1370 'hw/ppc', 1371 'hw/rdma', 1372 'hw/rdma/vmw', 1373 'hw/rtc', 1374 'hw/s390x', 1375 'hw/scsi', 1376 'hw/sd', 1377 'hw/sparc', 1378 'hw/sparc64', 1379 'hw/ssi', 1380 'hw/timer', 1381 'hw/tpm', 1382 'hw/usb', 1383 'hw/vfio', 1384 'hw/virtio', 1385 'hw/watchdog', 1386 'hw/xen', 1387 'hw/gpio', 1388 'migration', 1389 'net', 1390 'softmmu', 1391 'ui', 1392 ] 1393endif 1394trace_events_subdirs += [ 1395 'hw/core', 1396 'qapi', 1397 'qom', 1398 'target/arm', 1399 'target/hppa', 1400 'target/i386', 1401 'target/mips', 1402 'target/ppc', 1403 'target/riscv', 1404 'target/s390x', 1405 'target/sparc', 1406 'util', 1407] 1408 1409subdir('qapi') 1410subdir('qobject') 1411subdir('stubs') 1412subdir('trace') 1413subdir('util') 1414subdir('qom') 1415subdir('authz') 1416subdir('crypto') 1417subdir('ui') 1418 1419 1420if enable_modules 1421 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO') 1422 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO') 1423endif 1424 1425stub_ss = stub_ss.apply(config_all, strict: false) 1426 1427util_ss.add_all(trace_ss) 1428util_ss = util_ss.apply(config_all, strict: false) 1429libqemuutil = static_library('qemuutil', 1430 sources: util_ss.sources() + stub_ss.sources() + genh, 1431 dependencies: [util_ss.dependencies(), m, glib, socket, malloc]) 1432qemuutil = declare_dependency(link_with: libqemuutil, 1433 sources: genh + version_res) 1434 1435decodetree = generator(find_program('scripts/decodetree.py'), 1436 output: 'decode-@BASENAME@.c.inc', 1437 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@']) 1438 1439subdir('audio') 1440subdir('io') 1441subdir('chardev') 1442subdir('fsdev') 1443subdir('libdecnumber') 1444subdir('target') 1445subdir('dump') 1446 1447block_ss.add(files( 1448 'block.c', 1449 'blockdev-nbd.c', 1450 'blockjob.c', 1451 'job.c', 1452 'qemu-io-cmds.c', 1453)) 1454block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c')) 1455 1456subdir('nbd') 1457subdir('scsi') 1458subdir('block') 1459 1460blockdev_ss.add(files( 1461 'blockdev.c', 1462 'iothread.c', 1463 'job-qmp.c', 1464)) 1465 1466# os-posix.c contains POSIX-specific functions used by qemu-storage-daemon, 1467# os-win32.c does not 1468blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c')) 1469softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')]) 1470softmmu_ss.add_all(blockdev_ss) 1471 1472common_ss.add(files('cpus-common.c')) 1473 1474subdir('softmmu') 1475 1476common_ss.add(capstone) 1477specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone) 1478specific_ss.add(files('exec-vary.c')) 1479specific_ss.add(when: 'CONFIG_TCG', if_true: files( 1480 'fpu/softfloat.c', 1481 'tcg/optimize.c', 1482 'tcg/tcg-common.c', 1483 'tcg/tcg-op-gvec.c', 1484 'tcg/tcg-op-vec.c', 1485 'tcg/tcg-op.c', 1486 'tcg/tcg.c', 1487)) 1488specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c')) 1489 1490subdir('backends') 1491subdir('disas') 1492subdir('migration') 1493subdir('monitor') 1494subdir('net') 1495subdir('replay') 1496subdir('hw') 1497subdir('accel') 1498subdir('plugins') 1499subdir('bsd-user') 1500subdir('linux-user') 1501 1502bsd_user_ss.add(files('gdbstub.c')) 1503specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss) 1504 1505linux_user_ss.add(files('gdbstub.c', 'thunk.c')) 1506specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss) 1507 1508# needed for fuzzing binaries 1509subdir('tests/qtest/libqos') 1510subdir('tests/qtest/fuzz') 1511 1512######################## 1513# Library dependencies # 1514######################## 1515 1516block_mods = [] 1517softmmu_mods = [] 1518foreach d, list : modules 1519 foreach m, module_ss : list 1520 if enable_modules and targetos != 'windows' 1521 module_ss = module_ss.apply(config_all, strict: false) 1522 sl = static_library(d + '-' + m, [genh, module_ss.sources()], 1523 dependencies: [modulecommon, module_ss.dependencies()], pic: true) 1524 if d == 'block' 1525 block_mods += sl 1526 else 1527 softmmu_mods += sl 1528 endif 1529 else 1530 if d == 'block' 1531 block_ss.add_all(module_ss) 1532 else 1533 softmmu_ss.add_all(module_ss) 1534 endif 1535 endif 1536 endforeach 1537endforeach 1538 1539nm = find_program('nm') 1540undefsym = find_program('scripts/undefsym.py') 1541block_syms = custom_target('block.syms', output: 'block.syms', 1542 input: [libqemuutil, block_mods], 1543 capture: true, 1544 command: [undefsym, nm, '@INPUT@']) 1545qemu_syms = custom_target('qemu.syms', output: 'qemu.syms', 1546 input: [libqemuutil, softmmu_mods], 1547 capture: true, 1548 command: [undefsym, nm, '@INPUT@']) 1549 1550qom_ss = qom_ss.apply(config_host, strict: false) 1551libqom = static_library('qom', qom_ss.sources() + genh, 1552 dependencies: [qom_ss.dependencies()], 1553 name_suffix: 'fa') 1554 1555qom = declare_dependency(link_whole: libqom) 1556 1557authz_ss = authz_ss.apply(config_host, strict: false) 1558libauthz = static_library('authz', authz_ss.sources() + genh, 1559 dependencies: [authz_ss.dependencies()], 1560 name_suffix: 'fa', 1561 build_by_default: false) 1562 1563authz = declare_dependency(link_whole: libauthz, 1564 dependencies: qom) 1565 1566crypto_ss = crypto_ss.apply(config_host, strict: false) 1567libcrypto = static_library('crypto', crypto_ss.sources() + genh, 1568 dependencies: [crypto_ss.dependencies()], 1569 name_suffix: 'fa', 1570 build_by_default: false) 1571 1572crypto = declare_dependency(link_whole: libcrypto, 1573 dependencies: [authz, qom]) 1574 1575io_ss = io_ss.apply(config_host, strict: false) 1576libio = static_library('io', io_ss.sources() + genh, 1577 dependencies: [io_ss.dependencies()], 1578 link_with: libqemuutil, 1579 name_suffix: 'fa', 1580 build_by_default: false) 1581 1582io = declare_dependency(link_whole: libio, dependencies: [crypto, qom]) 1583 1584libmigration = static_library('migration', sources: migration_files + genh, 1585 name_suffix: 'fa', 1586 build_by_default: false) 1587migration = declare_dependency(link_with: libmigration, 1588 dependencies: [zlib, qom, io]) 1589softmmu_ss.add(migration) 1590 1591block_ss = block_ss.apply(config_host, strict: false) 1592libblock = static_library('block', block_ss.sources() + genh, 1593 dependencies: block_ss.dependencies(), 1594 link_depends: block_syms, 1595 name_suffix: 'fa', 1596 build_by_default: false) 1597 1598block = declare_dependency(link_whole: [libblock], 1599 link_args: '@block.syms', 1600 dependencies: [crypto, io]) 1601 1602qmp_ss = qmp_ss.apply(config_host, strict: false) 1603libqmp = static_library('qmp', qmp_ss.sources() + genh, 1604 dependencies: qmp_ss.dependencies(), 1605 name_suffix: 'fa', 1606 build_by_default: false) 1607 1608qmp = declare_dependency(link_whole: [libqmp]) 1609 1610libchardev = static_library('chardev', chardev_ss.sources() + genh, 1611 name_suffix: 'fa', 1612 build_by_default: false) 1613 1614chardev = declare_dependency(link_whole: libchardev) 1615 1616libhwcore = static_library('hwcore', sources: hwcore_files + genh, 1617 name_suffix: 'fa', 1618 build_by_default: false) 1619hwcore = declare_dependency(link_whole: libhwcore) 1620common_ss.add(hwcore) 1621 1622########### 1623# Targets # 1624########### 1625 1626foreach m : block_mods + softmmu_mods 1627 shared_module(m.name(), 1628 name_prefix: '', 1629 link_whole: m, 1630 install: true, 1631 install_dir: config_host['qemu_moddir']) 1632endforeach 1633 1634softmmu_ss.add(authz, block, chardev, crypto, io, qmp) 1635common_ss.add(qom, qemuutil) 1636 1637common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss]) 1638common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss) 1639 1640common_all = common_ss.apply(config_all, strict: false) 1641common_all = static_library('common', 1642 build_by_default: false, 1643 sources: common_all.sources() + genh, 1644 dependencies: common_all.dependencies(), 1645 name_suffix: 'fa') 1646 1647feature_to_c = find_program('scripts/feature_to_c.sh') 1648 1649emulators = {} 1650foreach target : target_dirs 1651 config_target = config_target_mak[target] 1652 target_name = config_target['TARGET_NAME'] 1653 arch = config_target['TARGET_BASE_ARCH'] 1654 arch_srcs = [config_target_h[target]] 1655 arch_deps = [] 1656 c_args = ['-DNEED_CPU_H', 1657 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 1658 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 1659 link_args = emulator_link_args 1660 1661 config_target += config_host 1662 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 1663 if targetos == 'linux' 1664 target_inc += include_directories('linux-headers', is_system: true) 1665 endif 1666 if target.endswith('-softmmu') 1667 qemu_target_name = 'qemu-system-' + target_name 1668 target_type='system' 1669 t = target_softmmu_arch[arch].apply(config_target, strict: false) 1670 arch_srcs += t.sources() 1671 arch_deps += t.dependencies() 1672 1673 hw_dir = target_name == 'sparc64' ? 'sparc64' : arch 1674 hw = hw_arch[hw_dir].apply(config_target, strict: false) 1675 arch_srcs += hw.sources() 1676 arch_deps += hw.dependencies() 1677 1678 arch_srcs += config_devices_h[target] 1679 link_args += ['@block.syms', '@qemu.syms'] 1680 else 1681 abi = config_target['TARGET_ABI_DIR'] 1682 target_type='user' 1683 qemu_target_name = 'qemu-' + target_name 1684 if 'CONFIG_LINUX_USER' in config_target 1685 base_dir = 'linux-user' 1686 target_inc += include_directories('linux-user/host/' / config_host['ARCH']) 1687 else 1688 base_dir = 'bsd-user' 1689 endif 1690 target_inc += include_directories( 1691 base_dir, 1692 base_dir / abi, 1693 ) 1694 if 'CONFIG_LINUX_USER' in config_target 1695 dir = base_dir / abi 1696 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c') 1697 if config_target.has_key('TARGET_SYSTBL_ABI') 1698 arch_srcs += \ 1699 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'], 1700 extra_args : config_target['TARGET_SYSTBL_ABI']) 1701 endif 1702 endif 1703 endif 1704 1705 if 'TARGET_XML_FILES' in config_target 1706 gdbstub_xml = custom_target(target + '-gdbstub-xml.c', 1707 output: target + '-gdbstub-xml.c', 1708 input: files(config_target['TARGET_XML_FILES'].split()), 1709 command: [feature_to_c, '@INPUT@'], 1710 capture: true) 1711 arch_srcs += gdbstub_xml 1712 endif 1713 1714 t = target_arch[arch].apply(config_target, strict: false) 1715 arch_srcs += t.sources() 1716 arch_deps += t.dependencies() 1717 1718 target_common = common_ss.apply(config_target, strict: false) 1719 objects = common_all.extract_objects(target_common.sources()) 1720 deps = target_common.dependencies() 1721 1722 target_specific = specific_ss.apply(config_target, strict: false) 1723 arch_srcs += target_specific.sources() 1724 arch_deps += target_specific.dependencies() 1725 1726 lib = static_library('qemu-' + target, 1727 sources: arch_srcs + genh, 1728 dependencies: arch_deps, 1729 objects: objects, 1730 include_directories: target_inc, 1731 c_args: c_args, 1732 build_by_default: false, 1733 name_suffix: 'fa') 1734 1735 if target.endswith('-softmmu') 1736 execs = [{ 1737 'name': 'qemu-system-' + target_name, 1738 'gui': false, 1739 'sources': files('softmmu/main.c'), 1740 'dependencies': [] 1741 }] 1742 if targetos == 'windows' and (sdl.found() or gtk.found()) 1743 execs += [{ 1744 'name': 'qemu-system-' + target_name + 'w', 1745 'gui': true, 1746 'sources': files('softmmu/main.c'), 1747 'dependencies': [] 1748 }] 1749 endif 1750 if config_host.has_key('CONFIG_FUZZ') 1751 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false) 1752 execs += [{ 1753 'name': 'qemu-fuzz-' + target_name, 1754 'gui': false, 1755 'sources': specific_fuzz.sources(), 1756 'dependencies': specific_fuzz.dependencies(), 1757 }] 1758 endif 1759 else 1760 execs = [{ 1761 'name': 'qemu-' + target_name, 1762 'gui': false, 1763 'sources': [], 1764 'dependencies': [] 1765 }] 1766 endif 1767 foreach exe: execs 1768 emulators += {exe['name']: 1769 executable(exe['name'], exe['sources'], 1770 install: true, 1771 c_args: c_args, 1772 dependencies: arch_deps + deps + exe['dependencies'], 1773 objects: lib.extract_all_objects(recursive: true), 1774 link_language: link_language, 1775 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []), 1776 link_args: link_args, 1777 gui_app: exe['gui']) 1778 } 1779 1780 if 'CONFIG_TRACE_SYSTEMTAP' in config_host 1781 foreach stp: [ 1782 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false}, 1783 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true}, 1784 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true}, 1785 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true}, 1786 ] 1787 custom_target(exe['name'] + stp['ext'], 1788 input: trace_events_all, 1789 output: exe['name'] + stp['ext'], 1790 capture: true, 1791 install: stp['install'], 1792 install_dir: qemu_datadir / '../systemtap/tapset', 1793 command: [ 1794 tracetool, '--group=all', '--format=' + stp['fmt'], 1795 '--binary=' + stp['bin'], 1796 '--target-name=' + target_name, 1797 '--target-type=' + target_type, 1798 '--probe-prefix=qemu.' + target_type + '.' + target_name, 1799 '@INPUT@', 1800 ]) 1801 endforeach 1802 endif 1803 endforeach 1804endforeach 1805 1806# Other build targets 1807 1808if 'CONFIG_PLUGIN' in config_host 1809 install_headers('include/qemu/qemu-plugin.h') 1810endif 1811 1812if 'CONFIG_GUEST_AGENT' in config_host 1813 subdir('qga') 1814endif 1815 1816# Don't build qemu-keymap if xkbcommon is not explicitly enabled 1817# when we don't build tools or system 1818if xkbcommon.found() 1819 # used for the update-keymaps target, so include rules even if !have_tools 1820 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh, 1821 dependencies: [qemuutil, xkbcommon], install: have_tools) 1822endif 1823 1824if have_tools 1825 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep], 1826 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true) 1827 qemu_io = executable('qemu-io', files('qemu-io.c'), 1828 dependencies: [block, qemuutil], install: true) 1829 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'), 1830 dependencies: [block, qemuutil], install: true) 1831 1832 subdir('storage-daemon') 1833 subdir('contrib/rdmacm-mux') 1834 subdir('contrib/elf2dmp') 1835 1836 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'), 1837 dependencies: qemuutil, 1838 install: true) 1839 1840 if 'CONFIG_VHOST_USER' in config_host 1841 subdir('contrib/libvhost-user') 1842 subdir('contrib/vhost-user-blk') 1843 subdir('contrib/vhost-user-gpu') 1844 subdir('contrib/vhost-user-input') 1845 subdir('contrib/vhost-user-scsi') 1846 endif 1847 1848 if targetos == 'linux' 1849 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'), 1850 dependencies: [qemuutil, libcap_ng], 1851 install: true, 1852 install_dir: get_option('libexecdir')) 1853 1854 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'), 1855 dependencies: [authz, crypto, io, qom, qemuutil, 1856 libcap_ng, mpathpersist], 1857 install: true) 1858 endif 1859 1860 if 'CONFIG_IVSHMEM' in config_host 1861 subdir('contrib/ivshmem-client') 1862 subdir('contrib/ivshmem-server') 1863 endif 1864endif 1865 1866subdir('scripts') 1867subdir('tools') 1868subdir('pc-bios') 1869subdir('tests') 1870subdir('docs') 1871if 'CONFIG_GTK' in config_host 1872 subdir('po') 1873endif 1874 1875if host_machine.system() == 'windows' 1876 nsis_cmd = [ 1877 find_program('scripts/nsis.py'), 1878 '@OUTPUT@', 1879 get_option('prefix'), 1880 meson.current_source_dir(), 1881 host_machine.cpu_family(), 1882 '--', 1883 '-DDISPLAYVERSION=' + meson.project_version(), 1884 ] 1885 if build_docs 1886 nsis_cmd += '-DCONFIG_DOCUMENTATION=y' 1887 endif 1888 if 'CONFIG_GTK' in config_host 1889 nsis_cmd += '-DCONFIG_GTK=y' 1890 endif 1891 1892 nsis = custom_target('nsis', 1893 output: 'qemu-setup-' + meson.project_version() + '.exe', 1894 input: files('qemu.nsi'), 1895 build_always_stale: true, 1896 command: nsis_cmd + ['@INPUT@']) 1897 alias_target('installer', nsis) 1898endif 1899 1900######################### 1901# Configuration summary # 1902######################### 1903 1904summary_info = {} 1905summary_info += {'Install prefix': config_host['prefix']} 1906summary_info += {'BIOS directory': config_host['qemu_datadir']} 1907summary_info += {'firmware path': config_host['qemu_firmwarepath']} 1908summary_info += {'binary directory': config_host['bindir']} 1909summary_info += {'library directory': config_host['libdir']} 1910summary_info += {'module directory': config_host['qemu_moddir']} 1911summary_info += {'libexec directory': config_host['libexecdir']} 1912summary_info += {'include directory': config_host['includedir']} 1913summary_info += {'config directory': config_host['sysconfdir']} 1914if targetos != 'windows' 1915 summary_info += {'local state directory': config_host['qemu_localstatedir']} 1916 summary_info += {'Manual directory': get_option('mandir')} 1917else 1918 summary_info += {'local state directory': 'queried at runtime'} 1919endif 1920summary_info += {'Doc directory': get_option('docdir')} 1921summary_info += {'Build directory': meson.current_build_dir()} 1922summary_info += {'Source path': meson.current_source_dir()} 1923summary_info += {'GIT binary': config_host['GIT']} 1924summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']} 1925summary_info += {'C compiler': meson.get_compiler('c').cmd_array()[0]} 1926summary_info += {'Host C compiler': meson.get_compiler('c', native: true).cmd_array()[0]} 1927if link_language == 'cpp' 1928 summary_info += {'C++ compiler': meson.get_compiler('cpp').cmd_array()[0]} 1929else 1930 summary_info += {'C++ compiler': false} 1931endif 1932if targetos == 'darwin' 1933 summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]} 1934endif 1935summary_info += {'ARFLAGS': config_host['ARFLAGS']} 1936summary_info += {'CFLAGS': ' '.join(get_option('c_args') 1937 + ['-O' + get_option('optimization')] 1938 + (get_option('debug') ? ['-g'] : []))} 1939if link_language == 'cpp' 1940 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') 1941 + ['-O' + get_option('optimization')] 1942 + (get_option('debug') ? ['-g'] : []))} 1943endif 1944link_args = get_option(link_language + '_link_args') 1945if link_args.length() > 0 1946 summary_info += {'LDFLAGS': ' '.join(link_args)} 1947endif 1948summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']} 1949summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']} 1950summary_info += {'make': config_host['MAKE']} 1951summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())} 1952summary_info += {'sphinx-build': config_host['SPHINX_BUILD']} 1953summary_info += {'genisoimage': config_host['GENISOIMAGE']} 1954# TODO: add back version 1955summary_info += {'slirp support': slirp_opt == 'disabled' ? false : slirp_opt} 1956if slirp_opt != 'disabled' 1957 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']} 1958endif 1959summary_info += {'module support': config_host.has_key('CONFIG_MODULES')} 1960if config_host.has_key('CONFIG_MODULES') 1961 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')} 1962endif 1963summary_info += {'host CPU': cpu} 1964summary_info += {'host endianness': build_machine.endian()} 1965summary_info += {'target list': ' '.join(target_dirs)} 1966summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')} 1967summary_info += {'sparse enabled': sparse.found()} 1968summary_info += {'strip binaries': get_option('strip')} 1969summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')} 1970summary_info += {'static build': config_host.has_key('CONFIG_STATIC')} 1971if targetos == 'darwin' 1972 summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')} 1973endif 1974# TODO: add back version 1975summary_info += {'SDL support': sdl.found()} 1976summary_info += {'SDL image support': sdl_image.found()} 1977# TODO: add back version 1978summary_info += {'GTK support': config_host.has_key('CONFIG_GTK')} 1979summary_info += {'GTK GL support': config_host.has_key('CONFIG_GTK_GL')} 1980summary_info += {'pixman': pixman.found()} 1981# TODO: add back version 1982summary_info += {'VTE support': config_host.has_key('CONFIG_VTE')} 1983summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']} 1984summary_info += {'GNUTLS support': config_host.has_key('CONFIG_GNUTLS')} 1985# TODO: add back version 1986summary_info += {'libgcrypt': config_host.has_key('CONFIG_GCRYPT')} 1987if config_host.has_key('CONFIG_GCRYPT') 1988 summary_info += {' hmac': config_host.has_key('CONFIG_GCRYPT_HMAC')} 1989 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')} 1990endif 1991# TODO: add back version 1992summary_info += {'nettle': config_host.has_key('CONFIG_NETTLE')} 1993if config_host.has_key('CONFIG_NETTLE') 1994 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')} 1995endif 1996summary_info += {'libtasn1': config_host.has_key('CONFIG_TASN1')} 1997summary_info += {'PAM': config_host.has_key('CONFIG_AUTH_PAM')} 1998summary_info += {'iconv support': iconv.found()} 1999summary_info += {'curses support': curses.found()} 2000# TODO: add back version 2001summary_info += {'virgl support': config_host.has_key('CONFIG_VIRGL')} 2002summary_info += {'curl support': config_host.has_key('CONFIG_CURL')} 2003summary_info += {'mingw32 support': targetos == 'windows'} 2004summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']} 2005summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']} 2006summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']} 2007summary_info += {'VirtFS support': config_host.has_key('CONFIG_VIRTFS')} 2008summary_info += {'Multipath support': mpathpersist.found()} 2009summary_info += {'VNC support': vnc.found()} 2010if vnc.found() 2011 summary_info += {'VNC SASL support': sasl.found()} 2012 summary_info += {'VNC JPEG support': jpeg.found()} 2013 summary_info += {'VNC PNG support': png.found()} 2014endif 2015summary_info += {'xen support': config_host.has_key('CONFIG_XEN_BACKEND')} 2016if config_host.has_key('CONFIG_XEN_BACKEND') 2017 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']} 2018endif 2019summary_info += {'brlapi support': config_host.has_key('CONFIG_BRLAPI')} 2020summary_info += {'Documentation': config_host.has_key('BUILD_DOCS')} 2021summary_info += {'PIE': get_option('b_pie')} 2022summary_info += {'vde support': config_host.has_key('CONFIG_VDE')} 2023summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')} 2024summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')} 2025summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')} 2026summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')} 2027summary_info += {'Install blobs': config_host.has_key('INSTALL_BLOBS')} 2028summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')} 2029summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')} 2030summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')} 2031summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')} 2032summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')} 2033if config_all.has_key('CONFIG_TCG') 2034 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')} 2035 summary_info += {'TCG interpreter': config_host.has_key('CONFIG_TCG_INTERPRETER')} 2036endif 2037summary_info += {'malloc trim support': has_malloc_trim} 2038summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')} 2039summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')} 2040summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt} 2041summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')} 2042summary_info += {'preadv support': config_host.has_key('CONFIG_PREADV')} 2043summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')} 2044summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')} 2045summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')} 2046summary_info += {'posix_memalign': config_host.has_key('CONFIG_POSIX_MEMALIGN')} 2047summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')} 2048summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')} 2049summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')} 2050summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')} 2051summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')} 2052summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_KERNEL')} 2053summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')} 2054summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')} 2055summary_info += {'Trace backends': config_host['TRACE_BACKENDS']} 2056if config_host['TRACE_BACKENDS'].split().contains('simple') 2057 summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'} 2058endif 2059# TODO: add back protocol and server version 2060summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')} 2061summary_info += {'rbd support': config_host.has_key('CONFIG_RBD')} 2062summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')} 2063summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')} 2064summary_info += {'U2F support': u2f.found()} 2065summary_info += {'libusb': config_host.has_key('CONFIG_USB_LIBUSB')} 2066summary_info += {'usb net redir': config_host.has_key('CONFIG_USB_REDIR')} 2067summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')} 2068summary_info += {'OpenGL dmabufs': config_host.has_key('CONFIG_OPENGL_DMABUF')} 2069summary_info += {'libiscsi support': config_host.has_key('CONFIG_LIBISCSI')} 2070summary_info += {'libnfs support': config_host.has_key('CONFIG_LIBNFS')} 2071summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')} 2072if targetos == 'windows' 2073 if 'WIN_SDK' in config_host 2074 summary_info += {'Windows SDK': config_host['WIN_SDK']} 2075 endif 2076 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')} 2077 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')} 2078 summary_info += {'QGA MSI support': config_host.has_key('CONFIG_QGA_MSI')} 2079endif 2080summary_info += {'seccomp support': config_host.has_key('CONFIG_SECCOMP')} 2081summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']} 2082summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'} 2083summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')} 2084summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')} 2085summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')} 2086summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')} 2087summary_info += {'gcov': get_option('b_coverage')} 2088summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')} 2089summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')} 2090summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')} 2091summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')} 2092summary_info += {'lzo support': config_host.has_key('CONFIG_LZO')} 2093summary_info += {'snappy support': config_host.has_key('CONFIG_SNAPPY')} 2094summary_info += {'bzip2 support': config_host.has_key('CONFIG_BZIP2')} 2095summary_info += {'lzfse support': config_host.has_key('CONFIG_LZFSE')} 2096summary_info += {'zstd support': config_host.has_key('CONFIG_ZSTD')} 2097summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')} 2098summary_info += {'libxml2': config_host.has_key('CONFIG_LIBXML2')} 2099summary_info += {'memory allocator': get_option('malloc')} 2100summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')} 2101summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')} 2102summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')} 2103summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')} 2104summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')} 2105summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')} 2106summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')} 2107summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')} 2108summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')} 2109summary_info += {'qed support': config_host.has_key('CONFIG_QED')} 2110summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')} 2111summary_info += {'sheepdog support': config_host.has_key('CONFIG_SHEEPDOG')} 2112summary_info += {'capstone': capstone_opt == 'disabled' ? false : capstone_opt} 2113summary_info += {'libpmem support': config_host.has_key('CONFIG_LIBPMEM')} 2114summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')} 2115summary_info += {'libudev': libudev.found()} 2116summary_info += {'default devices': config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'} 2117summary_info += {'plugin support': config_host.has_key('CONFIG_PLUGIN')} 2118summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')} 2119if config_host.has_key('HAVE_GDB_BIN') 2120 summary_info += {'gdb': config_host['HAVE_GDB_BIN']} 2121endif 2122summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')} 2123summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')} 2124summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')} 2125summary(summary_info, bool_yn: true) 2126 2127if not supported_cpus.contains(cpu) 2128 message() 2129 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!') 2130 message() 2131 message('CPU host architecture ' + cpu + ' support is not currently maintained.') 2132 message('The QEMU project intends to remove support for this host CPU in') 2133 message('a future release if nobody volunteers to maintain it and to') 2134 message('provide a build host for our continuous integration setup.') 2135 message('configure has succeeded and you can continue to build, but') 2136 message('if you care about QEMU on this platform you should contact') 2137 message('us upstream at qemu-devel@nongnu.org.') 2138endif 2139 2140if not supported_oses.contains(targetos) 2141 message() 2142 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!') 2143 message() 2144 message('Host OS ' + targetos + 'support is not currently maintained.') 2145 message('The QEMU project intends to remove support for this host OS in') 2146 message('a future release if nobody volunteers to maintain it and to') 2147 message('provide a build host for our continuous integration setup.') 2148 message('configure has succeeded and you can continue to build, but') 2149 message('if you care about QEMU on this platform you should contact') 2150 message('us upstream at qemu-devel@nongnu.org.') 2151endif 2152