options.pas 171 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749
  1. {
  2. Copyright (c) 1998-2008 by Florian Klaempfl and Peter Vreman
  3. Reads command line options and config files
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit options;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. cfileutl,cclasses,versioncmp,
  22. globtype,globals,verbose,systems,cpuinfo,comprsrc;
  23. Type
  24. TOption=class
  25. FirstPass,
  26. ParaLogo,
  27. NoPressEnter,
  28. FPCHelpLines,
  29. LogoWritten,
  30. ABISetExplicitly,
  31. FPUSetExplicitly,
  32. CPUSetExplicitly,
  33. OptCPUSetExplicitly: boolean;
  34. FileLevel : longint;
  35. QuickInfo : string;
  36. FPCBinaryPath: string;
  37. ParaIncludeCfgPath,
  38. ParaIncludePath,
  39. ParaUnitPath,
  40. ParaObjectPath,
  41. ParaLibraryPath,
  42. ParaFrameworkPath,
  43. parapackagepath : TSearchPathList;
  44. paranamespaces : TCmdStrList;
  45. ParaAlignment : TAlignmentInfo;
  46. parapackages : tfphashobjectlist;
  47. paratarget : tsystem;
  48. paratargetasm : tasm;
  49. paratargetdbg : tdbg;
  50. parasubtarget : string;
  51. LinkTypeSetExplicitly : boolean;
  52. LinkerSetExplicitly : boolean;
  53. Constructor Create;
  54. Destructor Destroy;override;
  55. procedure WriteLogo;
  56. procedure WriteInfo (More: string);
  57. procedure WriteHelpPages;
  58. procedure WriteQuickInfo;
  59. procedure IllegalPara(const opt:TCmdStr);
  60. procedure UnsupportedPara(const opt:TCmdStr);
  61. procedure IgnoredPara(const opt:TCmdStr);
  62. function Unsetbool(var Opts:TCmdStr; Pos: Longint; const FullPara: TCmdStr; RequireBoolPara: Boolean):boolean;
  63. procedure interpret_option(const opt :TCmdStr;ispara:boolean);
  64. procedure Interpret_envvar(const envname : TCmdStr);
  65. procedure Interpret_file(const filename : TPathStr);
  66. procedure Read_Parameters;
  67. procedure parsecmd(cmd:TCmdStr);
  68. procedure TargetOptions(def:boolean);
  69. procedure CheckOptionsCompatibility;
  70. procedure ForceStaticLinking;
  71. private
  72. // Format is Interpret_[A..Z]_(l|U)
  73. // with l for lowercase, U for uppercase
  74. procedure Interpret_A_l(opt, more: TCmdStr);
  75. procedure Interpret_A_U(opt, more: TCmdStr);
  76. procedure Interpret_B_l(opt, more: TCmdStr);
  77. procedure Interpret_B_U(opt, more: TCmdStr);
  78. procedure Interpret_C_U(opt, more: TCmdStr);
  79. procedure Interpret_D_l(opt, more: TCmdStr);
  80. procedure Interpret_D_U(opt, more: TCmdStr);
  81. procedure Interpret_E_l(opt, more: TCmdStr);
  82. procedure Interpret_E_U(opt, more: TCmdStr);
  83. procedure Interpret_F_l(opt, more: TCmdStr);
  84. procedure Interpret_F_U(opt, more: TCmdStr; ispara: boolean);
  85. procedure Interpret_G_l(opt, more: TCmdStr);
  86. procedure Interpret_Help(more: TCmdStr);
  87. procedure Interpret_H_l(more: TCmdStr);
  88. procedure Interpret_I_l(more: TCmdStr);
  89. procedure Interpret_I_U(more: TCmdStr; ispara: boolean);
  90. procedure Interpret_K_l(opt, more: TCmdStr);
  91. procedure Interpret_L_l(opt, more: TCmdStr);
  92. procedure Interpret_M_l(opt, more: TCmdStr);
  93. procedure Interpret_M_U(opt, more: TCmdStr);
  94. procedure Interpret_N_l(opt, more: TCmdStr);
  95. procedure Interpret_O_l(opt, more: TCmdStr);
  96. procedure Interpret_O_U(opt, more: TCmdStr);
  97. procedure Interpret_P_l(opt, more: TCmdStr);
  98. procedure Interpret_P_U(opt, more: TCmdStr);
  99. procedure Interpret_R_U(opt, more: TCmdStr);
  100. procedure Interpret_S_l(opt, more: TCmdStr);
  101. procedure Interpret_S_U(opt, more: TCmdStr);
  102. procedure Interpret_T_l(opt, more: TCmdStr);
  103. procedure Interpret_T_U(opt, more: TCmdStr);
  104. procedure Interpret_U_l(opt, more: TCmdStr);
  105. procedure Interpret_U_U(opt, more: TCmdStr);
  106. procedure Interpret_V_l(opt, more: TCmdStr);
  107. procedure Interpret_V_U(opt, more: TCmdStr);
  108. procedure Interpret_W_U(opt, more: TCmdStr);
  109. procedure Interpret_X_l(opt, more: TCmdStr);
  110. procedure Interpret_X_U(opt, more: TCmdStr);
  111. protected
  112. MacVersionSet: boolean;
  113. IdfVersionSet: boolean;
  114. processorstr: TCmdStr;
  115. function ParseMacVersionMin(out minversion, invalidateversion: tversion; const compvarname, value: string; ios: boolean): boolean;
  116. procedure MaybeSetDefaultMacVersionMacro;
  117. {$ifdef XTENSA}
  118. function ParseVersionStr(out ver: longint; const compvarname, value: string): boolean;
  119. procedure MaybeSetIdfVersionMacro;
  120. {$endif}
  121. {$ifdef llvm}
  122. procedure LLVMEnableSanitizers(sanitizers: TCmdStr);
  123. {$endif llvm}
  124. procedure VerifyTargetProcessor;
  125. end;
  126. TOptionClass=class of toption;
  127. var
  128. coption : TOptionClass;
  129. procedure read_arguments(cmd:TCmdStr);
  130. implementation
  131. uses
  132. widestr,
  133. charset,
  134. SysUtils,
  135. version,
  136. cutils,cmsgs,
  137. comphook,
  138. symtable,scanner,rabase,
  139. symconst,
  140. {$ifdef llvm}
  141. { override supported optimizer transformations at the compiler level }
  142. llvminfo,
  143. {$endif llvm}
  144. dirparse,
  145. pkgutil;
  146. const
  147. page_size = 24;
  148. page_width = 80;
  149. var
  150. option : toption;
  151. read_subfile, { read subtarget config file, set when a cfgfile is found }
  152. read_configfile, { read config file, set when a cfgfile is found }
  153. disable_configfile : boolean;
  154. subcfg,
  155. fpcdir,
  156. ppccfg,
  157. param_file : string; { file to compile specified on the commandline }
  158. {****************************************************************************
  159. Options not supported on all platforms
  160. ****************************************************************************}
  161. const
  162. { gprof (requires implementation of g_profilecode in the code generator) }
  163. supported_targets_pg = [system_i386_linux,system_x86_64_linux,system_mipseb_linux,system_mipsel_linux,system_arm_linux]
  164. + [system_i386_win32]
  165. + [system_powerpc_darwin,system_x86_64_darwin]
  166. + [system_i386_GO32V2]
  167. + [system_i386_freebsd]
  168. + [system_i386_netbsd]
  169. + [system_i386_wdosx]
  170. + [system_riscv32_linux,system_riscv64_linux]
  171. + [system_aarch64_linux];
  172. suppported_targets_x_smallr = systems_linux + systems_solaris + systems_android
  173. + systems_openbsd
  174. + [system_i386_haiku,system_x86_64_haiku]
  175. + [system_i386_beos]
  176. + [system_m68k_amiga];
  177. {****************************************************************************
  178. Defines
  179. ****************************************************************************}
  180. procedure set_default_link_type;
  181. begin
  182. undef_system_macro('FPC_LINK_SMART');
  183. def_system_macro('FPC_LINK_STATIC');
  184. undef_system_macro('FPC_LINK_DYNAMIC');
  185. init_settings.globalswitches:=init_settings.globalswitches+[cs_link_static];
  186. init_settings.globalswitches:=init_settings.globalswitches-[cs_link_shared,cs_link_smart];
  187. {$ifdef AIX}
  188. init_settings.globalswitches:=init_settings.globalswitches+[cs_link_native];
  189. {$endif}
  190. end;
  191. procedure set_endianess_macros;
  192. begin
  193. { endian define }
  194. case target_info.endian of
  195. endian_little :
  196. begin
  197. def_system_macro('ENDIAN_LITTLE');
  198. def_system_macro('FPC_LITTLE_ENDIAN');
  199. undef_system_macro('ENDIAN_BIG');
  200. undef_system_macro('FPC_BIG_ENDIAN');
  201. end;
  202. endian_big :
  203. begin
  204. def_system_macro('ENDIAN_BIG');
  205. def_system_macro('FPC_BIG_ENDIAN');
  206. undef_system_macro('ENDIAN_LITTLE');
  207. undef_system_macro('FPC_LITTLE_ENDIAN');
  208. end;
  209. end;
  210. end;
  211. {****************************************************************************
  212. Toption
  213. ****************************************************************************}
  214. procedure StopOptions(err:longint);
  215. begin
  216. if assigned(Option) then
  217. begin
  218. Option.free;
  219. Option:=nil;
  220. end;
  221. raise ECompilerAbortSilent.Create;
  222. end;
  223. function is_identifier(const s: TCmdStr): boolean;
  224. var
  225. i: longint;
  226. begin
  227. result:=false;
  228. if (s='') or not (s[1] in ['A'..'Z','a'..'z','_']) then
  229. exit;
  230. for i:=2 to length(s) do
  231. if not (s[I] in ['A'..'Z','a'..'z','0'..'9','_']) then
  232. exit;
  233. result:=true;
  234. end;
  235. procedure TOption.WriteLogo;
  236. var
  237. msg : TMsgStr;
  238. p : pchar;
  239. begin
  240. if not LogoWritten then
  241. begin
  242. msg:=MessageStr(option_logo);
  243. p:=pchar(msg);
  244. while assigned(p) do
  245. Comment(V_Normal,GetMsgLine(p));
  246. LogoWritten:= true;
  247. end;
  248. end;
  249. procedure TOption.WriteInfo(More: string);
  250. var
  251. msg_str: TMsgStr;
  252. p : pchar;
  253. hs,hs1,hs3,s : TCmdStr;
  254. J: longint;
  255. xmloutput: Text;
  256. const
  257. NewLineStr = '$\n';
  258. OSTargetsPlaceholder = '$OSTARGETS';
  259. CPUListPlaceholder = '$INSTRUCTIONSETS';
  260. FPUListPlaceholder = '$FPUINSTRUCTIONSETS';
  261. ABIListPlaceholder = '$ABITARGETS';
  262. OptListPlaceholder = '$OPTIMIZATIONS';
  263. WPOListPlaceholder = '$WPOPTIMIZATIONS';
  264. AsmModeListPlaceholder = '$ASMMODES';
  265. ControllerListPlaceholder = '$CONTROLLERTYPES';
  266. FeatureListPlaceholder = '$FEATURELIST';
  267. ModeSwitchListPlaceholder = '$MODESWITCHES';
  268. CodeGenerationBackendPlaceholder = '$CODEGENERATIONBACKEND';
  269. LLVMVersionPlaceholder = '$LLVMVERSIONS';
  270. procedure SplitLine (var OrigString: TCmdStr; const Placeholder: TCmdStr;
  271. out RemainderString: TCmdStr);
  272. var
  273. I: longint;
  274. HS2: TCmdStr;
  275. begin
  276. RemainderString := '';
  277. if OrigString = '' then
  278. Exit;
  279. repeat
  280. I := Pos (NewLineStr, OrigString);
  281. if I > 0 then
  282. begin
  283. HS2 := Copy (OrigString, 1, Pred (I));
  284. { Stop if this line contains the placeholder for list replacement }
  285. if Pos (Placeholder, HS2) > 0 then
  286. begin
  287. RemainderString := Copy (OrigString, I + Length (NewLineStr),
  288. Length (OrigString) - I - Length (NewLineStr));
  289. { Special case - NewLineStr at the end of the line }
  290. if RemainderString = '' then
  291. RemainderString := NewLineStr;
  292. OrigString := HS2;
  293. Exit;
  294. end;
  295. Comment (V_Normal, HS2);
  296. Delete (OrigString, 1, Pred (I) + Length (NewLineStr));
  297. end;
  298. until I = 0;
  299. if (OrigString <> '') and (Pos (Placeholder, OrigString) = 0) then
  300. Comment (V_Normal, OrigString);
  301. end;
  302. procedure ListOSTargets (OrigString: TCmdStr);
  303. var
  304. target : tsystem;
  305. begin
  306. SplitLine (OrigString, OSTargetsPlaceholder, HS3);
  307. for target:=low(tsystem) to high(tsystem) do
  308. if assigned(targetinfos[target]) then
  309. begin
  310. hs1:=targetinfos[target]^.shortname;
  311. if OrigString = '' then
  312. Comment (V_Normal, hs1)
  313. else
  314. begin
  315. hs := OrigString;
  316. hs1:=hs1 + ': ' + targetinfos[target]^.name;
  317. if tf_under_development in targetinfos[target]^.flags then
  318. hs1:=hs1+' {*}';
  319. Replace(hs,OSTargetsPlaceholder,hs1);
  320. Comment(V_Normal,hs);
  321. end;
  322. end;
  323. end;
  324. procedure ListOSTargetsXML;
  325. var
  326. target : tsystem;
  327. begin
  328. WriteLn(xmloutput,' <ostargets>');
  329. for target:=low(tsystem) to high(tsystem) do
  330. if assigned(targetinfos[target]) then
  331. begin
  332. Write(xmloutput,' <ostarget shortname="',targetinfos[target]^.shortname,'" name="',targetinfos[target]^.name,'"');
  333. if tf_under_development in targetinfos[target]^.flags then
  334. Write(' experimental="1"');
  335. WriteLn('/>');
  336. end;
  337. WriteLn(xmloutput,' </ostargets>');
  338. end;
  339. procedure ListCPUInstructionSets (OrigString: TCmdStr);
  340. var
  341. cpu : tcputype;
  342. begin
  343. SplitLine (OrigString, CPUListPlaceholder, HS3);
  344. hs1:='';
  345. for cpu:=low(tcputype) to high(tcputype) do
  346. begin
  347. if (OrigString = '') then
  348. begin
  349. if CPUTypeStr [CPU] <> '' then
  350. Comment (V_Normal, CPUTypeStr [CPU]);
  351. end
  352. else
  353. begin
  354. if length(hs1+cputypestr[cpu])>70 then
  355. begin
  356. hs:=OrigString;
  357. HS1 := HS1 + ',';
  358. Replace(hs,CPUListPlaceholder,hs1);
  359. Comment(V_Normal,hs);
  360. hs1:=''
  361. end
  362. else if hs1<>'' then
  363. hs1:=hs1+',';
  364. if cputypestr[cpu]<>'' then
  365. hs1:=hs1+cputypestr[cpu];
  366. end;
  367. end;
  368. if (OrigString <> '') and (hs1 <> '') then
  369. begin
  370. hs:=OrigString;
  371. Replace(hs,CPUListPlaceholder,hs1);
  372. Comment(V_Normal,hs);
  373. hs1:=''
  374. end;
  375. end;
  376. procedure ListCPUInstructionSetsXML;
  377. var
  378. cpu : tcputype;
  379. begin
  380. WriteLn(xmloutput,' <cpuinstructionsets>');
  381. for cpu:=low(tcputype) to high(tcputype) do
  382. if CPUTypeStr [CPU] <> '' then
  383. WriteLn(xmloutput,' <cpuinstructionset name="',CPUTypeStr [CPU], '"/>');
  384. WriteLn(xmloutput,' </cpuinstructionsets>');
  385. end;
  386. procedure ListFPUInstructionSets (OrigString: TCmdStr);
  387. var
  388. fpu : tfputype;
  389. begin
  390. SplitLine (OrigString, FPUListPlaceholder, HS3);
  391. hs1:='';
  392. for fpu:=low(tfputype) to high(tfputype) do
  393. begin
  394. if (OrigString = '') then
  395. begin
  396. if FPUTypeStr [FPU] <> '' then
  397. Comment (V_Normal, FPUTypeStr [FPU]);
  398. end
  399. else
  400. begin
  401. if length(hs1+fputypestr[fpu])>70 then
  402. begin
  403. hs:=OrigString;
  404. HS1 := HS1 + ',';
  405. Replace(hs,FPUListPlaceholder,hs1);
  406. Comment(V_Normal,hs);
  407. hs1:=''
  408. end
  409. else if hs1<>'' then
  410. hs1:=hs1+',';
  411. if fputypestr[fpu]<>'' then
  412. hs1:=hs1+fputypestr[fpu];
  413. end;
  414. end;
  415. if (OrigString <> '') and (hs1 <> '') then
  416. begin
  417. hs:=OrigString;
  418. Replace(hs,FPUListPlaceholder,hs1);
  419. Comment(V_Normal,hs);
  420. hs1:=''
  421. end;
  422. end;
  423. procedure ListFPUInstructionSetsXML;
  424. var
  425. fpu : tfputype;
  426. begin
  427. WriteLn(xmloutput,' <fpuinstructionsets>');
  428. for fpu:=low(tfputype) to high(tfputype) do
  429. if FPUTypeStr [fpu] <> '' then
  430. WriteLn(xmloutput,' <cpuinstructionset name="',FPUTypeStr [fpu], '"/>');
  431. WriteLn(xmloutput,' </fpuinstructionsets>');
  432. end;
  433. procedure ListABITargets (OrigString: TCmdStr);
  434. var
  435. abi : tabi;
  436. begin
  437. SplitLine (OrigString, ABIListPlaceholder, HS3);
  438. for abi:=low(abi) to high(abi) do
  439. begin
  440. if not abiinfo[abi].supported then
  441. continue;
  442. hs1:=abiinfo[abi].name;
  443. if hs1<>'' then
  444. begin
  445. if OrigString = '' then
  446. Comment (V_Normal, HS1)
  447. else
  448. begin
  449. hs:=OrigString;
  450. Replace(hs,ABIListPlaceholder,hs1);
  451. Comment(V_Normal,hs);
  452. end;
  453. end;
  454. end;
  455. end;
  456. procedure ListABITargetsXML;
  457. var
  458. abi : tabi;
  459. begin
  460. WriteLn(xmloutput,' <abis>');
  461. for abi:=low(abi) to high(abi) do
  462. begin
  463. if not abiinfo[abi].supported then
  464. continue;
  465. if abiinfo[abi].name<>'' then;
  466. WriteLn(xmloutput,' <abi name="',abiinfo[abi].name, '"/>');
  467. end;
  468. WriteLn(xmloutput,' </abis>');
  469. end;
  470. procedure ListOptimizations (OrigString: TCmdStr);
  471. var
  472. opt : toptimizerswitch;
  473. begin
  474. SplitLine (OrigString, OptListPlaceholder, HS3);
  475. for opt:=low(toptimizerswitch) to high(toptimizerswitch) do
  476. begin
  477. if opt in supported_optimizerswitches then
  478. begin
  479. hs1:=OptimizerSwitchStr[opt];
  480. if hs1<>'' then
  481. begin
  482. if OrigString = '' then
  483. Comment (V_Normal, hs1)
  484. else
  485. begin
  486. hs:=OrigString;
  487. Replace(hs,OptListPlaceholder,hs1);
  488. Comment(V_Normal,hs);
  489. end;
  490. end;
  491. end;
  492. end;
  493. end;
  494. procedure ListOptimizationsXML;
  495. var
  496. opt: toptimizerswitch;
  497. begin
  498. WriteLn(xmloutput,' <optimizations>');
  499. for opt:=low(toptimizerswitch) to high(toptimizerswitch) do
  500. if OptimizerSwitchStr[opt]<>'' then
  501. WriteLn(xmloutput,' <optimization name="',OptimizerSwitchStr[opt],'"/>');
  502. WriteLn(xmloutput,' </optimizations>');
  503. end;
  504. procedure ListWPOptimizations (OrigString: TCmdStr);
  505. var
  506. wpopt: twpoptimizerswitch;
  507. begin
  508. SplitLine (OrigString, WPOListPlaceholder, HS3);
  509. for wpopt:=low(twpoptimizerswitch) to high(twpoptimizerswitch) do
  510. begin
  511. { currently all whole program optimizations are platform-independent
  512. if opt in supported_wpoptimizerswitches then
  513. }
  514. begin
  515. hs1:=WPOptimizerSwitchStr[wpopt];
  516. if hs1<>'' then
  517. begin
  518. if OrigString = '' then
  519. Comment (V_Normal, hs1)
  520. else
  521. begin
  522. hs:=OrigString;
  523. Replace(hs,WPOListPlaceholder,hs1);
  524. Comment(V_Normal,hs);
  525. end;
  526. end;
  527. end;
  528. end;
  529. end;
  530. procedure ListWPOptimizationsXML;
  531. var
  532. wpopt: twpoptimizerswitch;
  533. begin
  534. WriteLn(xmloutput,' <wpoptimizations>');
  535. for wpopt:=low(twpoptimizerswitch) to high(twpoptimizerswitch) do
  536. if WPOptimizerSwitchStr[wpopt]<>'' then
  537. WriteLn(xmloutput,' <wpoptimization name="',WPOptimizerSwitchStr[wpopt],'"/>');
  538. WriteLn(xmloutput,' </wpoptimizations>');
  539. end;
  540. procedure ListAsmModes (OrigString: TCmdStr);
  541. var
  542. asmmode : tasmmode;
  543. begin
  544. SplitLine (OrigString, AsmModeListPlaceholder, HS3);
  545. for asmmode:=low(tasmmode) to high(tasmmode) do
  546. if assigned(asmmodeinfos[asmmode]) then
  547. begin
  548. hs1:=asmmodeinfos[asmmode]^.idtxt;
  549. if hs1<>'' then
  550. begin
  551. if OrigString = '' then
  552. Comment (V_Normal, hs1)
  553. else
  554. begin
  555. hs:=OrigString;
  556. Replace(hs,AsmModeListPlaceholder,hs1);
  557. Comment(V_Normal,hs);
  558. end;
  559. end;
  560. end;
  561. end;
  562. procedure ListAsmModesXML;
  563. var
  564. asmmode : tasmmode;
  565. begin
  566. WriteLn(xmloutput,' <asmmodes>');
  567. for asmmode:=low(tasmmode) to high(tasmmode) do
  568. if assigned(asmmodeinfos[asmmode]) then
  569. WriteLn(xmloutput,' <asmmode name="',asmmodeinfos[asmmode]^.idtxt,'"/>');
  570. WriteLn(xmloutput,' </asmmodes>');
  571. end;
  572. procedure ListControllerTypes (OrigString: TCmdStr);
  573. var
  574. controllertype : tcontrollertype;
  575. begin
  576. {$PUSH}
  577. {$WARN 6018 OFF} (* Unreachable code due to compile time evaluation *)
  578. if (ControllerSupport) then
  579. begin
  580. SplitLine (OrigString, ControllerListPlaceholder, HS3);
  581. hs1:='';
  582. for controllertype:=low(tcontrollertype) to high(tcontrollertype) do
  583. begin
  584. if (OrigString = '') then
  585. begin
  586. if Embedded_Controllers [ControllerType].ControllerTypeStr <> '' then
  587. Comment (V_Normal, Embedded_Controllers [ControllerType].ControllerTypeStr);
  588. end
  589. else
  590. begin
  591. if length(hs1+embedded_controllers[controllertype].ControllerTypeStr)
  592. >70 then
  593. begin
  594. hs:=OrigString;
  595. HS1 := HS1 + ',';
  596. Replace(hs,ControllerListPlaceholder,hs1);
  597. Comment(V_Normal,hs);
  598. hs1:=''
  599. end
  600. else if hs1<>'' then
  601. hs1:=hs1+',';
  602. if embedded_controllers[controllertype].ControllerTypeStr<>'' then
  603. hs1:=hs1+embedded_controllers[controllertype].ControllerTypeStr;
  604. end;
  605. end;
  606. if (OrigString <> '') and (hs1<>'') then
  607. begin
  608. hs:=OrigString;
  609. Replace(hs,ControllerListPlaceholder,hs1);
  610. Comment(V_Normal,hs);
  611. hs1:=''
  612. end;
  613. end;
  614. {$POP}
  615. end;
  616. procedure ListControllerTypesXML;
  617. var
  618. controllertype : tcontrollertype;
  619. begin
  620. {$PUSH}
  621. {$WARN 6018 OFF} (* Unreachable code due to compile time evaluation *)
  622. if (ControllerSupport) then
  623. begin
  624. WriteLn(xmloutput,' <controllertypes>');
  625. for controllertype:=low(tcontrollertype) to high(tcontrollertype) do
  626. if embedded_controllers[controllertype].ControllerTypeStr<>'' then
  627. WriteLn(xmloutput,' <controllertype name="',embedded_controllers[controllertype].ControllerTypeStr,
  628. '" controllerunit="',embedded_controllers[controllertype].controllerunitstr, '"/>');
  629. WriteLn(xmloutput,' </controllertypes>');
  630. end;
  631. {$POP}
  632. end;
  633. procedure ListFeatures (OrigString: TCmdStr);
  634. var
  635. Feature: TFeature;
  636. begin
  637. SplitLine (OrigString, FeatureListPlaceholder, HS3);
  638. HS1 := '';
  639. for Feature := Low (TFeature) to High (TFeature) do
  640. begin
  641. if (OrigString = '') then
  642. begin
  643. if FeatureStr [Feature] <> '' then
  644. Comment (V_Normal, FeatureStr [Feature]);
  645. end
  646. else
  647. begin
  648. if Length (HS1 + FeatureStr [Feature]) > 70 then
  649. begin
  650. HS := OrigString;
  651. HS1 := HS1 + ',';
  652. Replace (HS, FeatureListPlaceholder, HS1);
  653. Comment (V_Normal, HS);
  654. HS1 := ''
  655. end
  656. else if HS1 <> '' then
  657. HS1 := HS1 + ',';
  658. if FeatureStr [Feature] <> '' then
  659. HS1 := HS1 + FeatureStr [Feature];
  660. end;
  661. end;
  662. if (OrigString <> '') and (HS1 <> '') then
  663. begin
  664. HS := OrigString;
  665. Replace (HS, FeatureListPlaceholder, HS1);
  666. Comment (V_Normal, HS);
  667. HS1 := ''
  668. end;
  669. end;
  670. procedure ListFeaturesXML;
  671. var
  672. Feature: TFeature;
  673. begin
  674. WriteLn(xmloutput,' <features>');
  675. for Feature := Low (TFeature) to High (TFeature) do
  676. if FeatureStr [Feature] <> '' then
  677. WriteLn(xmloutput,' <feature name="',FeatureStr [Feature],'"/>');
  678. WriteLn(xmloutput,' </features>');
  679. end;
  680. procedure ListModeswitches (OrigString: TCmdStr);
  681. var
  682. Modeswitch: TModeswitch;
  683. begin
  684. SplitLine (OrigString, ModeswitchListPlaceholder, HS3);
  685. HS1 := '';
  686. for Modeswitch := Low (TModeswitch) to High (TModeswitch) do
  687. begin
  688. if (OrigString = '') then
  689. begin
  690. if ModeswitchStr [Modeswitch] <> '' then
  691. Comment (V_Normal, ModeswitchStr [Modeswitch]);
  692. end
  693. else
  694. begin
  695. if Length (HS1 + ModeswitchStr [Modeswitch]) > 60 then
  696. begin
  697. HS := OrigString;
  698. HS1 := HS1 + ',';
  699. Replace (HS, ModeswitchListPlaceholder, HS1);
  700. Comment (V_Normal, HS);
  701. HS1 := ''
  702. end
  703. else if HS1 <> '' then
  704. HS1 := HS1 + ',';
  705. if ModeswitchStr [Modeswitch] <> '' then
  706. HS1 := HS1 + ModeswitchStr [Modeswitch];
  707. end;
  708. end;
  709. if (OrigString <> '') and (HS1 <> '') then
  710. begin
  711. HS := OrigString;
  712. Replace (HS, ModeswitchListPlaceholder, HS1);
  713. Comment (V_Normal, HS);
  714. HS1 := ''
  715. end;
  716. end;
  717. procedure ListModeswitchesXML;
  718. var
  719. Modeswitch: TModeswitch;
  720. begin
  721. WriteLn(xmloutput,' <modeswitches>');
  722. for Modeswitch:=Low(TModeswitch) to High(TModeswitch) do
  723. if ModeswitchStr [Modeswitch]<>'' then
  724. WriteLn(xmloutput,' <modeswitch name="',ModeswitchStr [Modeswitch],'"/>');
  725. WriteLn(xmloutput,' </modeswitches>');
  726. end;
  727. procedure ListCodeGenerationBackend (OrigString: TCmdStr);
  728. begin
  729. SplitLine (OrigString, CodeGenerationBackendPlaceholder, HS3);
  730. hs1:=cgbackend2str[cgbackend];
  731. if OrigString = '' then
  732. Comment (V_Normal, hs1)
  733. else
  734. begin
  735. hs:=OrigString;
  736. Replace(hs,CodeGenerationBackendPlaceholder,hs1);
  737. Comment(V_Normal,hs);
  738. end;
  739. end;
  740. procedure ListCodeGenerationBackendXML;
  741. begin
  742. WriteLn(xmloutput,' <codegeneratorbackend>',cgbackend2str[cgbackend],'</codegeneratorbackend>');
  743. end;
  744. procedure ListLLVMVersions (OrigString: TCmdStr);
  745. {$ifdef LLVM}
  746. var
  747. llvmversion : tllvmversion;
  748. {$endif LLVM}
  749. begin
  750. {$ifdef LLVM}
  751. SplitLine (OrigString, LLVMVersionPlaceholder, HS3);
  752. for llvmversion:=low(llvmversion) to high(llvmversion) do
  753. begin
  754. hs1:=llvmversionstr[llvmversion];
  755. if hs1<>'' then
  756. begin
  757. if OrigString = '' then
  758. Comment (V_Normal, hs1)
  759. else
  760. begin
  761. hs:=OrigString;
  762. Replace(hs,LLVMVersionPlaceholder,hs1);
  763. Comment(V_Normal,hs);
  764. end;
  765. end;
  766. end;
  767. {$else LLVM}
  768. Comment (V_Normal, '')
  769. {$endif LLVM}
  770. end;
  771. procedure ListLLVMVersionsXML;
  772. {$ifdef LLVM}
  773. var
  774. llvmversion : tllvmversion;
  775. {$endif LLVM}
  776. begin
  777. {$ifdef LLVM}
  778. WriteLn(xmloutput,' <llvmversions>');
  779. for llvmversion:=Low(tllvmversion) to High(tllvmversion) do
  780. if llvmversionstr[llvmversion]<>'' then
  781. WriteLn(xmloutput,' <llvmversion name="',llvmversionstr[llvmversion],'"/>');
  782. WriteLn(xmloutput,' </llvmversions>');
  783. {$endif LLVM}
  784. end;
  785. begin
  786. if More = '' then
  787. begin
  788. msg_str:=MessageStr(option_info);
  789. p:=pchar(msg_str);
  790. while assigned(p) do
  791. begin
  792. s:=GetMsgLine(p);
  793. { list permitted values for certain options }
  794. if pos(OSTargetsPlaceholder,s)>0 then
  795. ListOSTargets (S)
  796. else if pos(CPUListPlaceholder,s)>0 then
  797. ListCPUInstructionSets (S)
  798. else if pos(FPUListPlaceholder,s)>0 then
  799. ListFPUInstructionSets (S)
  800. else if pos(ABIListPlaceholder,s)>0 then
  801. ListABITargets (S)
  802. else if pos(OptListPlaceholder,s)>0 then
  803. ListOptimizations (S)
  804. else if pos(WPOListPlaceholder,s)>0 then
  805. ListWPOptimizations (S)
  806. else if Pos (ModeswitchListPlaceholder, S) > 0 then
  807. ListModeswitches (S)
  808. else if pos(AsmModeListPlaceholder,s)>0 then
  809. ListAsmModes (S)
  810. else if pos(ControllerListPlaceholder,s)>0 then
  811. ListControllerTypes (S)
  812. else if pos(FeatureListPlaceholder,s)>0 then
  813. ListFeatures (S)
  814. else if pos(CodeGenerationBackendPlaceholder,s)>0 then
  815. ListCodeGenerationBackend (S)
  816. else if pos(LLVMVersionPlaceholder,s)>0 then
  817. ListLLVMVersions (s)
  818. else
  819. Comment(V_Normal,s);
  820. end;
  821. end
  822. else if Copy(More,1,1) = 'x' then
  823. begin
  824. Assign(xmloutput,Copy(More,2));
  825. Rewrite(xmloutput);
  826. WriteLn(xmloutput,'<?xml version="1.0" encoding="utf-8"?>');
  827. WriteLn(xmloutput,'<fpcoutput>');
  828. WriteLn(xmloutput,' <info>');
  829. ListOSTargetsXML;
  830. ListCPUInstructionSetsXML;
  831. ListFPUInstructionSetsXML;
  832. ListABITargetsXML;
  833. ListOptimizationsXML;
  834. ListWPOptimizationsXML;
  835. ListModeswitchesXML;
  836. ListAsmModesXML;
  837. ListControllerTypesXML;
  838. ListFeaturesXML;
  839. ListCodeGenerationBackendXML;
  840. ListLLVMVersionsXML;
  841. WriteLn(xmloutput,' </info>');
  842. WriteLn(xmloutput,'</fpcoutput>');
  843. Close(xmloutput);
  844. end
  845. else
  846. begin
  847. J := 1;
  848. while J <= Length (More) do
  849. begin
  850. if J > 1 then
  851. Comment(V_Normal,''); (* Put empty line between multiple sections *)
  852. case More [J] of
  853. 'a': ListABITargets ('');
  854. 'b': Comment(V_Normal, cgbackend2str[cgbackend]);
  855. 'c': ListCPUInstructionSets ('');
  856. 'f': ListFPUInstructionSets ('');
  857. 'i': ListAsmModes ('');
  858. {$ifdef LLVM}
  859. 'l': ListLLVMVersions ('');
  860. {$endif LLVM}
  861. 'm': ListModeswitches ('');
  862. 'o': ListOptimizations ('');
  863. 'r': ListFeatures ('');
  864. 't': ListOSTargets ('');
  865. 'u': ListControllerTypes ('');
  866. 'w': ListWPOptimizations ('');
  867. else
  868. IllegalPara ('-i' + More);
  869. end;
  870. Inc (J);
  871. end;
  872. end;
  873. StopOptions(0);
  874. end;
  875. procedure TOption.WriteHelpPages;
  876. function PadEnd(s:string;i:longint):string;
  877. begin
  878. if length(s) >= i then
  879. S := S + ' '
  880. else
  881. while (length(s)<i) do
  882. s:=s+' ';
  883. PadEnd:=s;
  884. end;
  885. var
  886. lastident,
  887. j,outline,
  888. ident,
  889. HelpLineHeight,
  890. lines : longint;
  891. show : boolean;
  892. opt : string[32];
  893. input,
  894. HelpLine,
  895. s : string;
  896. p : pchar;
  897. msg_str: TMsgStr;
  898. begin
  899. WriteLogo;
  900. Lines:=4;
  901. if FPCHelpLines then
  902. Message1(option_usage,FixFileName(FPCBinaryPath))
  903. else
  904. Message1(option_usage,FixFileName(system.paramstr(0)));
  905. lastident:=0;
  906. msg_str:=MessageStr(option_help_pages);
  907. p:=pchar(msg_str);
  908. while assigned(p) do
  909. begin
  910. { get a line and reset }
  911. s:=GetMsgLine(p);
  912. ident:=0;
  913. show:=false;
  914. { parse options }
  915. case s[1] of
  916. 'F': if FPCHelpLines then
  917. Show := true;
  918. {$ifdef UNITALIASES}
  919. 'a',
  920. {$endif}
  921. {$ifdef EXTDEBUG}
  922. 'e',
  923. {$endif EXTDEBUG}
  924. {$ifdef i386}
  925. '3',
  926. {$endif}
  927. {$ifdef x86_64}
  928. '4',
  929. {$endif}
  930. {$ifdef m68k}
  931. '6',
  932. {$endif}
  933. {$ifdef i8086}
  934. '8',
  935. {$endif}
  936. {$ifdef aarch64}
  937. 'a',
  938. {$endif}
  939. {$ifdef arm}
  940. 'A',
  941. {$endif}
  942. {$ifdef mipsel}
  943. 'm',
  944. {$endif}
  945. {$ifdef mipseb}
  946. 'M',
  947. {$endif}
  948. {$ifdef powerpc}
  949. 'P',
  950. {$endif}
  951. {$ifdef powerpc64}
  952. 'p',
  953. {$endif}
  954. {$ifdef sparc}
  955. 'S',
  956. {$endif}
  957. {$ifdef sparc64}
  958. 's',
  959. {$endif}
  960. {$ifdef riscv32}
  961. 'R',
  962. {$endif}
  963. {$ifdef riscv64}
  964. 'r',
  965. {$endif}
  966. {$ifdef avr}
  967. 'V',
  968. {$endif}
  969. {$ifdef jvm}
  970. 'J',
  971. {$endif}
  972. {$ifdef llvm}
  973. 'L',
  974. {$endif}
  975. {$ifdef xtensa}
  976. 'x',
  977. {$endif}
  978. {$ifdef z80}
  979. 'Z',
  980. {$endif}
  981. {$ifdef wasm32}
  982. 'W',
  983. {$endif}
  984. {$ifdef loongarch64}
  985. 'l',
  986. {$endif}
  987. '*' : show:=true;
  988. end;
  989. if show then
  990. begin
  991. case s[2] of
  992. 'g',
  993. {$ifdef Unix}
  994. 'L',
  995. {$endif}
  996. {$ifdef os2}
  997. 'O',
  998. {$endif}
  999. '*' : show:=true;
  1000. else
  1001. show:=false;
  1002. end;
  1003. end;
  1004. { now we may show the message or not }
  1005. if show then
  1006. begin
  1007. case s[3] of
  1008. '0' : begin
  1009. ident:=0;
  1010. outline:=0;
  1011. end;
  1012. '1' : begin
  1013. ident:=2;
  1014. outline:=7;
  1015. end;
  1016. '2' : begin
  1017. ident:=6;
  1018. outline:=11;
  1019. end;
  1020. '3' : begin
  1021. ident:=9;
  1022. outline:=11;
  1023. end;
  1024. else
  1025. internalerror(2013112906);
  1026. end;
  1027. j:=pos('_',s);
  1028. opt:=Copy(s,4,j-4);
  1029. if opt='*' then
  1030. opt:=''
  1031. else
  1032. if (opt=' ') or (opt[1]='@') then
  1033. opt:=PadEnd(opt,outline)
  1034. else
  1035. opt:=PadEnd('-'+opt,outline);
  1036. if (ident=0) and (lastident<>0) then
  1037. begin
  1038. Comment(V_Normal,'');
  1039. inc(Lines);
  1040. end;
  1041. HelpLine := PadEnd('',ident)+opt+Copy(s,j+1,255);
  1042. if HelpLine = '' then
  1043. HelpLineHeight := 1
  1044. else
  1045. HelpLineHeight := Succ (CharLength (HelpLine) div Page_Width);
  1046. { page full ? }
  1047. if (lines + HelpLineHeight >= page_size - 1) then
  1048. begin
  1049. if not NoPressEnter then
  1050. begin
  1051. Message(option_help_press_enter);
  1052. readln(input);
  1053. if upper(input)='Q' then
  1054. StopOptions(0);
  1055. end;
  1056. lines:=0;
  1057. end;
  1058. Comment(V_Normal,HelpLine);
  1059. LastIdent:=Ident;
  1060. Inc (Lines, HelpLineHeight);
  1061. end;
  1062. end;
  1063. StopOptions(0);
  1064. end;
  1065. procedure TOption.IllegalPara(const opt: TCmdStr);
  1066. begin
  1067. Message1(option_illegal_para,opt);
  1068. Message(option_help_pages_para);
  1069. StopOptions(1);
  1070. end;
  1071. procedure TOption.UnsupportedPara(const opt: TCmdStr);
  1072. begin
  1073. Message1(option_unsupported_target,opt);
  1074. StopOptions(1);
  1075. end;
  1076. procedure TOption.IgnoredPara(const opt: TCmdStr);
  1077. begin
  1078. Message1(option_ignored_target,opt);
  1079. end;
  1080. procedure TOption.ForceStaticLinking;
  1081. begin
  1082. def_system_macro('FPC_LINK_STATIC');
  1083. undef_system_macro('FPC_LINK_SMART');
  1084. undef_system_macro('FPC_LINK_DYNAMIC');
  1085. include(init_settings.globalswitches,cs_link_static);
  1086. exclude(init_settings.globalswitches,cs_link_smart);
  1087. exclude(init_settings.globalswitches,cs_link_shared);
  1088. LinkTypeSetExplicitly:=true;
  1089. end;
  1090. function TOption.ParseMacVersionMin(out minversion,
  1091. invalidateversion: tversion; const compvarname, value: string; ios: boolean
  1092. ): boolean;
  1093. function subval(start,maxlen: longint; out stop: longint): string;
  1094. var
  1095. i: longint;
  1096. begin
  1097. result:='';
  1098. i:=start;
  1099. while (i<=length(value)) and
  1100. (value[i] in ['0'..'9']) do
  1101. inc(i);
  1102. { sufficient amount of digits? }
  1103. if (i=start) or
  1104. (i-start>maxlen) then
  1105. exit;
  1106. result:=copy(value,start,i-start);
  1107. stop:=i;
  1108. end;
  1109. var
  1110. temp,
  1111. compvarvalue,
  1112. versionstr: string[15];
  1113. major, minor, patch: cardinal;
  1114. i, err: longint;
  1115. osx_minor_two_digits: boolean;
  1116. begin
  1117. invalidateversion.invalidate;
  1118. versionstr:=value;
  1119. MacVersionSet:=false;
  1120. { check whether the value is a valid version number }
  1121. if value='' then
  1122. begin
  1123. undef_system_macro(compvarname);
  1124. exit(true);
  1125. end;
  1126. { major version number }
  1127. compvarvalue:=subval(1,2,i);
  1128. { not enough digits -> invalid }
  1129. if compvarvalue='' then
  1130. exit(false);
  1131. { already end of string -> invalid }
  1132. if (i>=length(value)) or
  1133. (value[i]<>'.') then
  1134. exit(false);
  1135. val(compvarvalue,major,err);
  1136. if err<>0 then
  1137. exit(false);
  1138. { minor version number }
  1139. temp:=subval(i+1,2,i);
  1140. if temp='' then
  1141. exit(false);
  1142. val(temp,minor,err);
  1143. if err<>0 then
  1144. exit(false);
  1145. { on Mac OS X, the minor version number was originally limited to 1 digit;
  1146. with 10.10 the format changed and two digits were also supported; on iOS,
  1147. the minor version number always takes up two digits }
  1148. osx_minor_two_digits:=false;
  1149. if not ios then
  1150. begin
  1151. { if the minor version number is two digits on OS X (the case since
  1152. OS X 10.10), we also have to add two digits for the patch level}
  1153. if length(temp)=2 then
  1154. osx_minor_two_digits:=true;
  1155. end
  1156. { the minor version number always takes up two digits on iOS }
  1157. else if length(temp)=1 then
  1158. temp:='0'+temp;
  1159. compvarvalue:=compvarvalue+temp;
  1160. { optional patch level }
  1161. patch:=0;
  1162. if i<=length(value) then
  1163. begin
  1164. if value[i]<>'.' then
  1165. exit(false);
  1166. temp:=subval(i+1,2,i);
  1167. if temp='' then
  1168. exit(false);
  1169. { there's only room for a single digit patch level in the version macro
  1170. for Mac OS X. gcc sets it to zero if there are more digits, but that
  1171. seems worse than clamping to 9 (don't declare as invalid like with
  1172. minor version number, because there is a precedent like 10.4.11).
  1173. As of OS X 10.10 there are two digits for the patch level
  1174. }
  1175. if not ios and
  1176. not osx_minor_two_digits then
  1177. begin
  1178. if length(temp)<>1 then
  1179. temp:='9';
  1180. end
  1181. else
  1182. begin
  1183. { on iOS, the patch level is always two digits }
  1184. if length(temp)=1 then
  1185. temp:='0'+temp;
  1186. end;
  1187. compvarvalue:=compvarvalue+temp;
  1188. { must be the end }
  1189. if i<=length(value) then
  1190. exit(false);
  1191. val(temp,patch,err);
  1192. if err<>0 then
  1193. exit(false);
  1194. end
  1195. else if not ios and
  1196. not osx_minor_two_digits then
  1197. begin
  1198. compvarvalue:=compvarvalue+'0';
  1199. versionstr:=versionstr+'.0'
  1200. end
  1201. else
  1202. begin
  1203. compvarvalue:=compvarvalue+'00';
  1204. { command line versions still only use one 0 though }
  1205. versionstr:=versionstr+'.0'
  1206. end;
  1207. minversion.init(versionstr,major,minor,patch);
  1208. set_system_compvar(compvarname,compvarvalue);
  1209. MacVersionSet:=true;
  1210. result:=true;
  1211. end;
  1212. {$ifdef XTENSA}
  1213. function TOption.ParseVersionStr(out ver: longint;
  1214. const compvarname, value: string): boolean;
  1215. function subval(start,maxlen: longint; out stop: longint): string;
  1216. var
  1217. i: longint;
  1218. begin
  1219. result:='';
  1220. i:=start;
  1221. while (i<=length(value)) and
  1222. (value[i] in ['0'..'9']) do
  1223. inc(i);
  1224. { sufficient amount of digits? }
  1225. if (i=start) or
  1226. (i-start>maxlen) then
  1227. exit;
  1228. result:=copy(value,start,i-start);
  1229. stop:=i;
  1230. end;
  1231. var
  1232. temp,
  1233. compvarvalue: string[15];
  1234. i: longint;
  1235. begin
  1236. Result:=false;
  1237. IdfVersionSet:=false;
  1238. emptystr:='';
  1239. { check whether the value is a valid version number }
  1240. if value='' then
  1241. begin
  1242. undef_system_macro(compvarname);
  1243. exit(true);
  1244. end;
  1245. { major version number }
  1246. compvarvalue:=subval(1,2,i);
  1247. { not enough digits -> invalid }
  1248. if compvarvalue='' then
  1249. exit(false);
  1250. { already end of string -> invalid }
  1251. if (i>=length(value)) or
  1252. (value[i]<>'.') then
  1253. exit(false);
  1254. { minor version number }
  1255. temp:=subval(i+1,2,i);
  1256. if temp='' then
  1257. exit(false);
  1258. if length(temp)=1 then
  1259. temp:='0'+temp;
  1260. compvarvalue:=compvarvalue+temp;
  1261. { patch level }
  1262. if i<=length(value) then
  1263. begin
  1264. if value[i]<>'.' then
  1265. exit(false);
  1266. temp:=subval(i+1,2,i);
  1267. if temp='' then
  1268. exit(false);
  1269. if length(temp)=1 then
  1270. temp:='0'+temp;
  1271. compvarvalue:=compvarvalue+temp;
  1272. { must be the end }
  1273. if i<=length(value) then
  1274. exit(false);
  1275. end
  1276. else
  1277. begin
  1278. compvarvalue:=compvarvalue+'00';
  1279. end;
  1280. val(compvarvalue,idf_version,i);
  1281. if i=0 then
  1282. begin
  1283. set_system_compvar(compvarname,compvarvalue);
  1284. IdfVersionSet:=true;
  1285. result:=true;
  1286. end;
  1287. end;
  1288. {$endif XTENSA}
  1289. procedure TOption.MaybeSetDefaultMacVersionMacro;
  1290. var
  1291. envstr: ansistring;
  1292. begin
  1293. if not(target_info.system in systems_darwin) then
  1294. exit;
  1295. if MacVersionSet then
  1296. exit;
  1297. { check for deployment target set via environment variable }
  1298. if not(target_info.system in [system_i386_iphonesim,system_arm_ios,system_aarch64_ios,system_x86_64_iphonesim,system_aarch64_iphonesim]) then
  1299. begin
  1300. envstr:=GetEnvironmentVariable('MACOSX_DEPLOYMENT_TARGET');
  1301. if envstr<>'' then
  1302. if not ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED',envstr,false) then
  1303. Message1(option_invalid_macosx_deployment_target,envstr)
  1304. else
  1305. begin
  1306. {$ifdef llvm}
  1307. { We only support libunwind as part of libsystem, which happened in Mac OS X 10.6 }
  1308. if MacOSXVersionMin.relationto(10,6,0)<0 then
  1309. Message1(option_invalid_macosx_deployment_target,envstr);
  1310. {$endif}
  1311. exit;
  1312. end;
  1313. end
  1314. else
  1315. begin
  1316. envstr:=GetEnvironmentVariable('IPHONEOS_DEPLOYMENT_TARGET');
  1317. if envstr<>'' then
  1318. if not ParseMacVersionMin(iPhoneOSVersionMin,MacOSXVersionMin,'IPHONE_OS_VERSION_MIN_REQUIRED',envstr,true) then
  1319. Message1(option_invalid_iphoneos_deployment_target,envstr)
  1320. else
  1321. exit;
  1322. end;
  1323. { nothing specified -> defaults }
  1324. case target_info.system of
  1325. system_powerpc_darwin:
  1326. begin
  1327. if not ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED','10.3.0',false) then
  1328. internalerror(2022090910);
  1329. end;
  1330. system_powerpc64_darwin:
  1331. begin
  1332. if not ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED','10.4.0',false) then
  1333. internalerror(2022090911);
  1334. end;
  1335. system_i386_darwin,
  1336. system_x86_64_darwin:
  1337. begin
  1338. if not ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED','10.8.0',false) then
  1339. internalerror(2022090912);
  1340. end;
  1341. system_arm_ios,
  1342. system_i386_iphonesim:
  1343. begin
  1344. if not ParseMacVersionMin(iPhoneOSVersionMin,MacOSXVersionMin,'IPHONE_OS_VERSION_MIN_REQUIRED','9.0.0',false) then
  1345. internalerror(2022090913);
  1346. end;
  1347. system_aarch64_ios,
  1348. system_x86_64_iphonesim:
  1349. begin
  1350. if not ParseMacVersionMin(iPhoneOSVersionMin,MacOSXVersionMin,'IPHONE_OS_VERSION_MIN_REQUIRED','9.0.0',false) then
  1351. internalerror(2022090914);
  1352. end;
  1353. system_aarch64_iphonesim:
  1354. begin
  1355. if not ParseMacVersionMin(iPhoneOSVersionMin,MacOSXVersionMin,'IPHONE_OS_VERSION_MIN_REQUIRED','14.0.0',false) then
  1356. internalerror(2023032201);
  1357. end;
  1358. system_aarch64_darwin:
  1359. begin
  1360. if not ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED','11.0.0',false) then
  1361. internalerror(2022090915);
  1362. end
  1363. else
  1364. internalerror(2012031001);
  1365. end;
  1366. end;
  1367. {$ifdef llvm}
  1368. procedure TOption.LLVMEnableSanitizers(sanitizers: TCmdStr);
  1369. var
  1370. sanitizer: TCMdStr;
  1371. begin
  1372. sanitizer:=GetToken(sanitizers,',');
  1373. repeat
  1374. case sanitizer of
  1375. 'address':
  1376. include(init_settings.moduleswitches,cs_sanitize_address);
  1377. else
  1378. IllegalPara(sanitizer);
  1379. end;
  1380. sanitizer:=GetToken(sanitizers,',');
  1381. until sanitizer='';
  1382. end;
  1383. {$endif}
  1384. {$ifdef XTENSA}
  1385. procedure TOption.MaybeSetIdfVersionMacro;
  1386. begin
  1387. if not(target_info.system=system_xtensa_freertos) then
  1388. exit;
  1389. if IdfVersionSet then
  1390. exit;
  1391. { nothing specified -> defaults }
  1392. case current_settings.controllertype of
  1393. ct_esp8266:
  1394. begin
  1395. set_system_compvar('IDF_VERSION','30300');
  1396. idf_version:=30300;
  1397. end;
  1398. ct_esp32:
  1399. begin
  1400. set_system_compvar('IDF_VERSION','40200');
  1401. idf_version:=40200;
  1402. end;
  1403. else
  1404. begin
  1405. set_system_compvar('IDF_VERSION','00000');
  1406. idf_version:=0;
  1407. end;
  1408. end;
  1409. end;
  1410. {$endif XTENSA}
  1411. procedure TOption.VerifyTargetProcessor;
  1412. begin
  1413. { no custom target processor specified -> ok }
  1414. if processorstr='' then
  1415. exit;
  1416. { custom target processor specified -> verify it's the one we support }
  1417. if upcase(processorstr)<>upcase(target_cpu_string) then
  1418. Message1(option_invalid_target_architecture,processorstr);
  1419. end;
  1420. function TOption.Unsetbool(var Opts: TCmdStr; Pos: Longint;
  1421. const FullPara: TCmdStr; RequireBoolPara: Boolean): boolean;
  1422. { checks if the character after pos in Opts is a + or a - and returns resp.
  1423. false or true. If it is another character (or none), it also returns false }
  1424. begin
  1425. UnsetBool := false;
  1426. if Length(Opts)>Pos then
  1427. begin
  1428. inc(Pos);
  1429. UnsetBool := Opts[Pos] = '-';
  1430. if Opts[Pos] in ['-','+']then
  1431. delete(Opts,Pos,1)
  1432. else if RequireBoolPara then
  1433. IllegalPara(FullPara);
  1434. end;
  1435. end;
  1436. procedure TOption.interpret_option(const opt:TCmdStr;ispara:boolean);
  1437. var
  1438. more : TCmdStr;
  1439. begin
  1440. if opt='' then
  1441. exit;
  1442. { only parse define,undef,target,verbosity,link etc options the firsttime
  1443. -Us must now also be first-passed to avoid rejection of -Sf options
  1444. earlier in command line }
  1445. if firstpass and
  1446. not(
  1447. (opt[1]='-') and
  1448. (
  1449. ((length(opt)>1) and (opt[2] in ['i','d','v','T','t','u','n','x','X','l','U'])) or
  1450. ((length(opt)>3) and (opt[2]='F') and (opt[3]='e')) or
  1451. ((length(opt)>2) and (opt[2]='C') and (opt[3] in ['a','b','f','p'])) or
  1452. ((length(opt)>3) and (opt[2]='W') and (opt[3] in ['m','p']))
  1453. )
  1454. ) then
  1455. exit;
  1456. Message1(option_handling_option,opt);
  1457. case opt[1] of
  1458. '-' :
  1459. begin
  1460. more:=Copy(opt,3,2147483647);
  1461. if firstpass then
  1462. Message1(option_interpreting_firstpass_option,opt)
  1463. else
  1464. Message1(option_interpreting_option,opt);
  1465. case opt[2] of
  1466. '?' : Interpret_Help(more);
  1467. 'a' : Interpret_A_l(opt,more);
  1468. 'A' : Interpret_A_U(opt,more);
  1469. 'b' : Interpret_B_l(opt,more);
  1470. 'B' : Interpret_B_U(opt,more);
  1471. 'C' : Interpret_C_U(opt,more);
  1472. 'd' : Interpret_D_l(opt,more);
  1473. 'D' : Interpret_D_U(opt,more);
  1474. 'e' : Interpret_E_l(opt,more);
  1475. 'E' : Interpret_E_U(opt,more);
  1476. 'f' : Interpret_F_l(opt,more);
  1477. 'F' : Interpret_F_U(opt,more,ispara);
  1478. 'g' : Interpret_G_l(opt,more);
  1479. 'h' : Interpret_H_l(more);
  1480. 'i' : Interpret_I_l(more);
  1481. 'I' : Interpret_I_U(more,ispara);
  1482. 'k' : Interpret_K_l(opt,more);
  1483. 'l' : Interpret_L_l(opt,more);
  1484. 'm' : Interpret_M_l(opt,more);
  1485. 'M' : Interpret_M_U(opt,more);
  1486. 'n' : Interpret_N_l(opt,more);
  1487. 'o' : Interpret_O_l(opt,more);
  1488. 'O' : Interpret_O_U(opt,more);
  1489. 'p' : Interpret_P_l(opt,more);
  1490. 'P' : Interpret_P_U(opt,more);
  1491. 'R' : Interpret_R_U(opt,more);
  1492. 's' : Interpret_S_l(opt,more);
  1493. 'S' : Interpret_S_U(opt,more);
  1494. 'T' : Interpret_T_U(opt,more);
  1495. 't' : Interpret_T_l(opt,more);
  1496. 'u' : Interpret_U_l(opt,more);
  1497. 'U' : Interpret_U_U(opt,more);
  1498. 'v' : Interpret_V_l(opt,more);
  1499. 'V' : Interpret_V_U(opt,more);
  1500. 'W' : Interpret_W_U(opt,more);
  1501. 'x' : Interpret_X_l(opt,more);
  1502. 'X' : Interpret_X_U(opt,more);
  1503. else
  1504. IllegalPara(opt);
  1505. end;
  1506. end;
  1507. '@' :
  1508. begin
  1509. Message(option_no_nested_response_file);
  1510. StopOptions(1);
  1511. end;
  1512. else
  1513. begin
  1514. if (length(param_file)<>0) then
  1515. Message2(option_only_one_source_support,param_file,opt);
  1516. param_file:=opt;
  1517. Message1(option_found_file,opt);
  1518. end;
  1519. end;
  1520. end;
  1521. procedure TOption.Interpret_file(const filename: TPathStr);
  1522. procedure RemoveSep(var fn:TPathStr);
  1523. var
  1524. i : longint;
  1525. begin
  1526. i:=0;
  1527. while (i<length(fn)) and (fn[i+1] in [',',' ',#9]) do
  1528. inc(i);
  1529. Delete(fn,1,i);
  1530. i:=length(fn);
  1531. while (i>0) and (fn[i] in [',',' ',#9]) do
  1532. dec(i);
  1533. fn:=copy(fn,1,i);
  1534. end;
  1535. function GetName(var fn:TPathStr):TPathStr;
  1536. var
  1537. i : longint;
  1538. begin
  1539. i:=0;
  1540. while (i<length(fn)) and (fn[i+1] in ['a'..'z','A'..'Z','0'..'9','_','-']) do
  1541. inc(i);
  1542. GetName:=Copy(fn,1,i);
  1543. Delete(fn,1,i);
  1544. end;
  1545. const
  1546. maxlevel = 15;
  1547. var
  1548. f : text;
  1549. s, tmp,
  1550. opts : TCmdStr;
  1551. skip : array[0..maxlevel] of boolean;
  1552. line,
  1553. level : longint;
  1554. option_read : boolean;
  1555. oldfilemode : byte;
  1556. ConfigFile: TPathStr;
  1557. begin
  1558. { avoid infinite loop }
  1559. Inc(FileLevel);
  1560. Option_read:=false;
  1561. If FileLevel>MaxLevel then
  1562. Message(option_too_many_cfg_files);
  1563. if not ParaIncludeCfgPath.FindFile(fileName,true,ConfigFile) then
  1564. ConfigFile := ExpandFileName(filename);
  1565. { Maybe It's Directory ?} //Jaro Change:
  1566. if PathExists(ConfigFile,false) then
  1567. begin
  1568. Message1(option_config_is_dir,filename);
  1569. exit;
  1570. end;
  1571. { open file }
  1572. Message1(option_using_file,filename);
  1573. oldfilemode:=filemode;
  1574. filemode:=0;
  1575. assign(f,ConfigFile);
  1576. {$push}{$I-}
  1577. reset(f);
  1578. {$pop}
  1579. filemode:=oldfilemode;
  1580. if ioresult<>0 then
  1581. begin
  1582. Message1(option_unable_open_file,filename);
  1583. exit;
  1584. end;
  1585. Message1(option_start_reading_configfile,filename);
  1586. fillchar(skip,sizeof(skip),0);
  1587. level:=0;
  1588. line:=0;
  1589. while not eof(f) do
  1590. begin
  1591. readln(f,opts);
  1592. inc(line);
  1593. RemoveSep(opts);
  1594. if (opts<>'') and (opts[1]<>';') then
  1595. begin
  1596. if opts[1]='#' then
  1597. begin
  1598. Message1(option_interpreting_file_option,opts);
  1599. Delete(opts,1,1);
  1600. s:=upper(GetName(opts));
  1601. if (s='SECTION') then
  1602. begin
  1603. RemoveSep(opts);
  1604. s:=upper(GetName(opts));
  1605. if level=0 then
  1606. skip[level]:=not defined_macro(s) or (s='COMMON');
  1607. end
  1608. else
  1609. if (s='IFDEF') then
  1610. begin
  1611. RemoveSep(opts);
  1612. if Level>=maxlevel then
  1613. begin
  1614. Message2(option_too_many_ifdef,filename,tostr(line));
  1615. stopOptions(1);
  1616. end;
  1617. inc(Level);
  1618. { environment variable? }
  1619. if (opts[1]='$') and (opts[length(opts)]='$') then
  1620. skip[level]:=skip[level-1] or (GetEnvironmentVariable(copy(opts,2,length(opts)-2))='')
  1621. else
  1622. skip[level]:=(skip[level-1] or not defined_macro(upper(GetName(opts))));
  1623. end
  1624. else
  1625. if (s='IFNDEF') then
  1626. begin
  1627. RemoveSep(opts);
  1628. if Level>=maxlevel then
  1629. begin
  1630. Message2(option_too_many_ifdef,filename,tostr(line));
  1631. stopOptions(1);
  1632. end;
  1633. inc(Level);
  1634. { environment variable? }
  1635. if (opts[1]='$') and (opts[length(opts)]='$') then
  1636. skip[level]:=skip[level-1] or (GetEnvironmentVariable(copy(opts,2,length(opts)-2))<>'')
  1637. else
  1638. skip[level]:=skip[level-1] or defined_macro(upper(GetName(opts)));
  1639. end
  1640. else
  1641. if (s='ELSE') then
  1642. begin
  1643. if Level=0 then
  1644. begin
  1645. Message2(option_else_without_if,filename,tostr(line));
  1646. stopOptions(1);
  1647. end
  1648. else
  1649. skip[level]:=skip[level-1] or (not skip[level])
  1650. end
  1651. else
  1652. if (s='ENDIF') then
  1653. begin
  1654. skip[level]:=false;
  1655. if Level=0 then
  1656. begin
  1657. Message2(option_too_many_endif,filename,tostr(line));
  1658. stopOptions(1);
  1659. end;
  1660. dec(level);
  1661. end
  1662. else
  1663. if (not skip[level]) then
  1664. begin
  1665. if (s='DEFINE') then
  1666. begin
  1667. RemoveSep(opts);
  1668. tmp:= GetName(opts);
  1669. if tmp <> '' then
  1670. def_system_macro(tmp);
  1671. Option_read:=true;
  1672. end
  1673. else
  1674. if (s='UNDEF') then
  1675. begin
  1676. RemoveSep(opts);
  1677. tmp:= GetName(opts);
  1678. if tmp <> '' then
  1679. undef_system_macro(tmp);
  1680. Option_read:=true;
  1681. end
  1682. else
  1683. if (s='WRITE') then
  1684. begin
  1685. Delete(opts,1,1);
  1686. DefaultReplacements(opts);
  1687. WriteLn(opts);
  1688. Option_read:=true;
  1689. end
  1690. else
  1691. if (s='INCLUDE') then
  1692. begin
  1693. Delete(opts,1,1);
  1694. DefaultReplacements(opts);
  1695. Interpret_file(opts);
  1696. Option_read:=true;
  1697. end
  1698. else
  1699. if (s='CFGDIR') then
  1700. begin
  1701. Delete(opts,1,1);
  1702. DefaultReplacements(opts);
  1703. ParaIncludeCfgPath.AddPath(opts,false);
  1704. Option_read:=true;
  1705. end;
  1706. end;
  1707. end
  1708. else
  1709. begin
  1710. if (opts[1]='-') or (opts[1]='@') then
  1711. begin
  1712. if (not skip[level]) then
  1713. interpret_option(opts,false);
  1714. Option_read:=true;
  1715. end
  1716. else
  1717. Message1(option_illegal_para,opts);
  1718. end;
  1719. end;
  1720. end;
  1721. if Level>0 then
  1722. Message(option_too_less_endif);
  1723. if Not Option_read then
  1724. Message1(option_no_option_found,filename)
  1725. else
  1726. Message1(option_end_reading_configfile,filename);
  1727. Close(f);
  1728. Dec(FileLevel);
  1729. end;
  1730. procedure TOption.Interpret_envvar(const envname: TCmdStr);
  1731. var
  1732. argstart,
  1733. env,
  1734. pc : pchar;
  1735. arglen : longint;
  1736. quote : set of char;
  1737. hs : TCmdStr;
  1738. begin
  1739. Message1(option_using_env,envname);
  1740. env:=GetEnvPChar(envname);
  1741. pc:=env;
  1742. hs:='';
  1743. if assigned(pc) then
  1744. begin
  1745. repeat
  1746. { skip leading spaces }
  1747. while pc^ in [' ',#9,#13] do
  1748. inc(pc);
  1749. case pc^ of
  1750. #0 :
  1751. break;
  1752. '"' :
  1753. begin
  1754. quote:=['"'];
  1755. inc(pc);
  1756. end;
  1757. '''' :
  1758. begin
  1759. quote:=[''''];
  1760. inc(pc);
  1761. end;
  1762. else
  1763. quote:=[' ',#9,#13];
  1764. end;
  1765. { scan until the end of the argument }
  1766. argstart:=pc;
  1767. while (pc^<>#0) and not(pc^ in quote) do
  1768. inc(pc);
  1769. { create argument }
  1770. arglen:=pc-argstart;
  1771. { TODO: FIXME: silent truncation of environment parameters }
  1772. if (arglen > 255) then
  1773. arglen := 255;
  1774. setlength(hs,arglen);
  1775. move(argstart^,hs[1],arglen);
  1776. interpret_option(hs,true);
  1777. { skip quote }
  1778. if pc^ in quote then
  1779. inc(pc);
  1780. until false;
  1781. end
  1782. else
  1783. Message1(option_no_option_found,'(env) '+envname);
  1784. FreeEnvPChar(env);
  1785. end;
  1786. procedure TOption.Read_Parameters;
  1787. var
  1788. opts : TCmdStr;
  1789. paramindex : longint;
  1790. begin
  1791. paramindex:=0;
  1792. while paramindex<paramcount do
  1793. begin
  1794. inc(paramindex);
  1795. opts:=objpas.paramstr(paramindex);
  1796. if length(opts)>0 then
  1797. case opts[1] of
  1798. '@' :
  1799. if not firstpass then
  1800. begin
  1801. Delete(opts,1,1);
  1802. Message1(option_reading_further_from,opts);
  1803. interpret_file(opts);
  1804. end;
  1805. '!' :
  1806. if not firstpass then
  1807. begin
  1808. Delete(opts,1,1);
  1809. Message1(option_reading_further_from,'(env) '+opts);
  1810. interpret_envvar(opts);
  1811. end;
  1812. else
  1813. interpret_option(opts,true);
  1814. end;
  1815. end;
  1816. end;
  1817. procedure TOption.parsecmd(cmd: TCmdStr);
  1818. var
  1819. i,ps : longint;
  1820. opts : TCmdStr;
  1821. begin
  1822. while (cmd<>'') do
  1823. begin
  1824. while cmd[1]=' ' do
  1825. delete(cmd,1,1);
  1826. i:=pos(' ',cmd);
  1827. if i=0 then
  1828. i:=2147483647;
  1829. opts:=Copy(cmd,1,i-1);
  1830. Delete(cmd,1,i);
  1831. case opts[1] of
  1832. '@' :
  1833. if not firstpass then
  1834. begin
  1835. Delete(opts,1,1);
  1836. Message1(option_reading_further_from,opts);
  1837. interpret_file(opts);
  1838. end;
  1839. '!' :
  1840. if not firstpass then
  1841. begin
  1842. Delete(opts,1,1);
  1843. Message1(option_reading_further_from,'(env) '+opts);
  1844. interpret_envvar(opts);
  1845. end;
  1846. '"' :
  1847. begin
  1848. Delete(opts,1,1);
  1849. ps:=pos('"',cmd);
  1850. if (i<>256) and (ps>0) then
  1851. begin
  1852. opts:=opts + ' '+ copy(cmd,1,ps-1);
  1853. cmd:=copy(cmd,ps+1,255);
  1854. end;
  1855. interpret_option(opts,true);
  1856. end;
  1857. else
  1858. interpret_option(opts,true);
  1859. end;
  1860. end;
  1861. end;
  1862. procedure TOption.WriteQuickInfo;
  1863. var
  1864. s : string;
  1865. i : longint;
  1866. emptyOK : Boolean;
  1867. procedure addinfo(const hs:string);
  1868. begin
  1869. if s<>'' then
  1870. s:=s+' '+hs
  1871. else
  1872. s:=hs;
  1873. end;
  1874. begin
  1875. emptyOK:=False;
  1876. s:='';
  1877. i:=0;
  1878. while (i<length(quickinfo)) do
  1879. begin
  1880. inc(i);
  1881. case quickinfo[i] of
  1882. 'S' :
  1883. begin
  1884. inc(i);
  1885. case quickinfo[i] of
  1886. 'O' :
  1887. addinfo(lower(source_info.shortname));
  1888. 'P' :
  1889. addinfo(source_cpu_string);
  1890. else
  1891. IllegalPara('-i'+QuickInfo);
  1892. end;
  1893. end;
  1894. 'T' :
  1895. begin
  1896. inc(i);
  1897. case quickinfo[i] of
  1898. 'O' :
  1899. addinfo(lower(target_info.shortname));
  1900. 'P' :
  1901. AddInfo(target_cpu_string);
  1902. 'T' :
  1903. begin
  1904. addinfo(lower(self.parasubtarget));
  1905. emptyOK:=True;
  1906. end
  1907. else
  1908. IllegalPara('-i'+QuickInfo);
  1909. end;
  1910. end;
  1911. 'V' :
  1912. AddInfo(version_string);
  1913. 'W' :
  1914. AddInfo(full_version_string);
  1915. 'D' :
  1916. AddInfo(date_string);
  1917. '_' :
  1918. ;
  1919. else
  1920. IllegalPara('-i'+QuickInfo);
  1921. end;
  1922. end;
  1923. if (s<>'') or EmptyOK then
  1924. begin
  1925. writeln(s);
  1926. stopoptions(0);
  1927. end;
  1928. end;
  1929. procedure TOption.TargetOptions(def:boolean);
  1930. var
  1931. s : string;
  1932. i : integer;
  1933. target_unsup_features : tfeatures;
  1934. begin
  1935. if def then
  1936. def_system_macro(target_info.shortname)
  1937. else
  1938. undef_system_macro(target_info.shortname);
  1939. s:=target_info.extradefines;
  1940. while (s<>'') do
  1941. begin
  1942. i:=pos(';',s);
  1943. if i=0 then
  1944. i:=length(s)+1;
  1945. if def then
  1946. def_system_macro(Copy(s,1,i-1))
  1947. else
  1948. undef_system_macro(Copy(s,1,i-1));
  1949. delete(s,1,i);
  1950. end;
  1951. if (tf_winlikewidestring in target_info.flags) then
  1952. if def then
  1953. def_system_macro('FPC_WINLIKEWIDESTRING')
  1954. else
  1955. undef_system_macro('FPC_WINLIKEWIDESTRING');
  1956. if (tf_requires_proper_alignment in target_info.flags) then
  1957. if def then
  1958. def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT')
  1959. else
  1960. undef_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
  1961. if (tf_init_final_units_by_calls in target_info.flags) then
  1962. if def then
  1963. def_system_macro('FPC_INIT_FINAL_UNITS_BY_CALLS')
  1964. else
  1965. undef_system_macro('FPC_INIT_FINAL_UNITS_BY_CALLS');
  1966. if source_info.system<>target_info.system then
  1967. if def then
  1968. def_system_macro('FPC_CROSSCOMPILING')
  1969. else
  1970. undef_system_macro('FPC_CROSSCOMPILING');
  1971. if source_info.cpu<>target_info.cpu then
  1972. if def then
  1973. def_system_macro('FPC_CPUCROSSCOMPILING')
  1974. else
  1975. def_system_macro('FPC_CPUCROSSCOMPILING');
  1976. if (tf_no_generic_stackcheck in target_info.flags) then
  1977. if def then
  1978. def_system_macro('FPC_NO_GENERIC_STACK_CHECK')
  1979. else
  1980. undef_system_macro('FPC_NO_GENERIC_STACK_CHECK');
  1981. if (tf_section_threadvars in target_info.flags) then
  1982. if def then
  1983. def_system_macro('FPC_SECTION_THREADVARS')
  1984. else
  1985. undef_system_macro('FPC_SECTION_THREADVARS');
  1986. if (tf_use_psabieh in target_info.flags) then
  1987. if def then
  1988. def_system_macro('FPC_USE_PSABIEH')
  1989. else
  1990. undef_system_macro('FPC_USE_PSABIEH');
  1991. { Code generation flags }
  1992. if (tf_pic_default in target_info.flags) then
  1993. if def then
  1994. include(init_settings.moduleswitches,cs_create_pic)
  1995. else
  1996. exclude(init_settings.moduleswitches,cs_create_pic);
  1997. { Resources support }
  1998. if (tf_has_winlike_resources in target_info.flags) then
  1999. if def then
  2000. def_system_macro('FPC_HAS_WINLIKERESOURCES')
  2001. else
  2002. undef_system_macro('FPC_HAS_WINLIKERESOURCES');
  2003. { Features }
  2004. case target_info.system of
  2005. system_arm_gba:
  2006. target_unsup_features:=[f_dynlibs];
  2007. system_arm_nds:
  2008. target_unsup_features:=[f_threading,f_commandargs,f_fileio,f_textio,f_consoleio,f_dynlibs];
  2009. system_i386_nativent:
  2010. // until these features are implemented, they are disabled in the compiler
  2011. target_unsup_features:=[f_stackcheck];
  2012. system_i8086_msdos:
  2013. target_unsup_features:=[f_threading,f_dynlibs];
  2014. system_i8086_win16:
  2015. target_unsup_features:=[f_threading];
  2016. system_jvm_java32,
  2017. system_jvm_android32:
  2018. target_unsup_features:=[f_heap,f_textio,f_consoleio,f_fileio,
  2019. f_variants,f_objects,f_commandargs,
  2020. f_processes,f_stackcheck,f_dynlibs,f_softfpu,f_objectivec1,f_resources];
  2021. system_arm_palmos,
  2022. system_m68k_palmos:
  2023. target_unsup_features:=[f_threading];
  2024. system_m68k_atari:
  2025. target_unsup_features:=[f_threading];
  2026. { classic amiga has dynamic libraries, but they cannot be integrated in the
  2027. normal dynlibs infrastructure due to architectural differences, so therefore
  2028. lets disable the feature. }
  2029. system_m68k_amiga:
  2030. target_unsup_features:=[f_dynlibs];
  2031. system_m68k_sinclairql:
  2032. target_unsup_features:=[f_threading,f_dynlibs];
  2033. system_z80_zxspectrum:
  2034. target_unsup_features:=[f_threading,f_dynlibs{,f_fileio,f_textio},f_commandargs,f_exitcode];
  2035. system_z80_msxdos:
  2036. target_unsup_features:=[f_threading,f_dynlibs];
  2037. else
  2038. target_unsup_features:=[];
  2039. end;
  2040. if def then
  2041. features:=features-target_unsup_features
  2042. else
  2043. features:=features+target_unsup_features;
  2044. {$if defined(hasamiga)}
  2045. { enable vlink as default linker on Amiga but not for cross compilers (for now) }
  2046. if (target_info.system in [system_m68k_amiga,system_powerpc_amiga]) and
  2047. not LinkerSetExplicitly then
  2048. include(init_settings.globalswitches,cs_link_vlink);
  2049. {$endif}
  2050. {$ifdef m68k}
  2051. { always enable vlink as default linker for the Sinclair QL and Atari }
  2052. if (target_info.system in [system_m68k_sinclairql,system_m68k_atari]) and
  2053. not LinkerSetExplicitly then
  2054. include(init_settings.globalswitches,cs_link_vlink);
  2055. {$endif m68k}
  2056. end;
  2057. procedure TOption.CheckOptionsCompatibility;
  2058. begin
  2059. {$ifdef wasm}
  2060. if (Ord(ts_wasm_no_exceptions in init_settings.targetswitches)+
  2061. Ord(ts_wasm_js_exceptions in init_settings.targetswitches)+
  2062. Ord(ts_wasm_native_exceptions in init_settings.targetswitches)+
  2063. Ord(ts_wasm_bf_exceptions in init_settings.targetswitches))>1 then
  2064. begin
  2065. Message(option_too_many_exception_modes);
  2066. StopOptions(1);
  2067. end;
  2068. {$endif}
  2069. {$ifdef i8086}
  2070. if (apptype=app_com) and (init_settings.x86memorymodel<>mm_tiny) then
  2071. begin
  2072. Message(option_com_files_require_tiny_model);
  2073. StopOptions(1);
  2074. end;
  2075. {$endif i8086}
  2076. {$ifndef i8086_link_intern_debuginfo}
  2077. if (cs_debuginfo in init_settings.moduleswitches) and
  2078. (target_info.system in [system_i8086_msdos,system_i8086_win16,system_i8086_embedded]) and
  2079. not (cs_link_extern in init_settings.globalswitches) then
  2080. begin
  2081. Message(option_debug_info_requires_external_linker);
  2082. include(init_settings.globalswitches,cs_link_extern);
  2083. end;
  2084. {$endif i8086_link_intern_debuginfo}
  2085. if (paratargetdbg in [dbg_dwarf2,dbg_dwarf3,dbg_dwarf4]) and
  2086. not(target_info.system in (systems_darwin+[system_i8086_msdos,system_i8086_embedded])) then
  2087. begin
  2088. { smartlink creation does not yet work with DWARF
  2089. debug info on most targets, but it works in internal assembler }
  2090. if (cs_create_smart in init_settings.moduleswitches) and
  2091. not (af_outputbinary in target_asm.flags) then
  2092. begin
  2093. Message(option_dwarf_smartlink_creation);
  2094. exclude(init_settings.moduleswitches,cs_create_smart);
  2095. end;
  2096. { smart linking does not yet work with DWARF debug info on most targets }
  2097. if (cs_link_smart in init_settings.globalswitches) then
  2098. begin
  2099. Message(option_dwarf_smart_linking);
  2100. ForceStaticLinking;
  2101. end;
  2102. end;
  2103. { external debug info is only supported for DWARF on darwin }
  2104. if (target_info.system in systems_darwin) and
  2105. (cs_link_separate_dbg_file in init_settings.globalswitches) and
  2106. not(paratargetdbg in [dbg_dwarf2,dbg_dwarf3,dbg_dwarf4]) then
  2107. begin
  2108. Message(option_debug_external_unsupported);
  2109. exclude(init_settings.globalswitches,cs_link_separate_dbg_file);
  2110. end;
  2111. { Also create a smartlinked version, on an assembler that
  2112. does not support smartlink sections like nasm?
  2113. This is not compatible with using internal linker. }
  2114. if ((cs_link_smart in init_settings.globalswitches) or
  2115. (cs_create_smart in init_settings.moduleswitches)) and
  2116. (af_needar in target_asm.flags) and
  2117. not (af_smartlink_sections in target_asm.flags) and
  2118. not (cs_link_extern in init_settings.globalswitches) and
  2119. (target_info.link<>ld_none) and
  2120. not (cs_link_nolink in init_settings.globalswitches) then
  2121. begin
  2122. Message(option_smart_link_requires_external_linker);
  2123. include(init_settings.globalswitches,cs_link_extern);
  2124. end;
  2125. end;
  2126. constructor TOption.Create;
  2127. begin
  2128. LogoWritten:=false;
  2129. NoPressEnter:=false;
  2130. FirstPass:=false;
  2131. ABISetExplicitly:=false;
  2132. FPUSetExplicitly:=false;
  2133. CPUSetExplicitly:=false;
  2134. OptCPUSetExplicitly:=false;
  2135. FileLevel:=0;
  2136. Quickinfo:='';
  2137. ParaIncludeCfgPath:=TSearchPathList.Create;
  2138. ParaIncludePath:=TSearchPathList.Create;
  2139. ParaObjectPath:=TSearchPathList.Create;
  2140. ParaUnitPath:=TSearchPathList.Create;
  2141. ParaLibraryPath:=TSearchPathList.Create;
  2142. ParaFrameworkPath:=TSearchPathList.Create;
  2143. parapackagepath:=TSearchPathList.Create;
  2144. parapackages:=TFPHashObjectList.Create;
  2145. paranamespaces:=TCmdStrList.Create;
  2146. FillChar(ParaAlignment,sizeof(ParaAlignment),0);
  2147. MacVersionSet:=false;
  2148. paratarget:=system_none;
  2149. paratargetasm:=as_none;
  2150. paratargetdbg:=dbg_none;
  2151. LinkTypeSetExplicitly:=false;
  2152. LinkerSetExplicitly:=false;
  2153. end;
  2154. destructor TOption.Destroy;
  2155. begin
  2156. ParaIncludeCfgPath.Free;
  2157. ParaIncludePath.Free;
  2158. ParaObjectPath.Free;
  2159. ParaUnitPath.Free;
  2160. ParaLibraryPath.Free;
  2161. ParaFrameworkPath.Free;
  2162. parapackagepath.Free;
  2163. ParaPackages.Free;
  2164. paranamespaces.free;
  2165. end;
  2166. procedure TOption.Interpret_A_l(opt, more: TCmdStr);
  2167. var
  2168. j : integer;
  2169. begin
  2170. include(init_settings.globalswitches,cs_asm_leave);
  2171. j:=1;
  2172. while j<=length(more) do
  2173. begin
  2174. case more[j] of
  2175. '5' :
  2176. if (target_info.system in systems_all_windows+systems_nativent-[system_i8086_win16])
  2177. or (target_info.cpu in [cpu_mipseb, cpu_mipsel]) then
  2178. begin
  2179. if UnsetBool(More, j, opt, false) then
  2180. exclude(init_settings.globalswitches,cs_asm_pre_binutils_2_25)
  2181. else
  2182. include(init_settings.globalswitches,cs_asm_pre_binutils_2_25);
  2183. end
  2184. else
  2185. IllegalPara(opt);
  2186. 'l' :
  2187. include(init_settings.globalswitches,cs_asm_source);
  2188. 'r' :
  2189. include(init_settings.globalswitches,cs_asm_regalloc);
  2190. 'R' :
  2191. include(init_settings.globalswitches,cs_asm_rtti_source);
  2192. 't' :
  2193. include(init_settings.globalswitches,cs_asm_tempalloc);
  2194. 'n' :
  2195. include(init_settings.globalswitches,cs_asm_nodes);
  2196. { -ao option must be the last, everything behind it is passed directly to
  2197. external assembler, it is ignored if internal assembler is used. }
  2198. 'o' :
  2199. begin
  2200. asmextraopt:=copy(more,j+1);
  2201. break;
  2202. end;
  2203. 'p' :
  2204. begin
  2205. exclude(init_settings.globalswitches,cs_asm_leave);
  2206. if UnsetBool(More, 0, opt, false) then
  2207. exclude(init_settings.globalswitches,cs_asm_pipe)
  2208. else
  2209. include(init_settings.globalswitches,cs_asm_pipe);
  2210. end;
  2211. '-' :
  2212. init_settings.globalswitches:=init_settings.globalswitches -
  2213. [cs_asm_leave, cs_asm_source,cs_asm_regalloc, cs_asm_tempalloc,
  2214. cs_asm_nodes, cs_asm_pipe];
  2215. else
  2216. IllegalPara(opt);
  2217. end;
  2218. inc(j);
  2219. end;
  2220. end;
  2221. procedure TOption.Interpret_A_U(opt, more: TCmdStr);
  2222. begin
  2223. if CompareText(More,'DEFAULT') = 0 then
  2224. paratargetasm:=as_default
  2225. else
  2226. paratargetasm:=find_asm_by_string(More);
  2227. if paratargetasm=as_none then
  2228. IllegalPara(opt);
  2229. end;
  2230. procedure TOption.Interpret_B_l(opt, more: TCmdStr);
  2231. begin
  2232. // Message1(option_obsolete_switch,'-b');
  2233. if UnsetBool(More,0,opt,false) then
  2234. begin
  2235. init_settings.moduleswitches:=init_settings.moduleswitches-[cs_browser];
  2236. init_settings.moduleswitches:=init_settings.moduleswitches-[cs_local_browser];
  2237. end
  2238. else
  2239. begin
  2240. init_settings.moduleswitches:=init_settings.moduleswitches+[cs_browser];
  2241. end;
  2242. if More<>'' then
  2243. if (More='l') or (More='l+') then
  2244. init_settings.moduleswitches:=init_settings.moduleswitches+[cs_local_browser]
  2245. else if More='l-' then
  2246. init_settings.moduleswitches:=init_settings.moduleswitches-[cs_local_browser]
  2247. else
  2248. IllegalPara(opt);
  2249. end;
  2250. procedure TOption.Interpret_B_U(opt, more: TCmdStr);
  2251. begin
  2252. do_build:=not UnSetBool(more,0,opt,true);
  2253. end;
  2254. procedure TOption.Interpret_C_U(opt, more: TCmdStr);
  2255. var
  2256. j,l,code,deletepos : integer;
  2257. s : string;
  2258. includecapability : Boolean;
  2259. {$ifdef llvm}
  2260. disable: boolean;
  2261. {$endif}
  2262. {$ifdef cpucapabilities}
  2263. cf : tcpuflags;
  2264. cpuflagsstr,
  2265. extrasettings : string;
  2266. {$endif cpucapabilities}
  2267. begin
  2268. j:=1;
  2269. while j<=length(more) do
  2270. begin
  2271. case more[j] of
  2272. '3' :
  2273. If UnsetBool(More, j, opt, false) then
  2274. exclude(init_settings.localswitches,cs_ieee_errors)
  2275. Else
  2276. include(init_settings.localswitches,cs_ieee_errors);
  2277. 'a' :
  2278. begin
  2279. s:=upper(copy(more,j+1));
  2280. if not(SetAbiType(s,target_info.abi)) then
  2281. IllegalPara(opt);
  2282. ABISetExplicitly:=true;
  2283. break;
  2284. end;
  2285. 'b' :
  2286. begin
  2287. if UnsetBool(More, j, opt, false) then
  2288. target_info.endian:=endian_little
  2289. else
  2290. target_info.endian:=endian_big;
  2291. set_endianess_macros;
  2292. end;
  2293. 'c' :
  2294. begin
  2295. if not SetAktProcCall(upper(copy(more,j+1)),init_settings.defproccall) then
  2296. IllegalPara(opt);
  2297. break;
  2298. end;
  2299. {$ifdef cpufpemu}
  2300. 'e' :
  2301. begin
  2302. If UnsetBool(More, j, opt, false) then
  2303. exclude(init_settings.moduleswitches,cs_fp_emulation)
  2304. Else
  2305. include(init_settings.moduleswitches,cs_fp_emulation);
  2306. end;
  2307. {$endif cpufpemu}
  2308. 'E' :
  2309. If UnsetBool(More, j, opt, false) then
  2310. exclude(init_settings.localswitches,cs_check_fpu_exceptions)
  2311. Else
  2312. include(init_settings.localswitches,cs_check_fpu_exceptions);
  2313. 'f' :
  2314. begin
  2315. s:=upper(copy(more,j+1));
  2316. if not(SetFpuType(s,init_settings.fputype)) then
  2317. IllegalPara(opt);
  2318. FPUSetExplicitly:=True;
  2319. break;
  2320. end;
  2321. 'F' :
  2322. begin
  2323. if not SetMinFPConstPrec(copy(more,j+1),init_settings.minfpconstprec) then
  2324. IllegalPara(opt);
  2325. break;
  2326. end;
  2327. 'g' :
  2328. begin
  2329. if tf_no_pic_supported in target_info.flags then
  2330. begin
  2331. { consume a possible '-' coming after it }
  2332. UnsetBool(More, j, opt, false);
  2333. message(scan_w_pic_ignored);
  2334. end
  2335. else if UnsetBool(More, j, opt, false) then
  2336. exclude(init_settings.moduleswitches,cs_create_pic)
  2337. else
  2338. include(init_settings.moduleswitches,cs_create_pic);
  2339. end;
  2340. 'h' :
  2341. begin
  2342. l:=pos(',',copy(more,j+1));
  2343. if l=0 then
  2344. l:=length(more)-j+1;
  2345. val(copy(more,j+1,l-1),heapsize,code);
  2346. if (code<>0)
  2347. {$ifdef AVR}
  2348. or (heapsize<32)
  2349. {$else AVR}
  2350. or (heapsize<1024)
  2351. {$endif AVR}
  2352. then
  2353. IllegalPara(opt)
  2354. else if l<=length(more)-j then
  2355. begin
  2356. val(copy(more,j+l+1),maxheapsize,code);
  2357. if code<>0 then
  2358. IllegalPara(opt)
  2359. else if (maxheapsize<heapsize) then
  2360. begin
  2361. message(scan_w_heapmax_lessthan_heapmin);
  2362. maxheapsize:=heapsize;
  2363. end;
  2364. end;
  2365. break;
  2366. end;
  2367. 'i' :
  2368. If UnsetBool(More, j, opt, false) then
  2369. exclude(init_settings.localswitches,cs_check_io)
  2370. else
  2371. include(init_settings.localswitches,cs_check_io);
  2372. {$ifdef arm}
  2373. 'I' :
  2374. begin
  2375. if (upper(copy(more,j+1))='THUMB') and
  2376. { does selected CPU really understand thumb? }
  2377. (init_settings.cputype in cpu_has_thumb) then
  2378. init_settings.instructionset:=is_thumb
  2379. else if upper(copy(more,j+1))='ARM' then
  2380. init_settings.instructionset:=is_arm
  2381. else
  2382. IllegalPara(opt);
  2383. break;
  2384. end;
  2385. {$endif arm}
  2386. {$ifdef llvm}
  2387. 'l':
  2388. begin
  2389. l:=j+1;
  2390. while l<=length(More) do
  2391. begin
  2392. case More[l] of
  2393. 'f':
  2394. begin
  2395. delete(More,1,l);
  2396. disable:=Unsetbool(More,length(More)-1,opt,false);
  2397. case More of
  2398. 'lto':
  2399. begin
  2400. if not disable then
  2401. begin
  2402. include(init_settings.moduleswitches,cs_lto);
  2403. LTOExt:='.bc';
  2404. end
  2405. else
  2406. exclude(init_settings.moduleswitches,cs_lto);
  2407. end;
  2408. 'ltonosystem':
  2409. begin
  2410. if not disable then
  2411. begin
  2412. include(init_settings.globalswitches,cs_lto_nosystem);
  2413. end
  2414. else
  2415. exclude(init_settings.globalswitches,cs_lto_nosystem);
  2416. end;
  2417. else if More.StartsWith('sanitize=') then
  2418. begin
  2419. delete(More,1,length('sanitize='));
  2420. LLVMEnableSanitizers(more);
  2421. end
  2422. else
  2423. begin
  2424. IllegalPara(opt);
  2425. end;
  2426. end;
  2427. l:=length(more)+1;
  2428. end;
  2429. 'v':
  2430. begin
  2431. init_settings.llvmversion:=llvmversion2enum(copy(More,l+1));
  2432. if init_settings.llvmversion=llvmver_invalid then
  2433. begin
  2434. IllegalPara(opt);
  2435. end;
  2436. l:=length(More)+1;
  2437. end
  2438. else
  2439. begin
  2440. IllegalPara(opt);
  2441. end;
  2442. end;
  2443. end;
  2444. j:=l;
  2445. end;
  2446. {$endif llvm}
  2447. 'n' :
  2448. If UnsetBool(More, j, opt, false) then
  2449. exclude(init_settings.globalswitches,cs_link_nolink)
  2450. Else
  2451. include(init_settings.globalswitches,cs_link_nolink);
  2452. 'N' :
  2453. If UnsetBool(More, j, opt, false) then
  2454. exclude(init_settings.localswitches,cs_check_low_addr_load)
  2455. Else
  2456. include(init_settings.localswitches,cs_check_low_addr_load);
  2457. 'o' :
  2458. If UnsetBool(More, j, opt, false) then
  2459. exclude(init_settings.localswitches,cs_check_overflow)
  2460. Else
  2461. include(init_settings.localswitches,cs_check_overflow);
  2462. 'O' :
  2463. If UnsetBool(More, j, opt, false) then
  2464. exclude(init_settings.localswitches,cs_check_ordinal_size)
  2465. Else
  2466. include(init_settings.localswitches,cs_check_ordinal_size);
  2467. 'p' :
  2468. begin
  2469. s:=upper(copy(more,j+1));
  2470. {$ifdef cpucapabilities}
  2471. { find first occurrence of + or - }
  2472. deletepos:=PosCharset(['+','-'],s);
  2473. if deletepos<>0 then
  2474. begin
  2475. extrasettings:=Copy(s,deletepos,Length(s));
  2476. Delete(s,deletepos,Length(s));
  2477. end
  2478. else
  2479. extrasettings:='';
  2480. {$endif cpucapabilities}
  2481. if not(Setcputype(s,init_settings)) then
  2482. IllegalPara(opt);
  2483. {$ifdef cpucapabilities}
  2484. while extrasettings<>'' do
  2485. begin
  2486. Delete(extrasettings,1,1);
  2487. includecapability:=true;
  2488. deletepos:=PosCharset(['+','-'],extrasettings);
  2489. if deletepos<>0 then
  2490. begin
  2491. includecapability:=extrasettings[deletepos]='+';
  2492. s:=Copy(extrasettings,1,deletepos-1);
  2493. Delete(extrasettings,1,deletepos-1);
  2494. end
  2495. else
  2496. begin
  2497. s:=extrasettings;
  2498. extrasettings:='';
  2499. end;
  2500. for cf in tcpuflags do
  2501. begin
  2502. Str(cf,cpuflagsstr);
  2503. { expect that the cpuflagsstr i.e. the enum as well contains _HAS_ }
  2504. if Pos('_HAS_',cpuflagsstr)<>0 then
  2505. { get rid of prefix including _HAS_ }
  2506. Delete(cpuflagsstr,1,Pos('_HAS_',cpuflagsstr)+4)
  2507. else
  2508. Internalerror(2021110601);
  2509. if s=cpuflagsstr then
  2510. begin
  2511. if includecapability then
  2512. Include(cpu_capabilities[init_settings.cputype],cf)
  2513. else
  2514. Exclude(cpu_capabilities[init_settings.cputype],cf);
  2515. s:='';
  2516. break;
  2517. end;
  2518. end;
  2519. if s<>'' then
  2520. IllegalPara(opt);
  2521. end;
  2522. {$endif cpucapabilities}
  2523. CPUSetExplicitly:=true;
  2524. break;
  2525. end;
  2526. 'P':
  2527. begin
  2528. delete(more,1,1);
  2529. case upper(copy(more,1,pos('=',more)-1)) of
  2530. 'PACKSET':
  2531. begin
  2532. delete(more,1,pos('=',more));
  2533. case more of
  2534. '0','DEFAULT','NORMAL':
  2535. init_settings.setalloc:=0;
  2536. '1','2','4','8':
  2537. init_settings.setalloc:=StrToInt(more);
  2538. else
  2539. IllegalPara(opt);
  2540. end
  2541. end;
  2542. 'PACKENUM':
  2543. begin
  2544. delete(more,1,pos('=',more));
  2545. case more of
  2546. '0','DEFAULT','NORMAL':
  2547. init_settings.packenum:=4;
  2548. '1','2','4':
  2549. init_settings.packenum:=StrToInt(more);
  2550. else
  2551. IllegalPara(opt);
  2552. end;
  2553. end;
  2554. 'PACKRECORD':
  2555. begin
  2556. delete(more,1,pos('=',more));
  2557. case more of
  2558. '0','DEFAULT','NORMAL':
  2559. init_settings.packrecords:=default_settings.packrecords;
  2560. '1','2','4','8','16','32':
  2561. init_settings.packrecords:=StrToInt(more);
  2562. else
  2563. IllegalPara(opt);
  2564. end;
  2565. end
  2566. else
  2567. IllegalPara(opt);
  2568. end;
  2569. end;
  2570. 'r' :
  2571. If UnsetBool(More, j, opt, false) then
  2572. exclude(init_settings.localswitches,cs_check_range)
  2573. Else
  2574. include(init_settings.localswitches,cs_check_range);
  2575. 'R' :
  2576. If UnsetBool(More, j, opt, false) then
  2577. begin
  2578. exclude(init_settings.localswitches,cs_check_range);
  2579. exclude(init_settings.localswitches,cs_check_object);
  2580. end
  2581. Else
  2582. begin
  2583. include(init_settings.localswitches,cs_check_range);
  2584. include(init_settings.localswitches,cs_check_object);
  2585. end;
  2586. 's' :
  2587. begin
  2588. val(copy(more,j+1),stacksize,code);
  2589. if (code<>0)
  2590. {$ifdef cpu16bitaddr}
  2591. or (stacksize>=65521)
  2592. {$else cpu16bitaddr}
  2593. or (stacksize>=67107840)
  2594. {$endif cpu16bitaddr}
  2595. or (stacksize<1024) then
  2596. IllegalPara(opt);
  2597. break;
  2598. end;
  2599. 't' :
  2600. If UnsetBool(More, j, opt, false) then
  2601. exclude(init_settings.localswitches,cs_check_stack)
  2602. Else
  2603. include(init_settings.localswitches,cs_check_stack);
  2604. 'D' :
  2605. If UnsetBool(More, j, opt, false) then
  2606. exclude(init_settings.moduleswitches,cs_create_dynamic)
  2607. Else
  2608. include(init_settings.moduleswitches,cs_create_dynamic);
  2609. 'X' :
  2610. If UnsetBool(More, j, opt, false) then
  2611. exclude(init_settings.moduleswitches,cs_create_smart)
  2612. Else
  2613. include(init_settings.moduleswitches,cs_create_smart);
  2614. 'T' :
  2615. begin
  2616. if not UpdateTargetSwitchStr(copy(more,j+1),init_settings.targetswitches,true) then
  2617. IllegalPara(opt);
  2618. break;
  2619. end;
  2620. 'v' :
  2621. If target_info.system in systems_jvm then
  2622. If UnsetBool(More, j, opt, false) then
  2623. exclude(init_settings.localswitches,cs_check_var_copyout)
  2624. Else
  2625. include(init_settings.localswitches,cs_check_var_copyout)
  2626. else
  2627. IllegalPara(opt);
  2628. 'V':
  2629. begin
  2630. s:=upper(copy(more,j+1));
  2631. if s='GLOBAL-DYNAMIC' then
  2632. init_settings.tlsmodel:=tlsm_global_dynamic
  2633. else if s='LOCAL-EXEC' then
  2634. init_settings.tlsmodel:=tlsm_local_exec
  2635. else
  2636. IllegalPara(opt);
  2637. break;
  2638. end;
  2639. else
  2640. IllegalPara(opt);
  2641. end;
  2642. inc(j);
  2643. end;
  2644. end;
  2645. procedure TOption.Interpret_D_l(opt, more: TCmdStr);
  2646. Var
  2647. l : Integer;
  2648. hs : string;
  2649. begin
  2650. l:=Pos(':=',more);
  2651. DefaultReplacements(more);
  2652. if l>0 then
  2653. hs:=copy(more,1,l-1)
  2654. else
  2655. hs:=more;
  2656. if (not is_identifier(hs)) then
  2657. begin
  2658. if hs='' then
  2659. Message1(option_missing_arg,'-d')
  2660. else
  2661. Message1(option_malformed_para,opt);
  2662. StopOptions(1);
  2663. end;
  2664. if l>0 then
  2665. begin
  2666. if cs_support_macro in init_settings.moduleswitches then
  2667. set_system_macro(hs,Copy(more,l+2))
  2668. else
  2669. set_system_compvar(hs,Copy(more,l+2));
  2670. end
  2671. else
  2672. def_system_macro(hs);
  2673. end;
  2674. procedure TOption.Interpret_D_U(opt, more: TCmdStr);
  2675. var
  2676. major,minor : longint;
  2677. l,j,error : integer;
  2678. begin
  2679. j:=1;
  2680. while j<=length(more) do
  2681. begin
  2682. case more[j] of
  2683. 'd' :
  2684. begin
  2685. include(init_settings.globalswitches,cs_link_deffile);
  2686. description:=Copy(more,j+1);
  2687. break;
  2688. end;
  2689. 'D' :
  2690. begin
  2691. datestr:=Copy(more,j+1);
  2692. break;
  2693. end;
  2694. 'T' :
  2695. begin
  2696. timestr:=Copy(more,j+1);
  2697. break;
  2698. end;
  2699. 'v' :
  2700. begin
  2701. include(init_settings.globalswitches,cs_link_deffile);
  2702. dllversion:=Copy(more,j+1);
  2703. l:=pos('.',dllversion);
  2704. dllminor:=0;
  2705. error:=0;
  2706. if l>0 then
  2707. begin
  2708. val(copy(dllversion,l+1,255),minor,error);
  2709. if (error=0) and
  2710. (minor>=0) and (minor<=$ffff) then
  2711. dllminor:=minor
  2712. else
  2713. if error=0 then
  2714. error:=1;
  2715. end;
  2716. if l=0 then
  2717. l:=256;
  2718. dllmajor:=1;
  2719. major:=0;
  2720. if error=0 then
  2721. val(copy(dllversion,1,l-1),major,error);
  2722. if (error=0) and (major>=0) and (major<=$ffff) then
  2723. dllmajor:=major
  2724. else
  2725. if error=0 then
  2726. error:=1;
  2727. if error<>0 then
  2728. Message1(scan_w_wrong_version_ignored,dllversion);
  2729. break;
  2730. end;
  2731. 'w' :
  2732. begin
  2733. include(init_settings.globalswitches,cs_link_deffile);
  2734. usewindowapi:=true;
  2735. end;
  2736. '-' :
  2737. begin
  2738. exclude(init_settings.globalswitches,cs_link_deffile);
  2739. usewindowapi:=false;
  2740. end;
  2741. else
  2742. IllegalPara(opt);
  2743. end;
  2744. inc(j);
  2745. end;
  2746. end;
  2747. procedure TOption.Interpret_E_l(opt, more: TCmdStr);
  2748. begin
  2749. exepath:=FixPath(More,true);
  2750. end;
  2751. procedure TOption.Interpret_E_U(opt, more: TCmdStr);
  2752. begin
  2753. if UnsetBool(More, 0, opt, true) then
  2754. exclude(init_settings.globalswitches,cs_link_nolink)
  2755. else
  2756. include(init_settings.globalswitches,cs_link_nolink);
  2757. end;
  2758. procedure TOption.Interpret_F_l(opt, more: TCmdStr);
  2759. begin
  2760. if more='PIC' then
  2761. begin
  2762. if tf_no_pic_supported in target_info.flags then
  2763. message(scan_w_pic_ignored)
  2764. else
  2765. include(init_settings.moduleswitches,cs_create_pic)
  2766. end
  2767. else
  2768. IllegalPara(opt);
  2769. end;
  2770. procedure TOption.Interpret_F_U(opt, more: TCmdStr; ispara: boolean);
  2771. var
  2772. c : char;
  2773. d : string;
  2774. j : integer;
  2775. unicodemapping : punicodemap;
  2776. begin
  2777. if more='' then
  2778. IllegalPara(opt);
  2779. c:=more[1];
  2780. Delete(more,1,1);
  2781. DefaultReplacements(More);
  2782. case c of
  2783. 'a' :
  2784. autoloadunits:=more;
  2785. 'c' :
  2786. begin
  2787. { if we first specify that the system code page should be
  2788. used and then explicitly specify a code page, unset the
  2789. flag that we're using the system code page again }
  2790. SetCompileModeSwitch('SYSTEMCODEPAGE-',true);
  2791. if (upper(more)='UTF8') or (upper(more)='UTF-8') then
  2792. init_settings.sourcecodepage:=CP_UTF8
  2793. else if not(cpavailable(more)) then
  2794. Message1(option_code_page_not_available,more)
  2795. else
  2796. init_settings.sourcecodepage:=codepagebyname(more);
  2797. include(init_settings.moduleswitches,cs_explicit_codepage);
  2798. end;
  2799. 'C' :
  2800. RCCompiler:=More;
  2801. 'd' :
  2802. if UnsetBool(more, 0, opt, true) then
  2803. init_settings.disabledircache:=false
  2804. else
  2805. init_settings.disabledircache:=true;
  2806. 'D' :
  2807. utilsdirectory:=FixPath(More,true);
  2808. 'e' :
  2809. SetRedirectFile(More);
  2810. 'E' :
  2811. OutputExeDir:=FixPath(More,true);
  2812. 'f' :
  2813. if (target_info.system in systems_darwin) then
  2814. if ispara then
  2815. ParaFrameworkPath.AddPath(More,false)
  2816. else
  2817. frameworksearchpath.AddPath(More,true)
  2818. {$if defined(XTENSA) or defined(RISCV32)}
  2819. else if (target_info.system=system_xtensa_freertos) then
  2820. idfpath:=FixPath(More,true)
  2821. {$endif defined(XTENSA) or defined(RISCV32)}
  2822. else
  2823. IllegalPara(opt);
  2824. 'F' :
  2825. RCForceFPCRes:=true;
  2826. 'i' :
  2827. begin
  2828. if ispara then
  2829. ParaIncludePath.AddPath(More,false)
  2830. else
  2831. includesearchpath.AddPath(More,true);
  2832. end;
  2833. 'm' :
  2834. begin
  2835. if TryStrToInt(ExtractFileName(more),j) then
  2836. begin
  2837. unicodemapping:=loadunicodemapping(More,More+'.txt',j);
  2838. if assigned(unicodemapping) then
  2839. registermapping(unicodemapping)
  2840. else
  2841. IllegalPara(opt);
  2842. end
  2843. else
  2844. IllegalPara(opt);
  2845. end;
  2846. 'M' :
  2847. unicodepath:=FixPath(More,true);
  2848. 'g' :
  2849. Message2(option_obsolete_switch_use_new,'-Fg','-Fl');
  2850. 'l' :
  2851. begin
  2852. if ispara then
  2853. ParaLibraryPath.AddLibraryPath(sysrootpath,More,false)
  2854. else
  2855. LibrarySearchPath.AddLibraryPath(sysrootpath,More,true)
  2856. end;
  2857. 'L' :
  2858. begin
  2859. if More<>'' then
  2860. ParaDynamicLinker:=More
  2861. else
  2862. IllegalPara(opt);
  2863. end;
  2864. 'N' :
  2865. begin
  2866. if more<>'' then
  2867. paranamespaces.insert(more)
  2868. else
  2869. illegalpara(opt);
  2870. end;
  2871. 'o' :
  2872. begin
  2873. if ispara then
  2874. ParaObjectPath.AddPath(More,false)
  2875. else
  2876. ObjectSearchPath.AddPath(More,true);
  2877. end;
  2878. 'P' :
  2879. begin
  2880. if ispara then
  2881. parapackages.add(more,nil)
  2882. else
  2883. add_package(more,true,true);
  2884. end;
  2885. 'p' :
  2886. begin
  2887. if ispara then
  2888. parapackagepath.AddPath(More,false)
  2889. else
  2890. packagesearchpath.AddPath(More,true);
  2891. end;
  2892. 'r' :
  2893. Msgfilename:=More;
  2894. 'R' :
  2895. ResCompiler:=More;
  2896. 'u' :
  2897. begin
  2898. if ispara then
  2899. ParaUnitPath.AddPath(More,false)
  2900. else
  2901. unitsearchpath.AddPath(More,true);
  2902. end;
  2903. 'U' :
  2904. OutputUnitDir:=FixPath(More,true);
  2905. 'W',
  2906. 'w':
  2907. begin
  2908. if More<>'' then
  2909. begin
  2910. DefaultReplacements(More);
  2911. D:=ExtractFilePath(More);
  2912. if (D<>'') then
  2913. D:=FixPath(D,True);
  2914. D:=D+ExtractFileName(More);
  2915. if (c='W') then
  2916. WpoFeedbackOutput:=D
  2917. else
  2918. WpoFeedbackInput:=D;
  2919. end
  2920. else
  2921. IllegalPara(opt);
  2922. end;
  2923. else
  2924. IllegalPara(opt);
  2925. end;
  2926. end;
  2927. procedure TOption.Interpret_G_l(opt, more: TCmdStr);
  2928. var
  2929. j : integer;
  2930. begin
  2931. if UnsetBool(More, 0, opt, false) then
  2932. begin
  2933. exclude(init_settings.moduleswitches,cs_debuginfo);
  2934. exclude(init_settings.globalswitches,cs_use_heaptrc);
  2935. exclude(init_settings.globalswitches,cs_use_lineinfo);
  2936. exclude(init_settings.localswitches,cs_checkpointer);
  2937. paratargetdbg:=dbg_none;
  2938. localvartrashing := -1;
  2939. end
  2940. else
  2941. begin
  2942. include(init_settings.moduleswitches,cs_debuginfo);
  2943. if paratargetdbg=dbg_none then
  2944. paratargetdbg:=target_info.dbg;
  2945. end;
  2946. if not RelocSectionSetExplicitly then
  2947. RelocSection:=false;
  2948. j:=1;
  2949. while j<=length(more) do
  2950. begin
  2951. case more[j] of
  2952. 'c' :
  2953. begin
  2954. if UnsetBool(More, j, opt, false) then
  2955. exclude(init_settings.localswitches,cs_checkpointer)
  2956. else if (target_info.system in systems_support_checkpointer) then
  2957. begin
  2958. if do_release then
  2959. Message(option_gc_incompatible_with_release_flag)
  2960. else
  2961. include(init_settings.localswitches,cs_checkpointer);
  2962. end
  2963. else
  2964. UnsupportedPara('-gc');
  2965. end;
  2966. 'h' :
  2967. begin
  2968. if UnsetBool(More, j, opt, false) then
  2969. exclude(init_settings.globalswitches,cs_use_heaptrc)
  2970. else
  2971. begin
  2972. if cs_gdb_valgrind in init_settings.globalswitches then
  2973. Message2(option_valgrind_heaptrc_mismatch,'-gh', '-gv');
  2974. include(init_settings.globalswitches,cs_use_heaptrc);
  2975. end;
  2976. end;
  2977. 'l' :
  2978. begin
  2979. if UnsetBool(More, j, opt, false) then
  2980. exclude(init_settings.globalswitches,cs_use_lineinfo)
  2981. else
  2982. include(init_settings.globalswitches,cs_use_lineinfo);
  2983. end;
  2984. 'm' :
  2985. begin
  2986. paratargetdbg:=dbg_codeview;
  2987. end;
  2988. 'o' :
  2989. begin
  2990. if not UpdateDebugStr(copy(more,j+1),init_settings.debugswitches) then
  2991. IllegalPara(opt);
  2992. break;
  2993. end;
  2994. 'p' :
  2995. begin
  2996. if UnsetBool(More, j, opt, false) then
  2997. exclude(init_settings.globalswitches,cs_stabs_preservecase)
  2998. else
  2999. include(init_settings.globalswitches,cs_stabs_preservecase);
  3000. end;
  3001. 's' :
  3002. begin
  3003. paratargetdbg:=dbg_stabs;
  3004. end;
  3005. 't' :
  3006. begin
  3007. if UnsetBool(More, j, opt, false) then
  3008. localvartrashing := -1
  3009. else
  3010. localvartrashing := (localvartrashing + 1) mod nroftrashvalues;
  3011. end;
  3012. 'v' :
  3013. begin
  3014. if UnsetBool(More, j, opt, false) then
  3015. exclude(init_settings.globalswitches,cs_gdb_valgrind)
  3016. else
  3017. begin
  3018. if cs_use_heaptrc in init_settings.globalswitches then
  3019. Message2(option_valgrind_heaptrc_mismatch,'-gh', '-gv');
  3020. include(init_settings.globalswitches,cs_gdb_valgrind);
  3021. end;
  3022. end;
  3023. 'w' :
  3024. begin
  3025. if (j<length(more)) and (more[j+1] in ['2','3','4']) then
  3026. begin
  3027. case more[j+1] of
  3028. '2': paratargetdbg:=dbg_dwarf2;
  3029. '3': paratargetdbg:=dbg_dwarf3;
  3030. '4': paratargetdbg:=dbg_dwarf4;
  3031. end;
  3032. inc(j);
  3033. end
  3034. else
  3035. paratargetdbg:=dbg_dwarf2;
  3036. end;
  3037. else
  3038. IllegalPara(opt);
  3039. end;
  3040. inc(j);
  3041. end;
  3042. end;
  3043. procedure TOption.Interpret_Help(more: TCmdStr);
  3044. begin
  3045. if (More <> '') and (More [1] = 'F') then
  3046. begin
  3047. FPCHelpLines := true;
  3048. Delete (More, 1, 1);
  3049. FPCBinaryPath := More;
  3050. end;
  3051. WriteHelpPages;
  3052. end;
  3053. procedure TOption.Interpret_H_l(more: TCmdStr);
  3054. begin
  3055. NoPressEnter:=true;
  3056. if (More <> '') and (More [1] = 'F') then
  3057. begin
  3058. FPCHelpLines := true;
  3059. Delete (More, 1, 1);
  3060. FPCBinaryPath := More;
  3061. end;
  3062. WriteHelpPages;
  3063. end;
  3064. procedure TOption.Interpret_I_l(more: TCmdStr);
  3065. begin
  3066. if (More='') or
  3067. (More [1] in ['a', 'b', 'c', 'f', 'i', {$ifdef LLVM}'l',{$endif} 'm', 'o', 'r', 't', 'u', 'w', 'x']) then
  3068. WriteInfo (More)
  3069. else
  3070. QuickInfo:=QuickInfo+More;
  3071. end;
  3072. procedure TOption.Interpret_I_U(more: TCmdStr; ispara: boolean);
  3073. begin
  3074. if ispara then
  3075. ParaIncludePath.AddPath(More,false)
  3076. else
  3077. includesearchpath.AddPath(More,false);
  3078. end;
  3079. procedure TOption.Interpret_K_l(opt, more: TCmdStr);
  3080. begin
  3081. if more<>'' then
  3082. ParaLinkOptions:=ParaLinkOptions+' '+More
  3083. else
  3084. IllegalPara(opt);
  3085. end;
  3086. procedure TOption.Interpret_L_l(opt, more: TCmdStr);
  3087. begin
  3088. ParaLogo:=not UnSetBool(more,0,opt,true);
  3089. end;
  3090. procedure TOption.Interpret_M_l(opt, more: TCmdStr);
  3091. begin
  3092. {$ifdef PREPROCWRITE}
  3093. parapreprocess:=not UnSetBool(more,0,opt,true);
  3094. {$endif PREPROCWRITE}
  3095. end;
  3096. procedure TOption.Interpret_M_U(opt, more: TCmdStr);
  3097. begin
  3098. more:=Upper(more);
  3099. if not SetCompileMode(more, true) then
  3100. if not SetCompileModeSwitch(more, true) then
  3101. IllegalPara(opt);
  3102. end;
  3103. procedure TOption.Interpret_N_l(opt, more: TCmdStr);
  3104. begin
  3105. if More='' then
  3106. disable_configfile:=true
  3107. else
  3108. IllegalPara(opt);
  3109. end;
  3110. procedure TOption.Interpret_O_l(opt, more: TCmdStr);
  3111. var
  3112. D : String;
  3113. begin
  3114. if More<>'' then
  3115. begin
  3116. DefaultReplacements(More);
  3117. D:=ExtractFilePath(More);
  3118. if (D<>'') then
  3119. OutputExeDir:=FixPath(D,True);
  3120. OutputFileName:=ExtractFileName(More);
  3121. end
  3122. else
  3123. IllegalPara(opt);
  3124. end;
  3125. procedure TOption.Interpret_O_U(opt, more: TCmdStr);
  3126. var
  3127. j : integer;
  3128. begin
  3129. j:=1;
  3130. while j<=length(more) do
  3131. begin
  3132. case more[j] of
  3133. '1' :
  3134. init_settings.optimizerswitches:=init_settings.optimizerswitches+level1optimizerswitches;
  3135. '2' :
  3136. init_settings.optimizerswitches:=init_settings.optimizerswitches+level2optimizerswitches;
  3137. '3' :
  3138. init_settings.optimizerswitches:=init_settings.optimizerswitches+level3optimizerswitches;
  3139. '4' :
  3140. init_settings.optimizerswitches:=init_settings.optimizerswitches+level4optimizerswitches;
  3141. 'a' :
  3142. begin
  3143. if not(UpdateAlignmentStr(Copy(Opt,j+3,255),ParaAlignment)) then
  3144. IllegalPara(opt);
  3145. break;
  3146. end;
  3147. 's' :
  3148. include(init_settings.optimizerswitches,cs_opt_size);
  3149. 'p' :
  3150. begin
  3151. if not Setoptimizecputype(copy(more,j+1),init_settings.optimizecputype) then
  3152. begin
  3153. OptCPUSetExplicitly:=true;
  3154. { Give warning for old i386 switches }
  3155. if (Length(More)-j=1) and
  3156. (More[j+1]>='1') and (More[j+1]<='5')then
  3157. Message2(option_obsolete_switch_use_new,'-Op<nr>','-Op<name>')
  3158. else
  3159. IllegalPara(opt);
  3160. end;
  3161. break;
  3162. end;
  3163. 'o' :
  3164. begin
  3165. if not UpdateOptimizerStr(copy(more,j+1),init_settings.optimizerswitches) then
  3166. IllegalPara(opt);
  3167. break;
  3168. end;
  3169. '-' :
  3170. begin
  3171. init_settings.optimizerswitches:=[];
  3172. FillChar(ParaAlignment,sizeof(ParaAlignment),0);
  3173. end;
  3174. { Obsolete switches }
  3175. 'g' :
  3176. Message2(option_obsolete_switch_use_new,'-Og','-Os');
  3177. 'G' :
  3178. Message1(option_obsolete_switch,'-OG');
  3179. 'r' :
  3180. Message2(option_obsolete_switch_use_new,'-Or','-O2 or -Ooregvar');
  3181. 'u' :
  3182. Message2(option_obsolete_switch_use_new,'-Ou','-Oouncertain');
  3183. 'w' :
  3184. begin
  3185. if not UpdateWpoStr(copy(more,j+1),init_settings.dowpoptimizerswitches) then
  3186. IllegalPara(opt);
  3187. break;
  3188. end;
  3189. 'W' :
  3190. begin
  3191. if not UpdateWpoStr(copy(more,j+1),init_settings.genwpoptimizerswitches) then
  3192. IllegalPara(opt);
  3193. break;
  3194. end;
  3195. else
  3196. IllegalPara(opt);
  3197. end;
  3198. inc(j);
  3199. end;
  3200. end;
  3201. procedure TOption.Interpret_P_l(opt, more: TCmdStr);
  3202. begin
  3203. if UnsetBool(More, 0, opt, false) then
  3204. begin
  3205. init_settings.moduleswitches:=init_settings.moduleswitches-[cs_profile];
  3206. undef_system_macro('FPC_PROFILE');
  3207. end
  3208. else
  3209. if Length(More)=0 then
  3210. IllegalPara(opt)
  3211. else
  3212. case more[1] of
  3213. 'g' : if UnsetBool(more, 1, opt, false) then
  3214. begin
  3215. exclude(init_settings.moduleswitches,cs_profile);
  3216. undef_system_macro('FPC_PROFILE');
  3217. end
  3218. else if (target_info.system in supported_targets_pg) then
  3219. begin
  3220. include(init_settings.moduleswitches,cs_profile);
  3221. def_system_macro('FPC_PROFILE');
  3222. end
  3223. else
  3224. UnsupportedPara('-pg');
  3225. else
  3226. IllegalPara(opt);
  3227. end;
  3228. end;
  3229. procedure TOption.Interpret_P_U(opt, more: TCmdStr);
  3230. begin
  3231. { used to select the target processor with the "fpc" binary;
  3232. give an error if it's not the target architecture supported by
  3233. this compiler binary (will be verified after the target_info
  3234. is set) }
  3235. processorstr:=More;
  3236. end;
  3237. procedure TOption.Interpret_R_U(opt, more: TCmdStr);
  3238. begin
  3239. if not SetAsmReadMode(More,init_settings.asmmode) then
  3240. IllegalPara(opt);
  3241. end;
  3242. procedure TOption.Interpret_S_l(opt, more: TCmdStr);
  3243. begin
  3244. if UnsetBool(More, 0, opt, false) then
  3245. begin
  3246. init_settings.globalswitches:=init_settings.globalswitches-[cs_asm_extern,cs_link_extern,cs_link_nolink];
  3247. if more<>'' then
  3248. IllegalPara(opt);
  3249. end
  3250. else
  3251. begin
  3252. init_settings.globalswitches:=init_settings.globalswitches+[cs_asm_extern,cs_link_extern,cs_link_nolink];
  3253. if more='h' then
  3254. init_settings.globalswitches:=init_settings.globalswitches-[cs_link_on_target,cs_assemble_on_target]
  3255. else if more='t' then
  3256. init_settings.globalswitches:=init_settings.globalswitches+[cs_link_on_target,cs_assemble_on_target]
  3257. else if more='T' then
  3258. init_settings.globalswitches:=init_settings.globalswitches+[cs_link_on_target]-[cs_asm_extern]
  3259. else if more='r' then
  3260. init_settings.globalswitches:=init_settings.globalswitches+[cs_asm_leave,cs_no_regalloc]
  3261. else if more<>'' then
  3262. IllegalPara(opt);
  3263. end;
  3264. end;
  3265. procedure TOption.Interpret_S_U(opt, more: TCmdStr);
  3266. var
  3267. j : integer;
  3268. begin
  3269. if more='' then
  3270. IllegalPara(opt);
  3271. if more[1]='I' then
  3272. begin
  3273. {$ifdef jvm}
  3274. UnsupportedPara('-SI');
  3275. {$endif}
  3276. if upper(more)='ICOM' then
  3277. init_settings.interfacetype:=it_interfacecom
  3278. else if upper(more)='ICORBA' then
  3279. init_settings.interfacetype:=it_interfacecorba
  3280. else
  3281. IllegalPara(opt);
  3282. end
  3283. else
  3284. begin
  3285. j:=1;
  3286. while j<=length(more) do
  3287. begin
  3288. case more[j] of
  3289. '2' : //an alternative to -Mobjfpc
  3290. SetCompileMode('OBJFPC',true);
  3291. 'a' :
  3292. If UnsetBool(More, j, opt, false) then
  3293. exclude(init_settings.localswitches,cs_do_assertion)
  3294. else
  3295. include(init_settings.localswitches,cs_do_assertion);
  3296. 'c' :
  3297. If UnsetBool(More, j, opt, false) then
  3298. exclude(init_settings.moduleswitches,cs_support_c_operators)
  3299. else
  3300. include(init_settings.moduleswitches,cs_support_c_operators);
  3301. 'C':
  3302. If UnsetBool(More, j, opt, false) then
  3303. exclude(init_settings.localswitches,cs_check_all_case_coverage)
  3304. else
  3305. include(init_settings.localswitches,cs_check_all_case_coverage);
  3306. 'd' : //an alternative to -Mdelphi
  3307. SetCompileMode('DELPHI',true);
  3308. 'e' :
  3309. begin
  3310. SetErrorFlags(copy(more,j+1));
  3311. break;
  3312. end;
  3313. 'f' :
  3314. begin
  3315. if not(cs_compilesystem in init_settings.moduleswitches) then
  3316. Message(option_features_only_for_system_unit);
  3317. inc(j);
  3318. if more[j]='-' then
  3319. begin
  3320. if length(more)>j then
  3321. IllegalPara(opt)
  3322. else
  3323. features:=[];
  3324. end
  3325. else
  3326. begin
  3327. if (HandleFeature(upper(copy(more,j)))) then
  3328. j:=length(more)
  3329. else
  3330. IllegalPara(opt);
  3331. end;
  3332. end;
  3333. 'g' :
  3334. If UnsetBool(More, j, opt, false) then
  3335. exclude(init_settings.moduleswitches,cs_support_goto)
  3336. else
  3337. include(init_settings.moduleswitches,cs_support_goto);
  3338. 'h' :
  3339. If UnsetBool(More, j, opt, false) then
  3340. exclude(init_settings.localswitches,cs_refcountedstrings)
  3341. else
  3342. include(init_settings.localswitches,cs_refcountedstrings);
  3343. 'i' :
  3344. If UnsetBool(More, j, opt, false) then
  3345. exclude(init_settings.localswitches,cs_do_inline)
  3346. else
  3347. include(init_settings.localswitches,cs_do_inline);
  3348. 'j' :
  3349. If UnsetBool(More, j, opt, false) then
  3350. exclude(init_settings.localswitches,cs_typed_const_writable)
  3351. else
  3352. include(init_settings.localswitches,cs_typed_const_writable);
  3353. 'k' :
  3354. If UnsetBool(More, j, opt, false) then
  3355. exclude(init_settings.globalswitches,cs_load_fpcylix_unit)
  3356. else
  3357. include(init_settings.globalswitches,cs_load_fpcylix_unit);
  3358. 'm' :
  3359. If UnsetBool(More, j, opt, false) then
  3360. exclude(init_settings.moduleswitches,cs_support_macro)
  3361. else
  3362. include(init_settings.moduleswitches,cs_support_macro);
  3363. 'o' : //an alternative to -Mtp
  3364. SetCompileMode('TP',true);
  3365. 'r' :
  3366. If UnsetBool(More, j, opt, false) then
  3367. exclude(init_settings.globalswitches,cs_transparent_file_names)
  3368. else
  3369. include(init_settings.globalswitches,cs_transparent_file_names);
  3370. {$ifdef gpc_mode}
  3371. 'p' : //an alternative to -Mgpc
  3372. SetCompileMode('GPC',true);
  3373. {$endif}
  3374. 's' :
  3375. If UnsetBool(More, j, opt, false) then
  3376. exclude(init_settings.globalswitches,cs_constructor_name)
  3377. else
  3378. include(init_settings.globalswitches,cs_constructor_name);
  3379. 't' :
  3380. Message1(option_obsolete_switch,'-St');
  3381. 'v' :
  3382. If UnsetBool(More, j, opt, false) then
  3383. exclude(init_settings.globalswitches,cs_support_vectors)
  3384. else
  3385. include(init_settings.globalswitches,cs_support_vectors);
  3386. 'x' :
  3387. If UnsetBool(More, j, opt, false) then
  3388. SetCompileModeSwitch('EXCEPTIONS-',true)
  3389. else
  3390. SetCompileModeSwitch('EXCEPTIONS',true);
  3391. 'y' :
  3392. If UnsetBool(More, j, opt, false) then
  3393. exclude(init_settings.localswitches,cs_typed_addresses)
  3394. else
  3395. include(init_settings.localswitches,cs_typed_addresses);
  3396. '-' :
  3397. begin
  3398. init_settings.globalswitches:=init_settings.globalswitches - [cs_constructor_name,cs_support_exceptions,
  3399. cs_support_vectors,cs_load_fpcylix_unit];
  3400. init_settings.localswitches:=init_settings.localswitches - [cs_do_assertion,cs_do_inline, cs_refcountedstrings,
  3401. cs_typed_addresses];
  3402. init_settings.moduleswitches:=init_settings.moduleswitches - [cs_support_c_operators, cs_support_goto,
  3403. cs_support_macro];
  3404. end;
  3405. else
  3406. IllegalPara(opt);
  3407. end;
  3408. inc(j);
  3409. end;
  3410. end;
  3411. end;
  3412. procedure TOption.Interpret_T_l(opt, more: TCmdStr);
  3413. begin
  3414. more:=Upper(More);
  3415. if (more='') then
  3416. Message1(option_missing_arg,'-t')
  3417. else
  3418. begin
  3419. if (self.parasubtarget<>'') and (More<>upper(self.parasubtarget)) then
  3420. Message1(option_subtarget_is_already_set,self.parasubtarget)
  3421. else
  3422. self.parasubtarget:=more;
  3423. end;
  3424. end;
  3425. procedure TOption.Interpret_T_U(opt, more: TCmdStr);
  3426. begin
  3427. more:=Upper(More);
  3428. if paratarget=system_none then
  3429. begin
  3430. { remove old target define }
  3431. TargetOptions(false);
  3432. { load new target }
  3433. paratarget:=find_system_by_string(More);
  3434. if paratarget<>system_none then
  3435. set_target(paratarget)
  3436. else
  3437. IllegalPara(opt);
  3438. { set new define }
  3439. TargetOptions(true);
  3440. end
  3441. else
  3442. if More<>upper(target_info.shortname) then
  3443. Message1(option_target_is_already_set,target_info.shortname);
  3444. end;
  3445. procedure TOption.Interpret_U_l(opt, more: TCmdStr);
  3446. begin
  3447. if is_identifier(more) then
  3448. undef_system_macro(more)
  3449. else
  3450. begin
  3451. if (more='') then
  3452. Message1(option_missing_arg,'-u')
  3453. else
  3454. Message1(option_malformed_para,opt);
  3455. StopOptions(1);
  3456. end;
  3457. end;
  3458. procedure TOption.Interpret_U_U(opt, more: TCmdStr);
  3459. var
  3460. j : integer;
  3461. begin
  3462. j:=1;
  3463. while j<=length(more) do
  3464. begin
  3465. case more[j] of
  3466. {$ifdef UNITALIASES}
  3467. 'a' :
  3468. begin
  3469. AddUnitAlias(Copy(More,j+1));
  3470. break;
  3471. end;
  3472. {$endif UNITALIASES}
  3473. 'n' :
  3474. exclude(init_settings.globalswitches,cs_check_unit_name);
  3475. 'p' :
  3476. begin
  3477. Message2(option_obsolete_switch_use_new,'-Up','-Fu');
  3478. break;
  3479. end;
  3480. 'r' :
  3481. begin
  3482. do_release:=true;
  3483. if (cs_checkpointer in init_settings.localswitches) then
  3484. begin
  3485. Message(option_gc_incompatible_with_release_flag);
  3486. exclude(init_settings.localswitches,cs_checkpointer);
  3487. end;
  3488. end;
  3489. 's' :
  3490. include(init_settings.moduleswitches,cs_compilesystem);
  3491. '-' :
  3492. begin
  3493. exclude(init_settings.moduleswitches,cs_compilesystem);
  3494. exclude(init_settings.globalswitches,cs_check_unit_name);
  3495. end;
  3496. else
  3497. IllegalPara(opt);
  3498. end;
  3499. inc(j);
  3500. end;
  3501. end;
  3502. procedure TOption.Interpret_V_l(opt, more: TCmdStr);
  3503. begin
  3504. if not setverbosity(More) then
  3505. IllegalPara(opt);
  3506. end;
  3507. procedure TOption.Interpret_V_U(opt, more: TCmdStr);
  3508. begin
  3509. ; { Ignore used by fpc }
  3510. end;
  3511. procedure TOption.Interpret_W_U(opt, more: TCmdStr);
  3512. var
  3513. j,code : integer;
  3514. s : string;
  3515. begin
  3516. j:=1;
  3517. while j<=length(More) do
  3518. begin
  3519. case More[j] of
  3520. 'A':
  3521. begin
  3522. if target_info.system in systems_all_windows then
  3523. begin
  3524. if UnsetBool(More, j, opt, false) then
  3525. SetApptype(app_cui)
  3526. else
  3527. SetApptype(app_native);
  3528. end
  3529. else
  3530. IllegalPara(opt);
  3531. end;
  3532. 'b':
  3533. begin
  3534. if target_info.system in systems_darwin then
  3535. begin
  3536. if UnsetBool(More, j, opt, false) then
  3537. SetApptype(app_cui)
  3538. else
  3539. SetApptype(app_bundle)
  3540. end
  3541. else
  3542. IllegalPara(opt);
  3543. end;
  3544. 'B':
  3545. begin
  3546. if target_info.system in systems_all_windows+systems_symbian+[system_z80_zxspectrum] then
  3547. begin
  3548. { -WB200000 means set trefered base address
  3549. to $200000, but does not change relocsection boolean
  3550. this way we can create both relocatble and
  3551. non relocatable DLL at a specific base address PM }
  3552. if (length(More)>j) then
  3553. begin
  3554. val('$'+Copy(More,j+1),imagebase,code);
  3555. if code<>0 then
  3556. IllegalPara(opt);
  3557. ImageBaseSetExplicity:=true;
  3558. end
  3559. else
  3560. begin
  3561. RelocSection:=true;
  3562. RelocSectionSetExplicitly:=true;
  3563. end;
  3564. break;
  3565. end
  3566. else
  3567. IllegalPara(opt);
  3568. end;
  3569. 'C':
  3570. begin
  3571. if target_info.system in systems_all_windows+systems_os2+systems_macos then
  3572. begin
  3573. if UnsetBool(More, j, opt, false) then
  3574. SetApptype(app_gui)
  3575. else
  3576. SetApptype(app_cui);
  3577. end
  3578. else
  3579. IllegalPara(opt);
  3580. end;
  3581. 'D':
  3582. begin
  3583. if target_info.system in systems_all_windows then
  3584. begin
  3585. UseDeffileForExports:=not UnsetBool(More, j, opt, false);
  3586. UseDeffileForExportsSetExplicitly:=true;
  3587. end
  3588. else
  3589. IllegalPara(opt);
  3590. end;
  3591. 'e':
  3592. begin
  3593. if (target_info.system in systems_darwin) then
  3594. begin
  3595. set_target_res(res_ext);
  3596. target_info.resobjext:='.fpcres';
  3597. end
  3598. else
  3599. IllegalPara(opt);
  3600. end;
  3601. 'F':
  3602. begin
  3603. {$if defined(m68k)}
  3604. if target_info.system in [system_m68k_atari] then
  3605. begin
  3606. if (length(More)>j) then
  3607. begin
  3608. val(Copy(More,j+1),ataritos_exe_flags,code);
  3609. if code<>0 then
  3610. IllegalPara(opt);
  3611. end
  3612. else
  3613. IllegalPara(opt);
  3614. break;
  3615. end;
  3616. {$endif defined(m68k)}
  3617. if target_info.system in systems_os2 then
  3618. begin
  3619. if UnsetBool(More, j, opt, false) then
  3620. SetApptype(app_cui)
  3621. else
  3622. SetApptype(app_fs);
  3623. end
  3624. else
  3625. IllegalPara(opt);
  3626. end;
  3627. 'G':
  3628. begin
  3629. if target_info.system in systems_all_windows+systems_os2+systems_macos then
  3630. begin
  3631. if UnsetBool(More, j, opt, false) then
  3632. SetApptype(app_cui)
  3633. else
  3634. SetApptype(app_gui);
  3635. end
  3636. else
  3637. IllegalPara(opt);
  3638. end;
  3639. {$if defined(i8086)}
  3640. 'h':
  3641. begin
  3642. if UnsetBool(More, j, opt, false) then
  3643. exclude(init_settings.moduleswitches,cs_huge_code)
  3644. else
  3645. include(init_settings.moduleswitches,cs_huge_code);
  3646. end;
  3647. {$endif defined(i8086)}
  3648. 'I':
  3649. begin
  3650. if target_info.system in systems_all_windows then
  3651. begin
  3652. GenerateImportSection:=not UnsetBool(More,j,opt,false);
  3653. GenerateImportSectionSetExplicitly:=true;
  3654. end
  3655. else
  3656. IllegalPara(opt);
  3657. end;
  3658. 'i':
  3659. begin
  3660. if (target_info.system in systems_darwin) then
  3661. begin
  3662. set_target_res(res_macho);
  3663. target_info.resobjext:=
  3664. targetinfos[target_info.system]^.resobjext;
  3665. end
  3666. else
  3667. IllegalPara(opt);
  3668. end;
  3669. 'm':
  3670. begin
  3671. {$if defined(i8086)}
  3672. if (target_info.system in [system_i8086_msdos,system_i8086_win16,system_i8086_embedded]) then
  3673. begin
  3674. case Upper(Copy(More,j+1)) of
  3675. 'TINY': init_settings.x86memorymodel:=mm_tiny;
  3676. 'SMALL': init_settings.x86memorymodel:=mm_small;
  3677. 'MEDIUM': init_settings.x86memorymodel:=mm_medium;
  3678. 'COMPACT': init_settings.x86memorymodel:=mm_compact;
  3679. 'LARGE': init_settings.x86memorymodel:=mm_large;
  3680. 'HUGE': init_settings.x86memorymodel:=mm_huge;
  3681. else
  3682. IllegalPara(opt);
  3683. end;
  3684. break;
  3685. end
  3686. else
  3687. {$endif defined(i8086)}
  3688. IllegalPara(opt);
  3689. end;
  3690. 'M':
  3691. begin
  3692. if (target_info.system in (systems_darwin-[system_i386_iphonesim,system_arm_ios,system_aarch64_ios,system_x86_64_iphonesim,system_aarch64_iphonesim])) and
  3693. ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED',copy(More,2),false) then
  3694. begin
  3695. break;
  3696. end
  3697. else
  3698. IllegalPara(opt);
  3699. end;
  3700. 'N':
  3701. begin
  3702. if target_info.system in systems_all_windows then
  3703. begin
  3704. RelocSection:=UnsetBool(More,j,opt,false);
  3705. RelocSectionSetExplicitly:=true;
  3706. end
  3707. else
  3708. IllegalPara(opt);
  3709. end;
  3710. 'p':
  3711. begin
  3712. {$push}
  3713. {$warn 6018 off} { Unreachable code due to compile time evaluation }
  3714. if ((target_info.system in systems_embedded) or (target_info.system in systems_freertos)) and
  3715. ControllerSupport then
  3716. begin
  3717. s:=upper(copy(more,j+1));
  3718. if not(SetControllerType(s,init_settings.controllertype)) then
  3719. IllegalPara(opt)
  3720. else
  3721. begin
  3722. if init_settings.cputype<>embedded_controllers[init_settings.controllertype].cputype then
  3723. begin
  3724. Message(scan_n_changecputype);
  3725. init_settings.cputype:=embedded_controllers[init_settings.controllertype].cputype;
  3726. end;
  3727. end;
  3728. break;
  3729. end
  3730. else
  3731. IllegalPara(opt);
  3732. {$pop}
  3733. end;
  3734. 'P':
  3735. begin
  3736. if (target_info.system in [system_i386_iphonesim,system_arm_ios,system_aarch64_ios,system_x86_64_iphonesim,system_aarch64_iphonesim]) and
  3737. ParseMacVersionMin(iPhoneOSVersionMin,MacOSXVersionMin,'IPHONE_OS_VERSION_MIN_REQUIRED',copy(More,2),true) then
  3738. begin
  3739. break;
  3740. end
  3741. {$ifdef XTENSA}
  3742. else if (target_info.system in [system_xtensa_freertos]) and
  3743. ParseVersionStr(idf_version,'IDF_VERSION',copy(More,2)) then
  3744. begin
  3745. break;
  3746. end
  3747. {$endif XTENSA}
  3748. else
  3749. IllegalPara(opt);
  3750. end;
  3751. {$if defined(m68k)}
  3752. 'L':
  3753. begin
  3754. if (target_info.system in [system_m68k_sinclairql]) then
  3755. sinclairql_vlink_experimental:=false
  3756. else
  3757. IllegalPara(opt);
  3758. end;
  3759. 'Q':
  3760. begin
  3761. if (target_info.system in [system_m68k_sinclairql]) then
  3762. begin
  3763. sinclairql_metadata_format:=Upper(Copy(More,j+1));
  3764. case sinclairql_metadata_format of
  3765. 'QHDR', 'XTCC': ; { allowed formats }
  3766. else
  3767. IllegalPara(opt);
  3768. end;
  3769. break;
  3770. end
  3771. else
  3772. IllegalPara(opt);
  3773. end;
  3774. {$endif defined(m68k)}
  3775. 'R':
  3776. begin
  3777. if target_info.system in systems_all_windows then
  3778. begin
  3779. { support -WR+ / -WR- as synonyms to -WR / -WN }
  3780. RelocSection:=not UnsetBool(More,j,opt,false);
  3781. RelocSectionSetExplicitly:=true;
  3782. end
  3783. else
  3784. IllegalPara(opt);
  3785. end;
  3786. 't':
  3787. begin
  3788. {$if defined(i8086)}
  3789. if (target_info.system in [system_i8086_msdos,system_i8086_embedded]) then
  3790. begin
  3791. case Upper(Copy(More,j+1)) of
  3792. 'EXE': SetAppType(app_cui);
  3793. 'COM': SetAppType(app_com);
  3794. else
  3795. IllegalPara(opt);
  3796. end;
  3797. break;
  3798. end
  3799. else
  3800. {$endif defined(i8086)}
  3801. {$if defined(m68k)}
  3802. if (target_info.system in [system_m68k_atari]) then
  3803. begin
  3804. case Upper(Copy(More,j+1)) of
  3805. 'TOS': ataritos_exe_format := 'ataritos';
  3806. 'MINT': ataritos_exe_format := 'aoutmint';
  3807. else
  3808. IllegalPara(opt);
  3809. end;
  3810. break;
  3811. end
  3812. else
  3813. {$endif defined(m68k)}
  3814. IllegalPara(opt);
  3815. end;
  3816. 'T':
  3817. begin
  3818. if target_info.system in systems_macos then
  3819. begin
  3820. if UnsetBool(More, j, opt, false) then
  3821. SetApptype(app_cui)
  3822. else
  3823. SetApptype(app_tool);
  3824. end
  3825. else
  3826. IllegalPara(opt);
  3827. end;
  3828. 'X':
  3829. begin
  3830. if (target_info.system in systems_linux) then
  3831. begin
  3832. if UnsetBool(More, j, opt, false) then
  3833. exclude(init_settings.moduleswitches,cs_executable_stack)
  3834. else
  3835. include(init_settings.moduleswitches,cs_executable_stack)
  3836. end
  3837. else
  3838. IllegalPara(opt);
  3839. end;
  3840. else
  3841. IllegalPara(opt);
  3842. end;
  3843. inc(j);
  3844. end;
  3845. end;
  3846. procedure TOption.Interpret_X_l(opt, more: TCmdStr);
  3847. begin
  3848. message1(option_x_ignored,more);
  3849. end;
  3850. procedure TOption.Interpret_X_U(opt, more: TCmdStr);
  3851. var
  3852. j : integer;
  3853. s : string;
  3854. begin
  3855. j:=1;
  3856. while j<=length(more) do
  3857. begin
  3858. case More[j] of
  3859. '9' :
  3860. begin
  3861. if target_info.system in systems_linux then
  3862. begin
  3863. if UnsetBool(More, j, opt, false) then
  3864. exclude(init_settings.globalswitches,cs_link_pre_binutils_2_19)
  3865. else
  3866. include(init_settings.globalswitches,cs_link_pre_binutils_2_19);
  3867. end
  3868. else
  3869. IllegalPara(opt);
  3870. end;
  3871. 'a' :
  3872. begin
  3873. If UnsetBool(More, j, opt, false) then
  3874. exclude(init_settings.globalswitches,cs_large)
  3875. else
  3876. include(init_settings.globalswitches,cs_large);
  3877. end;
  3878. 'c' : Cshared:=TRUE;
  3879. 'd' : Dontlinkstdlibpath:=TRUE;
  3880. 'e' :
  3881. begin
  3882. If UnsetBool(More, j, opt, false) then
  3883. exclude(init_settings.globalswitches,cs_link_extern)
  3884. else
  3885. include(init_settings.globalswitches,cs_link_extern);
  3886. end;
  3887. 'f' :
  3888. include(init_settings.globalswitches,cs_link_pthread);
  3889. 'g' :
  3890. begin
  3891. If UnsetBool(More, j, opt, false) then
  3892. exclude(init_settings.globalswitches,cs_link_separate_dbg_file)
  3893. else
  3894. include(init_settings.globalswitches,cs_link_separate_dbg_file);
  3895. end;
  3896. 'i' :
  3897. begin
  3898. If UnsetBool(More, j, opt, false) then
  3899. include(init_settings.globalswitches,cs_link_extern)
  3900. else
  3901. exclude(init_settings.globalswitches,cs_link_extern);
  3902. end;
  3903. 'n' :
  3904. begin
  3905. If UnsetBool(More, j, opt, false) then
  3906. exclude(init_settings.globalswitches,cs_link_native)
  3907. else
  3908. include(init_settings.globalswitches,cs_link_native);
  3909. end;
  3910. {$ifdef llvm}
  3911. 'l' :
  3912. begin
  3913. if j=length(more) then
  3914. IllegalPara(opt)
  3915. else
  3916. begin
  3917. case more[j+1] of
  3918. 'S':
  3919. begin
  3920. llvmutilssuffix:=copy(more,j+2);
  3921. j:=length(more);
  3922. end
  3923. else
  3924. IllegalPara(opt);
  3925. end;
  3926. end;
  3927. end;
  3928. {$endif}
  3929. 'm' :
  3930. begin
  3931. If UnsetBool(More, j, opt, false) then
  3932. exclude(init_settings.globalswitches,cs_link_map)
  3933. else
  3934. include(init_settings.globalswitches,cs_link_map);
  3935. end;
  3936. 'p' : ; { Ignore used by fpc.pp }
  3937. 'r' :
  3938. begin
  3939. if (target_info.system in suppported_targets_x_smallr) then
  3940. begin
  3941. rlinkpath:=Copy(more,2);
  3942. DefaultReplacements(rlinkpath);
  3943. end
  3944. else
  3945. IgnoredPara('-Xr');
  3946. more:='';
  3947. end;
  3948. 'R' :
  3949. begin
  3950. sysrootpath:=copy(more,2);
  3951. defaultreplacements(sysrootpath);
  3952. more:='';
  3953. end;
  3954. 's' :
  3955. begin
  3956. If UnsetBool(More, j, opt, false) then
  3957. exclude(init_settings.globalswitches,cs_link_strip)
  3958. else
  3959. include(init_settings.globalswitches,cs_link_strip);
  3960. end;
  3961. 't' :
  3962. include(init_settings.globalswitches,cs_link_staticflag);
  3963. 'u' :
  3964. begin
  3965. if target_info.system in systems_support_uf2 then
  3966. begin
  3967. if UnsetBool(More, j, opt, false) then
  3968. exclude(init_settings.globalswitches,cs_generate_uf2)
  3969. else
  3970. include(init_settings.globalswitches,cs_generate_uf2);
  3971. end
  3972. else
  3973. IgnoredPara('-Xu');
  3974. end;
  3975. 'v' :
  3976. begin
  3977. If UnsetBool(More, j, opt, false) then
  3978. exclude(init_settings.globalswitches,cs_link_opt_vtable)
  3979. else
  3980. include(init_settings.globalswitches,cs_link_opt_vtable);
  3981. end;
  3982. 'D' :
  3983. begin
  3984. def_system_macro('FPC_LINK_DYNAMIC');
  3985. undef_system_macro('FPC_LINK_SMART');
  3986. undef_system_macro('FPC_LINK_STATIC');
  3987. exclude(init_settings.globalswitches,cs_link_static);
  3988. exclude(init_settings.globalswitches,cs_link_smart);
  3989. include(init_settings.globalswitches,cs_link_shared);
  3990. LinkTypeSetExplicitly:=true;
  3991. end;
  3992. 'M' :
  3993. begin
  3994. mainaliasname:=Copy(more,2);
  3995. More:='';
  3996. end;
  3997. 'P' :
  3998. begin
  3999. utilsprefix:=Copy(more,2);
  4000. DefaultReplacements(utilsprefix);
  4001. More:='';
  4002. end;
  4003. 'L' : begin // -XLO is link order -XLA is link alias. -XLD avoids load defaults.
  4004. // these are not aggregable.
  4005. if (j=length(more)) or not (more[j+1] in ['O','A','D','L']) then
  4006. IllegalPara(opt)
  4007. else
  4008. begin
  4009. case more[j+1] of
  4010. 'A' : begin
  4011. s:=Copy(more,3);
  4012. if not LinkLibraryAliases.AddDep(s) Then
  4013. IllegalPara(opt);
  4014. end;
  4015. 'O' : begin
  4016. s:=Copy(more,3);
  4017. if not LinkLibraryOrder.AddWeight(s) Then
  4018. IllegalPara(opt);
  4019. end;
  4020. 'D' : include(init_settings.globalswitches,cs_link_no_default_lib_order);
  4021. 'L' :
  4022. begin
  4023. if UnsetBool(More, j, opt, false) then
  4024. exclude(init_settings.globalswitches,cs_link_lld)
  4025. else
  4026. begin
  4027. include(init_settings.globalswitches,cs_link_lld);
  4028. include(init_settings.globalswitches,cs_link_extern);
  4029. end;
  4030. LinkerSetExplicitly:=true;
  4031. end
  4032. else
  4033. IllegalPara(opt);
  4034. end; {case}
  4035. j:=length(more);
  4036. end; {else begin}
  4037. end;
  4038. 'S' :
  4039. begin
  4040. ForceStaticLinking;
  4041. end;
  4042. 'V' :
  4043. begin
  4044. if UnsetBool(More, j, opt, false) then
  4045. exclude(init_settings.globalswitches,cs_link_vlink)
  4046. else
  4047. begin
  4048. include(init_settings.globalswitches,cs_link_vlink);
  4049. include(init_settings.globalswitches,cs_link_extern);
  4050. end;
  4051. LinkerSetExplicitly:=true;
  4052. end;
  4053. 'X' :
  4054. begin
  4055. def_system_macro('FPC_LINK_SMART');
  4056. undef_system_macro('FPC_LINK_STATIC');
  4057. undef_system_macro('FPC_LINK_DYNAMIC');
  4058. exclude(init_settings.globalswitches,cs_link_static);
  4059. include(init_settings.globalswitches,cs_link_smart);
  4060. exclude(init_settings.globalswitches,cs_link_shared);
  4061. LinkTypeSetExplicitly:=true;
  4062. end;
  4063. '-' :
  4064. begin
  4065. exclude(init_settings.globalswitches,cs_link_staticflag);
  4066. exclude(init_settings.globalswitches,cs_link_strip);
  4067. exclude(init_settings.globalswitches,cs_link_map);
  4068. set_default_link_type;
  4069. end;
  4070. else
  4071. IllegalPara(opt);
  4072. end;
  4073. inc(j);
  4074. end;
  4075. end;
  4076. {****************************************************************************
  4077. Callable Routines
  4078. ****************************************************************************}
  4079. function check_configfile(fn:string; var foundfn:string):boolean;
  4080. function CfgFileExists(const fn:string):boolean;
  4081. begin
  4082. Comment(V_Tried,'Configfile search: '+fn);
  4083. CfgFileExists:=FileExists(fn);
  4084. end;
  4085. var
  4086. {$ifdef Unix}
  4087. hs,
  4088. {$endif Unix}
  4089. configpath : string;
  4090. begin
  4091. foundfn:=fn;
  4092. check_configfile:=true;
  4093. { retrieve configpath }
  4094. configpath:=FixPath(GetEnvironmentVariable('PPC_CONFIG_PATH'),false);
  4095. {$ifdef Unix}
  4096. if configpath='' then
  4097. configpath:=ExpandFileName(FixPath(exepath+'../etc/',false));
  4098. {$endif}
  4099. {
  4100. Order to read configuration file :
  4101. try reading fpc.cfg in :
  4102. 1 - current dir
  4103. 2 - configpath
  4104. 3 - compiler path
  4105. }
  4106. if not FileExists(fn) then
  4107. begin
  4108. {$ifdef Unix}
  4109. hs:=GetEnvironmentVariable('HOME');
  4110. if (hs<>'') and CfgFileExists(FixPath(hs,false)+'.'+fn) then
  4111. foundfn:=FixPath(hs,false)+'.'+fn
  4112. else
  4113. {$endif}
  4114. if CfgFileExists(configpath+fn) then
  4115. foundfn:=configpath+fn
  4116. else
  4117. {$ifdef WINDOWS}
  4118. if (GetEnvironmentVariable('USERPROFILE')<>'') and CfgFileExists(FixPath(GetEnvironmentVariable('USERPROFILE'),false)+fn) then
  4119. foundfn:=FixPath(GetEnvironmentVariable('USERPROFILE'),false)+fn
  4120. else
  4121. if (GetEnvironmentVariable('ALLUSERSPROFILE')<>'') and CfgFileExists(FixPath(GetEnvironmentVariable('ALLUSERSPROFILE'),false)+fn) then
  4122. foundfn:=FixPath(GetEnvironmentVariable('ALLUSERSPROFILE'),false)+fn
  4123. else
  4124. {$endif WINDOWS}
  4125. {$ifndef Unix}
  4126. if CfgFileExists(exepath+fn) then
  4127. foundfn:=exepath+fn
  4128. else
  4129. {$else}
  4130. if CfgFileExists('/etc/'+fn) then
  4131. foundfn:='/etc/'+fn
  4132. else
  4133. {$endif}
  4134. check_configfile:=false;
  4135. end;
  4136. end;
  4137. procedure read_arguments(cmd:TCmdStr);
  4138. procedure def_cpu_macros;
  4139. var
  4140. abi : tabi;
  4141. fputype : tfputype;
  4142. cputype : tcputype;
  4143. controller: tcontrollertype;
  4144. s: string;
  4145. begin
  4146. {$ifdef llvm}
  4147. def_system_macro('CPULLVM');
  4148. {$endif}
  4149. for cputype:=low(tcputype) to high(tcputype) do
  4150. undef_system_macro('CPU'+Cputypestr[cputype]);
  4151. def_system_macro('CPU'+Cputypestr[init_settings.cputype]);
  4152. for fputype:=low(tfputype) to high(tfputype) do
  4153. undef_system_macro('FPU'+fputypestr[fputype]);
  4154. def_system_macro('FPU'+fputypestr[init_settings.fputype]);
  4155. {$PUSH}
  4156. {$WARN 6018 OFF} { Unreachable code due to compile time evaluation }
  4157. if ControllerSupport then
  4158. begin
  4159. for controller:=low(tcontrollertype) to high(tcontrollertype) do
  4160. begin
  4161. s:=embedded_controllers[controller].controllertypestr;
  4162. if s<>'' then
  4163. undef_system_macro('FPC_MCU_'+s);
  4164. end;
  4165. s:=embedded_controllers[init_settings.controllertype].controllertypestr;
  4166. if s<>'' then
  4167. def_system_macro('FPC_MCU_'+s);
  4168. end;
  4169. {$POP}
  4170. { define abi }
  4171. for abi:=low(tabi) to high(tabi) do
  4172. undef_system_macro('FPC_ABI_'+abiinfo[abi].name);
  4173. def_system_macro('FPC_ABI_'+abiinfo[target_info.abi].name);
  4174. { Define FPC_ABI_EABI in addition to FPC_ABI_EABIHF on EABI VFP hardfloat
  4175. systems since most code needs to behave the same on both}
  4176. if target_info.abi = abi_eabihf then
  4177. def_system_macro('FPC_ABI_EABI');
  4178. { using a case is pretty useless here (FK) }
  4179. { some stuff for TP compatibility }
  4180. {$ifdef i386}
  4181. def_system_macro('CPU86');
  4182. def_system_macro('CPU87');
  4183. def_system_macro('CPU386');
  4184. {$endif}
  4185. { new processor stuff }
  4186. {$ifdef i386}
  4187. def_system_macro('CPUI386');
  4188. def_system_macro('CPU32');
  4189. def_system_macro('CPUX86');
  4190. def_system_macro('FPC_HAS_TYPE_EXTENDED');
  4191. def_system_macro('FPC_HAS_TYPE_DOUBLE');
  4192. def_system_macro('FPC_HAS_TYPE_SINGLE');
  4193. {$endif}
  4194. {$ifdef m68k}
  4195. def_system_macro('CPU68');
  4196. def_system_macro('CPU68K');
  4197. def_system_macro('CPUM68K');
  4198. def_system_macro('CPU32');
  4199. def_system_macro('FPC_CURRENCY_IS_INT64');
  4200. def_system_macro('FPC_COMP_IS_INT64');
  4201. {$endif}
  4202. {$ifdef powerpc}
  4203. def_system_macro('CPUPOWERPC');
  4204. def_system_macro('CPUPOWERPC32');
  4205. def_system_macro('CPU32');
  4206. def_system_macro('FPC_CURRENCY_IS_INT64');
  4207. def_system_macro('FPC_COMP_IS_INT64');
  4208. {$endif}
  4209. {$ifdef POWERPC64}
  4210. def_system_macro('CPUPOWERPC');
  4211. def_system_macro('CPUPOWERPC64');
  4212. def_system_macro('CPU64');
  4213. def_system_macro('FPC_CURRENCY_IS_INT64');
  4214. def_system_macro('FPC_COMP_IS_INT64');
  4215. {$endif}
  4216. {$ifdef x86_64}
  4217. def_system_macro('CPUX86_64');
  4218. def_system_macro('CPUAMD64');
  4219. def_system_macro('CPU64');
  4220. def_system_macro('CPUX64');
  4221. { not supported for now, afaik (FK)
  4222. def_system_macro('FPC_HAS_TYPE_FLOAT128'); }
  4223. {$ifndef FPC_SUPPORT_X87_TYPES_ON_WIN64}
  4224. { normally, win64 doesn't support the legacy fpu }
  4225. if target_info.system=system_x86_64_win64 then
  4226. begin
  4227. def_system_macro('FPC_CURRENCY_IS_INT64');
  4228. def_system_macro('FPC_COMP_IS_INT64');
  4229. end;
  4230. {$endif FPC_SUPPORT_X87_TYPES_ON_WIN64}
  4231. {$endif}
  4232. {$ifdef sparc}
  4233. def_system_macro('CPUSPARCGEN');
  4234. def_system_macro('CPUSPARC');
  4235. def_system_macro('CPUSPARC32');
  4236. def_system_macro('CPU32');
  4237. def_system_macro('FPC_CURRENCY_IS_INT64');
  4238. def_system_macro('FPC_COMP_IS_INT64');
  4239. {$endif}
  4240. {$ifdef sparc64}
  4241. def_system_macro('CPUSPARCGEN');
  4242. def_system_macro('CPUSPARC64');
  4243. def_system_macro('CPU64');
  4244. def_system_macro('FPC_CURRENCY_IS_INT64');
  4245. def_system_macro('FPC_COMP_IS_INT64');
  4246. {$endif}
  4247. {$ifdef arm}
  4248. def_system_macro('CPUARM');
  4249. def_system_macro('CPU32');
  4250. def_system_macro('FPC_CURRENCY_IS_INT64');
  4251. def_system_macro('FPC_COMP_IS_INT64');
  4252. {$endif arm}
  4253. {$ifdef avr}
  4254. def_system_macro('CPUAVR');
  4255. def_system_macro('CPU16');
  4256. def_system_macro('FPC_CURRENCY_IS_INT64');
  4257. def_system_macro('FPC_COMP_IS_INT64');
  4258. {$endif avr}
  4259. {$ifdef jvm}
  4260. def_system_macro('CPUJVM');
  4261. def_system_macro('CPU32');
  4262. def_system_macro('FPC_CURRENCY_IS_INT64');
  4263. def_system_macro('FPC_COMP_IS_INT64');
  4264. {$endif jvm}
  4265. {$ifdef mipsel}
  4266. def_system_macro('CPUMIPS');
  4267. def_system_macro('CPUMIPSEL');
  4268. def_system_macro('CPUMIPS32');
  4269. def_system_macro('CPUMIPSEL32');
  4270. def_system_macro('CPU32');
  4271. def_system_macro('FPC_HAS_TYPE_DOUBLE');
  4272. def_system_macro('FPC_HAS_TYPE_SINGLE');
  4273. def_system_macro('FPC_INCLUDE_SOFTWARE_INT64_TO_DOUBLE');
  4274. def_system_macro('FPC_CURRENCY_IS_INT64');
  4275. def_system_macro('FPC_COMP_IS_INT64');
  4276. def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
  4277. { On most systems, locals are accessed relative to base pointer,
  4278. but for MIPS cpu, they are accessed relative to stack pointer.
  4279. This needs adaptation for so low level routines,
  4280. like MethodPointerLocal and related objects unit functions. }
  4281. def_system_macro('FPC_LOCALS_ARE_STACK_REG_RELATIVE');
  4282. {$endif mipsel}
  4283. {$ifdef mipseb}
  4284. def_system_macro('CPUMIPS');
  4285. def_system_macro('CPUMIPSEB');
  4286. def_system_macro('CPUMIPS32');
  4287. def_system_macro('CPUMIPSEB32');
  4288. def_system_macro('CPU32');
  4289. def_system_macro('FPC_HAS_TYPE_DOUBLE');
  4290. def_system_macro('FPC_HAS_TYPE_SINGLE');
  4291. def_system_macro('FPC_INCLUDE_SOFTWARE_INT64_TO_DOUBLE');
  4292. def_system_macro('FPC_CURRENCY_IS_INT64');
  4293. def_system_macro('FPC_COMP_IS_INT64');
  4294. def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
  4295. { See comment above for mipsel }
  4296. def_system_macro('FPC_LOCALS_ARE_STACK_REG_RELATIVE');
  4297. {$endif mipseb}
  4298. {$ifdef mips64eb}
  4299. def_system_macro('CPUMIPS');
  4300. def_system_macro('CPUMIPS64');
  4301. def_system_macro('CPUMIPSEB64');
  4302. def_system_macro('CPUMIPS64EB');
  4303. def_system_macro('CPU64');
  4304. def_system_macro('FPC_INCLUDE_SOFTWARE_INT64_TO_DOUBLE');
  4305. def_system_macro('FPC_CURRENCY_IS_INT64');
  4306. def_system_macro('FPC_COMP_IS_INT64');
  4307. def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
  4308. { See comment above for mipsel }
  4309. def_system_macro('FPC_LOCALS_ARE_STACK_REG_RELATIVE');
  4310. {$endif mips64eb}
  4311. {$ifdef mips64el}
  4312. def_system_macro('CPUMIPS');
  4313. def_system_macro('CPUMIPS64');
  4314. def_system_macro('CPUMIPSEL64');
  4315. def_system_macro('CPUMIPS64EL');
  4316. def_system_macro('CPU64');
  4317. def_system_macro('FPC_HAS_TYPE_DOUBLE');
  4318. def_system_macro('FPC_HAS_TYPE_SINGLE');
  4319. def_system_macro('FPC_INCLUDE_SOFTWARE_INT64_TO_DOUBLE');
  4320. def_system_macro('FPC_CURRENCY_IS_INT64');
  4321. def_system_macro('FPC_COMP_IS_INT64');
  4322. def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
  4323. { On most systems, locals are accessed relative to base pointer,
  4324. but for MIPS cpu, they are accessed relative to stack pointer.
  4325. This needs adaptation for so low level routines,
  4326. like MethodPointerLocal and related objects unit functions. }
  4327. def_system_macro('FPC_LOCALS_ARE_STACK_REG_RELATIVE');
  4328. {$endif mips64el}
  4329. {$ifdef i8086}
  4330. def_system_macro('CPU86'); { Borland compatibility }
  4331. def_system_macro('CPU87'); { Borland compatibility }
  4332. def_system_macro('CPUI8086');
  4333. def_system_macro('CPU16');
  4334. def_system_macro('FPC_HAS_TYPE_EXTENDED');
  4335. def_system_macro('FPC_HAS_TYPE_DOUBLE');
  4336. def_system_macro('FPC_HAS_TYPE_SINGLE');
  4337. case init_settings.x86memorymodel of
  4338. mm_tiny: def_system_macro('FPC_MM_TINY');
  4339. mm_small: def_system_macro('FPC_MM_SMALL');
  4340. mm_medium: def_system_macro('FPC_MM_MEDIUM');
  4341. mm_compact: def_system_macro('FPC_MM_COMPACT');
  4342. mm_large: def_system_macro('FPC_MM_LARGE');
  4343. mm_huge: def_system_macro('FPC_MM_HUGE');
  4344. end;
  4345. {$endif i8086}
  4346. {$ifdef aarch64}
  4347. def_system_macro('CPUAARCH64');
  4348. def_system_macro('CPU64');
  4349. def_system_macro('FPC_CURRENCY_IS_INT64');
  4350. def_system_macro('FPC_COMP_IS_INT64');
  4351. {$endif aarch64}
  4352. {$ifdef riscv32}
  4353. def_system_macro('CPURISCV');
  4354. def_system_macro('CPURISCV32');
  4355. def_system_macro('CPU32');
  4356. def_system_macro('FPC_CURRENCY_IS_INT64');
  4357. def_system_macro('FPC_COMP_IS_INT64');
  4358. def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
  4359. {$endif riscv32}
  4360. {$ifdef riscv64}
  4361. def_system_macro('CPURISCV');
  4362. def_system_macro('CPURISCV64');
  4363. def_system_macro('CPU64');
  4364. def_system_macro('FPC_CURRENCY_IS_INT64');
  4365. def_system_macro('FPC_COMP_IS_INT64');
  4366. def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
  4367. {$endif riscv64}
  4368. {$ifdef xtensa}
  4369. def_system_macro('CPUXTENSA');
  4370. def_system_macro('CPU32');
  4371. def_system_macro('FPC_CURRENCY_IS_INT64');
  4372. def_system_macro('FPC_COMP_IS_INT64');
  4373. def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
  4374. {$endif xtensa}
  4375. {$ifdef z80}
  4376. def_system_macro('CPUZ80');
  4377. def_system_macro('CPU16');
  4378. def_system_macro('FPC_CURRENCY_IS_INT64');
  4379. def_system_macro('FPC_COMP_IS_INT64');
  4380. {$endif z80}
  4381. {$ifdef wasm32}
  4382. def_system_macro('CPUWASM');
  4383. def_system_macro('CPUWASM32');
  4384. def_system_macro('CPU32');
  4385. def_system_macro('FPC_CURRENCY_IS_INT64');
  4386. def_system_macro('FPC_COMP_IS_INT64');
  4387. {$endif wasm32}
  4388. {$ifdef loongarch64}
  4389. def_system_macro('CPULOONGARCH');
  4390. def_system_macro('CPULOONGARCH64');
  4391. def_system_macro('CPU64');
  4392. def_system_macro('FPC_CURRENCY_IS_INT64');
  4393. def_system_macro('FPC_COMP_IS_INT64');
  4394. def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
  4395. def_system_macro('FPC_LOCALS_ARE_STACK_REG_RELATIVE');
  4396. {$endif loongarch64}
  4397. {$if defined(cpu8bitalu)}
  4398. def_system_macro('CPUINT8');
  4399. {$elseif defined(cpu16bitalu)}
  4400. def_system_macro('CPUINT16');
  4401. {$elseif defined(cpu32bitalu)}
  4402. def_system_macro('CPUINT32');
  4403. {$elseif defined(cpu64bitalu)}
  4404. def_system_macro('CPUINT64');
  4405. {$endif defined(cpu64bitalu)}
  4406. {$if defined(avr)}
  4407. def_system_macro('FPC_HAS_INTERNAL_ABS_SHORTINT');
  4408. {$endif}
  4409. {$if defined(i8086) or defined(avr)}
  4410. def_system_macro('FPC_HAS_INTERNAL_ABS_SMALLINT');
  4411. {$endif i8086 or avr}
  4412. { abs(long) is handled internally on all CPUs }
  4413. def_system_macro('FPC_HAS_INTERNAL_ABS_LONG');
  4414. {$if defined(i8086) or defined(i386) or defined(x86_64) or defined(powerpc64) or defined(aarch64)}
  4415. def_system_macro('FPC_HAS_INTERNAL_ABS_INT64');
  4416. {$endif i8086 or i386 or x86_64 or powerpc64 or aarch64}
  4417. def_system_macro('FPC_HAS_UNICODESTRING');
  4418. def_system_macro('FPC_RTTI_PACKSET1');
  4419. def_system_macro('FPC_HAS_CPSTRING');
  4420. {$ifdef x86_64}
  4421. def_system_macro('FPC_HAS_RIP_RELATIVE');
  4422. {$endif x86_64}
  4423. def_system_macro('FPC_HAS_CEXTENDED');
  4424. def_system_macro('FPC_HAS_RESSTRINITS');
  4425. { these cpus have an inline rol/ror implementaion }
  4426. {$ifdef cpurox}
  4427. {$ifdef m68k}
  4428. if CPUM68K_HAS_ROLROR in cpu_capabilities[init_settings.cputype] then
  4429. def_system_macro('FPC_HAS_INTERNAL_ROX');
  4430. {$else}
  4431. def_system_macro('FPC_HAS_INTERNAL_ROX');
  4432. {$endif}
  4433. {$endif}
  4434. {$ifdef powerpc64}
  4435. def_system_macro('FPC_HAS_LWSYNC');
  4436. {$endif}
  4437. def_system_macro('FPC_HAS_ANSICHAR_CHAR');
  4438. { currently, all supported CPUs have an internal sar implementation }
  4439. def_system_macro('FPC_HAS_INTERNAL_SAR');
  4440. {$ifdef SUPPORT_GET_FRAME}
  4441. def_system_macro('INTERNAL_BACKTRACE');
  4442. {$endif SUPPORT_GET_FRAME}
  4443. def_system_macro('STR_CONCAT_PROCS');
  4444. {$warnings off}
  4445. if pocall_default = pocall_register then
  4446. def_system_macro('REGCALL');
  4447. {$warnings on}
  4448. end;
  4449. var
  4450. env: ansistring;
  4451. i : tfeature;
  4452. j : longint;
  4453. tmplist : TCmdStrList;
  4454. cmditem,
  4455. tmpcmditem : TCmdStrListItem;
  4456. cmdstr : TCmdStr;
  4457. {$if defined(cpucapabilities)}
  4458. cpuflag : tcpuflags;
  4459. {$endif defined(cpucapabilities)}
  4460. {$if defined(fpucapabilities)}
  4461. fpuflag : tfpuflags;
  4462. {$endif defined(fpucapabilities)}
  4463. {$if defined(cpucapabilities) or defined(fpucapabilities)}
  4464. hs : string;
  4465. {$endif defined(cpucapabilities) or defined(fpucapabilities)}
  4466. begin
  4467. option:=coption.create;
  4468. disable_configfile:=false;
  4469. { Non-core target defines }
  4470. Option.TargetOptions(true);
  4471. { get default messagefile }
  4472. msgfilename:=GetEnvironmentVariable('PPC_ERROR_FILE');
  4473. { default configfile can be specified on the commandline,
  4474. remove it first }
  4475. if (cmd<>'') and (cmd[1]='[') then
  4476. begin
  4477. ppccfg:=Copy(cmd,2,pos(']',cmd)-2);
  4478. Delete(cmd,1,pos(']',cmd));
  4479. end
  4480. else
  4481. ppccfg:='fpc.cfg';
  4482. { first pass reading of parameters, only -i -v -T etc.}
  4483. option.firstpass:=true;
  4484. if cmd<>'' then
  4485. option.parsecmd(cmd)
  4486. else
  4487. begin
  4488. option.read_parameters;
  4489. { Write only quickinfo }
  4490. if option.quickinfo<>'' then
  4491. option.writequickinfo;
  4492. end;
  4493. option.firstpass:=false;
  4494. { redefine target options so all defines are written even if no -Txxx is passed on the command line }
  4495. Option.TargetOptions(true);
  4496. { target is set here, for wince the default app type is gui }
  4497. if target_info.system in systems_wince then
  4498. SetApptype(app_gui)
  4499. else
  4500. SetApptype(apptype);
  4501. { default defines }
  4502. def_system_macro(target_info.shortname);
  4503. def_system_macro('FPC');
  4504. def_system_macro('VER'+version_nr);
  4505. def_system_macro('VER'+version_nr+'_'+release_nr);
  4506. def_system_macro('VER'+version_nr+'_'+release_nr+'_'+patch_nr);
  4507. { Temporary defines, until things settle down }
  4508. def_system_macro('FPC_HAS_OPERATOR_ENUMERATOR');
  4509. def_system_macro('FPC_HAS_CONSTREF');
  4510. def_system_macro('FPC_STATICRIPFIXED');
  4511. def_system_macro('FPC_VARIANTCOPY_FIXED');
  4512. def_system_macro('FPC_DYNARRAYCOPY_FIXED');
  4513. def_system_macro('FPC_HAS_MEMBAR');
  4514. def_system_macro('FPC_SETBASE_USED');
  4515. def_system_macro('FPC_ALIGNED_THREADVARTABLES');
  4516. { don't remove this, it's also for fpdoc necessary (FK) }
  4517. def_system_macro('FPC_HAS_FEATURE_SUPPORT');
  4518. if (Option.parasubtarget<>'') then
  4519. begin
  4520. def_system_macro('FPC_SUBTARGET_'+Option.parasubtarget);
  4521. if cs_support_macro in init_settings.moduleswitches then
  4522. set_system_macro('FPC_SUBTARGET',Option.parasubtarget)
  4523. else
  4524. set_system_compvar('FPC_SUBTARGET',Option.parasubtarget);
  4525. // So it can be used in macro substitution.
  4526. globals.subtarget:=Option.parasubtarget;
  4527. end;
  4528. { make cpu makros available when reading the config files the second time }
  4529. def_cpu_macros;
  4530. set_endianess_macros;
  4531. if tf_cld in target_info.flags then
  4532. if not UpdateTargetSwitchStr('CLD', init_settings.targetswitches, true) then
  4533. InternalError(2013092801);
  4534. if tf_x86_far_procs_push_odd_bp in target_info.flags then
  4535. if not UpdateTargetSwitchStr('FARPROCSPUSHODDBP', init_settings.targetswitches, true) then
  4536. InternalError(2013092802);
  4537. { Use standard Android NDK prefixes when cross-compiling }
  4538. if (source_info.system<>target_info.system) and (target_info.system in systems_android) then
  4539. case target_info.system of
  4540. system_arm_android:
  4541. utilsprefix:='arm-linux-androideabi-';
  4542. system_i386_android:
  4543. utilsprefix:='i686-linux-android-';
  4544. else
  4545. utilsprefix:=target_cpu_string + '-linux-android-';
  4546. end;
  4547. { Set up default value for the heap on Amiga-likes (values only apply if the OSHeap allocator is used) }
  4548. if target_info.system in systems_amigalike then
  4549. begin
  4550. case target_info.system of
  4551. system_m68k_amiga:
  4552. heapsize:=256*1024;
  4553. system_powerpc_amiga,
  4554. system_powerpc_morphos,
  4555. system_arm_aros,
  4556. system_i386_aros,
  4557. system_x86_64_aros:
  4558. heapsize:=1024*1024;
  4559. else
  4560. heapsize:=256*1024;
  4561. end;
  4562. end;
  4563. if target_info.system in (systems_embedded+systems_freertos+[system_z80_zxspectrum,system_z80_msxdos]) then
  4564. begin
  4565. case target_info.system of
  4566. {$ifdef AVR}
  4567. system_avr_embedded:
  4568. if init_settings.controllertype=ct_avrsim then
  4569. heapsize:=8192
  4570. else
  4571. heapsize:=128;
  4572. {$endif AVR}
  4573. system_arm_freertos:
  4574. heapsize:=8192;
  4575. system_xtensa_freertos:
  4576. { keep default value }
  4577. ;
  4578. system_arm_embedded:
  4579. heapsize:=256;
  4580. system_mipsel_embedded:
  4581. heapsize:=256;
  4582. else
  4583. heapsize:=256;
  4584. end;
  4585. end;
  4586. { read configuration file }
  4587. if (not disable_configfile) and
  4588. (ppccfg<>'') then
  4589. read_configfile:=check_configfile(ppccfg,ppccfg)
  4590. else
  4591. read_configfile := false;
  4592. if (option.parasubtarget<>'') then
  4593. begin
  4594. subcfg:='fpc-'+lower(option.parasubtarget)+'.cfg';
  4595. read_subfile:=check_configfile(subcfg,subcfg);
  4596. // Warn if we didn't find an architecture-specific file
  4597. if not read_subfile then
  4598. message2(option_subtarget_config_not_found,option.parasubtarget,subcfg);
  4599. end;
  4600. { Read commandline and configfile }
  4601. param_file:='';
  4602. { read configfile }
  4603. if read_configfile then
  4604. option.interpret_file(ppccfg);
  4605. if read_subfile then
  4606. option.interpret_file(subcfg);
  4607. { read parameters again to override config file }
  4608. if cmd<>'' then
  4609. option.parsecmd(cmd)
  4610. else
  4611. begin
  4612. { Write help pages if no parameters are passed }
  4613. if (paramcount=0) then
  4614. Option.WriteHelpPages;
  4615. option.read_parameters;
  4616. { Write only quickinfo }
  4617. if option.quickinfo<>'' then
  4618. option.writequickinfo;
  4619. end;
  4620. { check the compatibility of different options and adjust them if necessary
  4621. (and print possible errors)
  4622. }
  4623. option.checkoptionscompatibility;
  4624. { uses the CPUXXX-defines and target_info to determine whether the selected
  4625. target processor, if any, is supported }
  4626. Option.VerifyTargetProcessor;
  4627. { Stop if errors in options }
  4628. if ErrorCount>0 then
  4629. StopOptions(1);
  4630. { Write logo }
  4631. if option.ParaLogo then
  4632. option.writelogo;
  4633. { Check file to compile }
  4634. if param_file='' then
  4635. begin
  4636. Message(option_no_source_found);
  4637. StopOptions(1);
  4638. end;
  4639. {$ifndef Unix}
  4640. param_file:=FixFileName(param_file);
  4641. {$endif not unix}
  4642. inputfilepath:=ExtractFilePath(param_file);
  4643. inputfilename:=ExtractFileName(param_file);
  4644. if ExtractFileExt(inputfilename)='' then
  4645. begin
  4646. if FileExists(inputfilepath+ChangeFileExt(inputfilename,sourceext)) then
  4647. inputfilename:=ChangeFileExt(inputfilename,sourceext)
  4648. else if FileExists(inputfilepath+ChangeFileExt(inputfilename,pasext)) then
  4649. inputfilename:=ChangeFileExt(inputfilename,pasext)
  4650. else if ((m_mac in current_settings.modeswitches) or
  4651. (tf_p_ext_support in target_info.flags))
  4652. and FileExists(inputfilepath+ChangeFileExt(inputfilename,pext)) then
  4653. inputfilename:=ChangeFileExt(inputfilename,pext);
  4654. end;
  4655. { Check output dir }
  4656. if (OutputExeDir<>'') and
  4657. not PathExists(OutputExeDir,false) then
  4658. begin
  4659. Message1(general_e_path_does_not_exist,OutputExeDir);
  4660. StopOptions(1);
  4661. end;
  4662. { Add paths specified with parameters to the searchpaths }
  4663. UnitSearchPath.AddList(option.ParaUnitPath,true);
  4664. ObjectSearchPath.AddList(option.ParaObjectPath,true);
  4665. IncludeSearchPath.AddList(option.ParaIncludePath,true);
  4666. LibrarySearchPath.AddList(option.ParaLibraryPath,true);
  4667. FrameworkSearchPath.AddList(option.ParaFrameworkPath,true);
  4668. packagesearchpath.addlist(option.parapackagepath,true);
  4669. for j:=0 to option.parapackages.count-1 do
  4670. add_package(option.parapackages.NameOfIndex(j),true,true);
  4671. { add default namespaces }
  4672. tmplist:=TCmdStrList.Create;
  4673. cmditem:=TCmdStrListItem(option.paranamespaces.First);
  4674. while assigned(cmditem) do
  4675. begin
  4676. { use a temporary list cause if ";" are involved we need to reverse the
  4677. order due to how TCmdStrList behaves }
  4678. cmdstr:=cmditem.str;
  4679. repeat
  4680. j:=Pos(';',cmdstr);
  4681. if j>0 then
  4682. begin
  4683. tmplist.insert(copy(cmdstr,1,j-1));
  4684. delete(cmdstr,1,j);
  4685. end
  4686. else
  4687. tmplist.insert(cmdstr);
  4688. until j=0;
  4689. tmpcmditem:=TCmdStrListItem(tmplist.First);
  4690. while assigned(tmpcmditem) do
  4691. begin
  4692. namespacelist.insert(tmpcmditem.Str);
  4693. tmpcmditem:=TCmdStrListItem(tmpcmditem.Next);
  4694. end;
  4695. tmplist.clear;
  4696. cmditem:=TCmdStrListItem(cmditem.Next);
  4697. end;
  4698. tmplist.Free;
  4699. { add unit environment and exepath to the unit search path }
  4700. if inputfilepath<>'' then
  4701. Unitsearchpath.AddPath(inputfilepath,true);
  4702. if not disable_configfile then
  4703. begin
  4704. env:=GetEnvironmentVariable(target_info.unit_env);
  4705. if env<>'' then
  4706. UnitSearchPath.AddPath(GetEnvironmentVariable(target_info.unit_env),false);
  4707. end;
  4708. {$ifdef Unix}
  4709. fpcdir:=FixPath(GetEnvironmentVariable('FPCDIR'),false);
  4710. if fpcdir='' then
  4711. begin
  4712. if PathExists('/usr/local/lib/fpc/'+version_string,true) then
  4713. fpcdir:='/usr/local/lib/fpc/'+version_string+'/'
  4714. else
  4715. fpcdir:='/usr/lib/fpc/'+version_string+'/';
  4716. end;
  4717. {$else unix}
  4718. fpcdir:=FixPath(GetEnvironmentVariable('FPCDIR'),false);
  4719. if fpcdir='' then
  4720. begin
  4721. fpcdir:=ExePath+'../';
  4722. if not(PathExists(fpcdir+'units',true)) and
  4723. not(PathExists(fpcdir+'rtl',true)) then
  4724. fpcdir:=fpcdir+'../';
  4725. end;
  4726. {$endif unix}
  4727. { first try development RTL, else use the default installation path }
  4728. if not disable_configfile then
  4729. begin
  4730. if PathExists(FpcDir+'rtl',true) then
  4731. if (tf_use_8_3 in Source_Info.Flags) or
  4732. (tf_use_8_3 in Target_Info.Flags) then
  4733. UnitSearchPath.AddPath(FpcDir+'rtl/'+target_os_string,false)
  4734. else
  4735. UnitSearchPath.AddPath(FpcDir+'rtl/'+target_full_string,false)
  4736. else
  4737. if (tf_use_8_3 in Source_Info.Flags) or
  4738. (tf_use_8_3 in Target_Info.Flags) then
  4739. UnitSearchPath.AddPath(FpcDir+'units/'+target_os_string+'/rtl',false)
  4740. else
  4741. UnitSearchPath.AddPath(FpcDir+'units/'+target_full_string+'/rtl',false);
  4742. end;
  4743. { Add exepath if the exe is not in the current dir, because that is always searched already.
  4744. Do not add it when linking on the target because then we can maybe already find
  4745. .o files that are not for the target }
  4746. if (ExePath<>cfileutl.GetCurrentDir) and
  4747. not(cs_link_on_target in init_settings.globalswitches) then
  4748. UnitSearchPath.AddPath(ExePath,false);
  4749. { Add unit dir to the object and library path }
  4750. objectsearchpath.AddList(unitsearchpath,false);
  4751. librarysearchpath.AddList(unitsearchpath,false);
  4752. {$ifdef llvm}
  4753. { default to clang }
  4754. if (option.paratargetasm=as_none) then
  4755. begin
  4756. if not(target_info.system in systems_darwin) then
  4757. option.paratargetasm:=as_clang_llvm
  4758. else
  4759. option.paratargetasm:=as_clang_llvm_darwin;
  4760. end;
  4761. {$endif llvm}
  4762. { maybe override assembler }
  4763. if (option.paratargetasm<>as_none) then
  4764. begin
  4765. if (option.paratargetasm=as_default) then
  4766. begin
  4767. option.paratargetasm:=target_info.assem;
  4768. end;
  4769. if not set_target_asm(option.paratargetasm) then
  4770. begin
  4771. if assigned(asminfos[option.paratargetasm]) then
  4772. Message2(option_incompatible_asm,asminfos[option.paratargetasm]^.idtxt,target_info.name)
  4773. else
  4774. Message2(option_incompatible_asm,'<invalid assembler>',target_info.name);
  4775. set_target_asm(target_info.assemextern);
  4776. Message1(option_asm_forced,target_asm.idtxt);
  4777. end;
  4778. if (af_no_debug in asminfos[option.paratargetasm]^.flags) and
  4779. (option.paratargetdbg<>dbg_none) then
  4780. begin
  4781. Message1(option_confict_asm_debug,
  4782. asminfos[option.paratargetasm]^.idtxt);
  4783. option.paratargetdbg:=dbg_none;
  4784. exclude(init_settings.moduleswitches,cs_debuginfo);
  4785. end;
  4786. { Some assemblers, like clang, do not support
  4787. stabs debugging format, switch to dwardé in that case }
  4788. if (af_no_stabs in asminfos[option.paratargetasm]^.flags) and
  4789. (option.paratargetdbg=dbg_stabs) then
  4790. begin
  4791. option.paratargetdbg:=dbg_dwarf2;
  4792. end;
  4793. end;
  4794. {TOptionheck a second time as we might have changed assembler just above }
  4795. option.checkoptionscompatibility;
  4796. { maybe override debug info format }
  4797. if (option.paratargetdbg<>dbg_none) then
  4798. if not set_target_dbg(option.paratargetdbg) then
  4799. Message(option_w_unsupported_debug_format);
  4800. { switch assembler if it's binary and we got -a on the cmdline }
  4801. if (af_outputbinary in target_asm.flags) and
  4802. ((cs_asm_leave in init_settings.globalswitches) or
  4803. { if -s is passed, we shouldn't call the internal assembler }
  4804. (cs_asm_extern in init_settings.globalswitches)) then
  4805. begin
  4806. Message(option_switch_bin_to_src_assembler);
  4807. {$ifdef llvm}
  4808. if not(target_info.system in systems_darwin) then
  4809. set_target_asm(as_clang_llvm)
  4810. else
  4811. set_target_asm(as_clang_llvm_darwin);
  4812. {$else}
  4813. set_target_asm(target_info.assemextern);
  4814. {$endif}
  4815. { At least i8086 needs that for nasm and -CX
  4816. which is incompatible with internal linker }
  4817. option.checkoptionscompatibility;
  4818. end;
  4819. { Force use of external linker if there is no
  4820. internal linker or the linking is skipped }
  4821. if not(cs_link_extern in init_settings.globalswitches) and
  4822. ((target_info.link=ld_none) or
  4823. (cs_link_nolink in init_settings.globalswitches)) then
  4824. begin
  4825. include(init_settings.globalswitches,cs_link_extern);
  4826. end;
  4827. { turn off stripping if compiling with debuginfo or profile }
  4828. if (
  4829. (cs_debuginfo in init_settings.moduleswitches) or
  4830. (cs_profile in init_settings.moduleswitches)
  4831. ) and
  4832. not(cs_link_separate_dbg_file in init_settings.globalswitches) then
  4833. exclude(init_settings.globalswitches,cs_link_strip);
  4834. { choose a reasonable tls model }
  4835. if (tf_section_threadvars in target_info.flags) and (init_settings.tlsmodel=tlsm_none) then
  4836. begin
  4837. if cs_create_pic in init_settings.moduleswitches then
  4838. init_settings.tlsmodel:=tlsm_global_dynamic
  4839. else
  4840. init_settings.tlsmodel:=tlsm_local_exec;
  4841. end;
  4842. { set Mac OS X version default macros if not specified explicitly }
  4843. option.MaybeSetDefaultMacVersionMacro;
  4844. {$ifdef XTENSA}
  4845. { set ESP32 or ESP8266 default SDK versions }
  4846. option.MaybeSetIdfVersionMacro;
  4847. {$endif XTENSA}
  4848. {$ifdef cpufpemu}
  4849. { force fpu emulation on arm/wince, arm/gba, arm/embedded and arm/nds etc.
  4850. if fpu type not explicitly set }
  4851. if not(option.FPUSetExplicitly) and
  4852. ((target_info.system in [system_arm_wince,system_arm_gba,
  4853. system_m68k_amiga,system_m68k_atari,
  4854. system_arm_nds,system_arm_embedded,system_arm_freertos,
  4855. system_riscv32_embedded,system_riscv64_embedded,system_xtensa_linux,
  4856. system_z80_embedded,system_z80_zxspectrum,system_riscv32_freertos])
  4857. {$ifdef arm}
  4858. or (target_info.abi=abi_eabi)
  4859. {$endif arm}
  4860. )
  4861. or (init_settings.fputype=fpu_soft)
  4862. then
  4863. begin
  4864. include(init_settings.moduleswitches,cs_fp_emulation);
  4865. { cs_fp_emulation and fpu_soft are equal on arm and m68k }
  4866. init_settings.fputype:=fpu_soft;
  4867. end;
  4868. {$endif cpufpemu}
  4869. {$ifdef i386}
  4870. if target_info.system in systems_i386_default_486 then
  4871. begin
  4872. { Avoid use of MMX/CMOVcc instructions on older systems.
  4873. Some systems might not handle these instructions correctly,
  4874. Used emulators might also be problematic. PM }
  4875. if not option.CPUSetExplicitly then
  4876. init_settings.cputype:=cpu_486;
  4877. end;
  4878. case target_info.system of
  4879. system_i386_android:
  4880. begin
  4881. { set default cpu type to PentiumM for Android unless specified otherwise }
  4882. if not option.CPUSetExplicitly then
  4883. init_settings.cputype:=cpu_PentiumM;
  4884. if not option.OptCPUSetExplicitly then
  4885. init_settings.optimizecputype:=cpu_PentiumM;
  4886. { set default fpu type to SSSE3 for Android unless specified otherwise }
  4887. if not option.FPUSetExplicitly then
  4888. init_settings.fputype:=fpu_ssse3;
  4889. end;
  4890. else
  4891. ;
  4892. end;
  4893. {$endif i386}
  4894. {$ifdef xtensa}
  4895. { xtensa-linux target does not support controller setting option -Wp }
  4896. if not(option.FPUSetExplicitly) and not(target_info.system = system_xtensa_linux) then
  4897. begin
  4898. init_settings.fputype:=embedded_controllers[init_settings.controllertype].fputype;
  4899. if (init_settings.fputype=fpu_soft) then
  4900. include(init_settings.moduleswitches,cs_fp_emulation);
  4901. end;
  4902. if not(option.CPUSetExplicitly) and (target_info.system=system_xtensa_linux) then
  4903. init_settings.cputype:=cpu_lx6;
  4904. if (target_info.system in [system_xtensa_embedded,system_xtensa_freertos]) and not(option.ABISetExplicitly) then
  4905. begin
  4906. if CPUXTENSA_REGWINDOW in cpu_capabilities[init_settings.cputype] then
  4907. target_info.abi:=abi_xtensa_windowed
  4908. else
  4909. target_info.abi:=abi_xtensa_call0;
  4910. end;
  4911. {$endif xtensa}
  4912. {$ifdef arm}
  4913. case target_info.system of
  4914. system_arm_ios:
  4915. begin
  4916. { set default cpu type to ARMv7 for Darwin unless specified otherwise, and fpu
  4917. to VFPv3 (that's what all 32 bit ARM iOS devices use nowadays)
  4918. }
  4919. if not option.CPUSetExplicitly then
  4920. init_settings.cputype:=cpu_armv7;
  4921. if not option.OptCPUSetExplicitly then
  4922. init_settings.optimizecputype:=cpu_armv7;
  4923. if not option.FPUSetExplicitly then
  4924. init_settings.fputype:=fpu_vfpv3;
  4925. end;
  4926. system_arm_android:
  4927. begin
  4928. { set default cpu type to ARMv5T for Android unless specified otherwise }
  4929. if not option.CPUSetExplicitly then
  4930. init_settings.cputype:=cpu_armv5t;
  4931. if not option.OptCPUSetExplicitly then
  4932. init_settings.optimizecputype:=cpu_armv5t;
  4933. end;
  4934. else
  4935. ;
  4936. end;
  4937. { set ABI defaults }
  4938. case target_info.abi of
  4939. abi_eabihf:
  4940. { set default cpu type to ARMv7a for ARMHF unless specified otherwise }
  4941. begin
  4942. {$ifdef CPUARMV6}
  4943. { if the compiler is built for armv6, then
  4944. inherit this setting, e.g. Raspian is armhf but
  4945. only armv6, this makes rebuilds of the compiler
  4946. easier }
  4947. if not option.CPUSetExplicitly then
  4948. init_settings.cputype:=cpu_armv6;
  4949. if not option.OptCPUSetExplicitly then
  4950. init_settings.optimizecputype:=cpu_armv6;
  4951. {$else CPUARMV6}
  4952. if not option.CPUSetExplicitly then
  4953. init_settings.cputype:=cpu_armv7a;
  4954. if not option.OptCPUSetExplicitly then
  4955. init_settings.optimizecputype:=cpu_armv7a;
  4956. {$endif CPUARMV6}
  4957. { Set FPU type }
  4958. if not(option.FPUSetExplicitly) then
  4959. begin
  4960. if init_settings.cputype < cpu_armv7 then
  4961. init_settings.fputype:=fpu_vfpv2
  4962. else
  4963. init_settings.fputype:=fpu_vfpv3_d16;
  4964. end
  4965. else
  4966. begin
  4967. if (not(FPUARM_HAS_VFP_EXTENSION in fpu_capabilities[init_settings.fputype]))
  4968. or (target_info.system = system_arm_ios) then
  4969. begin
  4970. Message(option_illegal_fpu_eabihf);
  4971. StopOptions(1);
  4972. end;
  4973. end;
  4974. end;
  4975. abi_eabi:
  4976. begin
  4977. if target_info.system=system_arm_linux then
  4978. begin
  4979. { this is what Debian uses }
  4980. if not option.CPUSetExplicitly then
  4981. init_settings.cputype:=cpu_armv4t;
  4982. if not option.OptCPUSetExplicitly then
  4983. init_settings.optimizecputype:=cpu_armv4t;
  4984. if not(option.FPUSetExplicitly) then
  4985. init_settings.fputype:=fpu_soft;
  4986. end;
  4987. end;
  4988. else
  4989. ;
  4990. end;
  4991. if (init_settings.instructionset=is_thumb) and not(CPUARM_HAS_THUMB2 in cpu_capabilities[init_settings.cputype]) then
  4992. begin
  4993. def_system_macro('CPUTHUMB');
  4994. if not option.FPUSetExplicitly then
  4995. init_settings.fputype:=fpu_soft;
  4996. if not(init_settings.fputype in [fpu_none,fpu_soft,fpu_libgcc]) then
  4997. Message2(option_unsupported_fpu,fputypestr[init_settings.fputype],'Thumb');
  4998. {$if defined(FPC_ARMEL) or defined(FPC_ARMHF)}
  4999. target_info.llvmdatalayout:='e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a0:0:32-n32-S64';
  5000. {$else FPC_ARMAL or FPC_ARMHF}
  5001. if target_info.endian=endian_little then
  5002. target_info.llvmdatalayout:='e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32';
  5003. {$endif FPC_ARMAL or FPC_ARMHF}
  5004. end;
  5005. if (init_settings.instructionset=is_thumb) and (CPUARM_HAS_THUMB2 in cpu_capabilities[init_settings.cputype]) then
  5006. def_system_macro('CPUTHUMB2');
  5007. {$endif arm}
  5008. {$ifdef aarch64}
  5009. case target_info.system of
  5010. system_aarch64_darwin:
  5011. begin
  5012. if not option.CPUSetExplicitly then
  5013. init_settings.cputype:=cpu_armv84a;
  5014. if not option.OptCPUSetExplicitly then
  5015. init_settings.optimizecputype:=cpu_armv84a;
  5016. end;
  5017. else
  5018. ;
  5019. end;
  5020. {$endif aarch64}
  5021. {$if defined(riscv32) or defined(riscv64)}
  5022. { RISC-V defaults }
  5023. if (target_info.abi = abi_riscv_hf) then
  5024. begin
  5025. {$ifdef riscv32}
  5026. if not option.CPUSetExplicitly then
  5027. init_settings.cputype:=cpu_rv32ima;
  5028. if not option.OptCPUSetExplicitly then
  5029. init_settings.optimizecputype:=cpu_rv32ima;
  5030. {$else}
  5031. if not option.CPUSetExplicitly then
  5032. init_settings.cputype:=cpu_rv64imac;
  5033. if not option.OptCPUSetExplicitly then
  5034. init_settings.optimizecputype:=cpu_rv64imac;
  5035. {$endif}
  5036. { Set FPU type }
  5037. if not(option.FPUSetExplicitly) then
  5038. init_settings.fputype:=fpu_fd
  5039. else
  5040. begin
  5041. if not (init_settings.fputype in [fpu_fd]) then
  5042. begin
  5043. Message(option_illegal_fpu_eabihf);
  5044. StopOptions(1);
  5045. end;
  5046. end;
  5047. end;
  5048. {$endif defined(riscv32) or defined(riscv64)}
  5049. {$ifdef jvm}
  5050. { set default CPU type to Dalvik when targeting Android }
  5051. if target_info.system=system_jvm_android32 then
  5052. begin
  5053. if not option.CPUSetExplicitly then
  5054. init_settings.cputype:=cpu_dalvik;
  5055. end;
  5056. {$endif jvm}
  5057. {$ifdef llvm}
  5058. { standard extension for llvm bitcode files }
  5059. target_info.asmext:='.ll';
  5060. { don't generate dwarf cfi, llvm will do that }
  5061. exclude(target_info.flags,tf_needs_dwarf_cfi);
  5062. {$endif llvm}
  5063. {$ifdef mipsel}
  5064. case target_info.system of
  5065. system_mipsel_android:
  5066. begin
  5067. { set default cpu type to MIPS32 rev. 1 and hard float for MIPS-Android unless specified otherwise }
  5068. if not option.CPUSetExplicitly then
  5069. init_settings.cputype:=cpu_mips32;
  5070. if not option.OptCPUSetExplicitly then
  5071. init_settings.optimizecputype:=cpu_mips32;
  5072. if not option.FPUSetExplicitly then
  5073. init_settings.fputype:=fpu_mips2;
  5074. end;
  5075. system_mipsel_embedded:
  5076. begin
  5077. { set default cpu type to PIC32MX and softfloat for MIPSEL-EMBEDDED target unless specified otherwise }
  5078. if not option.CPUSetExplicitly then
  5079. init_settings.cputype:=cpu_pic32mx;
  5080. if not option.OptCPUSetExplicitly then
  5081. init_settings.optimizecputype:=cpu_pic32mx;
  5082. if not option.FPUSetExplicitly then
  5083. init_settings.fputype:=fpu_soft;
  5084. end;
  5085. else
  5086. ;
  5087. end;
  5088. {$endif mipsel}
  5089. {$ifdef m68k}
  5090. if init_settings.cputype in cpu_coldfire then
  5091. def_system_macro('CPUCOLDFIRE');
  5092. case target_info.system of
  5093. system_m68k_linux,
  5094. system_m68k_netbsd:
  5095. begin
  5096. if not (option.FPUSetExplicitly) and
  5097. not (init_settings.cputype in cpu_coldfire) then
  5098. begin
  5099. { enable HW FPU for UNIX by default, but only for
  5100. original 68k, not Coldfire }
  5101. exclude(init_settings.moduleswitches,cs_fp_emulation);
  5102. init_settings.fputype:=fpu_68881;
  5103. end;
  5104. end;
  5105. system_m68k_atari,
  5106. system_m68k_sinclairql:
  5107. begin
  5108. if not option.CPUSetExplicitly then
  5109. init_settings.cputype:=cpu_mc68000;
  5110. end;
  5111. system_m68k_palmos:
  5112. begin
  5113. if not option.CPUSetExplicitly then
  5114. init_settings.cputype:=cpu_mc68000;
  5115. if not (option.FPUSetExplicitly) then
  5116. begin
  5117. { No FPU for PalmOS by default }
  5118. exclude(init_settings.moduleswitches,cs_fp_emulation);
  5119. init_settings.fputype:=fpu_none;
  5120. end;
  5121. end;
  5122. else
  5123. ;
  5124. end;
  5125. {$endif m68k}
  5126. {$ifdef wasm}
  5127. { if no explicit exception handling mode is set for WebAssembly, assume no exceptions }
  5128. if init_settings.targetswitches*[ts_wasm_no_exceptions,ts_wasm_js_exceptions,ts_wasm_native_exceptions,ts_wasm_bf_exceptions]=[] then
  5129. begin
  5130. def_system_macro(TargetSwitchStr[ts_wasm_no_exceptions].define);
  5131. include(init_settings.targetswitches,ts_wasm_no_exceptions);
  5132. end;
  5133. {$endif wasm}
  5134. {$if defined(loongarch64)}
  5135. { LoongArch defaults }
  5136. if (target_info.abi = abi_riscv_hf) then
  5137. begin
  5138. init_settings.cputype:=cpu_3a;
  5139. init_settings.fputype:=fpu_fd;
  5140. end;
  5141. {$endif defined(loongarch64)}
  5142. { now we can define cpu and fpu type }
  5143. def_cpu_macros;
  5144. set_endianess_macros;
  5145. { Use init_settings cpu type for asm cpu type,
  5146. if asmcputype is cpu_none,
  5147. at least as long as there is no explicit
  5148. option to set it on command line PM }
  5149. if init_settings.asmcputype = cpu_none then
  5150. init_settings.asmcputype:=init_settings.cputype;
  5151. {$ifdef llvm}
  5152. def_system_macro('CPULLVM');
  5153. {$endif llvm}
  5154. {$if defined(cpucapabilities)}
  5155. for cpuflag:=low(cpuflag) to high(cpuflag) do
  5156. begin
  5157. str(cpuflag,hs);
  5158. if cpuflag in cpu_capabilities[init_settings.cputype] then
  5159. def_system_macro(hs)
  5160. else
  5161. undef_system_macro(hs);
  5162. end;
  5163. {$endif defined(cpucapabilities)}
  5164. {$if defined(fpucapabilities)}
  5165. for fpuflag:=low(fpuflag) to high(fpuflag) do
  5166. begin
  5167. str(fpuflag,hs);
  5168. if fpuflag in fpu_capabilities[init_settings.fputype] then
  5169. def_system_macro(hs)
  5170. else
  5171. undef_system_macro(hs);
  5172. end;
  5173. {$endif defined(fpucapabilities)}
  5174. if init_settings.fputype<>fpu_none then
  5175. begin
  5176. {$if defined(i386) or defined(i8086)}
  5177. def_system_macro('FPC_HAS_TYPE_EXTENDED');
  5178. {$endif}
  5179. def_system_macro('FPC_HAS_TYPE_SINGLE');
  5180. def_system_macro('FPC_HAS_TYPE_DOUBLE');
  5181. {$if not defined(i386) and not defined(x86_64) and not defined(i8086) and not defined(aarch64)}
  5182. def_system_macro('FPC_INCLUDE_SOFTWARE_INT64_TO_DOUBLE');
  5183. {$endif}
  5184. {$if defined(m68k)}
  5185. def_system_macro('FPC_INCLUDE_SOFTWARE_LONGWORD_TO_DOUBLE');
  5186. {$endif}
  5187. {$ifdef x86_64}
  5188. {$ifndef FPC_SUPPORT_X87_TYPES_ON_WIN64}
  5189. { normally, win64 doesn't support the legacy fpu }
  5190. if target_info.system=system_x86_64_win64 then
  5191. undef_system_macro('FPC_HAS_TYPE_EXTENDED')
  5192. else
  5193. {$endif FPC_SUPPORT_X87_TYPES_ON_WIN64}
  5194. def_system_macro('FPC_HAS_TYPE_EXTENDED');
  5195. {$endif}
  5196. end;
  5197. { Enable now for testing }
  5198. {$ifndef DISABLE_TLS_DIRECTORY}
  5199. if target_info.system in systems_windows then
  5200. def_system_macro('FPC_USE_TLS_DIRECTORY');
  5201. {$endif not DISABLE_TLS_DIRECTORY}
  5202. {$ifndef DISABLE_WIN64_SEH}
  5203. if target_info.system=system_x86_64_win64 then
  5204. def_system_macro('FPC_USE_WIN64_SEH');
  5205. {$endif DISABLE_WIN64_SEH}
  5206. {$ifndef DISABLE_WIN32_SEH}
  5207. if target_info.system=system_i386_win32 then
  5208. def_system_macro('FPC_USE_WIN32_SEH');
  5209. {$endif not DISABLE_WIN32_SEH}
  5210. {$ifdef ARM}
  5211. { define FPC_DOUBLE_HILO_SWAPPED if needed to properly handle doubles in RTL }
  5212. if (init_settings.fputype in [fpu_fpa,fpu_fpa10,fpu_fpa11]) and
  5213. not(cs_fp_emulation in init_settings.moduleswitches) then
  5214. def_system_macro('FPC_DOUBLE_HILO_SWAPPED');
  5215. {$endif ARM}
  5216. { inline bsf/bsr implementation }
  5217. {$if defined(i386) or defined(x86_64) or defined(aarch64) or defined(powerpc) or defined(powerpc64)}
  5218. def_system_macro('FPC_HAS_INTERNAL_BSF');
  5219. def_system_macro('FPC_HAS_INTERNAL_BSR');
  5220. {$endif}
  5221. { hardware FMA support }
  5222. {$if defined(i386) or defined(x86_64)}
  5223. if (fpu_capabilities[current_settings.fputype]*[FPUX86_HAS_FMA,FPUX86_HAS_FMA4])<>[] then
  5224. begin
  5225. def_system_macro('FPC_HAS_FAST_FMA_SINGLE');
  5226. def_system_macro('FPC_HAS_FAST_FMA_DOUBLE');
  5227. end;
  5228. {$endif defined(i386) or defined(x86_64)}
  5229. {$if defined(arm)}
  5230. { it is determined during system unit compilation if clz is used for bsf or not,
  5231. this is not perfect but the current implementation bsf/bsr does not allow another
  5232. solution }
  5233. if (CPUARM_HAS_CLZ in cpu_capabilities[init_settings.cputype]) and
  5234. ((init_settings.instructionset=is_arm) or
  5235. (CPUARM_HAS_THUMB2 in cpu_capabilities[init_settings.cputype])) then
  5236. begin
  5237. def_system_macro('FPC_HAS_INTERNAL_BSR');
  5238. if CPUARM_HAS_RBIT in cpu_capabilities[init_settings.cputype] then
  5239. def_system_macro('FPC_HAS_INTERNAL_BSF');
  5240. end;
  5241. {$endif}
  5242. {$if defined(xtensa)}
  5243. { it is determined during system unit compilation if nsau is used for bsr or not,
  5244. this is not perfect but the current implementation bsf/bsr does not allow another
  5245. solution }
  5246. if CPUXTENSA_HAS_NSAx in cpu_capabilities[init_settings.cputype] then
  5247. begin
  5248. def_system_macro('FPC_HAS_INTERNAL_BSR');
  5249. end;
  5250. {$endif}
  5251. {$if defined(powerpc64)}
  5252. { on sysv targets, default to elfv2 for little endian and to elfv1 for
  5253. big endian (unless specified otherwise). As the gcc man page says:
  5254. "Overriding the default ABI requires special system support and is
  5255. likely to fail in spectacular ways" }
  5256. if not option.ABISetExplicitly then
  5257. begin
  5258. if (target_info.abi=abi_powerpc_sysv) and
  5259. (target_info.endian=endian_little) then
  5260. target_info.abi:=abi_powerpc_elfv2
  5261. else
  5262. if (target_info.abi=abi_powerpc_elfv2) and
  5263. (target_info.endian=endian_big) then
  5264. target_info.abi:=abi_powerpc_sysv
  5265. end;
  5266. {$endif}
  5267. {$if defined(powerpc) or defined(powerpc64)}
  5268. { define _CALL_ELF symbol like gcc }
  5269. case target_info.abi of
  5270. abi_powerpc_sysv:
  5271. set_system_compvar('_CALL_ELF','1');
  5272. abi_powerpc_elfv2:
  5273. set_system_compvar('_CALL_ELF','2');
  5274. else
  5275. ;
  5276. end;
  5277. {$endif}
  5278. { Section smartlinking conflicts with import sections on Windows }
  5279. if GenerateImportSection and
  5280. (target_info.system in [system_i386_win32,system_x86_64_win64,system_aarch64_win64]) then
  5281. exclude(target_info.flags,tf_smartlink_sections);
  5282. if not option.LinkTypeSetExplicitly then
  5283. set_default_link_type;
  5284. { Default alignment settings,
  5285. 1. load the defaults for the target
  5286. 2. adapt defaults specifically for the target
  5287. 3. override with generic optimizer setting (little size)
  5288. 4. override with the user specified -Oa }
  5289. UpdateAlignment(init_settings.alignment,target_info.alignment);
  5290. {$ifdef arm}
  5291. if (init_settings.instructionset=is_thumb) and not(CPUARM_HAS_THUMB2 in cpu_capabilities[init_settings.cputype]) then
  5292. begin
  5293. init_settings.alignment.procalign:=2;
  5294. init_settings.alignment.jumpalign:=2;
  5295. init_settings.alignment.coalescealign:=2;
  5296. init_settings.alignment.loopalign:=2;
  5297. end;
  5298. {$endif arm}
  5299. if (cs_opt_size in init_settings.optimizerswitches) then
  5300. begin
  5301. init_settings.alignment.procalign:=1;
  5302. init_settings.alignment.jumpalign:=1;
  5303. init_settings.alignment.coalescealign:=1;
  5304. init_settings.alignment.loopalign:=1;
  5305. {$ifdef x86}
  5306. { constalignmax=1 keeps the executable and thus the memory foot print small but
  5307. all processors except x86 are really hurt by this or might even crash }
  5308. init_settings.alignment.constalignmax:=1;
  5309. {$endif x86}
  5310. end;
  5311. UpdateAlignment(init_settings.alignment,option.paraalignment);
  5312. set_system_macro('FPC_VERSION',version_nr);
  5313. set_system_macro('FPC_RELEASE',release_nr);
  5314. set_system_macro('FPC_PATCH',patch_nr);
  5315. set_system_macro('FPC_FULLVERSION',Format('%d%.02d%.02d',[StrToInt(version_nr),StrToInt(release_nr),StrToInt(patch_nr)]));
  5316. if target_info.system in systems_indirect_entry_information then
  5317. def_system_macro('FPC_HAS_INDIRECT_ENTRY_INFORMATION');
  5318. if not (tf_winlikewidestring in target_info.flags) then
  5319. def_system_macro('FPC_WIDESTRING_EQUAL_UNICODESTRING');
  5320. if tf_supports_packages in target_info.flags then
  5321. def_system_macro('FPC_HAS_DYNAMIC_PACKAGES');
  5322. if target_info.system in systems_indirect_var_imports then
  5323. def_system_macro('FPC_HAS_INDIRECT_VAR_ACCESS');
  5324. if cs_compilesystem in init_settings.moduleswitches then
  5325. for i:=low(tfeature) to high(tfeature) do
  5326. if i in features then
  5327. def_system_macro('FPC_HAS_FEATURE_'+featurestr[i]);
  5328. {$push}
  5329. {$warn 6018 off} { Unreachable code due to compile time evaluation }
  5330. if ControllerSupport and (target_info.system in (systems_embedded+systems_freertos)) and
  5331. (init_settings.controllertype<>ct_none) then
  5332. begin
  5333. with embedded_controllers[init_settings.controllertype] do
  5334. begin
  5335. set_system_macro('FPC_FLASHBASE',tostr(flashbase));
  5336. set_system_macro('FPC_FLASHSIZE',tostr(flashsize));
  5337. set_system_macro('FPC_SRAMBASE',tostr(srambase));
  5338. set_system_macro('FPC_SRAMSIZE',tostr(sramsize));
  5339. set_system_macro('FPC_EEPROMBASE',tostr(eeprombase));
  5340. set_system_macro('FPC_EEPROMSIZE',tostr(eepromsize));
  5341. set_system_macro('FPC_BOOTBASE',tostr(bootbase));
  5342. set_system_macro('FPC_BOOTSIZE',tostr(bootsize));
  5343. end;
  5344. end;
  5345. {$pop}
  5346. { as stackalign is not part of the alignment record, we do not need to define the others alignments for symmetry yet }
  5347. set_system_macro('FPC_STACKALIGNMENT',tostr(target_info.stackalign));
  5348. option.free;
  5349. Option:=nil;
  5350. clearstack_pocalls := [pocall_cdecl,pocall_cppdecl,pocall_syscall,pocall_mwpascal,pocall_sysv_abi_cdecl,pocall_ms_abi_cdecl{$ifdef z80},pocall_stdcall{$endif}];
  5351. cdecl_pocalls := [pocall_cdecl, pocall_cppdecl, pocall_mwpascal, pocall_sysv_abi_cdecl, pocall_ms_abi_cdecl];
  5352. if (tf_safecall_clearstack in target_info.flags) then
  5353. begin
  5354. include (cdecl_pocalls, pocall_safecall);
  5355. include (clearstack_pocalls, pocall_safecall)
  5356. end;
  5357. end;
  5358. initialization
  5359. coption:=toption;
  5360. finalization
  5361. if assigned(option) then
  5362. option.free;
  5363. end.