options.pas 142 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240
  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,
  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. ParaAlignment : TAlignmentInfo;
  45. parapackages : tfphashobjectlist;
  46. paratarget : tsystem;
  47. paratargetasm : tasm;
  48. paratargetdbg : tdbg;
  49. LinkTypeSetExplicitly : boolean;
  50. LinkerSetExplicitly : boolean;
  51. Constructor Create;
  52. Destructor Destroy;override;
  53. procedure WriteLogo;
  54. procedure WriteInfo (More: string);
  55. procedure WriteHelpPages;
  56. procedure WriteQuickInfo;
  57. procedure IllegalPara(const opt:TCmdStr);
  58. procedure UnsupportedPara(const opt:TCmdStr);
  59. procedure IgnoredPara(const opt:TCmdStr);
  60. function Unsetbool(var Opts:TCmdStr; Pos: Longint; const FullPara: TCmdStr; RequireBoolPara: Boolean):boolean;
  61. procedure interpret_option(const opt :TCmdStr;ispara:boolean);
  62. procedure Interpret_envvar(const envname : TCmdStr);
  63. procedure Interpret_file(const filename : TPathStr);
  64. procedure Read_Parameters;
  65. procedure parsecmd(cmd:TCmdStr);
  66. procedure TargetOptions(def:boolean);
  67. procedure CheckOptionsCompatibility;
  68. procedure ForceStaticLinking;
  69. protected
  70. MacVersionSet: boolean;
  71. processorstr: TCmdStr;
  72. function ParseMacVersionMin(out minstr, emptystr: string; const compvarname, value: string; ios: boolean): boolean;
  73. procedure MaybeSetDefaultMacVersionMacro;
  74. procedure VerifyTargetProcessor;
  75. end;
  76. TOptionClass=class of toption;
  77. var
  78. coption : TOptionClass;
  79. procedure read_arguments(cmd:TCmdStr);
  80. implementation
  81. uses
  82. widestr,
  83. {$if FPC_FULLVERSION<20700}ccharset{$else}charset{$endif},
  84. SysUtils,
  85. version,
  86. cutils,cmsgs,
  87. comphook,
  88. symtable,scanner,rabase,
  89. symconst,
  90. {$ifdef llvm}
  91. { override supported optimizer transformations at the compiler level }
  92. llvminfo,
  93. {$endif llvm}
  94. dirparse,
  95. pkgutil,
  96. i_bsd;
  97. const
  98. page_size = 24;
  99. page_width = 80;
  100. var
  101. option : toption;
  102. read_configfile, { read config file, set when a cfgfile is found }
  103. disable_configfile : boolean;
  104. fpcdir,
  105. ppccfg,
  106. param_file : string; { file to compile specified on the commandline }
  107. {****************************************************************************
  108. Options not supported on all platforms
  109. ****************************************************************************}
  110. const
  111. { gprof (requires implementation of g_profilecode in the code generator) }
  112. supported_targets_pg = [system_i386_linux,system_x86_64_linux,system_mipseb_linux,system_mipsel_linux,system_arm_linux]
  113. + [system_i386_win32]
  114. + [system_powerpc_darwin,system_x86_64_darwin]
  115. + [system_i386_GO32V2]
  116. + [system_i386_freebsd]
  117. + [system_i386_netbsd]
  118. + [system_i386_wdosx];
  119. suppported_targets_x_smallr = systems_linux + systems_solaris
  120. + [system_i386_haiku]
  121. + [system_i386_beos]
  122. + [system_m68k_amiga];
  123. {****************************************************************************
  124. Defines
  125. ****************************************************************************}
  126. procedure set_default_link_type;
  127. begin
  128. undef_system_macro('FPC_LINK_SMART');
  129. def_system_macro('FPC_LINK_STATIC');
  130. undef_system_macro('FPC_LINK_DYNAMIC');
  131. init_settings.globalswitches:=init_settings.globalswitches+[cs_link_static];
  132. init_settings.globalswitches:=init_settings.globalswitches-[cs_link_shared,cs_link_smart];
  133. {$ifdef AIX}
  134. init_settings.globalswitches:=init_settings.globalswitches+[cs_link_native];
  135. {$endif}
  136. end;
  137. {****************************************************************************
  138. Toption
  139. ****************************************************************************}
  140. procedure StopOptions(err:longint);
  141. begin
  142. if assigned(Option) then
  143. begin
  144. Option.free;
  145. Option:=nil;
  146. end;
  147. raise ECompilerAbortSilent.Create;
  148. end;
  149. function is_identifier(const s: TCmdStr): boolean;
  150. var
  151. i: longint;
  152. begin
  153. result:=false;
  154. if (s='') or not (s[1] in ['A'..'Z','a'..'z','_']) then
  155. exit;
  156. for i:=2 to length(s) do
  157. if not (s[I] in ['A'..'Z','a'..'z','0'..'9','_']) then
  158. exit;
  159. result:=true;
  160. end;
  161. procedure Toption.WriteLogo;
  162. var
  163. msg : TMsgStr;
  164. p : pchar;
  165. begin
  166. if not LogoWritten then
  167. begin
  168. msg:=MessageStr(option_logo);
  169. p:=pchar(msg);
  170. while assigned(p) do
  171. Comment(V_Normal,GetMsgLine(p));
  172. LogoWritten:= true;
  173. end;
  174. end;
  175. procedure Toption.WriteInfo (More: string);
  176. var
  177. msg_str: TMsgStr;
  178. p : pchar;
  179. hs,hs1,hs3,s : TCmdStr;
  180. J: longint;
  181. const
  182. NewLineStr = '$\n';
  183. OSTargetsPlaceholder = '$OSTARGETS';
  184. CPUListPlaceholder = '$INSTRUCTIONSETS';
  185. FPUListPlaceholder = '$FPUINSTRUCTIONSETS';
  186. ABIListPlaceholder = '$ABITARGETS';
  187. OptListPlaceholder = '$OPTIMIZATIONS';
  188. WPOListPlaceholder = '$WPOPTIMIZATIONS';
  189. AsmModeListPlaceholder = '$ASMMODES';
  190. ControllerListPlaceholder = '$CONTROLLERTYPES';
  191. FeatureListPlaceholder = '$FEATURELIST';
  192. procedure SplitLine (var OrigString: TCmdStr; const Placeholder: TCmdStr;
  193. var RemainderString: TCmdStr);
  194. var
  195. I: longint;
  196. HS2: TCmdStr;
  197. begin
  198. RemainderString := '';
  199. if OrigString = '' then
  200. Exit;
  201. repeat
  202. I := Pos (NewLineStr, OrigString);
  203. if I > 0 then
  204. begin
  205. HS2 := Copy (OrigString, 1, Pred (I));
  206. { Stop if this line contains the placeholder for list replacement }
  207. if Pos (Placeholder, HS2) > 0 then
  208. begin
  209. RemainderString := Copy (OrigString, I + Length (NewLineStr),
  210. Length (OrigString) - I - Length (NewLineStr));
  211. { Special case - NewLineStr at the end of the line }
  212. if RemainderString = '' then
  213. RemainderString := NewLineStr;
  214. OrigString := HS2;
  215. Exit;
  216. end;
  217. Comment (V_Normal, HS2);
  218. Delete (OrigString, 1, Pred (I) + Length (NewLineStr));
  219. end;
  220. until I = 0;
  221. if (OrigString <> '') and (Pos (Placeholder, OrigString) = 0) then
  222. Comment (V_Normal, OrigString);
  223. end;
  224. procedure ListOSTargets (OrigString: TCmdStr);
  225. var
  226. target : tsystem;
  227. begin
  228. SplitLine (OrigString, OSTargetsPlaceholder, HS3);
  229. for target:=low(tsystem) to high(tsystem) do
  230. if assigned(targetinfos[target]) then
  231. begin
  232. hs1:=targetinfos[target]^.shortname;
  233. if OrigString = '' then
  234. WriteLn (hs1)
  235. else
  236. begin
  237. hs := OrigString;
  238. hs1:=hs1 + ': ' + targetinfos[target]^.name;
  239. if tf_under_development in targetinfos[target]^.flags then
  240. hs1:=hs1+' {*}';
  241. Replace(hs,OSTargetsPlaceholder,hs1);
  242. Comment(V_Normal,hs);
  243. end;
  244. end;
  245. OrigString := HS3;
  246. SplitLine (OrigString, OSTargetsPlaceholder, HS3);
  247. end;
  248. procedure ListCPUInstructionSets (OrigString: TCmdStr);
  249. var
  250. cpu : tcputype;
  251. begin
  252. SplitLine (OrigString, CPUListPlaceholder, HS3);
  253. hs1:='';
  254. for cpu:=low(tcputype) to high(tcputype) do
  255. begin
  256. if (OrigString = '') then
  257. begin
  258. if CPUTypeStr [CPU] <> '' then
  259. WriteLn (CPUTypeStr [CPU]);
  260. end
  261. else
  262. begin
  263. if length(hs1+cputypestr[cpu])>70 then
  264. begin
  265. hs:=OrigString;
  266. Replace(hs,CPUListPlaceholder,hs1);
  267. Comment(V_Normal,hs);
  268. hs1:=''
  269. end
  270. else if hs1<>'' then
  271. hs1:=hs1+',';
  272. if cputypestr[cpu]<>'' then
  273. hs1:=hs1+cputypestr[cpu];
  274. end;
  275. end;
  276. if (OrigString <> '') and (hs1 <> '') then
  277. begin
  278. hs:=OrigString;
  279. Replace(hs,CPUListPlaceholder,hs1);
  280. Comment(V_Normal,hs);
  281. hs1:=''
  282. end;
  283. OrigString := HS3;
  284. SplitLine (OrigString, CPUListPlaceholder, HS3);
  285. end;
  286. procedure ListFPUInstructionSets (OrigString: TCmdStr);
  287. var
  288. fpu : tfputype;
  289. begin
  290. SplitLine (OrigString, FPUListPlaceholder, HS3);
  291. hs1:='';
  292. for fpu:=low(tfputype) to high(tfputype) do
  293. begin
  294. if (OrigString = '') then
  295. begin
  296. if FPUTypeStr [FPU] <> '' then
  297. WriteLn (FPUTypeStr [FPU]);
  298. end
  299. else
  300. begin
  301. if length(hs1+fputypestr[fpu])>70 then
  302. begin
  303. hs:=OrigString;
  304. Replace(hs,FPUListPlaceholder,hs1);
  305. Comment(V_Normal,hs);
  306. hs1:=''
  307. end
  308. else if hs1<>'' then
  309. hs1:=hs1+',';
  310. if fputypestr[fpu]<>'' then
  311. hs1:=hs1+fputypestr[fpu];
  312. end;
  313. end;
  314. if (OrigString <> '') and (hs1 <> '') then
  315. begin
  316. hs:=OrigString;
  317. Replace(hs,FPUListPlaceholder,hs1);
  318. Comment(V_Normal,hs);
  319. hs1:=''
  320. end;
  321. OrigString := HS3;
  322. SplitLine (OrigString, FPUListPlaceholder, HS3);
  323. end;
  324. procedure ListABITargets (OrigString: TCmdStr);
  325. var
  326. abi : tabi;
  327. begin
  328. SplitLine (OrigString, ABIListPlaceholder, HS3);
  329. for abi:=low(abi) to high(abi) do
  330. begin
  331. if not abiinfo[abi].supported then
  332. continue;
  333. hs1:=abiinfo[abi].name;
  334. if hs1<>'' then
  335. begin
  336. if OrigString = '' then
  337. WriteLn (HS1)
  338. else
  339. begin
  340. hs:=OrigString;
  341. Replace(hs,ABIListPlaceholder,hs1);
  342. Comment(V_Normal,hs);
  343. end;
  344. end;
  345. end;
  346. OrigString := HS3;
  347. SplitLine (OrigString, ABIListPlaceholder, HS3);
  348. end;
  349. procedure ListOptimizations (OrigString: TCmdStr);
  350. var
  351. opt : toptimizerswitch;
  352. begin
  353. SplitLine (OrigString, OptListPlaceholder, HS3);
  354. for opt:=low(toptimizerswitch) to high(toptimizerswitch) do
  355. begin
  356. if opt in supported_optimizerswitches then
  357. begin
  358. hs1:=OptimizerSwitchStr[opt];
  359. if hs1<>'' then
  360. begin
  361. if OrigString = '' then
  362. WriteLn (hs1)
  363. else
  364. begin
  365. hs:=OrigString;
  366. Replace(hs,OptListPlaceholder,hs1);
  367. Comment(V_Normal,hs);
  368. end;
  369. end;
  370. end;
  371. end;
  372. OrigString := HS3;
  373. SplitLine (OrigString, OptListPlaceholder, HS3);
  374. end;
  375. procedure ListWPOptimizations (OrigString: TCmdStr);
  376. var
  377. wpopt: twpoptimizerswitch;
  378. begin
  379. SplitLine (OrigString, WPOListPlaceholder, HS3);
  380. for wpopt:=low(twpoptimizerswitch) to high(twpoptimizerswitch) do
  381. begin
  382. { currently all whole program optimizations are platform-independent
  383. if opt in supported_wpoptimizerswitches then
  384. }
  385. begin
  386. hs1:=WPOptimizerSwitchStr[wpopt];
  387. if hs1<>'' then
  388. begin
  389. if OrigString = '' then
  390. WriteLn (hs1)
  391. else
  392. begin
  393. hs:=OrigString;
  394. Replace(hs,WPOListPlaceholder,hs1);
  395. Comment(V_Normal,hs);
  396. end;
  397. end;
  398. end;
  399. end;
  400. OrigString := HS3;
  401. SplitLine (OrigString, WPOListPlaceholder, HS3);
  402. end;
  403. procedure ListAsmModes (OrigString: TCmdStr);
  404. var
  405. asmmode : tasmmode;
  406. begin
  407. SplitLine (OrigString, AsmModeListPlaceholder, HS3);
  408. for asmmode:=low(tasmmode) to high(tasmmode) do
  409. if assigned(asmmodeinfos[asmmode]) then
  410. begin
  411. hs1:=asmmodeinfos[asmmode]^.idtxt;
  412. if hs1<>'' then
  413. begin
  414. if OrigString = '' then
  415. WriteLn (hs1)
  416. else
  417. begin
  418. hs:=OrigString;
  419. Replace(hs,AsmModeListPlaceholder,hs1);
  420. Comment(V_Normal,hs);
  421. end;
  422. end;
  423. end;
  424. OrigString := HS3;
  425. SplitLine (OrigString, AsmModeListPlaceholder, HS3);
  426. end;
  427. procedure ListControllerTypes (OrigString: TCmdStr);
  428. var
  429. controllertype : tcontrollertype;
  430. begin
  431. {$PUSH}
  432. {$WARN 6018 OFF} (* Unreachable code due to compile time evaluation *)
  433. if (ControllerSupport) then
  434. begin
  435. SplitLine (OrigString, ControllerListPlaceholder, HS3);
  436. hs1:='';
  437. for controllertype:=low(tcontrollertype) to high(tcontrollertype) do
  438. begin
  439. if (OrigString = '') then
  440. begin
  441. if Embedded_Controllers [ControllerType].ControllerTypeStr <> '' then
  442. WriteLn (Embedded_Controllers [ControllerType].ControllerTypeStr);
  443. end
  444. else
  445. begin
  446. if length(hs1+embedded_controllers[controllertype].ControllerTypeStr)
  447. >70 then
  448. begin
  449. hs:=OrigString;
  450. Replace(hs,ControllerListPlaceholder,hs1);
  451. Comment(V_Normal,hs);
  452. hs1:=''
  453. end
  454. else if hs1<>'' then
  455. hs1:=hs1+',';
  456. if embedded_controllers[controllertype].ControllerTypeStr<>'' then
  457. hs1:=hs1+embedded_controllers[controllertype].ControllerTypeStr;
  458. end;
  459. end;
  460. if (OrigString <> '') and (hs1<>'') then
  461. begin
  462. hs:=OrigString;
  463. Replace(hs,ControllerListPlaceholder,hs1);
  464. Comment(V_Normal,hs);
  465. hs1:=''
  466. end;
  467. OrigString := HS3;
  468. SplitLine (OrigString, ControllerListPlaceholder, HS3);
  469. end;
  470. {$POP}
  471. end;
  472. procedure ListFeatures (OrigString: TCmdStr);
  473. var
  474. Feature: TFeature;
  475. begin
  476. SplitLine (OrigString, FeatureListPlaceholder, HS3);
  477. HS1 := '';
  478. for Feature := Low (TFeature) to High (TFeature) do
  479. begin
  480. if (OrigString = '') then
  481. begin
  482. if FeatureStr [Feature] <> '' then
  483. WriteLn (FeatureStr [Feature]);
  484. end
  485. else
  486. begin
  487. if Length (HS1 + FeatureStr [Feature]) > 70 then
  488. begin
  489. HS := OrigString;
  490. Replace (HS, FeatureListPlaceholder, HS1);
  491. Comment (V_Normal, HS);
  492. HS1 := ''
  493. end
  494. else if HS1 <> '' then
  495. HS1 := HS1 + ',';
  496. if FeatureStr [Feature] <> '' then
  497. HS1 := HS1 + FeatureStr [Feature];
  498. end;
  499. end;
  500. if (OrigString <> '') and (HS1 <> '') then
  501. begin
  502. HS := OrigString;
  503. Replace (HS, FeatureListPlaceholder, HS1);
  504. Comment (V_Normal, HS);
  505. HS1 := ''
  506. end;
  507. OrigString := HS3;
  508. SplitLine (OrigString, FeatureListPlaceholder, HS3);
  509. end;
  510. begin
  511. if More = '' then
  512. begin
  513. msg_str:=MessageStr(option_info);
  514. p:=pchar(msg_str);
  515. while assigned(p) do
  516. begin
  517. s:=GetMsgLine(p);
  518. { list permitted values for certain options }
  519. if pos(OSTargetsPlaceholder,s)>0 then
  520. ListOSTargets (S)
  521. else if pos(CPUListPlaceholder,s)>0 then
  522. ListCPUInstructionSets (S)
  523. else if pos(FPUListPlaceholder,s)>0 then
  524. ListFPUInstructionSets (S)
  525. else if pos(ABIListPlaceholder,s)>0 then
  526. ListABITargets (S)
  527. else if pos(OptListPlaceholder,s)>0 then
  528. ListOptimizations (S)
  529. else if pos(WPOListPlaceholder,s)>0 then
  530. ListWPOptimizations (S)
  531. else if pos(AsmModeListPlaceholder,s)>0 then
  532. ListAsmModes (S)
  533. else if pos(ControllerListPlaceholder,s)>0 then
  534. ListControllerTypes (S)
  535. else if pos(FeatureListPlaceholder,s)>0 then
  536. ListFeatures (S)
  537. else
  538. Comment(V_Normal,s);
  539. end;
  540. end
  541. else
  542. begin
  543. J := 1;
  544. while J <= Length (More) do
  545. begin
  546. if J > 1 then
  547. WriteLn; (* Put empty line between multiple sections *)
  548. case More [J] of
  549. 'a': ListABITargets ('');
  550. 'c': ListCPUInstructionSets ('');
  551. 'f': ListFPUInstructionSets ('');
  552. 'i': ListAsmModes ('');
  553. 'o': ListOptimizations ('');
  554. 'r': ListFeatures ('');
  555. 't': ListOSTargets ('');
  556. 'u': ListControllerTypes ('');
  557. 'w': ListWPOptimizations ('');
  558. else
  559. IllegalPara ('-i' + More);
  560. end;
  561. Inc (J);
  562. end;
  563. end;
  564. StopOptions(0);
  565. end;
  566. procedure Toption.WriteHelpPages;
  567. function PadEnd(s:string;i:longint):string;
  568. begin
  569. if length(s) >= i then
  570. S := S + ' '
  571. else
  572. while (length(s)<i) do
  573. s:=s+' ';
  574. PadEnd:=s;
  575. end;
  576. var
  577. lastident,
  578. j,outline,
  579. ident,
  580. HelpLineHeight,
  581. lines : longint;
  582. show : boolean;
  583. opt : string[32];
  584. input,
  585. HelpLine,
  586. s : string;
  587. p : pchar;
  588. msg_str: TMsgStr;
  589. begin
  590. WriteLogo;
  591. Lines:=4;
  592. if FPCHelpLines then
  593. Message1(option_usage,FixFileName(FPCBinaryPath))
  594. else
  595. Message1(option_usage,FixFileName(system.paramstr(0)));
  596. lastident:=0;
  597. msg_str:=MessageStr(option_help_pages);
  598. p:=pchar(msg_str);
  599. while assigned(p) do
  600. begin
  601. { get a line and reset }
  602. s:=GetMsgLine(p);
  603. ident:=0;
  604. show:=false;
  605. { parse options }
  606. case s[1] of
  607. 'F': if FPCHelpLines then
  608. Show := true;
  609. {$ifdef UNITALIASES}
  610. 'a',
  611. {$endif}
  612. {$ifdef EXTDEBUG}
  613. 'e',
  614. {$endif EXTDEBUG}
  615. {$ifdef i386}
  616. '3',
  617. {$endif}
  618. {$ifdef x86_64}
  619. '4',
  620. {$endif}
  621. {$ifdef m68k}
  622. '6',
  623. {$endif}
  624. {$ifdef i8086}
  625. '8',
  626. {$endif}
  627. {$ifdef aarch64}
  628. 'a',
  629. {$endif}
  630. {$ifdef arm}
  631. 'A',
  632. {$endif}
  633. {$ifdef mipsel}
  634. 'm',
  635. {$endif}
  636. {$ifdef mipseb}
  637. 'M',
  638. {$endif}
  639. {$ifdef powerpc}
  640. 'P',
  641. {$endif}
  642. {$ifdef powerpc64}
  643. 'p',
  644. {$endif}
  645. {$ifdef sparc}
  646. 'S',
  647. {$endif}
  648. {$ifdef avr}
  649. 'V',
  650. {$endif}
  651. {$ifdef jvm}
  652. 'J',
  653. {$endif}
  654. '*' : show:=true;
  655. end;
  656. if show then
  657. begin
  658. case s[2] of
  659. 'g',
  660. {$ifdef Unix}
  661. 'L',
  662. {$endif}
  663. {$ifdef os2}
  664. 'O',
  665. {$endif}
  666. '*' : show:=true;
  667. else
  668. show:=false;
  669. end;
  670. end;
  671. { now we may show the message or not }
  672. if show then
  673. begin
  674. case s[3] of
  675. '0' : begin
  676. ident:=0;
  677. outline:=0;
  678. end;
  679. '1' : begin
  680. ident:=2;
  681. outline:=7;
  682. end;
  683. '2' : begin
  684. ident:=6;
  685. outline:=11;
  686. end;
  687. '3' : begin
  688. ident:=9;
  689. outline:=11;
  690. end;
  691. else
  692. internalerror(2013112906);
  693. end;
  694. j:=pos('_',s);
  695. opt:=Copy(s,4,j-4);
  696. if opt='*' then
  697. opt:=''
  698. else
  699. if (opt=' ') or (opt[1]='@') then
  700. opt:=PadEnd(opt,outline)
  701. else
  702. opt:=PadEnd('-'+opt,outline);
  703. if (ident=0) and (lastident<>0) then
  704. begin
  705. Comment(V_Normal,'');
  706. inc(Lines);
  707. end;
  708. HelpLine := PadEnd('',ident)+opt+Copy(s,j+1,255);
  709. if HelpLine = '' then
  710. HelpLineHeight := 1
  711. else
  712. HelpLineHeight := Succ (CharLength (HelpLine) div Page_Width);
  713. { page full ? }
  714. if (lines + HelpLineHeight >= page_size - 1) then
  715. begin
  716. if not NoPressEnter then
  717. begin
  718. Message(option_help_press_enter);
  719. readln(input);
  720. if upper(input)='Q' then
  721. StopOptions(0);
  722. end;
  723. lines:=0;
  724. end;
  725. Comment(V_Normal,HelpLine);
  726. LastIdent:=Ident;
  727. Inc (Lines, HelpLineHeight);
  728. end;
  729. end;
  730. StopOptions(0);
  731. end;
  732. procedure Toption.IllegalPara(const opt:TCmdStr);
  733. begin
  734. Message1(option_illegal_para,opt);
  735. Message(option_help_pages_para);
  736. StopOptions(1);
  737. end;
  738. procedure toption.UnsupportedPara(const opt: TCmdStr);
  739. begin
  740. Message1(option_unsupported_target,opt);
  741. StopOptions(1);
  742. end;
  743. procedure toption.IgnoredPara(const opt: TCmdStr);
  744. begin
  745. Message1(option_ignored_target,opt);
  746. end;
  747. procedure toption.ForceStaticLinking;
  748. begin
  749. def_system_macro('FPC_LINK_STATIC');
  750. undef_system_macro('FPC_LINK_SMART');
  751. undef_system_macro('FPC_LINK_DYNAMIC');
  752. include(init_settings.globalswitches,cs_link_static);
  753. exclude(init_settings.globalswitches,cs_link_smart);
  754. exclude(init_settings.globalswitches,cs_link_shared);
  755. LinkTypeSetExplicitly:=true;
  756. end;
  757. function toption.ParseMacVersionMin(out minstr, emptystr: string; const compvarname, value: string; ios: boolean): boolean;
  758. function subval(start,maxlen: longint; out stop: longint): string;
  759. var
  760. i: longint;
  761. begin
  762. result:='';
  763. i:=start;
  764. while (i<=length(value)) and
  765. (value[i] in ['0'..'9']) do
  766. inc(i);
  767. { sufficient amount of digits? }
  768. if (i=start) or
  769. (i-start>maxlen) then
  770. exit;
  771. result:=copy(value,start,i-start);
  772. stop:=i;
  773. end;
  774. var
  775. temp,
  776. compvarvalue: string[15];
  777. i: longint;
  778. osx_minor_two_digits: boolean;
  779. begin
  780. minstr:=value;
  781. emptystr:='';
  782. MacVersionSet:=false;
  783. { check whether the value is a valid version number }
  784. if value='' then
  785. begin
  786. undef_system_macro(compvarname);
  787. exit(true);
  788. end;
  789. { major version number }
  790. compvarvalue:=subval(1,2,i);
  791. { not enough digits -> invalid }
  792. if compvarvalue='' then
  793. exit(false);
  794. { already end of string -> invalid }
  795. if (i>=length(value)) or
  796. (value[i]<>'.') then
  797. exit(false);
  798. { minor version number }
  799. temp:=subval(i+1,2,i);
  800. if temp='' then
  801. exit(false);
  802. { on Mac OS X, the minor version number was originally limited to 1 digit;
  803. with 10.10 the format changed and two digits were also supported; on iOS,
  804. the minor version number always takes up two digits }
  805. osx_minor_two_digits:=false;
  806. if not ios then
  807. begin
  808. { if the minor version number is two digits on OS X (the case since
  809. OS X 10.10), we also have to add two digits for the patch level}
  810. if length(temp)=2 then
  811. osx_minor_two_digits:=true;
  812. end
  813. { the minor version number always takes up two digits on iOS }
  814. else if length(temp)=1 then
  815. temp:='0'+temp;
  816. compvarvalue:=compvarvalue+temp;
  817. { optional patch level }
  818. if i<=length(value) then
  819. begin
  820. if value[i]<>'.' then
  821. exit(false);
  822. temp:=subval(i+1,2,i);
  823. if temp='' then
  824. exit(false);
  825. { there's only room for a single digit patch level in the version macro
  826. for Mac OS X. gcc sets it to zero if there are more digits, but that
  827. seems worse than clamping to 9 (don't declare as invalid like with
  828. minor version number, because there is a precedent like 10.4.11).
  829. As of OS X 10.10 there are two digits for the patch level
  830. }
  831. if not ios and
  832. not osx_minor_two_digits then
  833. begin
  834. if length(temp)<>1 then
  835. temp:='9';
  836. end
  837. else
  838. begin
  839. { on iOS, the patch level is always two digits }
  840. if length(temp)=1 then
  841. temp:='0'+temp;
  842. end;
  843. compvarvalue:=compvarvalue+temp;
  844. { must be the end }
  845. if i<=length(value) then
  846. exit(false);
  847. end
  848. else if not ios and
  849. not osx_minor_two_digits then
  850. compvarvalue:=compvarvalue+'0'
  851. else
  852. compvarvalue:=compvarvalue+'00';
  853. set_system_compvar(compvarname,compvarvalue);
  854. MacVersionSet:=true;
  855. result:=true;
  856. end;
  857. procedure TOption.MaybeSetDefaultMacVersionMacro;
  858. var
  859. envstr: ansistring;
  860. begin
  861. if not(target_info.system in systems_darwin) then
  862. exit;
  863. if MacVersionSet then
  864. exit;
  865. { check for deployment target set via environment variable }
  866. if not(target_info.system in [system_i386_iphonesim,system_arm_darwin,system_aarch64_darwin,system_x86_64_iphonesim]) then
  867. begin
  868. envstr:=GetEnvironmentVariable('MACOSX_DEPLOYMENT_TARGET');
  869. if envstr<>'' then
  870. if not ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED',envstr,false) then
  871. Message1(option_invalid_macosx_deployment_target,envstr)
  872. else
  873. exit;
  874. end
  875. else
  876. begin
  877. envstr:=GetEnvironmentVariable('IPHONEOS_DEPLOYMENT_TARGET');
  878. if envstr<>'' then
  879. if not ParseMacVersionMin(iPhoneOSVersionMin,MacOSXVersionMin,'IPHONE_OS_VERSION_MIN_REQUIRED',envstr,true) then
  880. Message1(option_invalid_iphoneos_deployment_target,envstr)
  881. else
  882. exit;
  883. end;
  884. { nothing specified -> defaults }
  885. case target_info.system of
  886. system_powerpc_darwin:
  887. begin
  888. set_system_compvar('MAC_OS_X_VERSION_MIN_REQUIRED','1030');
  889. MacOSXVersionMin:='10.3';
  890. end;
  891. system_powerpc64_darwin,
  892. system_i386_darwin:
  893. begin
  894. set_system_compvar('MAC_OS_X_VERSION_MIN_REQUIRED','1040');
  895. MacOSXVersionMin:='10.4';
  896. end;
  897. system_x86_64_darwin:
  898. begin
  899. { actually already works on 10.4, but it's unlikely any 10.4 system
  900. with an x86-64 is still in use, so don't default to it }
  901. set_system_compvar('MAC_OS_X_VERSION_MIN_REQUIRED','1050');
  902. MacOSXVersionMin:='10.5';
  903. end;
  904. system_arm_darwin,
  905. system_i386_iphonesim:
  906. begin
  907. set_system_compvar('IPHONE_OS_VERSION_MIN_REQUIRED','30000');
  908. iPhoneOSVersionMin:='3.0';
  909. end;
  910. system_aarch64_darwin,
  911. system_x86_64_iphonesim:
  912. begin
  913. set_system_compvar('IPHONE_OS_VERSION_MIN_REQUIRED','70000');
  914. iPhoneOSVersionMin:='7.0';
  915. end
  916. else
  917. internalerror(2012031001);
  918. end;
  919. end;
  920. procedure TOption.VerifyTargetProcessor;
  921. begin
  922. { no custom target processor specified -> ok }
  923. if processorstr='' then
  924. exit;
  925. { custom target processor specified -> verify it's the one we support }
  926. if upcase(processorstr)<>upcase(target_cpu_string) then
  927. Message1(option_invalid_target_architecture,processorstr);
  928. end;
  929. function Toption.Unsetbool(var Opts:TCmdStr; Pos: Longint; const FullPara: TCmdStr; RequireBoolPara: boolean):boolean;
  930. { checks if the character after pos in Opts is a + or a - and returns resp.
  931. false or true. If it is another character (or none), it also returns false }
  932. begin
  933. UnsetBool := false;
  934. if Length(Opts)>Pos then
  935. begin
  936. inc(Pos);
  937. UnsetBool := Opts[Pos] = '-';
  938. if Opts[Pos] in ['-','+']then
  939. delete(Opts,Pos,1)
  940. else if RequireBoolPara then
  941. IllegalPara(FullPara);
  942. end;
  943. end;
  944. procedure TOption.interpret_option(const opt:TCmdStr;ispara:boolean);
  945. var
  946. code : integer;
  947. c : char;
  948. more : TCmdStr;
  949. major,minor : longint;
  950. error : integer;
  951. j,l : longint;
  952. d,s : TCmdStr;
  953. hs : TCmdStr;
  954. unicodemapping : punicodemap;
  955. begin
  956. if opt='' then
  957. exit;
  958. { only parse define,undef,target,verbosity,link etc options the firsttime }
  959. if firstpass and
  960. not(
  961. (opt[1]='-') and
  962. (
  963. ((length(opt)>1) and (opt[2] in ['i','d','v','T','u','n','X','l'])) or
  964. ((length(opt)>3) and (opt[2]='F') and (opt[3]='e')) or
  965. ((length(opt)>3) and (opt[2]='C') and (opt[3]='p')) or
  966. ((length(opt)>3) and (opt[2]='W') and (opt[3] in ['m','p']))
  967. )
  968. ) then
  969. exit;
  970. Message1(option_handling_option,opt);
  971. case opt[1] of
  972. '-' :
  973. begin
  974. more:=Copy(opt,3,2147483647);
  975. if firstpass then
  976. Message1(option_interpreting_firstpass_option,opt)
  977. else
  978. Message1(option_interpreting_option,opt);
  979. case opt[2] of
  980. '?' :
  981. begin
  982. if (More <> '') and (More [1] = 'F') then
  983. begin
  984. FPCHelpLines := true;
  985. Delete (More, 1, 1);
  986. FPCBinaryPath := More;
  987. end;
  988. WriteHelpPages;
  989. end;
  990. 'a' :
  991. begin
  992. include(init_settings.globalswitches,cs_asm_leave);
  993. j:=1;
  994. while j<=length(more) do
  995. begin
  996. case more[j] of
  997. '5' :
  998. if target_info.system in systems_all_windows+systems_nativent-[system_i8086_win16] then
  999. begin
  1000. if UnsetBool(More, j, opt, false) then
  1001. exclude(init_settings.globalswitches,cs_asm_pre_binutils_2_25)
  1002. else
  1003. include(init_settings.globalswitches,cs_asm_pre_binutils_2_25);
  1004. end
  1005. else
  1006. IllegalPara(opt);
  1007. 'l' :
  1008. include(init_settings.globalswitches,cs_asm_source);
  1009. 'r' :
  1010. include(init_settings.globalswitches,cs_asm_regalloc);
  1011. 't' :
  1012. include(init_settings.globalswitches,cs_asm_tempalloc);
  1013. 'n' :
  1014. include(init_settings.globalswitches,cs_asm_nodes);
  1015. { -ao option must be the last, everything behind it is passed directly to
  1016. external assembler, it is ignored if internal assembler is used. }
  1017. 'o' :
  1018. begin
  1019. asmextraopt:=copy(more,j+1,length(more)-j);
  1020. break;
  1021. end;
  1022. 'p' :
  1023. begin
  1024. exclude(init_settings.globalswitches,cs_asm_leave);
  1025. if UnsetBool(More, 0, opt, false) then
  1026. exclude(init_settings.globalswitches,cs_asm_pipe)
  1027. else
  1028. include(init_settings.globalswitches,cs_asm_pipe);
  1029. end;
  1030. '-' :
  1031. init_settings.globalswitches:=init_settings.globalswitches -
  1032. [cs_asm_leave, cs_asm_source,cs_asm_regalloc, cs_asm_tempalloc,
  1033. cs_asm_nodes, cs_asm_pipe];
  1034. else
  1035. IllegalPara(opt);
  1036. end;
  1037. inc(j);
  1038. end;
  1039. end;
  1040. 'A' :
  1041. begin
  1042. paratargetasm:=find_asm_by_string(More);
  1043. if paratargetasm=as_none then
  1044. IllegalPara(opt);
  1045. end;
  1046. 'b' :
  1047. begin
  1048. // Message1(option_obsolete_switch,'-b');
  1049. if UnsetBool(More,0,opt,false) then
  1050. begin
  1051. init_settings.moduleswitches:=init_settings.moduleswitches-[cs_browser];
  1052. init_settings.moduleswitches:=init_settings.moduleswitches-[cs_local_browser];
  1053. end
  1054. else
  1055. begin
  1056. init_settings.moduleswitches:=init_settings.moduleswitches+[cs_browser];
  1057. end;
  1058. if More<>'' then
  1059. if (More='l') or (More='l+') then
  1060. init_settings.moduleswitches:=init_settings.moduleswitches+[cs_local_browser]
  1061. else if More='l-' then
  1062. init_settings.moduleswitches:=init_settings.moduleswitches-[cs_local_browser]
  1063. else
  1064. IllegalPara(opt);
  1065. end;
  1066. 'B' :
  1067. do_build:=not UnSetBool(more,0,opt,true);
  1068. 'C' :
  1069. begin
  1070. j:=1;
  1071. while j<=length(more) do
  1072. begin
  1073. case more[j] of
  1074. '3' :
  1075. If UnsetBool(More, j, opt, false) then
  1076. exclude(init_settings.localswitches,cs_ieee_errors)
  1077. Else
  1078. include(init_settings.localswitches,cs_ieee_errors);
  1079. 'a' :
  1080. begin
  1081. s:=upper(copy(more,j+1,length(more)-j));
  1082. if not(SetAbiType(s,target_info.abi)) then
  1083. IllegalPara(opt);
  1084. ABISetExplicitly:=true;
  1085. break;
  1086. end;
  1087. 'b' :
  1088. begin
  1089. if UnsetBool(More, j, opt, false) then
  1090. target_info.endian:=endian_little
  1091. else
  1092. target_info.endian:=endian_big;
  1093. end;
  1094. 'c' :
  1095. begin
  1096. if not SetAktProcCall(upper(copy(more,j+1,length(more)-j)),init_settings.defproccall) then
  1097. IllegalPara(opt);
  1098. break;
  1099. end;
  1100. {$ifdef cpufpemu}
  1101. 'e' :
  1102. begin
  1103. If UnsetBool(More, j, opt, false) then
  1104. exclude(init_settings.moduleswitches,cs_fp_emulation)
  1105. Else
  1106. include(init_settings.moduleswitches,cs_fp_emulation);
  1107. end;
  1108. {$endif cpufpemu}
  1109. 'f' :
  1110. begin
  1111. s:=upper(copy(more,j+1,length(more)-j));
  1112. if not(SetFpuType(s,init_settings.fputype)) then
  1113. IllegalPara(opt);
  1114. FPUSetExplicitly:=True;
  1115. break;
  1116. end;
  1117. 'F' :
  1118. begin
  1119. if not SetMinFPConstPrec(copy(more,j+1,length(more)-j),init_settings.minfpconstprec) then
  1120. IllegalPara(opt);
  1121. break;
  1122. end;
  1123. 'g' :
  1124. begin
  1125. if tf_no_pic_supported in target_info.flags then
  1126. begin
  1127. { consume a possible '-' coming after it }
  1128. UnsetBool(More, j, opt, false);
  1129. message(scan_w_pic_ignored);
  1130. end
  1131. else if UnsetBool(More, j, opt, false) then
  1132. exclude(init_settings.moduleswitches,cs_create_pic)
  1133. else
  1134. include(init_settings.moduleswitches,cs_create_pic);
  1135. end;
  1136. 'h' :
  1137. begin
  1138. l:=pos(',',copy(more,j+1,length(more)-j));
  1139. if l=0 then
  1140. l:=length(more)-j+1;
  1141. val(copy(more,j+1,l-1),heapsize,code);
  1142. if (code<>0)
  1143. {$ifdef AVR}
  1144. or (heapsize<32)
  1145. {$else AVR}
  1146. or (heapsize<1024)
  1147. {$endif AVR}
  1148. then
  1149. IllegalPara(opt)
  1150. else if l<=length(more)-j then
  1151. begin
  1152. val(copy(more,j+l+1,length(more)),maxheapsize,code);
  1153. if code<>0 then
  1154. IllegalPara(opt)
  1155. else if (maxheapsize<heapsize) then
  1156. begin
  1157. message(scan_w_heapmax_lessthan_heapmin);
  1158. maxheapsize:=heapsize;
  1159. end;
  1160. end;
  1161. break;
  1162. end;
  1163. 'i' :
  1164. If UnsetBool(More, j, opt, false) then
  1165. exclude(init_settings.localswitches,cs_check_io)
  1166. else
  1167. include(init_settings.localswitches,cs_check_io);
  1168. {$ifdef arm}
  1169. 'I' :
  1170. begin
  1171. if (upper(copy(more,j+1,length(more)-j))='THUMB') and
  1172. { does selected CPU really understand thumb? }
  1173. (init_settings.cputype in cpu_has_thumb) then
  1174. init_settings.instructionset:=is_thumb
  1175. else if upper(copy(more,j+1,length(more)-j))='ARM' then
  1176. init_settings.instructionset:=is_arm
  1177. else
  1178. IllegalPara(opt);
  1179. break;
  1180. end;
  1181. {$endif arm}
  1182. 'n' :
  1183. If UnsetBool(More, j, opt, false) then
  1184. exclude(init_settings.globalswitches,cs_link_nolink)
  1185. Else
  1186. include(init_settings.globalswitches,cs_link_nolink);
  1187. 'N' :
  1188. If UnsetBool(More, j, opt, false) then
  1189. exclude(init_settings.localswitches,cs_check_low_addr_load)
  1190. Else
  1191. include(init_settings.localswitches,cs_check_low_addr_load);
  1192. 'o' :
  1193. If UnsetBool(More, j, opt, false) then
  1194. exclude(init_settings.localswitches,cs_check_overflow)
  1195. Else
  1196. include(init_settings.localswitches,cs_check_overflow);
  1197. 'O' :
  1198. If UnsetBool(More, j, opt, false) then
  1199. exclude(init_settings.localswitches,cs_check_ordinal_size)
  1200. Else
  1201. include(init_settings.localswitches,cs_check_ordinal_size);
  1202. 'p' :
  1203. begin
  1204. s:=upper(copy(more,j+1,length(more)-j));
  1205. if not(Setcputype(s,init_settings)) then
  1206. IllegalPara(opt);
  1207. CPUSetExplicitly:=true;
  1208. break;
  1209. end;
  1210. 'P':
  1211. begin
  1212. delete(more,1,1);
  1213. case upper(copy(more,1,pos('=',more)-1)) of
  1214. 'PACKSET':
  1215. begin
  1216. delete(more,1,pos('=',more));
  1217. case more of
  1218. '0','DEFAULT','NORMAL':
  1219. init_settings.setalloc:=0;
  1220. '1','2','4','8':
  1221. init_settings.setalloc:=StrToInt(more);
  1222. else
  1223. IllegalPara(opt);
  1224. end
  1225. end;
  1226. 'PACKENUM':
  1227. begin
  1228. delete(more,1,pos('=',more));
  1229. case more of
  1230. '0','DEFAULT','NORMAL':
  1231. init_settings.packenum:=4;
  1232. '1','2','4':
  1233. init_settings.packenum:=StrToInt(more);
  1234. else
  1235. IllegalPara(opt);
  1236. end;
  1237. end;
  1238. 'PACKRECORD':
  1239. begin
  1240. delete(more,1,pos('=',more));
  1241. case more of
  1242. '0','DEFAULT','NORMAL':
  1243. init_settings.packrecords:=default_settings.packrecords;
  1244. '1','2','4','8','16','32':
  1245. init_settings.packrecords:=StrToInt(more);
  1246. else
  1247. IllegalPara(opt);
  1248. end;
  1249. end
  1250. else
  1251. IllegalPara(opt);
  1252. end;
  1253. end;
  1254. 'r' :
  1255. If UnsetBool(More, j, opt, false) then
  1256. exclude(init_settings.localswitches,cs_check_range)
  1257. Else
  1258. include(init_settings.localswitches,cs_check_range);
  1259. 'R' :
  1260. If UnsetBool(More, j, opt, false) then
  1261. begin
  1262. exclude(init_settings.localswitches,cs_check_range);
  1263. exclude(init_settings.localswitches,cs_check_object);
  1264. end
  1265. Else
  1266. begin
  1267. include(init_settings.localswitches,cs_check_range);
  1268. include(init_settings.localswitches,cs_check_object);
  1269. end;
  1270. 's' :
  1271. begin
  1272. val(copy(more,j+1,length(more)-j),stacksize,code);
  1273. if (code<>0)
  1274. {$ifdef cpu16bitaddr}
  1275. or (stacksize>=65521)
  1276. {$else cpu16bitaddr}
  1277. or (stacksize>=67107840)
  1278. {$endif cpu16bitaddr}
  1279. or (stacksize<1024) then
  1280. IllegalPara(opt);
  1281. break;
  1282. end;
  1283. 't' :
  1284. If UnsetBool(More, j, opt, false) then
  1285. exclude(init_settings.localswitches,cs_check_stack)
  1286. Else
  1287. include(init_settings.localswitches,cs_check_stack);
  1288. 'D' :
  1289. If UnsetBool(More, j, opt, false) then
  1290. exclude(init_settings.moduleswitches,cs_create_dynamic)
  1291. Else
  1292. include(init_settings.moduleswitches,cs_create_dynamic);
  1293. 'X' :
  1294. If UnsetBool(More, j, opt, false) then
  1295. exclude(init_settings.moduleswitches,cs_create_smart)
  1296. Else
  1297. include(init_settings.moduleswitches,cs_create_smart);
  1298. 'T' :
  1299. begin
  1300. if not UpdateTargetSwitchStr(copy(more,j+1,length(more)),init_settings.targetswitches,true) then
  1301. IllegalPara(opt);
  1302. break;
  1303. end;
  1304. 'v' :
  1305. If target_info.system in systems_jvm then
  1306. If UnsetBool(More, j, opt, false) then
  1307. exclude(init_settings.localswitches,cs_check_var_copyout)
  1308. Else
  1309. include(init_settings.localswitches,cs_check_var_copyout)
  1310. else
  1311. IllegalPara(opt)
  1312. else
  1313. IllegalPara(opt);
  1314. end;
  1315. inc(j);
  1316. end;
  1317. end;
  1318. 'd' :
  1319. begin
  1320. l:=Pos(':=',more);
  1321. if l>0 then
  1322. hs:=copy(more,1,l-1)
  1323. else
  1324. hs:=more;
  1325. if (not is_identifier(hs)) then
  1326. begin
  1327. if hs='' then
  1328. Message1(option_missing_arg,'-d')
  1329. else
  1330. Message1(option_malformed_para,opt);
  1331. StopOptions(1);
  1332. end;
  1333. if l>0 then
  1334. begin
  1335. if cs_support_macro in init_settings.moduleswitches then
  1336. set_system_macro(hs,Copy(more,l+2,255))
  1337. else
  1338. set_system_compvar(hs,Copy(more,l+2,255));
  1339. end
  1340. else
  1341. def_system_macro(hs);
  1342. end;
  1343. 'D' :
  1344. begin
  1345. include(init_settings.globalswitches,cs_link_deffile);
  1346. j:=1;
  1347. while j<=length(more) do
  1348. begin
  1349. case more[j] of
  1350. 'd' :
  1351. begin
  1352. description:=Copy(more,j+1,255);
  1353. break;
  1354. end;
  1355. 'v' :
  1356. begin
  1357. dllversion:=Copy(more,j+1,255);
  1358. l:=pos('.',dllversion);
  1359. dllminor:=0;
  1360. error:=0;
  1361. if l>0 then
  1362. begin
  1363. val(copy(dllversion,l+1,255),minor,error);
  1364. if (error=0) and
  1365. (minor>=0) and (minor<=$ffff) then
  1366. dllminor:=minor
  1367. else
  1368. if error=0 then
  1369. error:=1;
  1370. end;
  1371. if l=0 then
  1372. l:=256;
  1373. dllmajor:=1;
  1374. major:=0;
  1375. if error=0 then
  1376. val(copy(dllversion,1,l-1),major,error);
  1377. if (error=0) and (major>=0) and (major<=$ffff) then
  1378. dllmajor:=major
  1379. else
  1380. if error=0 then
  1381. error:=1;
  1382. if error<>0 then
  1383. Message1(scan_w_wrong_version_ignored,dllversion);
  1384. break;
  1385. end;
  1386. 'w' :
  1387. usewindowapi:=true;
  1388. '-' :
  1389. begin
  1390. exclude(init_settings.globalswitches,cs_link_deffile);
  1391. usewindowapi:=false;
  1392. end;
  1393. else
  1394. IllegalPara(opt);
  1395. end;
  1396. inc(j);
  1397. end;
  1398. end;
  1399. 'e' :
  1400. exepath:=FixPath(More,true);
  1401. 'E' :
  1402. begin
  1403. if UnsetBool(More, 0, opt, true) then
  1404. exclude(init_settings.globalswitches,cs_link_nolink)
  1405. else
  1406. include(init_settings.globalswitches,cs_link_nolink);
  1407. end;
  1408. 'f' :
  1409. begin
  1410. if more='PIC' then
  1411. begin
  1412. if tf_no_pic_supported in target_info.flags then
  1413. message(scan_w_pic_ignored)
  1414. else
  1415. include(init_settings.moduleswitches,cs_create_pic)
  1416. end
  1417. else
  1418. IllegalPara(opt);
  1419. end;
  1420. 'F' :
  1421. begin
  1422. if more='' then
  1423. IllegalPara(opt);
  1424. c:=more[1];
  1425. Delete(more,1,1);
  1426. DefaultReplacements(More);
  1427. case c of
  1428. 'a' :
  1429. autoloadunits:=more;
  1430. 'c' :
  1431. begin
  1432. { if we first specify that the system code page should be
  1433. used and then explicitly specify a code page, unset the
  1434. flag that we're using the system code page again }
  1435. SetCompileModeSwitch('SYSTEMCODEPAGE-',true);
  1436. if (upper(more)='UTF8') or (upper(more)='UTF-8') then
  1437. init_settings.sourcecodepage:=CP_UTF8
  1438. else if not(cpavailable(more)) then
  1439. Message1(option_code_page_not_available,more)
  1440. else
  1441. init_settings.sourcecodepage:=codepagebyname(more);
  1442. include(init_settings.moduleswitches,cs_explicit_codepage);
  1443. end;
  1444. 'C' :
  1445. RCCompiler:=More;
  1446. 'd' :
  1447. if UnsetBool(more, 0, opt, true) then
  1448. init_settings.disabledircache:=false
  1449. else
  1450. init_settings.disabledircache:=true;
  1451. 'D' :
  1452. utilsdirectory:=FixPath(More,true);
  1453. 'e' :
  1454. SetRedirectFile(More);
  1455. 'E' :
  1456. OutputExeDir:=FixPath(More,true);
  1457. 'f' :
  1458. if (target_info.system in systems_darwin) then
  1459. if ispara then
  1460. ParaFrameworkPath.AddPath(More,false)
  1461. else
  1462. frameworksearchpath.AddPath(More,true)
  1463. else
  1464. IllegalPara(opt);
  1465. 'i' :
  1466. begin
  1467. if ispara then
  1468. ParaIncludePath.AddPath(More,false)
  1469. else
  1470. includesearchpath.AddPath(More,true);
  1471. end;
  1472. 'm' :
  1473. begin
  1474. s:=ExtractFileDir(more);
  1475. if TryStrToInt(ExtractFileName(more),j) then
  1476. begin
  1477. unicodemapping:=loadunicodemapping(More,More+'.txt',j);
  1478. if assigned(unicodemapping) then
  1479. registermapping(unicodemapping)
  1480. else
  1481. IllegalPara(opt);
  1482. end
  1483. else
  1484. IllegalPara(opt);
  1485. end;
  1486. 'M' :
  1487. unicodepath:=FixPath(More,true);
  1488. 'g' :
  1489. Message2(option_obsolete_switch_use_new,'-Fg','-Fl');
  1490. 'l' :
  1491. begin
  1492. if path_absolute(More) then
  1493. if ispara then
  1494. ParaLibraryPath.AddPath(sysrootpath,More,false)
  1495. else
  1496. LibrarySearchPath.AddPath(sysrootpath,More,true)
  1497. else
  1498. if ispara then
  1499. ParaLibraryPath.AddPath('',More,false)
  1500. else
  1501. LibrarySearchPath.AddPath('',More,true);
  1502. end;
  1503. 'L' :
  1504. begin
  1505. if More<>'' then
  1506. ParaDynamicLinker:=More
  1507. else
  1508. IllegalPara(opt);
  1509. end;
  1510. 'o' :
  1511. begin
  1512. if ispara then
  1513. ParaObjectPath.AddPath(More,false)
  1514. else
  1515. ObjectSearchPath.AddPath(More,true);
  1516. end;
  1517. 'P' :
  1518. begin
  1519. if ispara then
  1520. parapackages.add(more,nil)
  1521. else
  1522. add_package(more,true,true);
  1523. end;
  1524. 'p' :
  1525. begin
  1526. if ispara then
  1527. parapackagepath.AddPath(More,false)
  1528. else
  1529. packagesearchpath.AddPath(More,true);
  1530. end;
  1531. 'r' :
  1532. Msgfilename:=More;
  1533. 'R' :
  1534. ResCompiler:=More;
  1535. 'u' :
  1536. begin
  1537. if ispara then
  1538. ParaUnitPath.AddPath(More,false)
  1539. else
  1540. unitsearchpath.AddPath(More,true);
  1541. end;
  1542. 'U' :
  1543. OutputUnitDir:=FixPath(More,true);
  1544. 'W',
  1545. 'w':
  1546. begin
  1547. if More<>'' then
  1548. begin
  1549. DefaultReplacements(More);
  1550. D:=ExtractFilePath(More);
  1551. if (D<>'') then
  1552. D:=FixPath(D,True);
  1553. D:=D+ExtractFileName(More);
  1554. if (c='W') then
  1555. WpoFeedbackOutput:=D
  1556. else
  1557. WpoFeedbackInput:=D;
  1558. end
  1559. else
  1560. IllegalPara(opt);
  1561. end;
  1562. else
  1563. IllegalPara(opt);
  1564. end;
  1565. end;
  1566. 'g' :
  1567. begin
  1568. if UnsetBool(More, 0, opt, false) then
  1569. begin
  1570. exclude(init_settings.moduleswitches,cs_debuginfo);
  1571. exclude(init_settings.globalswitches,cs_use_heaptrc);
  1572. exclude(init_settings.globalswitches,cs_use_lineinfo);
  1573. exclude(init_settings.localswitches,cs_checkpointer);
  1574. localvartrashing := -1;
  1575. end
  1576. else
  1577. begin
  1578. include(init_settings.moduleswitches,cs_debuginfo);
  1579. if paratargetdbg=dbg_none then
  1580. paratargetdbg:=target_info.dbg;
  1581. end;
  1582. if not RelocSectionSetExplicitly then
  1583. RelocSection:=false;
  1584. j:=1;
  1585. while j<=length(more) do
  1586. begin
  1587. case more[j] of
  1588. 'c' :
  1589. begin
  1590. if UnsetBool(More, j, opt, false) then
  1591. exclude(init_settings.localswitches,cs_checkpointer)
  1592. else if (target_info.system in systems_support_checkpointer) then
  1593. begin
  1594. if do_release then
  1595. Message(option_gc_incompatible_with_release_flag)
  1596. else
  1597. include(init_settings.localswitches,cs_checkpointer);
  1598. end
  1599. else
  1600. UnsupportedPara('-gc');
  1601. end;
  1602. 'h' :
  1603. begin
  1604. if UnsetBool(More, j, opt, false) then
  1605. exclude(init_settings.globalswitches,cs_use_heaptrc)
  1606. else
  1607. include(init_settings.globalswitches,cs_use_heaptrc);
  1608. end;
  1609. 'l' :
  1610. begin
  1611. if UnsetBool(More, j, opt, false) then
  1612. exclude(init_settings.globalswitches,cs_use_lineinfo)
  1613. else
  1614. include(init_settings.globalswitches,cs_use_lineinfo);
  1615. end;
  1616. 'o' :
  1617. begin
  1618. if not UpdateDebugStr(copy(more,j+1,length(more)),init_settings.debugswitches) then
  1619. IllegalPara(opt);
  1620. break;
  1621. end;
  1622. 'p' :
  1623. begin
  1624. if UnsetBool(More, j, opt, false) then
  1625. exclude(init_settings.globalswitches,cs_stabs_preservecase)
  1626. else
  1627. include(init_settings.globalswitches,cs_stabs_preservecase);
  1628. end;
  1629. 's' :
  1630. begin
  1631. paratargetdbg:=dbg_stabs;
  1632. end;
  1633. 't' :
  1634. begin
  1635. if UnsetBool(More, j, opt, false) then
  1636. localvartrashing := -1
  1637. else
  1638. localvartrashing := (localvartrashing + 1) mod nroftrashvalues;
  1639. end;
  1640. 'v' :
  1641. begin
  1642. if UnsetBool(More, j, opt, false) then
  1643. exclude(init_settings.globalswitches,cs_gdb_valgrind)
  1644. else
  1645. include(init_settings.globalswitches,cs_gdb_valgrind);
  1646. end;
  1647. 'w' :
  1648. begin
  1649. if (j<length(more)) and (more[j+1] in ['2','3','4']) then
  1650. begin
  1651. case more[j+1] of
  1652. '2': paratargetdbg:=dbg_dwarf2;
  1653. '3': paratargetdbg:=dbg_dwarf3;
  1654. '4': paratargetdbg:=dbg_dwarf4;
  1655. end;
  1656. inc(j);
  1657. end
  1658. else
  1659. paratargetdbg:=dbg_dwarf2;
  1660. end;
  1661. else
  1662. IllegalPara(opt);
  1663. end;
  1664. inc(j);
  1665. end;
  1666. end;
  1667. 'h' :
  1668. begin
  1669. NoPressEnter:=true;
  1670. if (More <> '') and (More [1] = 'F') then
  1671. begin
  1672. FPCHelpLines := true;
  1673. Delete (More, 1, 1);
  1674. FPCBinaryPath := More;
  1675. end;
  1676. WriteHelpPages;
  1677. end;
  1678. 'i' :
  1679. begin
  1680. if (More='') or
  1681. (More [1] in ['a', 'c', 'f', 'i', 'o', 'r', 't', 'u', 'w']) then
  1682. WriteInfo (More)
  1683. else
  1684. QuickInfo:=QuickInfo+More;
  1685. end;
  1686. 'I' :
  1687. begin
  1688. if ispara then
  1689. ParaIncludePath.AddPath(More,false)
  1690. else
  1691. includesearchpath.AddPath(More,false);
  1692. end;
  1693. 'k' :
  1694. begin
  1695. if more<>'' then
  1696. ParaLinkOptions:=ParaLinkOptions+' '+More
  1697. else
  1698. IllegalPara(opt);
  1699. end;
  1700. 'l' :
  1701. ParaLogo:=not UnSetBool(more,0,opt,true);
  1702. {$ifdef PREPROCWRITE}
  1703. 'm' :
  1704. parapreprocess:=not UnSetBool(more,0,opt,true);
  1705. {$endif PREPROCWRITE}
  1706. 'M' :
  1707. begin
  1708. more:=Upper(more);
  1709. if not SetCompileMode(more, true) then
  1710. if not SetCompileModeSwitch(more, true) then
  1711. IllegalPara(opt);
  1712. end;
  1713. 'n' :
  1714. begin
  1715. if More='' then
  1716. disable_configfile:=true
  1717. else
  1718. IllegalPara(opt);
  1719. end;
  1720. 'o' :
  1721. begin
  1722. if More<>'' then
  1723. begin
  1724. DefaultReplacements(More);
  1725. D:=ExtractFilePath(More);
  1726. if (D<>'') then
  1727. OutputExeDir:=FixPath(D,True);
  1728. OutputFileName:=ExtractFileName(More);
  1729. end
  1730. else
  1731. IllegalPara(opt);
  1732. end;
  1733. 'O' :
  1734. begin
  1735. j:=1;
  1736. while j<=length(more) do
  1737. begin
  1738. case more[j] of
  1739. '1' :
  1740. init_settings.optimizerswitches:=init_settings.optimizerswitches+level1optimizerswitches;
  1741. '2' :
  1742. init_settings.optimizerswitches:=init_settings.optimizerswitches+level2optimizerswitches;
  1743. '3' :
  1744. init_settings.optimizerswitches:=init_settings.optimizerswitches+level3optimizerswitches;
  1745. '4' :
  1746. init_settings.optimizerswitches:=init_settings.optimizerswitches+level4optimizerswitches;
  1747. 'a' :
  1748. begin
  1749. if not(UpdateAlignmentStr(Copy(Opt,j+3,255),ParaAlignment)) then
  1750. IllegalPara(opt);
  1751. break;
  1752. end;
  1753. 's' :
  1754. include(init_settings.optimizerswitches,cs_opt_size);
  1755. 'p' :
  1756. begin
  1757. if not Setoptimizecputype(copy(more,j+1,length(more)),init_settings.optimizecputype) then
  1758. begin
  1759. OptCPUSetExplicitly:=true;
  1760. { Give warning for old i386 switches }
  1761. if (Length(More)-j=1) and
  1762. (More[j+1]>='1') and (More[j+1]<='5')then
  1763. Message2(option_obsolete_switch_use_new,'-Op<nr>','-Op<name>')
  1764. else
  1765. IllegalPara(opt);
  1766. end;
  1767. break;
  1768. end;
  1769. 'o' :
  1770. begin
  1771. if not UpdateOptimizerStr(copy(more,j+1,length(more)),init_settings.optimizerswitches) then
  1772. IllegalPara(opt);
  1773. break;
  1774. end;
  1775. '-' :
  1776. begin
  1777. init_settings.optimizerswitches:=[];
  1778. FillChar(ParaAlignment,sizeof(ParaAlignment),0);
  1779. end;
  1780. { Obsolete switches }
  1781. 'g' :
  1782. Message2(option_obsolete_switch_use_new,'-Og','-Os');
  1783. 'G' :
  1784. Message1(option_obsolete_switch,'-OG');
  1785. 'r' :
  1786. Message2(option_obsolete_switch_use_new,'-Or','-O2 or -Ooregvar');
  1787. 'u' :
  1788. Message2(option_obsolete_switch_use_new,'-Ou','-Oouncertain');
  1789. 'w' :
  1790. begin
  1791. if not UpdateWpoStr(copy(more,j+1,length(more)),init_settings.dowpoptimizerswitches) then
  1792. IllegalPara(opt);
  1793. break;
  1794. end;
  1795. 'W' :
  1796. begin
  1797. if not UpdateWpoStr(copy(more,j+1,length(more)),init_settings.genwpoptimizerswitches) then
  1798. IllegalPara(opt);
  1799. break;
  1800. end;
  1801. else
  1802. IllegalPara(opt);
  1803. end;
  1804. inc(j);
  1805. end;
  1806. end;
  1807. 'p' :
  1808. begin
  1809. if UnsetBool(More, 0, opt, false) then
  1810. begin
  1811. init_settings.moduleswitches:=init_settings.moduleswitches-[cs_profile];
  1812. undef_system_macro('FPC_PROFILE');
  1813. end
  1814. else
  1815. if Length(More)=0 then
  1816. IllegalPara(opt)
  1817. else
  1818. case more[1] of
  1819. 'g' : if UnsetBool(more, 1, opt, false) then
  1820. begin
  1821. exclude(init_settings.moduleswitches,cs_profile);
  1822. undef_system_macro('FPC_PROFILE');
  1823. end
  1824. else if (target_info.system in supported_targets_pg) then
  1825. begin
  1826. include(init_settings.moduleswitches,cs_profile);
  1827. def_system_macro('FPC_PROFILE');
  1828. end
  1829. else
  1830. UnsupportedPara('-pg');
  1831. else
  1832. IllegalPara(opt);
  1833. end;
  1834. end;
  1835. 'P' :
  1836. begin
  1837. { used to select the target processor with the "fpc" binary;
  1838. give an error if it's not the target architecture supported by
  1839. this compiler binary (will be verified after the target_info
  1840. is set) }
  1841. processorstr:=More;
  1842. end;
  1843. 'R' :
  1844. begin
  1845. if not SetAsmReadMode(More,init_settings.asmmode) then
  1846. IllegalPara(opt);
  1847. end;
  1848. 's' :
  1849. begin
  1850. if UnsetBool(More, 0, opt, false) then
  1851. begin
  1852. init_settings.globalswitches:=init_settings.globalswitches-[cs_asm_extern,cs_link_extern,cs_link_nolink];
  1853. if more<>'' then
  1854. IllegalPara(opt);
  1855. end
  1856. else
  1857. begin
  1858. init_settings.globalswitches:=init_settings.globalswitches+[cs_asm_extern,cs_link_extern,cs_link_nolink];
  1859. if more='h' then
  1860. init_settings.globalswitches:=init_settings.globalswitches-[cs_link_on_target]
  1861. else if more='t' then
  1862. init_settings.globalswitches:=init_settings.globalswitches+[cs_link_on_target]
  1863. else if more='r' then
  1864. init_settings.globalswitches:=init_settings.globalswitches+[cs_asm_leave,cs_no_regalloc]
  1865. else if more<>'' then
  1866. IllegalPara(opt);
  1867. end;
  1868. end;
  1869. 'S' :
  1870. begin
  1871. if more='' then
  1872. IllegalPara(opt);
  1873. if more[1]='I' then
  1874. begin
  1875. {$ifdef jvm}
  1876. UnsupportedPara('-SI');
  1877. {$endif}
  1878. if upper(more)='ICOM' then
  1879. init_settings.interfacetype:=it_interfacecom
  1880. else if upper(more)='ICORBA' then
  1881. init_settings.interfacetype:=it_interfacecorba
  1882. else
  1883. IllegalPara(opt);
  1884. end
  1885. else
  1886. begin
  1887. j:=1;
  1888. while j<=length(more) do
  1889. begin
  1890. case more[j] of
  1891. '2' : //an alternative to -Mobjfpc
  1892. SetCompileMode('OBJFPC',true);
  1893. 'a' :
  1894. If UnsetBool(More, j, opt, false) then
  1895. exclude(init_settings.localswitches,cs_do_assertion)
  1896. else
  1897. include(init_settings.localswitches,cs_do_assertion);
  1898. 'c' :
  1899. If UnsetBool(More, j, opt, false) then
  1900. exclude(init_settings.moduleswitches,cs_support_c_operators)
  1901. else
  1902. include(init_settings.moduleswitches,cs_support_c_operators);
  1903. 'd' : //an alternative to -Mdelphi
  1904. SetCompileMode('DELPHI',true);
  1905. 'e' :
  1906. begin
  1907. SetErrorFlags(copy(more,j+1,length(more)));
  1908. break;
  1909. end;
  1910. 'f' :
  1911. begin
  1912. inc(j);
  1913. if more[j]='-' then
  1914. begin
  1915. if length(more)>j then
  1916. IllegalPara(opt)
  1917. else
  1918. features:=[];
  1919. end
  1920. else
  1921. begin
  1922. if (HandleFeature(upper(copy(more,j,length(more)-j+1)))) then
  1923. j:=length(more)
  1924. else
  1925. IllegalPara(opt);
  1926. end;
  1927. end;
  1928. 'g' :
  1929. If UnsetBool(More, j, opt, false) then
  1930. exclude(init_settings.moduleswitches,cs_support_goto)
  1931. else
  1932. include(init_settings.moduleswitches,cs_support_goto);
  1933. 'h' :
  1934. If UnsetBool(More, j, opt, false) then
  1935. exclude(init_settings.localswitches,cs_refcountedstrings)
  1936. else
  1937. include(init_settings.localswitches,cs_refcountedstrings);
  1938. 'i' :
  1939. If UnsetBool(More, j, opt, false) then
  1940. exclude(init_settings.localswitches,cs_do_inline)
  1941. else
  1942. include(init_settings.localswitches,cs_do_inline);
  1943. 'k' :
  1944. If UnsetBool(More, j, opt, false) then
  1945. exclude(init_settings.globalswitches,cs_load_fpcylix_unit)
  1946. else
  1947. include(init_settings.globalswitches,cs_load_fpcylix_unit);
  1948. 'm' :
  1949. If UnsetBool(More, j, opt, false) then
  1950. exclude(init_settings.moduleswitches,cs_support_macro)
  1951. else
  1952. include(init_settings.moduleswitches,cs_support_macro);
  1953. 'o' : //an alternative to -Mtp
  1954. SetCompileMode('TP',true);
  1955. 'r' :
  1956. If UnsetBool(More, j, opt, false) then
  1957. exclude(init_settings.globalswitches,cs_transparent_file_names)
  1958. else
  1959. include(init_settings.globalswitches,cs_transparent_file_names);
  1960. {$ifdef gpc_mode}
  1961. 'p' : //an alternative to -Mgpc
  1962. SetCompileMode('GPC',true);
  1963. {$endif}
  1964. 's' :
  1965. If UnsetBool(More, j, opt, false) then
  1966. exclude(init_settings.globalswitches,cs_constructor_name)
  1967. else
  1968. include(init_settings.globalswitches,cs_constructor_name);
  1969. 't' :
  1970. Message1(option_obsolete_switch,'-St');
  1971. 'v' :
  1972. If UnsetBool(More, j, opt, false) then
  1973. exclude(init_settings.globalswitches,cs_support_vectors)
  1974. else
  1975. include(init_settings.globalswitches,cs_support_vectors);
  1976. 'x' :
  1977. If UnsetBool(More, j, opt, false) then
  1978. SetCompileModeSwitch('EXCEPTIONS-',true)
  1979. else
  1980. SetCompileModeSwitch('EXCEPTIONS',true);
  1981. 'y' :
  1982. If UnsetBool(More, j, opt, false) then
  1983. exclude(init_settings.localswitches,cs_typed_addresses)
  1984. else
  1985. include(init_settings.localswitches,cs_typed_addresses);
  1986. '-' :
  1987. begin
  1988. init_settings.globalswitches:=init_settings.globalswitches - [cs_constructor_name,cs_support_exceptions,
  1989. cs_support_vectors,cs_load_fpcylix_unit];
  1990. init_settings.localswitches:=init_settings.localswitches - [cs_do_assertion,cs_do_inline, cs_refcountedstrings,
  1991. cs_typed_addresses];
  1992. init_settings.moduleswitches:=init_settings.moduleswitches - [cs_support_c_operators, cs_support_goto,
  1993. cs_support_macro];
  1994. end;
  1995. else
  1996. IllegalPara(opt);
  1997. end;
  1998. inc(j);
  1999. end;
  2000. end;
  2001. end;
  2002. 'T' :
  2003. begin
  2004. more:=Upper(More);
  2005. if paratarget=system_none then
  2006. begin
  2007. { remove old target define }
  2008. TargetOptions(false);
  2009. { load new target }
  2010. paratarget:=find_system_by_string(More);
  2011. if paratarget<>system_none then
  2012. set_target(paratarget)
  2013. else
  2014. IllegalPara(opt);
  2015. { set new define }
  2016. TargetOptions(true);
  2017. end
  2018. else
  2019. if More<>upper(target_info.shortname) then
  2020. Message1(option_target_is_already_set,target_info.shortname);
  2021. end;
  2022. 'u' :
  2023. if is_identifier(more) then
  2024. undef_system_macro(more)
  2025. else
  2026. begin
  2027. if (more='') then
  2028. Message1(option_missing_arg,'-u')
  2029. else
  2030. Message1(option_malformed_para,opt);
  2031. StopOptions(1);
  2032. end;
  2033. 'U' :
  2034. begin
  2035. j:=1;
  2036. while j<=length(more) do
  2037. begin
  2038. case more[j] of
  2039. {$ifdef UNITALIASES}
  2040. 'a' :
  2041. begin
  2042. AddUnitAlias(Copy(More,j+1,255));
  2043. break;
  2044. end;
  2045. {$endif UNITALIASES}
  2046. 'n' :
  2047. exclude(init_settings.globalswitches,cs_check_unit_name);
  2048. 'p' :
  2049. begin
  2050. Message2(option_obsolete_switch_use_new,'-Up','-Fu');
  2051. break;
  2052. end;
  2053. 'r' :
  2054. begin
  2055. do_release:=true;
  2056. if (cs_checkpointer in init_settings.localswitches) then
  2057. begin
  2058. Message(option_gc_incompatible_with_release_flag);
  2059. exclude(init_settings.localswitches,cs_checkpointer);
  2060. end;
  2061. end;
  2062. 's' :
  2063. include(init_settings.moduleswitches,cs_compilesystem);
  2064. '-' :
  2065. begin
  2066. exclude(init_settings.moduleswitches,cs_compilesystem);
  2067. exclude(init_settings.globalswitches,cs_check_unit_name);
  2068. end;
  2069. else
  2070. IllegalPara(opt);
  2071. end;
  2072. inc(j);
  2073. end;
  2074. end;
  2075. 'v' :
  2076. begin
  2077. if not setverbosity(More) then
  2078. IllegalPara(opt);
  2079. end;
  2080. 'V' : ; { Ignore used by fpc }
  2081. 'W' :
  2082. begin
  2083. j:=1;
  2084. while j<=length(More) do
  2085. begin
  2086. case More[j] of
  2087. 'A':
  2088. begin
  2089. if target_info.system in systems_all_windows then
  2090. begin
  2091. if UnsetBool(More, j, opt, false) then
  2092. SetApptype(app_cui)
  2093. else
  2094. SetApptype(app_native);
  2095. end
  2096. else
  2097. IllegalPara(opt);
  2098. end;
  2099. 'b':
  2100. begin
  2101. if target_info.system in systems_darwin then
  2102. begin
  2103. if UnsetBool(More, j, opt, false) then
  2104. SetApptype(app_cui)
  2105. else
  2106. SetApptype(app_bundle)
  2107. end
  2108. else
  2109. IllegalPara(opt);
  2110. end;
  2111. 'B':
  2112. begin
  2113. if target_info.system in systems_all_windows+systems_symbian then
  2114. begin
  2115. { -WB200000 means set trefered base address
  2116. to $200000, but does not change relocsection boolean
  2117. this way we can create both relocatble and
  2118. non relocatable DLL at a specific base address PM }
  2119. if (length(More)>j) then
  2120. begin
  2121. val('$'+Copy(More,j+1,255),imagebase,code);
  2122. if code<>0 then
  2123. IllegalPara(opt);
  2124. ImageBaseSetExplicity:=true;
  2125. end
  2126. else
  2127. begin
  2128. RelocSection:=true;
  2129. RelocSectionSetExplicitly:=true;
  2130. end;
  2131. break;
  2132. end
  2133. else
  2134. IllegalPara(opt);
  2135. end;
  2136. 'C':
  2137. begin
  2138. if target_info.system in systems_all_windows+systems_os2+systems_macos then
  2139. begin
  2140. if UnsetBool(More, j, opt, false) then
  2141. SetApptype(app_gui)
  2142. else
  2143. SetApptype(app_cui);
  2144. end
  2145. else
  2146. IllegalPara(opt);
  2147. end;
  2148. 'D':
  2149. begin
  2150. if target_info.system in systems_all_windows then
  2151. begin
  2152. UseDeffileForExports:=not UnsetBool(More, j, opt, false);
  2153. UseDeffileForExportsSetExplicitly:=true;
  2154. end
  2155. else
  2156. IllegalPara(opt);
  2157. end;
  2158. 'e':
  2159. begin
  2160. if (target_info.system in systems_darwin) then
  2161. begin
  2162. RegisterRes(res_macosx_ext_info,TWinLikeResourceFile);
  2163. set_target_res(res_ext);
  2164. target_info.resobjext:='.fpcres';
  2165. end
  2166. else
  2167. IllegalPara(opt);
  2168. end;
  2169. 'F':
  2170. begin
  2171. if target_info.system in systems_os2 then
  2172. begin
  2173. if UnsetBool(More, j, opt, false) then
  2174. SetApptype(app_cui)
  2175. else
  2176. SetApptype(app_fs);
  2177. end
  2178. else
  2179. IllegalPara(opt);
  2180. end;
  2181. 'G':
  2182. begin
  2183. if target_info.system in systems_all_windows+systems_os2+systems_macos then
  2184. begin
  2185. if UnsetBool(More, j, opt, false) then
  2186. SetApptype(app_cui)
  2187. else
  2188. SetApptype(app_gui);
  2189. end
  2190. else
  2191. IllegalPara(opt);
  2192. end;
  2193. {$if defined(i8086)}
  2194. 'h':
  2195. begin
  2196. if UnsetBool(More, j, opt, false) then
  2197. exclude(init_settings.moduleswitches,cs_huge_code)
  2198. else
  2199. include(init_settings.moduleswitches,cs_huge_code);
  2200. end;
  2201. {$endif defined(i8086)}
  2202. 'I':
  2203. begin
  2204. if target_info.system in systems_all_windows then
  2205. begin
  2206. GenerateImportSection:=not UnsetBool(More,j,opt,false);
  2207. GenerateImportSectionSetExplicitly:=true;
  2208. end
  2209. else
  2210. IllegalPara(opt);
  2211. end;
  2212. 'i':
  2213. begin
  2214. if (target_info.system in systems_darwin) then
  2215. begin
  2216. set_target_res(res_macho);
  2217. target_info.resobjext:=
  2218. targetinfos[target_info.system]^.resobjext;
  2219. end
  2220. else
  2221. IllegalPara(opt);
  2222. end;
  2223. 'm':
  2224. begin
  2225. {$if defined(i8086)}
  2226. if (target_info.system in [system_i8086_msdos,system_i8086_win16,system_i8086_embedded]) then
  2227. begin
  2228. case Upper(Copy(More,j+1,255)) of
  2229. 'TINY': init_settings.x86memorymodel:=mm_tiny;
  2230. 'SMALL': init_settings.x86memorymodel:=mm_small;
  2231. 'MEDIUM': init_settings.x86memorymodel:=mm_medium;
  2232. 'COMPACT': init_settings.x86memorymodel:=mm_compact;
  2233. 'LARGE': init_settings.x86memorymodel:=mm_large;
  2234. 'HUGE': init_settings.x86memorymodel:=mm_huge;
  2235. else
  2236. IllegalPara(opt);
  2237. end;
  2238. break;
  2239. end
  2240. else
  2241. {$endif defined(i8086)}
  2242. IllegalPara(opt);
  2243. end;
  2244. 'M':
  2245. begin
  2246. if (target_info.system in (systems_darwin-[system_i386_iphonesim,system_arm_darwin,system_aarch64_darwin,system_x86_64_iphonesim])) and
  2247. ParseMacVersionMin(MacOSXVersionMin,iPhoneOSVersionMin,'MAC_OS_X_VERSION_MIN_REQUIRED',copy(More,2,255),false) then
  2248. begin
  2249. break;
  2250. end
  2251. else
  2252. IllegalPara(opt);
  2253. end;
  2254. 'N':
  2255. begin
  2256. if target_info.system in systems_all_windows then
  2257. begin
  2258. RelocSection:=UnsetBool(More,j,opt,false);
  2259. RelocSectionSetExplicitly:=true;
  2260. end
  2261. else
  2262. IllegalPara(opt);
  2263. end;
  2264. 'p':
  2265. begin
  2266. {$push}
  2267. {$warn 6018 off} { Unreachable code due to compile time evaluation }
  2268. if (target_info.system in systems_embedded) and
  2269. ControllerSupport then
  2270. begin
  2271. s:=upper(copy(more,j+1,length(more)-j));
  2272. if not(SetControllerType(s,init_settings.controllertype)) then
  2273. IllegalPara(opt);
  2274. break;
  2275. end
  2276. else
  2277. IllegalPara(opt);
  2278. {$pop}
  2279. end;
  2280. 'P':
  2281. begin
  2282. if (target_info.system in [system_i386_iphonesim,system_arm_darwin,system_aarch64_darwin,system_x86_64_iphonesim]) and
  2283. ParseMacVersionMin(iPhoneOSVersionMin,MacOSXVersionMin,'IPHONE_OS_VERSION_MIN_REQUIRED',copy(More,2,255),true) then
  2284. begin
  2285. break;
  2286. end
  2287. else
  2288. IllegalPara(opt);
  2289. end;
  2290. 'R':
  2291. begin
  2292. if target_info.system in systems_all_windows then
  2293. begin
  2294. { support -WR+ / -WR- as synonyms to -WR / -WN }
  2295. RelocSection:=not UnsetBool(More,j,opt,false);
  2296. RelocSectionSetExplicitly:=true;
  2297. end
  2298. else
  2299. IllegalPara(opt);
  2300. end;
  2301. 't':
  2302. begin
  2303. {$if defined(i8086)}
  2304. if (target_info.system in [system_i8086_msdos,system_i8086_embedded]) then
  2305. begin
  2306. case Upper(Copy(More,j+1,255)) of
  2307. 'EXE': SetAppType(app_cui);
  2308. 'COM': SetAppType(app_com);
  2309. else
  2310. IllegalPara(opt);
  2311. end;
  2312. break;
  2313. end
  2314. else
  2315. {$endif defined(i8086)}
  2316. IllegalPara(opt);
  2317. end;
  2318. 'T':
  2319. begin
  2320. if target_info.system in systems_macos then
  2321. begin
  2322. if UnsetBool(More, j, opt, false) then
  2323. SetApptype(app_cui)
  2324. else
  2325. SetApptype(app_tool);
  2326. end
  2327. else
  2328. IllegalPara(opt);
  2329. end;
  2330. 'X':
  2331. begin
  2332. if (target_info.system in systems_linux) then
  2333. begin
  2334. if UnsetBool(More, j, opt, false) then
  2335. exclude(init_settings.moduleswitches,cs_executable_stack)
  2336. else
  2337. include(init_settings.moduleswitches,cs_executable_stack)
  2338. end
  2339. else
  2340. IllegalPara(opt);
  2341. end;
  2342. else
  2343. IllegalPara(opt);
  2344. end;
  2345. inc(j);
  2346. end;
  2347. end;
  2348. 'X' :
  2349. begin
  2350. j:=1;
  2351. while j<=length(more) do
  2352. begin
  2353. case More[j] of
  2354. '9' :
  2355. begin
  2356. if target_info.system in systems_linux then
  2357. begin
  2358. if UnsetBool(More, j, opt, false) then
  2359. exclude(init_settings.globalswitches,cs_link_pre_binutils_2_19)
  2360. else
  2361. include(init_settings.globalswitches,cs_link_pre_binutils_2_19);
  2362. end
  2363. else
  2364. IllegalPara(opt);
  2365. end;
  2366. 'c' : Cshared:=TRUE;
  2367. 'd' : Dontlinkstdlibpath:=TRUE;
  2368. 'e' :
  2369. begin
  2370. If UnsetBool(More, j, opt, false) then
  2371. exclude(init_settings.globalswitches,cs_link_extern)
  2372. else
  2373. include(init_settings.globalswitches,cs_link_extern);
  2374. end;
  2375. 'f' :
  2376. include(init_settings.globalswitches,cs_link_pthread);
  2377. 'g' :
  2378. begin
  2379. If UnsetBool(More, j, opt, false) then
  2380. exclude(init_settings.globalswitches,cs_link_separate_dbg_file)
  2381. else
  2382. include(init_settings.globalswitches,cs_link_separate_dbg_file);
  2383. end;
  2384. 'i' :
  2385. begin
  2386. If UnsetBool(More, j, opt, false) then
  2387. include(init_settings.globalswitches,cs_link_extern)
  2388. else
  2389. exclude(init_settings.globalswitches,cs_link_extern);
  2390. end;
  2391. 'n' :
  2392. begin
  2393. If UnsetBool(More, j, opt, false) then
  2394. exclude(init_settings.globalswitches,cs_link_native)
  2395. else
  2396. include(init_settings.globalswitches,cs_link_native);
  2397. end;
  2398. 'm' :
  2399. begin
  2400. If UnsetBool(More, j, opt, false) then
  2401. exclude(init_settings.globalswitches,cs_link_map)
  2402. else
  2403. include(init_settings.globalswitches,cs_link_map);
  2404. end;
  2405. 'p' : ; { Ignore used by fpc.pp }
  2406. 'r' :
  2407. begin
  2408. if (target_info.system in suppported_targets_x_smallr) then
  2409. begin
  2410. rlinkpath:=Copy(more,2,length(More)-1);
  2411. DefaultReplacements(rlinkpath);
  2412. end
  2413. else
  2414. IgnoredPara('-Xr');
  2415. more:='';
  2416. end;
  2417. 'R' :
  2418. begin
  2419. sysrootpath:=copy(more,2,length(more)-1);
  2420. defaultreplacements(sysrootpath);
  2421. more:='';
  2422. end;
  2423. 's' :
  2424. begin
  2425. If UnsetBool(More, j, opt, false) then
  2426. exclude(init_settings.globalswitches,cs_link_strip)
  2427. else
  2428. include(init_settings.globalswitches,cs_link_strip);
  2429. end;
  2430. 't' :
  2431. include(init_settings.globalswitches,cs_link_staticflag);
  2432. 'v' :
  2433. begin
  2434. If UnsetBool(More, j, opt, false) then
  2435. exclude(init_settings.globalswitches,cs_link_opt_vtable)
  2436. else
  2437. include(init_settings.globalswitches,cs_link_opt_vtable);
  2438. end;
  2439. 'D' :
  2440. begin
  2441. def_system_macro('FPC_LINK_DYNAMIC');
  2442. undef_system_macro('FPC_LINK_SMART');
  2443. undef_system_macro('FPC_LINK_STATIC');
  2444. exclude(init_settings.globalswitches,cs_link_static);
  2445. exclude(init_settings.globalswitches,cs_link_smart);
  2446. include(init_settings.globalswitches,cs_link_shared);
  2447. LinkTypeSetExplicitly:=true;
  2448. end;
  2449. 'M' :
  2450. begin
  2451. mainaliasname:=Copy(more,2,length(More)-1);
  2452. More:='';
  2453. end;
  2454. 'P' :
  2455. begin
  2456. utilsprefix:=Copy(more,2,length(More)-1);
  2457. DefaultReplacements(utilsprefix);
  2458. More:='';
  2459. end;
  2460. 'L' : begin // -XLO is link order -XLA is link alias. -XLD avoids load defaults.
  2461. // these are not aggregable.
  2462. if (j=length(more)) or not (more[j+1] in ['O','A','D']) then
  2463. IllegalPara(opt)
  2464. else
  2465. begin
  2466. case more[j+1] of
  2467. 'A' : begin
  2468. s:=Copy(more,3,length(More)-2);
  2469. if not LinkLibraryAliases.AddDep(s) Then
  2470. IllegalPara(opt);
  2471. end;
  2472. 'O' : begin
  2473. s:=Copy(more,3,length(More)-2);
  2474. if not LinkLibraryOrder.AddWeight(s) Then
  2475. IllegalPara(opt);
  2476. end;
  2477. 'D' : include(init_settings.globalswitches,cs_link_no_default_lib_order)
  2478. else
  2479. IllegalPara(opt);
  2480. end; {case}
  2481. j:=length(more);
  2482. end; {else begin}
  2483. end;
  2484. 'S' :
  2485. begin
  2486. ForceStaticLinking;
  2487. end;
  2488. 'V' :
  2489. begin
  2490. if UnsetBool(More, j, opt, false) then
  2491. exclude(init_settings.globalswitches,cs_link_vlink)
  2492. else
  2493. begin
  2494. include(init_settings.globalswitches,cs_link_vlink);
  2495. include(init_settings.globalswitches,cs_link_extern);
  2496. end;
  2497. LinkerSetExplicitly:=true;
  2498. end;
  2499. 'X' :
  2500. begin
  2501. def_system_macro('FPC_LINK_SMART');
  2502. undef_system_macro('FPC_LINK_STATIC');
  2503. undef_system_macro('FPC_LINK_DYNAMIC');
  2504. exclude(init_settings.globalswitches,cs_link_static);
  2505. include(init_settings.globalswitches,cs_link_smart);
  2506. exclude(init_settings.globalswitches,cs_link_shared);
  2507. LinkTypeSetExplicitly:=true;
  2508. end;
  2509. '-' :
  2510. begin
  2511. exclude(init_settings.globalswitches,cs_link_staticflag);
  2512. exclude(init_settings.globalswitches,cs_link_strip);
  2513. exclude(init_settings.globalswitches,cs_link_map);
  2514. set_default_link_type;
  2515. end;
  2516. else
  2517. IllegalPara(opt);
  2518. end;
  2519. inc(j);
  2520. end;
  2521. end;
  2522. else
  2523. IllegalPara(opt);
  2524. end;
  2525. end;
  2526. '@' :
  2527. begin
  2528. Message(option_no_nested_response_file);
  2529. StopOptions(1);
  2530. end;
  2531. else
  2532. begin
  2533. if (length(param_file)<>0) then
  2534. Message2(option_only_one_source_support,param_file,opt);
  2535. param_file:=opt;
  2536. Message1(option_found_file,opt);
  2537. end;
  2538. end;
  2539. end;
  2540. procedure Toption.Interpret_file(const filename : TPathStr);
  2541. procedure RemoveSep(var fn:TPathStr);
  2542. var
  2543. i : longint;
  2544. begin
  2545. i:=0;
  2546. while (i<length(fn)) and (fn[i+1] in [',',' ',#9]) do
  2547. inc(i);
  2548. Delete(fn,1,i);
  2549. i:=length(fn);
  2550. while (i>0) and (fn[i] in [',',' ',#9]) do
  2551. dec(i);
  2552. fn:=copy(fn,1,i);
  2553. end;
  2554. function GetName(var fn:TPathStr):TPathStr;
  2555. var
  2556. i : longint;
  2557. begin
  2558. i:=0;
  2559. while (i<length(fn)) and (fn[i+1] in ['a'..'z','A'..'Z','0'..'9','_','-']) do
  2560. inc(i);
  2561. GetName:=Copy(fn,1,i);
  2562. Delete(fn,1,i);
  2563. end;
  2564. const
  2565. maxlevel = 15;
  2566. var
  2567. f : text;
  2568. s, tmp,
  2569. opts : TCmdStr;
  2570. skip : array[0..maxlevel] of boolean;
  2571. line,
  2572. level : longint;
  2573. option_read : boolean;
  2574. oldfilemode : byte;
  2575. ConfigFile: TPathStr;
  2576. begin
  2577. { avoid infinite loop }
  2578. Inc(FileLevel);
  2579. Option_read:=false;
  2580. If FileLevel>MaxLevel then
  2581. Message(option_too_many_cfg_files);
  2582. if not ParaIncludeCfgPath.FindFile(fileName,true,ConfigFile) then
  2583. ConfigFile := ExpandFileName(filename);
  2584. { Maybe It's Directory ?} //Jaro Change:
  2585. if PathExists(ConfigFile,false) then
  2586. begin
  2587. Message1(option_config_is_dir,filename);
  2588. exit;
  2589. end;
  2590. { open file }
  2591. Message1(option_using_file,filename);
  2592. oldfilemode:=filemode;
  2593. filemode:=0;
  2594. assign(f,ConfigFile);
  2595. {$push}{$I-}
  2596. reset(f);
  2597. {$pop}
  2598. filemode:=oldfilemode;
  2599. if ioresult<>0 then
  2600. begin
  2601. Message1(option_unable_open_file,filename);
  2602. exit;
  2603. end;
  2604. Message1(option_start_reading_configfile,filename);
  2605. fillchar(skip,sizeof(skip),0);
  2606. level:=0;
  2607. line:=0;
  2608. while not eof(f) do
  2609. begin
  2610. readln(f,opts);
  2611. inc(line);
  2612. RemoveSep(opts);
  2613. if (opts<>'') and (opts[1]<>';') then
  2614. begin
  2615. if opts[1]='#' then
  2616. begin
  2617. Message1(option_interpreting_file_option,opts);
  2618. Delete(opts,1,1);
  2619. s:=upper(GetName(opts));
  2620. if (s='SECTION') then
  2621. begin
  2622. RemoveSep(opts);
  2623. s:=upper(GetName(opts));
  2624. if level=0 then
  2625. skip[level]:=not defined_macro(s) or (s='COMMON');
  2626. end
  2627. else
  2628. if (s='IFDEF') then
  2629. begin
  2630. RemoveSep(opts);
  2631. if Level>=maxlevel then
  2632. begin
  2633. Message2(option_too_many_ifdef,filename,tostr(line));
  2634. stopOptions(1);
  2635. end;
  2636. inc(Level);
  2637. skip[level]:=(skip[level-1] or not defined_macro(upper(GetName(opts))));
  2638. end
  2639. else
  2640. if (s='IFNDEF') then
  2641. begin
  2642. RemoveSep(opts);
  2643. if Level>=maxlevel then
  2644. begin
  2645. Message2(option_too_many_ifdef,filename,tostr(line));
  2646. stopOptions(1);
  2647. end;
  2648. inc(Level);
  2649. skip[level]:=(skip[level-1] or defined_macro(upper(GetName(opts))));
  2650. end
  2651. else
  2652. if (s='ELSE') then
  2653. begin
  2654. if Level=0 then
  2655. begin
  2656. Message2(option_else_without_if,filename,tostr(line));
  2657. stopOptions(1);
  2658. end
  2659. else
  2660. skip[level]:=skip[level-1] or (not skip[level])
  2661. end
  2662. else
  2663. if (s='ENDIF') then
  2664. begin
  2665. skip[level]:=false;
  2666. if Level=0 then
  2667. begin
  2668. Message2(option_too_many_endif,filename,tostr(line));
  2669. stopOptions(1);
  2670. end;
  2671. dec(level);
  2672. end
  2673. else
  2674. if (not skip[level]) then
  2675. begin
  2676. if (s='DEFINE') then
  2677. begin
  2678. RemoveSep(opts);
  2679. tmp:= GetName(opts);
  2680. if tmp <> '' then
  2681. def_system_macro(tmp);
  2682. Option_read:=true;
  2683. end
  2684. else
  2685. if (s='UNDEF') then
  2686. begin
  2687. RemoveSep(opts);
  2688. tmp:= GetName(opts);
  2689. if tmp <> '' then
  2690. undef_system_macro(tmp);
  2691. Option_read:=true;
  2692. end
  2693. else
  2694. if (s='WRITE') then
  2695. begin
  2696. Delete(opts,1,1);
  2697. DefaultReplacements(opts);
  2698. WriteLn(opts);
  2699. Option_read:=true;
  2700. end
  2701. else
  2702. if (s='INCLUDE') then
  2703. begin
  2704. Delete(opts,1,1);
  2705. DefaultReplacements(opts);
  2706. Interpret_file(opts);
  2707. Option_read:=true;
  2708. end
  2709. else
  2710. if (s='CFGDIR') then
  2711. begin
  2712. Delete(opts,1,1);
  2713. DefaultReplacements(opts);
  2714. ParaIncludeCfgPath.AddPath(opts,false);
  2715. Option_read:=true;
  2716. end;
  2717. end;
  2718. end
  2719. else
  2720. begin
  2721. if (opts[1]='-') or (opts[1]='@') then
  2722. begin
  2723. if (not skip[level]) then
  2724. interpret_option(opts,false);
  2725. Option_read:=true;
  2726. end
  2727. else
  2728. Message1(option_illegal_para,opts);
  2729. end;
  2730. end;
  2731. end;
  2732. if Level>0 then
  2733. Message(option_too_less_endif);
  2734. if Not Option_read then
  2735. Message1(option_no_option_found,filename)
  2736. else
  2737. Message1(option_end_reading_configfile,filename);
  2738. Close(f);
  2739. Dec(FileLevel);
  2740. end;
  2741. procedure Toption.Interpret_envvar(const envname : TCmdStr);
  2742. var
  2743. argstart,
  2744. env,
  2745. pc : pchar;
  2746. arglen : longint;
  2747. quote : set of char;
  2748. hs : TCmdStr;
  2749. begin
  2750. Message1(option_using_env,envname);
  2751. env:=GetEnvPChar(envname);
  2752. pc:=env;
  2753. if assigned(pc) then
  2754. begin
  2755. repeat
  2756. { skip leading spaces }
  2757. while pc^ in [' ',#9,#13] do
  2758. inc(pc);
  2759. case pc^ of
  2760. #0 :
  2761. break;
  2762. '"' :
  2763. begin
  2764. quote:=['"'];
  2765. inc(pc);
  2766. end;
  2767. '''' :
  2768. begin
  2769. quote:=[''''];
  2770. inc(pc);
  2771. end;
  2772. else
  2773. quote:=[' ',#9,#13];
  2774. end;
  2775. { scan until the end of the argument }
  2776. argstart:=pc;
  2777. while (pc^<>#0) and not(pc^ in quote) do
  2778. inc(pc);
  2779. { create argument }
  2780. arglen:=pc-argstart;
  2781. { TODO: FIXME: silent truncation of environment parameters }
  2782. if (arglen > 255) then
  2783. arglen := 255;
  2784. setlength(hs,arglen);
  2785. move(argstart^,hs[1],arglen);
  2786. interpret_option(hs,true);
  2787. { skip quote }
  2788. if pc^ in quote then
  2789. inc(pc);
  2790. until false;
  2791. end
  2792. else
  2793. Message1(option_no_option_found,'(env) '+envname);
  2794. FreeEnvPChar(env);
  2795. end;
  2796. procedure toption.read_parameters;
  2797. var
  2798. opts : TCmdStr;
  2799. paramindex : longint;
  2800. begin
  2801. paramindex:=0;
  2802. while paramindex<paramcount do
  2803. begin
  2804. inc(paramindex);
  2805. opts:=objpas.paramstr(paramindex);
  2806. if length(opts)>0 then
  2807. case opts[1] of
  2808. '@' :
  2809. if not firstpass then
  2810. begin
  2811. Delete(opts,1,1);
  2812. Message1(option_reading_further_from,opts);
  2813. interpret_file(opts);
  2814. end;
  2815. '!' :
  2816. if not firstpass then
  2817. begin
  2818. Delete(opts,1,1);
  2819. Message1(option_reading_further_from,'(env) '+opts);
  2820. interpret_envvar(opts);
  2821. end;
  2822. else
  2823. interpret_option(opts,true);
  2824. end;
  2825. end;
  2826. end;
  2827. procedure toption.parsecmd(cmd:TCmdStr);
  2828. var
  2829. i,ps : longint;
  2830. opts : TCmdStr;
  2831. begin
  2832. while (cmd<>'') do
  2833. begin
  2834. while cmd[1]=' ' do
  2835. delete(cmd,1,1);
  2836. i:=pos(' ',cmd);
  2837. if i=0 then
  2838. i:=2147483647;
  2839. opts:=Copy(cmd,1,i-1);
  2840. Delete(cmd,1,i);
  2841. case opts[1] of
  2842. '@' :
  2843. if not firstpass then
  2844. begin
  2845. Delete(opts,1,1);
  2846. Message1(option_reading_further_from,opts);
  2847. interpret_file(opts);
  2848. end;
  2849. '!' :
  2850. if not firstpass then
  2851. begin
  2852. Delete(opts,1,1);
  2853. Message1(option_reading_further_from,'(env) '+opts);
  2854. interpret_envvar(opts);
  2855. end;
  2856. '"' :
  2857. begin
  2858. Delete(opts,1,1);
  2859. ps:=pos('"',cmd);
  2860. if (i<>256) and (ps>0) then
  2861. begin
  2862. opts:=opts + ' '+ copy(cmd,1,ps-1);
  2863. cmd:=copy(cmd,ps+1,255);
  2864. end;
  2865. interpret_option(opts,true);
  2866. end;
  2867. else
  2868. interpret_option(opts,true);
  2869. end;
  2870. end;
  2871. end;
  2872. procedure toption.writequickinfo;
  2873. var
  2874. s : string;
  2875. i : longint;
  2876. procedure addinfo(const hs:string);
  2877. begin
  2878. if s<>'' then
  2879. s:=s+' '+hs
  2880. else
  2881. s:=hs;
  2882. end;
  2883. begin
  2884. s:='';
  2885. i:=0;
  2886. while (i<length(quickinfo)) do
  2887. begin
  2888. inc(i);
  2889. case quickinfo[i] of
  2890. 'S' :
  2891. begin
  2892. inc(i);
  2893. case quickinfo[i] of
  2894. 'O' :
  2895. addinfo(lower(source_info.shortname));
  2896. 'P' :
  2897. addinfo(source_cpu_string);
  2898. else
  2899. IllegalPara('-i'+QuickInfo);
  2900. end;
  2901. end;
  2902. 'T' :
  2903. begin
  2904. inc(i);
  2905. case quickinfo[i] of
  2906. 'O' :
  2907. addinfo(lower(target_info.shortname));
  2908. 'P' :
  2909. AddInfo(target_cpu_string);
  2910. else
  2911. IllegalPara('-i'+QuickInfo);
  2912. end;
  2913. end;
  2914. 'V' :
  2915. AddInfo(version_string);
  2916. 'W' :
  2917. AddInfo(full_version_string);
  2918. 'D' :
  2919. AddInfo(date_string);
  2920. '_' :
  2921. ;
  2922. else
  2923. IllegalPara('-i'+QuickInfo);
  2924. end;
  2925. end;
  2926. if s<>'' then
  2927. begin
  2928. writeln(s);
  2929. stopoptions(0);
  2930. end;
  2931. end;
  2932. procedure TOption.TargetOptions(def:boolean);
  2933. var
  2934. s : string;
  2935. i : integer;
  2936. target_unsup_features : tfeatures;
  2937. begin
  2938. if def then
  2939. def_system_macro(target_info.shortname)
  2940. else
  2941. undef_system_macro(target_info.shortname);
  2942. s:=target_info.extradefines;
  2943. while (s<>'') do
  2944. begin
  2945. i:=pos(';',s);
  2946. if i=0 then
  2947. i:=length(s)+1;
  2948. if def then
  2949. def_system_macro(Copy(s,1,i-1))
  2950. else
  2951. undef_system_macro(Copy(s,1,i-1));
  2952. delete(s,1,i);
  2953. end;
  2954. if (tf_winlikewidestring in target_info.flags) then
  2955. if def then
  2956. def_system_macro('FPC_WINLIKEWIDESTRING')
  2957. else
  2958. undef_system_macro('FPC_WINLIKEWIDESTRING');
  2959. if (tf_requires_proper_alignment in target_info.flags) then
  2960. if def then
  2961. def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT')
  2962. else
  2963. undef_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
  2964. if source_info.system<>target_info.system then
  2965. if def then
  2966. def_system_macro('FPC_CROSSCOMPILING')
  2967. else
  2968. undef_system_macro('FPC_CROSSCOMPILING');
  2969. if source_info.cpu<>target_info.cpu then
  2970. if def then
  2971. def_system_macro('FPC_CPUCROSSCOMPILING')
  2972. else
  2973. def_system_macro('FPC_CPUCROSSCOMPILING');
  2974. if (tf_no_generic_stackcheck in target_info.flags) then
  2975. if def then
  2976. def_system_macro('FPC_NO_GENERIC_STACK_CHECK')
  2977. else
  2978. undef_system_macro('FPC_NO_GENERIC_STACK_CHECK');
  2979. if (tf_section_threadvars in target_info.flags) then
  2980. if def then
  2981. def_system_macro('FPC_SECTION_THREADVARS')
  2982. else
  2983. undef_system_macro('FPC_SECTION_THREADVARS');
  2984. { Code generation flags }
  2985. if (tf_pic_default in target_info.flags) then
  2986. if def then
  2987. include(init_settings.moduleswitches,cs_create_pic)
  2988. else
  2989. exclude(init_settings.moduleswitches,cs_create_pic);
  2990. { Resources support }
  2991. if (tf_has_winlike_resources in target_info.flags) then
  2992. if def then
  2993. def_system_macro('FPC_HAS_WINLIKERESOURCES')
  2994. else
  2995. undef_system_macro('FPC_HAS_WINLIKERESOURCES');
  2996. { Features }
  2997. case target_info.system of
  2998. system_arm_gba:
  2999. target_unsup_features:=[f_dynlibs];
  3000. system_arm_nds:
  3001. target_unsup_features:=[f_threading,f_commandargs,f_fileio,f_textio,f_consoleio,f_dynlibs];
  3002. system_i386_nativent:
  3003. // until these features are implemented, they are disabled in the compiler
  3004. target_unsup_features:=[f_stackcheck];
  3005. system_i8086_msdos:
  3006. target_unsup_features:=[f_threading,f_dynlibs];
  3007. system_jvm_java32,
  3008. system_jvm_android32:
  3009. target_unsup_features:=[f_heap,f_textio,f_consoleio,f_fileio,
  3010. f_variants,f_objects,f_commandargs,
  3011. f_processes,f_stackcheck,f_dynlibs,f_softfpu,f_objectivec1,f_resources];
  3012. else
  3013. target_unsup_features:=[];
  3014. end;
  3015. if def then
  3016. features:=features-target_unsup_features
  3017. else
  3018. features:=features+target_unsup_features;
  3019. {$if defined(atari) or defined(hasamiga)}
  3020. { enable vlink as default linker on Atari, Amiga, and MorphOS, but not for cross compilers (for now) }
  3021. if (target_info.system in [system_m68k_amiga,system_m68k_atari,
  3022. system_powerpc_amiga,system_powerpc_morphos]) and
  3023. not LinkerSetExplicitly then
  3024. include(init_settings.globalswitches,cs_link_vlink);
  3025. {$endif}
  3026. end;
  3027. procedure TOption.checkoptionscompatibility;
  3028. begin
  3029. {$ifdef i8086}
  3030. if (apptype=app_com) and (init_settings.x86memorymodel<>mm_tiny) then
  3031. begin
  3032. Message(option_com_files_require_tiny_model);
  3033. StopOptions(1);
  3034. end;
  3035. {$endif i8086}
  3036. if (paratargetdbg in [dbg_dwarf2,dbg_dwarf3]) and
  3037. not(target_info.system in (systems_darwin+[system_i8086_msdos,system_i8086_embedded])) then
  3038. begin
  3039. { smartlink creation does not yet work with DWARF
  3040. debug info on most targets, but it works in internal assembler }
  3041. if (cs_create_smart in init_settings.moduleswitches) and
  3042. not (af_outputbinary in target_asm.flags) then
  3043. begin
  3044. Message(option_dwarf_smartlink_creation);
  3045. exclude(init_settings.moduleswitches,cs_create_smart);
  3046. end;
  3047. { smart linking does not yet work with DWARF debug info on most targets }
  3048. if (cs_link_smart in init_settings.globalswitches) then
  3049. begin
  3050. Message(option_dwarf_smart_linking);
  3051. ForceStaticLinking;
  3052. end;
  3053. end;
  3054. { external debug info is only supported for DWARF on darwin }
  3055. if (target_info.system in systems_darwin) and
  3056. (cs_link_separate_dbg_file in init_settings.globalswitches) and
  3057. not(paratargetdbg in [dbg_dwarf2,dbg_dwarf3]) then
  3058. begin
  3059. Message(option_debug_external_unsupported);
  3060. exclude(init_settings.globalswitches,cs_link_separate_dbg_file);
  3061. end;
  3062. { Also create a smartlinked version, on an assembler that
  3063. does not support smartlink sections like nasm?
  3064. This is not compatible with using internal linker. }
  3065. if ((cs_link_smart in init_settings.globalswitches) or
  3066. (cs_create_smart in init_settings.moduleswitches)) and
  3067. (af_needar in target_asm.flags) and
  3068. not (af_smartlink_sections in target_asm.flags) and
  3069. not (cs_link_extern in init_settings.globalswitches) and
  3070. (target_info.link<>ld_none) and
  3071. not (cs_link_nolink in init_settings.globalswitches) then
  3072. begin
  3073. Message(option_smart_link_requires_external_linker);
  3074. include(init_settings.globalswitches,cs_link_extern);
  3075. end;
  3076. end;
  3077. constructor TOption.create;
  3078. begin
  3079. LogoWritten:=false;
  3080. NoPressEnter:=false;
  3081. FirstPass:=false;
  3082. ABISetExplicitly:=false;
  3083. FPUSetExplicitly:=false;
  3084. CPUSetExplicitly:=false;
  3085. OptCPUSetExplicitly:=false;
  3086. FileLevel:=0;
  3087. Quickinfo:='';
  3088. ParaIncludeCfgPath:=TSearchPathList.Create;
  3089. ParaIncludePath:=TSearchPathList.Create;
  3090. ParaObjectPath:=TSearchPathList.Create;
  3091. ParaUnitPath:=TSearchPathList.Create;
  3092. ParaLibraryPath:=TSearchPathList.Create;
  3093. ParaFrameworkPath:=TSearchPathList.Create;
  3094. parapackagepath:=TSearchPathList.Create;
  3095. parapackages:=TFPHashObjectList.Create;
  3096. FillChar(ParaAlignment,sizeof(ParaAlignment),0);
  3097. MacVersionSet:=false;
  3098. paratarget:=system_none;
  3099. paratargetasm:=as_none;
  3100. paratargetdbg:=dbg_none;
  3101. LinkTypeSetExplicitly:=false;
  3102. LinkerSetExplicitly:=false;
  3103. end;
  3104. destructor TOption.destroy;
  3105. begin
  3106. ParaIncludeCfgPath.Free;
  3107. ParaIncludePath.Free;
  3108. ParaObjectPath.Free;
  3109. ParaUnitPath.Free;
  3110. ParaLibraryPath.Free;
  3111. ParaFrameworkPath.Free;
  3112. parapackagepath.Free;
  3113. ParaPackages.Free;
  3114. end;
  3115. {****************************************************************************
  3116. Callable Routines
  3117. ****************************************************************************}
  3118. function check_configfile(fn:string; var foundfn:string):boolean;
  3119. function CfgFileExists(const fn:string):boolean;
  3120. begin
  3121. Comment(V_Tried,'Configfile search: '+fn);
  3122. CfgFileExists:=FileExists(fn);
  3123. end;
  3124. var
  3125. {$ifdef Unix}
  3126. hs,
  3127. {$endif Unix}
  3128. configpath : string;
  3129. begin
  3130. foundfn:=fn;
  3131. check_configfile:=true;
  3132. { retrieve configpath }
  3133. configpath:=FixPath(GetEnvironmentVariable('PPC_CONFIG_PATH'),false);
  3134. {$ifdef Unix}
  3135. if configpath='' then
  3136. configpath:=ExpandFileName(FixPath(exepath+'../etc/',false));
  3137. {$endif}
  3138. {
  3139. Order to read configuration file :
  3140. try reading fpc.cfg in :
  3141. 1 - current dir
  3142. 2 - configpath
  3143. 3 - compiler path
  3144. }
  3145. if not FileExists(fn) then
  3146. begin
  3147. {$ifdef Unix}
  3148. hs:=GetEnvironmentVariable('HOME');
  3149. if (hs<>'') and CfgFileExists(FixPath(hs,false)+'.'+fn) then
  3150. foundfn:=FixPath(hs,false)+'.'+fn
  3151. else
  3152. {$endif}
  3153. if CfgFileExists(configpath+fn) then
  3154. foundfn:=configpath+fn
  3155. else
  3156. {$ifdef WINDOWS}
  3157. if (GetEnvironmentVariable('USERPROFILE')<>'') and CfgFileExists(FixPath(GetEnvironmentVariable('USERPROFILE'),false)+fn) then
  3158. foundfn:=FixPath(GetEnvironmentVariable('USERPROFILE'),false)+fn
  3159. else
  3160. if (GetEnvironmentVariable('ALLUSERSPROFILE')<>'') and CfgFileExists(FixPath(GetEnvironmentVariable('ALLUSERSPROFILE'),false)+fn) then
  3161. foundfn:=FixPath(GetEnvironmentVariable('ALLUSERSPROFILE'),false)+fn
  3162. else
  3163. {$endif WINDOWS}
  3164. {$ifndef Unix}
  3165. if CfgFileExists(exepath+fn) then
  3166. foundfn:=exepath+fn
  3167. else
  3168. {$else}
  3169. if CfgFileExists('/etc/'+fn) then
  3170. foundfn:='/etc/'+fn
  3171. else
  3172. {$endif}
  3173. check_configfile:=false;
  3174. end;
  3175. end;
  3176. procedure read_arguments(cmd:TCmdStr);
  3177. var
  3178. env: ansistring;
  3179. i : tfeature;
  3180. j : longint;
  3181. abi : tabi;
  3182. {$if defined(cpucapabilities)}
  3183. cpuflag : tcpuflags;
  3184. hs : string;
  3185. {$endif defined(cpucapabilities)}
  3186. begin
  3187. option:=coption.create;
  3188. disable_configfile:=false;
  3189. { Non-core target defines }
  3190. Option.TargetOptions(true);
  3191. { get default messagefile }
  3192. msgfilename:=GetEnvironmentVariable('PPC_ERROR_FILE');
  3193. { default configfile can be specified on the commandline,
  3194. remove it first }
  3195. if (cmd<>'') and (cmd[1]='[') then
  3196. begin
  3197. ppccfg:=Copy(cmd,2,pos(']',cmd)-2);
  3198. Delete(cmd,1,pos(']',cmd));
  3199. end
  3200. else
  3201. ppccfg:='fpc.cfg';
  3202. { first pass reading of parameters, only -i -v -T etc.}
  3203. option.firstpass:=true;
  3204. if cmd<>'' then
  3205. option.parsecmd(cmd)
  3206. else
  3207. begin
  3208. option.read_parameters;
  3209. { Write only quickinfo }
  3210. if option.quickinfo<>'' then
  3211. option.writequickinfo;
  3212. end;
  3213. option.firstpass:=false;
  3214. { redefine target options so all defines are written even if no -Txxx is passed on the command line }
  3215. Option.TargetOptions(true);
  3216. { target is set here, for wince the default app type is gui }
  3217. if target_info.system in systems_wince then
  3218. SetApptype(app_gui)
  3219. else
  3220. SetApptype(apptype);
  3221. { default defines }
  3222. def_system_macro(target_info.shortname);
  3223. def_system_macro('FPC');
  3224. def_system_macro('VER'+version_nr);
  3225. def_system_macro('VER'+version_nr+'_'+release_nr);
  3226. def_system_macro('VER'+version_nr+'_'+release_nr+'_'+patch_nr);
  3227. { Temporary defines, until things settle down }
  3228. def_system_macro('FPC_HAS_OPERATOR_ENUMERATOR');
  3229. def_system_macro('FPC_HAS_CONSTREF');
  3230. def_system_macro('FPC_STATICRIPFIXED');
  3231. def_system_macro('FPC_VARIANTCOPY_FIXED');
  3232. def_system_macro('FPC_DYNARRAYCOPY_FIXED');
  3233. {$if defined(avr)}
  3234. def_system_macro('FPC_HAS_INTERNAL_ABS_SHORTINT');
  3235. {$endif}
  3236. {$if defined(i8086) or defined(avr)}
  3237. def_system_macro('FPC_HAS_INTERNAL_ABS_SMALLINT');
  3238. {$endif i8086 or avr}
  3239. { abs(long) is handled internally on all CPUs }
  3240. def_system_macro('FPC_HAS_INTERNAL_ABS_LONG');
  3241. {$if defined(x86_64) or defined(powerpc64) or defined(cpuaarch64)}
  3242. def_system_macro('FPC_HAS_INTERNAL_ABS_INT64');
  3243. {$endif x86_64 or powerpc64 or aarch64}
  3244. def_system_macro('FPC_HAS_MANAGEMENT_OPERATORS');
  3245. def_system_macro('FPC_HAS_UNICODESTRING');
  3246. def_system_macro('FPC_RTTI_PACKSET1');
  3247. def_system_macro('FPC_HAS_CPSTRING');
  3248. {$ifdef x86_64}
  3249. def_system_macro('FPC_HAS_RIP_RELATIVE');
  3250. {$endif x86_64}
  3251. def_system_macro('FPC_HAS_CEXTENDED');
  3252. def_system_macro('FPC_HAS_RESSTRINITS');
  3253. { these cpus have an inline rol/ror implementaion }
  3254. {$ifdef cpurox}
  3255. {$ifdef m68k}
  3256. if CPUM68K_HAS_ROLROR in cpu_capabilities[init_settings.cputype] then
  3257. def_system_macro('FPC_HAS_INTERNAL_ROX');
  3258. {$else}
  3259. def_system_macro('FPC_HAS_INTERNAL_ROX');
  3260. {$endif}
  3261. {$endif}
  3262. { these cpus have an inline sar implementaion }
  3263. { currently, all supported CPUs have an internal sar implementation }
  3264. { $if defined(x86) or defined(arm) or defined(powerpc) or defined(powerpc64) or defined(sparc) or defined(mips)}
  3265. def_system_macro('FPC_HAS_INTERNAL_SAR');
  3266. { $endif}
  3267. {$ifdef powerpc64}
  3268. def_system_macro('FPC_HAS_LWSYNC');
  3269. {$endif}
  3270. def_system_macro('FPC_HAS_MEMBAR');
  3271. def_system_macro('FPC_SETBASE_USED');
  3272. {$ifdef SUPPORT_GET_FRAME}
  3273. def_system_macro('INTERNAL_BACKTRACE');
  3274. {$endif SUPPORT_GET_FRAME}
  3275. def_system_macro('STR_CONCAT_PROCS');
  3276. {$warnings off}
  3277. if pocall_default = pocall_register then
  3278. def_system_macro('REGCALL');
  3279. {$warnings on}
  3280. { don't remove this, it's also for fpdoc necessary (FK) }
  3281. def_system_macro('FPC_HAS_FEATURE_SUPPORT');
  3282. { using a case is pretty useless here (FK) }
  3283. { some stuff for TP compatibility }
  3284. {$ifdef i386}
  3285. def_system_macro('CPU86');
  3286. def_system_macro('CPU87');
  3287. def_system_macro('CPU386');
  3288. {$endif}
  3289. { new processor stuff }
  3290. {$ifdef i386}
  3291. def_system_macro('CPUI386');
  3292. def_system_macro('CPU32');
  3293. def_system_macro('CPUX86');
  3294. def_system_macro('FPC_HAS_TYPE_EXTENDED');
  3295. def_system_macro('FPC_HAS_TYPE_DOUBLE');
  3296. def_system_macro('FPC_HAS_TYPE_SINGLE');
  3297. {$endif}
  3298. {$ifdef m68k}
  3299. def_system_macro('CPU68');
  3300. def_system_macro('CPU68K');
  3301. def_system_macro('CPUM68K');
  3302. def_system_macro('CPU32');
  3303. def_system_macro('FPC_CURRENCY_IS_INT64');
  3304. def_system_macro('FPC_COMP_IS_INT64');
  3305. {$endif}
  3306. {$ifdef powerpc}
  3307. def_system_macro('CPUPOWERPC');
  3308. def_system_macro('CPUPOWERPC32');
  3309. def_system_macro('CPU32');
  3310. def_system_macro('FPC_CURRENCY_IS_INT64');
  3311. def_system_macro('FPC_COMP_IS_INT64');
  3312. {$endif}
  3313. {$ifdef POWERPC64}
  3314. def_system_macro('CPUPOWERPC');
  3315. def_system_macro('CPUPOWERPC64');
  3316. def_system_macro('CPU64');
  3317. def_system_macro('FPC_CURRENCY_IS_INT64');
  3318. def_system_macro('FPC_COMP_IS_INT64');
  3319. {$endif}
  3320. {$ifdef x86_64}
  3321. def_system_macro('CPUX86_64');
  3322. def_system_macro('CPUAMD64');
  3323. def_system_macro('CPU64');
  3324. def_system_macro('CPUX64');
  3325. { not supported for now, afaik (FK)
  3326. def_system_macro('FPC_HAS_TYPE_FLOAT128'); }
  3327. {$ifndef FPC_SUPPORT_X87_TYPES_ON_WIN64}
  3328. { normally, win64 doesn't support the legacy fpu }
  3329. if target_info.system=system_x86_64_win64 then
  3330. begin
  3331. def_system_macro('FPC_CURRENCY_IS_INT64');
  3332. def_system_macro('FPC_COMP_IS_INT64');
  3333. end;
  3334. {$endif FPC_SUPPORT_X87_TYPES_ON_WIN64}
  3335. {$endif}
  3336. {$ifdef sparc}
  3337. def_system_macro('CPUSPARCGEN');
  3338. def_system_macro('CPUSPARC');
  3339. def_system_macro('CPUSPARC32');
  3340. def_system_macro('CPU32');
  3341. def_system_macro('FPC_CURRENCY_IS_INT64');
  3342. def_system_macro('FPC_COMP_IS_INT64');
  3343. {$endif}
  3344. {$ifdef sparc64}
  3345. def_system_macro('CPUSPARCGEN');
  3346. def_system_macro('CPUSPARC64');
  3347. def_system_macro('CPU64');
  3348. def_system_macro('FPC_CURRENCY_IS_INT64');
  3349. def_system_macro('FPC_COMP_IS_INT64');
  3350. {$endif}
  3351. {$ifdef arm}
  3352. def_system_macro('CPUARM');
  3353. def_system_macro('CPU32');
  3354. def_system_macro('FPC_CURRENCY_IS_INT64');
  3355. def_system_macro('FPC_COMP_IS_INT64');
  3356. {$endif arm}
  3357. {$ifdef avr}
  3358. def_system_macro('CPUAVR');
  3359. def_system_macro('CPU16');
  3360. def_system_macro('FPC_CURRENCY_IS_INT64');
  3361. def_system_macro('FPC_COMP_IS_INT64');
  3362. {$endif avr}
  3363. {$ifdef jvm}
  3364. def_system_macro('CPUJVM');
  3365. def_system_macro('CPU32');
  3366. def_system_macro('FPC_CURRENCY_IS_INT64');
  3367. def_system_macro('FPC_COMP_IS_INT64');
  3368. {$endif jvm}
  3369. {$ifdef mipsel}
  3370. def_system_macro('CPUMIPS');
  3371. def_system_macro('CPUMIPS32');
  3372. def_system_macro('CPUMIPSEL');
  3373. def_system_macro('CPUMIPSEL32');
  3374. def_system_macro('CPU32');
  3375. def_system_macro('FPC_HAS_TYPE_DOUBLE');
  3376. def_system_macro('FPC_HAS_TYPE_SINGLE');
  3377. def_system_macro('FPC_INCLUDE_SOFTWARE_INT64_TO_DOUBLE');
  3378. def_system_macro('FPC_CURRENCY_IS_INT64');
  3379. def_system_macro('FPC_COMP_IS_INT64');
  3380. def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
  3381. { On most systems, locals are accessed relative to base pointer,
  3382. but for MIPS cpu, they are accessed relative to stack pointer.
  3383. This needs adaptation for so low level routines,
  3384. like MethodPointerLocal and related objects unit functions. }
  3385. def_system_macro('FPC_LOCALS_ARE_STACK_REG_RELATIVE');
  3386. {$endif mipsel}
  3387. {$ifdef mipseb}
  3388. def_system_macro('CPUMIPS');
  3389. def_system_macro('CPUMIPS32');
  3390. def_system_macro('CPUMIPSEB');
  3391. def_system_macro('CPUMIPSEB32');
  3392. def_system_macro('CPU32');
  3393. def_system_macro('FPC_HAS_TYPE_DOUBLE');
  3394. def_system_macro('FPC_HAS_TYPE_SINGLE');
  3395. def_system_macro('FPC_INCLUDE_SOFTWARE_INT64_TO_DOUBLE');
  3396. def_system_macro('FPC_CURRENCY_IS_INT64');
  3397. def_system_macro('FPC_COMP_IS_INT64');
  3398. def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
  3399. { See comment above for mipsel }
  3400. def_system_macro('FPC_LOCALS_ARE_STACK_REG_RELATIVE');
  3401. {$endif}
  3402. {$ifdef i8086}
  3403. def_system_macro('CPU86'); { Borland compatibility }
  3404. def_system_macro('CPU87'); { Borland compatibility }
  3405. def_system_macro('CPUI8086');
  3406. def_system_macro('CPU16');
  3407. def_system_macro('FPC_HAS_TYPE_EXTENDED');
  3408. def_system_macro('FPC_HAS_TYPE_DOUBLE');
  3409. def_system_macro('FPC_HAS_TYPE_SINGLE');
  3410. case init_settings.x86memorymodel of
  3411. mm_tiny: def_system_macro('FPC_MM_TINY');
  3412. mm_small: def_system_macro('FPC_MM_SMALL');
  3413. mm_medium: def_system_macro('FPC_MM_MEDIUM');
  3414. mm_compact: def_system_macro('FPC_MM_COMPACT');
  3415. mm_large: def_system_macro('FPC_MM_LARGE');
  3416. mm_huge: def_system_macro('FPC_MM_HUGE');
  3417. end;
  3418. {$endif i8086}
  3419. {$ifdef aarch64}
  3420. def_system_macro('CPUAARCH64');
  3421. def_system_macro('CPU64');
  3422. def_system_macro('FPC_CURRENCY_IS_INT64');
  3423. def_system_macro('FPC_COMP_IS_INT64');
  3424. {$endif aarch64}
  3425. {$if defined(cpu8bitalu)}
  3426. def_system_macro('CPUINT8');
  3427. {$elseif defined(cpu16bitalu)}
  3428. def_system_macro('CPUINT16');
  3429. {$elseif defined(cpu32bitalu)}
  3430. def_system_macro('CPUINT32');
  3431. {$elseif defined(cpu64bitalu)}
  3432. def_system_macro('CPUINT64');
  3433. {$endif defined(cpu64bitalu)}
  3434. if tf_cld in target_info.flags then
  3435. if not UpdateTargetSwitchStr('CLD', init_settings.targetswitches, true) then
  3436. InternalError(2013092801);
  3437. if tf_x86_far_procs_push_odd_bp in target_info.flags then
  3438. if not UpdateTargetSwitchStr('FARPROCSPUSHODDBP', init_settings.targetswitches, true) then
  3439. InternalError(2013092801);
  3440. { Set up a default prefix for binutils when cross-compiling }
  3441. if source_info.system<>target_info.system then
  3442. case target_info.system of
  3443. { Use standard Android NDK prefixes }
  3444. system_arm_android:
  3445. utilsprefix:='arm-linux-androideabi-';
  3446. system_i386_android:
  3447. utilsprefix:='i686-linux-android-';
  3448. system_mipsel_android:
  3449. utilsprefix:='mipsel-linux-android-';
  3450. end;
  3451. { Set up default value for the heap }
  3452. if target_info.system in systems_embedded then
  3453. begin
  3454. case target_info.system of
  3455. {$ifdef AVR}
  3456. system_avr_embedded:
  3457. if init_settings.controllertype=ct_avrsim then
  3458. heapsize:=8192
  3459. else
  3460. heapsize:=128;
  3461. {$endif AVR}
  3462. system_arm_embedded:
  3463. heapsize:=256;
  3464. system_mipsel_embedded:
  3465. heapsize:=256;
  3466. else
  3467. heapsize:=256;
  3468. end;
  3469. end;
  3470. { read configuration file }
  3471. if (not disable_configfile) and
  3472. (ppccfg<>'') then
  3473. read_configfile:=check_configfile(ppccfg,ppccfg)
  3474. else
  3475. read_configfile := false;
  3476. { Read commandline and configfile }
  3477. param_file:='';
  3478. { read configfile }
  3479. if read_configfile then
  3480. option.interpret_file(ppccfg);
  3481. { read parameters again to override config file }
  3482. if cmd<>'' then
  3483. option.parsecmd(cmd)
  3484. else
  3485. begin
  3486. { Write help pages if no parameters are passed }
  3487. if (paramcount=0) then
  3488. Option.WriteHelpPages;
  3489. option.read_parameters;
  3490. { Write only quickinfo }
  3491. if option.quickinfo<>'' then
  3492. option.writequickinfo;
  3493. end;
  3494. { check the compatibility of different options and adjust them if necessary
  3495. (and print possible errors)
  3496. }
  3497. option.checkoptionscompatibility;
  3498. { uses the CPUXXX-defines and target_info to determine whether the selected
  3499. target processor, if any, is supported }
  3500. Option.VerifyTargetProcessor;
  3501. { Stop if errors in options }
  3502. if ErrorCount>0 then
  3503. StopOptions(1);
  3504. { endian define }
  3505. case target_info.endian of
  3506. endian_little :
  3507. begin
  3508. def_system_macro('ENDIAN_LITTLE');
  3509. def_system_macro('FPC_LITTLE_ENDIAN');
  3510. end;
  3511. endian_big :
  3512. begin
  3513. def_system_macro('ENDIAN_BIG');
  3514. def_system_macro('FPC_BIG_ENDIAN');
  3515. end;
  3516. end;
  3517. { define abi }
  3518. for abi:=low(tabi) to high(tabi) do
  3519. undef_system_macro('FPC_ABI_'+abiinfo[abi].name);
  3520. def_system_macro('FPC_ABI_'+abiinfo[target_info.abi].name);
  3521. { Define FPC_ABI_EABI in addition to FPC_ABI_EABIHF on EABI VFP hardfloat
  3522. systems since most code needs to behave the same on both}
  3523. if target_info.abi = abi_eabihf then
  3524. def_system_macro('FPC_ABI_EABI');
  3525. { Write logo }
  3526. if option.ParaLogo then
  3527. option.writelogo;
  3528. { Check file to compile }
  3529. if param_file='' then
  3530. begin
  3531. Message(option_no_source_found);
  3532. StopOptions(1);
  3533. end;
  3534. {$ifndef Unix}
  3535. param_file:=FixFileName(param_file);
  3536. {$endif not unix}
  3537. inputfilepath:=ExtractFilePath(param_file);
  3538. inputfilename:=ExtractFileName(param_file);
  3539. if ExtractFileExt(inputfilename)='' then
  3540. begin
  3541. if FileExists(inputfilepath+ChangeFileExt(inputfilename,sourceext)) then
  3542. inputfilename:=ChangeFileExt(inputfilename,sourceext)
  3543. else if FileExists(inputfilepath+ChangeFileExt(inputfilename,pasext)) then
  3544. inputfilename:=ChangeFileExt(inputfilename,pasext)
  3545. else if ((m_mac in current_settings.modeswitches) or
  3546. (tf_p_ext_support in target_info.flags))
  3547. and FileExists(inputfilepath+ChangeFileExt(inputfilename,pext)) then
  3548. inputfilename:=ChangeFileExt(inputfilename,pext);
  3549. end;
  3550. { Check output dir }
  3551. if (OutputExeDir<>'') and
  3552. not PathExists(OutputExeDir,false) then
  3553. begin
  3554. Message1(general_e_path_does_not_exist,OutputExeDir);
  3555. StopOptions(1);
  3556. end;
  3557. { Add paths specified with parameters to the searchpaths }
  3558. UnitSearchPath.AddList(option.ParaUnitPath,true);
  3559. ObjectSearchPath.AddList(option.ParaObjectPath,true);
  3560. IncludeSearchPath.AddList(option.ParaIncludePath,true);
  3561. LibrarySearchPath.AddList(option.ParaLibraryPath,true);
  3562. FrameworkSearchPath.AddList(option.ParaFrameworkPath,true);
  3563. packagesearchpath.addlist(option.parapackagepath,true);
  3564. for j:=0 to option.parapackages.count-1 do
  3565. add_package(option.parapackages.NameOfIndex(j),true,true);
  3566. { add unit environment and exepath to the unit search path }
  3567. if inputfilepath<>'' then
  3568. Unitsearchpath.AddPath(inputfilepath,true);
  3569. if not disable_configfile then
  3570. begin
  3571. env:=GetEnvironmentVariable(target_info.unit_env);
  3572. if env<>'' then
  3573. UnitSearchPath.AddPath(GetEnvironmentVariable(target_info.unit_env),false);
  3574. end;
  3575. {$ifdef Unix}
  3576. fpcdir:=FixPath(GetEnvironmentVariable('FPCDIR'),false);
  3577. if fpcdir='' then
  3578. begin
  3579. if PathExists('/usr/local/lib/fpc/'+version_string,true) then
  3580. fpcdir:='/usr/local/lib/fpc/'+version_string+'/'
  3581. else
  3582. fpcdir:='/usr/lib/fpc/'+version_string+'/';
  3583. end;
  3584. {$else unix}
  3585. fpcdir:=FixPath(GetEnvironmentVariable('FPCDIR'),false);
  3586. if fpcdir='' then
  3587. begin
  3588. fpcdir:=ExePath+'../';
  3589. if not(PathExists(fpcdir+'units',true)) and
  3590. not(PathExists(fpcdir+'rtl',true)) then
  3591. fpcdir:=fpcdir+'../';
  3592. end;
  3593. {$endif unix}
  3594. { first try development RTL, else use the default installation path }
  3595. if not disable_configfile then
  3596. begin
  3597. if PathExists(FpcDir+'rtl',true) then
  3598. if (tf_use_8_3 in Source_Info.Flags) or
  3599. (tf_use_8_3 in Target_Info.Flags) then
  3600. UnitSearchPath.AddPath(FpcDir+'rtl/'+target_os_string,false)
  3601. else
  3602. UnitSearchPath.AddPath(FpcDir+'rtl/'+target_full_string,false)
  3603. else
  3604. if (tf_use_8_3 in Source_Info.Flags) or
  3605. (tf_use_8_3 in Target_Info.Flags) then
  3606. UnitSearchPath.AddPath(FpcDir+'units/'+target_os_string+'/rtl',false)
  3607. else
  3608. UnitSearchPath.AddPath(FpcDir+'units/'+target_full_string+'/rtl',false);
  3609. end;
  3610. { Add exepath if the exe is not in the current dir, because that is always searched already.
  3611. Do not add it when linking on the target because then we can maybe already find
  3612. .o files that are not for the target }
  3613. if (ExePath<>cfileutl.GetCurrentDir) and
  3614. not(cs_link_on_target in init_settings.globalswitches) then
  3615. UnitSearchPath.AddPath(ExePath,false);
  3616. { Add unit dir to the object and library path }
  3617. objectsearchpath.AddList(unitsearchpath,false);
  3618. librarysearchpath.AddList(unitsearchpath,false);
  3619. {$ifdef llvm}
  3620. { force llvm assembler writer }
  3621. option.paratargetasm:=as_llvm;
  3622. {$endif llvm}
  3623. { maybe override assembler }
  3624. if (option.paratargetasm<>as_none) then
  3625. begin
  3626. if not set_target_asm(option.paratargetasm) then
  3627. begin
  3628. Message2(option_incompatible_asm,asminfos[option.paratargetasm]^.idtxt,target_info.name);
  3629. set_target_asm(target_info.assemextern);
  3630. Message1(option_asm_forced,target_asm.idtxt);
  3631. end;
  3632. if (af_no_debug in asminfos[option.paratargetasm]^.flags) and
  3633. (option.paratargetdbg<>dbg_none) then
  3634. begin
  3635. Message1(option_confict_asm_debug,
  3636. asminfos[option.paratargetasm]^.idtxt);
  3637. option.paratargetdbg:=dbg_none;
  3638. exclude(init_settings.moduleswitches,cs_debuginfo);
  3639. end;
  3640. end;
  3641. {TOptionheck a second time as we might have changed assembler just above }
  3642. option.checkoptionscompatibility;
  3643. { maybe override debug info format }
  3644. if (option.paratargetdbg<>dbg_none) then
  3645. if not set_target_dbg(option.paratargetdbg) then
  3646. Message(option_w_unsupported_debug_format);
  3647. { switch assembler if it's binary and we got -a on the cmdline }
  3648. if (cs_asm_leave in init_settings.globalswitches) and
  3649. (af_outputbinary in target_asm.flags) then
  3650. begin
  3651. Message(option_switch_bin_to_src_assembler);
  3652. set_target_asm(target_info.assemextern);
  3653. { At least i8086 needs that for nasm and -CX
  3654. which is incompatible with internal linker }
  3655. option.checkoptionscompatibility;
  3656. end;
  3657. { Force use of external linker if there is no
  3658. internal linker or the linking is skipped }
  3659. if not(cs_link_extern in init_settings.globalswitches) and
  3660. ((target_info.link=ld_none) or
  3661. (cs_link_nolink in init_settings.globalswitches)) then
  3662. begin
  3663. include(init_settings.globalswitches,cs_link_extern);
  3664. end;
  3665. { turn off stripping if compiling with debuginfo or profile }
  3666. if (
  3667. (cs_debuginfo in init_settings.moduleswitches) or
  3668. (cs_profile in init_settings.moduleswitches)
  3669. ) and
  3670. not(cs_link_separate_dbg_file in init_settings.globalswitches) then
  3671. exclude(init_settings.globalswitches,cs_link_strip);
  3672. { set Mac OS X version default macros if not specified explicitly }
  3673. option.MaybeSetDefaultMacVersionMacro;
  3674. { force fpu emulation on arm/wince, arm/gba, arm/embedded and arm/nds
  3675. if fpu type not explicitly set }
  3676. if not(option.FPUSetExplicitly) and
  3677. ((target_info.system in [system_arm_wince,system_arm_gba,
  3678. system_m68k_amiga,system_m68k_atari,system_m68k_linux,
  3679. system_arm_nds,system_arm_embedded])
  3680. {$ifdef arm}
  3681. or (target_info.abi=abi_eabi)
  3682. {$endif arm}
  3683. )
  3684. {$if defined(arm) or defined (m68k)}
  3685. or (init_settings.fputype=fpu_soft)
  3686. {$endif arm or m68k}
  3687. then
  3688. begin
  3689. {$ifdef cpufpemu}
  3690. include(init_settings.moduleswitches,cs_fp_emulation);
  3691. { cs_fp_emulation and fpu_soft are equal on arm and m68k }
  3692. init_settings.fputype:=fpu_soft;
  3693. {$endif cpufpemu}
  3694. end;
  3695. {$ifdef i386}
  3696. case target_info.system of
  3697. system_i386_android:
  3698. begin
  3699. { set default cpu type to PentiumM for Android unless specified otherwise }
  3700. if not option.CPUSetExplicitly then
  3701. init_settings.cputype:=cpu_PentiumM;
  3702. if not option.OptCPUSetExplicitly then
  3703. init_settings.optimizecputype:=cpu_PentiumM;
  3704. { set default fpu type to SSSE3 for Android unless specified otherwise }
  3705. if not option.FPUSetExplicitly then
  3706. init_settings.fputype:=fpu_ssse3;
  3707. end;
  3708. end;
  3709. {$endif i386}
  3710. {$ifdef arm}
  3711. case target_info.system of
  3712. system_arm_darwin:
  3713. begin
  3714. { set default cpu type to ARMv7 for Darwin unless specified otherwise, and fpu
  3715. to VFPv3 (that's what all 32 bit ARM iOS devices use nowadays)
  3716. }
  3717. if not option.CPUSetExplicitly then
  3718. init_settings.cputype:=cpu_armv7;
  3719. if not option.OptCPUSetExplicitly then
  3720. init_settings.optimizecputype:=cpu_armv7;
  3721. if not option.FPUSetExplicitly then
  3722. init_settings.fputype:=fpu_vfpv3;
  3723. end;
  3724. system_arm_android:
  3725. begin
  3726. { set default cpu type to ARMv5T for Android unless specified otherwise }
  3727. if not option.CPUSetExplicitly then
  3728. init_settings.cputype:=cpu_armv5t;
  3729. if not option.OptCPUSetExplicitly then
  3730. init_settings.optimizecputype:=cpu_armv5t;
  3731. end;
  3732. end;
  3733. { ARMHF defaults }
  3734. if (target_info.abi = abi_eabihf) then
  3735. { set default cpu type to ARMv7a for ARMHF unless specified otherwise }
  3736. begin
  3737. {$ifdef CPUARMV6}
  3738. { if the compiler is built for armv6, then
  3739. inherit this setting, e.g. Raspian is armhf but
  3740. only armv6, this makes rebuilds of the compiler
  3741. easier }
  3742. if not option.CPUSetExplicitly then
  3743. init_settings.cputype:=cpu_armv6;
  3744. if not option.OptCPUSetExplicitly then
  3745. init_settings.optimizecputype:=cpu_armv6;
  3746. {$else CPUARMV6}
  3747. if not option.CPUSetExplicitly then
  3748. init_settings.cputype:=cpu_armv7a;
  3749. if not option.OptCPUSetExplicitly then
  3750. init_settings.optimizecputype:=cpu_armv7a;
  3751. {$endif CPUARMV6}
  3752. { Set FPU type }
  3753. if not(option.FPUSetExplicitly) then
  3754. begin
  3755. init_settings.fputype:=fpu_vfpv3_d16
  3756. end
  3757. else
  3758. begin
  3759. if not (init_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv3_d16,fpu_vfpv4]) then
  3760. begin
  3761. Message(option_illegal_fpu_eabihf);
  3762. StopOptions(1);
  3763. end;
  3764. end;
  3765. end;
  3766. if (init_settings.instructionset=is_thumb) and not(CPUARM_HAS_THUMB2 in cpu_capabilities[init_settings.cputype]) then
  3767. begin
  3768. def_system_macro('CPUTHUMB');
  3769. if not option.FPUSetExplicitly then
  3770. init_settings.fputype:=fpu_soft;
  3771. {$if defined(FPC_ARMEL) or defined(FPC_ARMHF)}
  3772. 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';
  3773. {$else FPC_ARMAL or FPC_ARMHF}
  3774. if target_info.endian=endian_little then
  3775. 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';
  3776. {$endif FPC_ARMAL or FPC_ARMHF}
  3777. end;
  3778. if (init_settings.instructionset=is_thumb) and (CPUARM_HAS_THUMB2 in cpu_capabilities[init_settings.cputype]) then
  3779. def_system_macro('CPUTHUMB2');
  3780. {$endif arm}
  3781. {$ifdef jvm}
  3782. { set default CPU type to Dalvik when targeting Android }
  3783. if target_info.system=system_jvm_android32 then
  3784. begin
  3785. if not option.CPUSetExplicitly then
  3786. init_settings.cputype:=cpu_dalvik;
  3787. end;
  3788. {$endif jvm}
  3789. {$ifdef llvm}
  3790. { standard extension for llvm bitcode files }
  3791. target_info.asmext:='.ll';
  3792. { don't generate dwarf cfi, llvm will do that }
  3793. exclude(target_info.flags,tf_needs_dwarf_cfi);
  3794. {$endif llvm}
  3795. {$ifdef mipsel}
  3796. case target_info.system of
  3797. system_mipsel_android:
  3798. begin
  3799. { set default cpu type to MIPS32 rev. 1 and hard float for MIPS-Android unless specified otherwise }
  3800. if not option.CPUSetExplicitly then
  3801. init_settings.cputype:=cpu_mips32;
  3802. if not option.OptCPUSetExplicitly then
  3803. init_settings.optimizecputype:=cpu_mips32;
  3804. if not option.FPUSetExplicitly then
  3805. init_settings.fputype:=fpu_mips2;
  3806. end;
  3807. system_mipsel_embedded:
  3808. begin
  3809. { set default cpu type to PIC32MX and softfloat for MIPSEL-EMBEDDED target unless specified otherwise }
  3810. if not option.CPUSetExplicitly then
  3811. init_settings.cputype:=cpu_pic32mx;
  3812. if not option.OptCPUSetExplicitly then
  3813. init_settings.optimizecputype:=cpu_pic32mx;
  3814. if not option.FPUSetExplicitly then
  3815. init_settings.fputype:=fpu_soft;
  3816. end;
  3817. end;
  3818. {$endif mipsel}
  3819. {$ifdef m68k}
  3820. if init_settings.cputype in cpu_coldfire then
  3821. def_system_macro('CPUCOLDFIRE');
  3822. {$endif m68k}
  3823. { now we can define cpu and fpu type }
  3824. def_system_macro('CPU'+Cputypestr[init_settings.cputype]);
  3825. { Use init_settings cpu type for asm cpu type,
  3826. if asmcputype is cpu_none,
  3827. at least as long as there is no explicit
  3828. option to set it on command line PM }
  3829. if init_settings.asmcputype = cpu_none then
  3830. init_settings.asmcputype:=init_settings.cputype;
  3831. def_system_macro('FPU'+fputypestr[init_settings.fputype]);
  3832. {$ifdef llvm}
  3833. def_system_macro('CPULLVM');
  3834. {$endif llvm}
  3835. {$if defined(cpucapabilities)}
  3836. for cpuflag:=low(cpuflag) to high(cpuflag) do
  3837. begin
  3838. str(cpuflag,hs);
  3839. if cpuflag in cpu_capabilities[init_settings.cputype] then
  3840. def_system_macro(hs)
  3841. else
  3842. undef_system_macro(hs);
  3843. end;
  3844. {$endif defined(cpucapabilities)}
  3845. if init_settings.fputype<>fpu_none then
  3846. begin
  3847. {$if defined(i386) or defined(i8086)}
  3848. def_system_macro('FPC_HAS_TYPE_EXTENDED');
  3849. {$endif}
  3850. def_system_macro('FPC_HAS_TYPE_SINGLE');
  3851. def_system_macro('FPC_HAS_TYPE_DOUBLE');
  3852. {$if not defined(i386) and not defined(x86_64) and not defined(i8086) and not defined(aarch64)}
  3853. def_system_macro('FPC_INCLUDE_SOFTWARE_INT64_TO_DOUBLE');
  3854. {$endif}
  3855. {$if defined(m68k)}
  3856. def_system_macro('FPC_INCLUDE_SOFTWARE_LONGWORD_TO_DOUBLE');
  3857. {$endif}
  3858. {$ifdef x86_64}
  3859. {$ifndef FPC_SUPPORT_X87_TYPES_ON_WIN64}
  3860. { normally, win64 doesn't support the legacy fpu }
  3861. if target_info.system=system_x86_64_win64 then
  3862. undef_system_macro('FPC_HAS_TYPE_EXTENDED')
  3863. else
  3864. {$endif FPC_SUPPORT_X87_TYPES_ON_WIN64}
  3865. def_system_macro('FPC_HAS_TYPE_EXTENDED');
  3866. {$endif}
  3867. end;
  3868. { Enable now for testing }
  3869. {$ifndef DISABLE_TLS_DIRECTORY}
  3870. if target_info.system in systems_windows then
  3871. def_system_macro('FPC_USE_TLS_DIRECTORY');
  3872. {$endif not DISABLE_TLS_DIRECTORY}
  3873. {$ifndef DISABLE_WIN64_SEH}
  3874. if target_info.system=system_x86_64_win64 then
  3875. def_system_macro('FPC_USE_WIN64_SEH');
  3876. {$endif DISABLE_WIN64_SEH}
  3877. {$ifdef TEST_WIN32_SEH}
  3878. if target_info.system=system_i386_win32 then
  3879. def_system_macro('FPC_USE_WIN32_SEH');
  3880. {$endif TEST_WIN32_SEH}
  3881. {$ifdef ARM}
  3882. { define FPC_DOUBLE_HILO_SWAPPED if needed to properly handle doubles in RTL }
  3883. if (init_settings.fputype in [fpu_fpa,fpu_fpa10,fpu_fpa11]) and
  3884. not(cs_fp_emulation in init_settings.moduleswitches) then
  3885. def_system_macro('FPC_DOUBLE_HILO_SWAPPED');
  3886. {$endif ARM}
  3887. { inline bsf/bsr implementation }
  3888. {$if not defined(llvm) and (defined(i386) or defined(x86_64) or defined(aarch64) or defined(powerpc) or defined(powerpc64))}
  3889. def_system_macro('FPC_HAS_INTERNAL_BSF');
  3890. def_system_macro('FPC_HAS_INTERNAL_BSR');
  3891. {$endif}
  3892. { hardware FMA support }
  3893. {$if defined(i386) or defined(x86_64)}
  3894. if (cpu_capabilities[current_settings.cputype]*[CPUX86_HAS_FMA,CPUX86_HAS_FMA4])<>[] then
  3895. begin
  3896. def_system_macro('FPC_HAS_FAST_FMA_SINGLE');
  3897. def_system_macro('FPC_HAS_FAST_FMA_DOUBLE');
  3898. end;
  3899. {$endif defined(i386) or defined(x86_64)}
  3900. {$if defined(arm)}
  3901. { it is determined during system unit compilation if clz is used for bsf or not,
  3902. this is not perfect but the current implementation bsf/bsr does not allow another
  3903. solution }
  3904. if (CPUARM_HAS_CLZ in cpu_capabilities[init_settings.cputype]) and
  3905. ((init_settings.instructionset=is_arm) or
  3906. (CPUARM_HAS_THUMB2 in cpu_capabilities[init_settings.cputype])) then
  3907. begin
  3908. def_system_macro('FPC_HAS_INTERNAL_BSR');
  3909. if CPUARM_HAS_RBIT in cpu_capabilities[init_settings.cputype] then
  3910. def_system_macro('FPC_HAS_INTERNAL_BSF');
  3911. end;
  3912. {$endif}
  3913. {$if defined(powerpc64)}
  3914. { on sysv targets, default to elfv2 for little endian and to elfv1 for
  3915. big endian (unless specified otherwise). As the gcc man page says:
  3916. "Overriding the default ABI requires special system support and is
  3917. likely to fail in spectacular ways" }
  3918. if not option.ABISetExplicitly then
  3919. begin
  3920. if (target_info.abi=abi_powerpc_sysv) and
  3921. (target_info.endian=endian_little) then
  3922. target_info.abi:=abi_powerpc_elfv2
  3923. else
  3924. if (target_info.abi=abi_powerpc_elfv2) and
  3925. (target_info.endian=endian_big) then
  3926. target_info.abi:=abi_powerpc_sysv
  3927. end;
  3928. {$endif}
  3929. {$if defined(powerpc) or defined(powerpc64)}
  3930. { define _CALL_ELF symbol like gcc }
  3931. case target_info.abi of
  3932. abi_powerpc_sysv:
  3933. set_system_compvar('_CALL_ELF','1');
  3934. abi_powerpc_elfv2:
  3935. set_system_compvar('_CALL_ELF','2');
  3936. end;
  3937. {$endif}
  3938. { Section smartlinking conflicts with import sections on Windows }
  3939. if GenerateImportSection and
  3940. (target_info.system in [system_i386_win32,system_x86_64_win64]) then
  3941. exclude(target_info.flags,tf_smartlink_sections);
  3942. if not option.LinkTypeSetExplicitly then
  3943. set_default_link_type;
  3944. { Default alignment settings,
  3945. 1. load the defaults for the target
  3946. 2. override with generic optimizer setting (little size)
  3947. 3. override with the user specified -Oa }
  3948. UpdateAlignment(init_settings.alignment,target_info.alignment);
  3949. if (cs_opt_size in init_settings.optimizerswitches) then
  3950. begin
  3951. init_settings.alignment.procalign:=1;
  3952. init_settings.alignment.jumpalign:=1;
  3953. init_settings.alignment.loopalign:=1;
  3954. {$ifdef x86}
  3955. { constalignmax=1 keeps the executable and thus the memory foot print small but
  3956. all processors except x86 are really hurt by this or might even crash }
  3957. init_settings.alignment.constalignmax:=1;
  3958. {$endif x86}
  3959. end;
  3960. UpdateAlignment(init_settings.alignment,option.paraalignment);
  3961. set_system_macro('FPC_VERSION',version_nr);
  3962. set_system_macro('FPC_RELEASE',release_nr);
  3963. set_system_macro('FPC_PATCH',patch_nr);
  3964. set_system_macro('FPC_FULLVERSION',Format('%d%.02d%.02d',[StrToInt(version_nr),StrToInt(release_nr),StrToInt(patch_nr)]));
  3965. if target_info.system in systems_indirect_entry_information then
  3966. def_system_macro('FPC_HAS_INDIRECT_ENTRY_INFORMATION');
  3967. if not (tf_winlikewidestring in target_info.flags) then
  3968. def_system_macro('FPC_WIDESTRING_EQUAL_UNICODESTRING');
  3969. if tf_supports_packages in target_info.flags then
  3970. def_system_macro('FPC_HAS_DYNAMIC_PACKAGES');
  3971. if target_info.system in systems_indirect_var_imports then
  3972. def_system_macro('FPC_HAS_INDIRECT_VAR_ACCESS');
  3973. for i:=low(tfeature) to high(tfeature) do
  3974. if i in features then
  3975. def_system_macro('FPC_HAS_FEATURE_'+featurestr[i]);
  3976. {$push}
  3977. {$warn 6018 off} { Unreachable code due to compile time evaluation }
  3978. if ControllerSupport and (target_info.system in systems_embedded) and
  3979. (init_settings.controllertype<>ct_none) then
  3980. begin
  3981. with embedded_controllers[init_settings.controllertype] do
  3982. begin
  3983. set_system_macro('FPC_FLASHBASE',tostr(flashbase));
  3984. set_system_macro('FPC_FLASHSIZE',tostr(flashsize));
  3985. set_system_macro('FPC_SRAMBASE',tostr(srambase));
  3986. set_system_macro('FPC_SRAMSIZE',tostr(sramsize));
  3987. set_system_macro('FPC_EEPROMBASE',tostr(eeprombase));
  3988. set_system_macro('FPC_EEPROMSIZE',tostr(eepromsize));
  3989. set_system_macro('FPC_BOOTBASE',tostr(bootbase));
  3990. set_system_macro('FPC_BOOTSIZE',tostr(bootsize));
  3991. end;
  3992. end;
  3993. {$pop}
  3994. option.free;
  3995. Option:=nil;
  3996. clearstack_pocalls := [pocall_cdecl,pocall_cppdecl,pocall_syscall,pocall_mwpascal,pocall_sysv_abi_cdecl,pocall_ms_abi_cdecl];
  3997. cdecl_pocalls := [pocall_cdecl, pocall_cppdecl, pocall_mwpascal, pocall_sysv_abi_cdecl, pocall_ms_abi_cdecl];
  3998. if (tf_safecall_clearstack in target_info.flags) then
  3999. begin
  4000. include (cdecl_pocalls, pocall_safecall);
  4001. include (clearstack_pocalls, pocall_safecall)
  4002. end;
  4003. end;
  4004. initialization
  4005. coption:=toption;
  4006. finalization
  4007. if assigned(option) then
  4008. option.free;
  4009. end.