meson.build 177 KB

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