meson.build 174 KB

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