options.pas 87 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711
  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. CClasses,cfileutl,
  22. globtype,globals,verbose,systems,cpuinfo, comprsrc;
  23. Type
  24. TOption=class
  25. FirstPass,
  26. ParaLogo,
  27. NoPressEnter,
  28. LogoWritten : boolean;
  29. FileLevel : longint;
  30. QuickInfo : string;
  31. ParaIncludePath,
  32. ParaUnitPath,
  33. ParaObjectPath,
  34. ParaLibraryPath,
  35. ParaFrameworkPath : TSearchPathList;
  36. ParaAlignment : TAlignmentInfo;
  37. Constructor Create;
  38. Destructor Destroy;override;
  39. procedure WriteLogo;
  40. procedure WriteInfo;
  41. procedure WriteHelpPages;
  42. procedure WriteQuickInfo;
  43. procedure IllegalPara(const opt:string);
  44. procedure UnsupportedPara(const opt:string);
  45. function Unsetbool(var Opts:TCmdStr; Pos: Longint):boolean;
  46. procedure interpret_option(const opt :string;ispara:boolean);
  47. procedure Interpret_envvar(const envname : string);
  48. procedure Interpret_file(const filename : string);
  49. procedure Read_Parameters;
  50. procedure parsecmd(cmd:string);
  51. procedure TargetOptions(def:boolean);
  52. end;
  53. TOptionClass=class of toption;
  54. var
  55. coption : TOptionClass;
  56. procedure read_arguments(cmd:string);
  57. implementation
  58. uses
  59. widestr,
  60. {$ifdef VER2_2}ccharset{$else VER2_2}charset{$endif VER2_2},
  61. SysUtils,
  62. version,
  63. cutils,cmsgs,
  64. comphook,
  65. symtable,scanner,rabase,
  66. wpobase,
  67. i_bsd
  68. ;
  69. const
  70. page_size = 24;
  71. var
  72. option : toption;
  73. read_configfile, { read config file, set when a cfgfile is found }
  74. disable_configfile : boolean;
  75. fpcdir,
  76. ppccfg,
  77. ppcaltcfg,
  78. param_file : string; { file to compile specified on the commandline }
  79. {****************************************************************************
  80. Options not supported on all platforms
  81. ****************************************************************************}
  82. const
  83. { pointer checking (requires special code in FPC_CHECKPOINTER,
  84. and can never work for libc-based targets or any other program
  85. linking to an external library)
  86. }
  87. supported_targets_gc = [system_i386_linux,system_powerpc_linux]
  88. + [system_i386_win32]
  89. + [system_i386_GO32V2]
  90. + [system_i386_os2]
  91. + [system_i386_beos,system_i386_haiku]
  92. + [system_powerpc_morphos];
  93. { gprof (requires implementation of g_profilecode in the code generator) }
  94. supported_targets_pg = [system_i386_linux,system_x86_64_linux]
  95. + [system_i386_win32]
  96. + [system_powerpc_darwin,system_x86_64_darwin]
  97. + [system_i386_GO32V2]
  98. + [system_i386_freebsd]
  99. + [system_i386_netbsd]
  100. + [system_i386_wdosx];
  101. {****************************************************************************
  102. Defines
  103. ****************************************************************************}
  104. procedure set_default_link_type;
  105. begin
  106. undef_system_macro('FPC_LINK_SMART');
  107. def_system_macro('FPC_LINK_STATIC');
  108. undef_system_macro('FPC_LINK_DYNAMIC');
  109. init_settings.globalswitches:=init_settings.globalswitches+[cs_link_static];
  110. init_settings.globalswitches:=init_settings.globalswitches-[cs_link_shared,cs_link_smart];
  111. end;
  112. {****************************************************************************
  113. Toption
  114. ****************************************************************************}
  115. procedure StopOptions(err:longint);
  116. begin
  117. if assigned(Option) then
  118. begin
  119. Option.free;
  120. Option:=nil;
  121. end;
  122. raise ECompilerAbortSilent.Create;
  123. end;
  124. procedure Toption.WriteLogo;
  125. var
  126. p : pchar;
  127. begin
  128. if not LogoWritten then
  129. begin
  130. p:=MessagePchar(option_logo);
  131. while assigned(p) do
  132. Comment(V_Normal,GetMsgLine(p));
  133. LogoWritten:= true;
  134. end;
  135. end;
  136. procedure Toption.WriteInfo;
  137. var
  138. p : pchar;
  139. hs,hs1,s : TCmdStr;
  140. target : tsystem;
  141. cpu : tcputype;
  142. fpu : tfputype;
  143. opt : toptimizerswitch;
  144. wpopt: twpoptimizerswitch;
  145. abi : tabi;
  146. begin
  147. p:=MessagePchar(option_info);
  148. while assigned(p) do
  149. begin
  150. s:=GetMsgLine(p);
  151. { list OS Targets }
  152. if pos('$OSTARGETS',s)>0 then
  153. begin
  154. for target:=low(tsystem) to high(tsystem) do
  155. if assigned(targetinfos[target]) then
  156. begin
  157. hs:=s;
  158. hs1:=targetinfos[target]^.name;
  159. if tf_under_development in targetinfos[target]^.flags then
  160. hs1:=hs1+' (under development)';
  161. Replace(hs,'$OSTARGETS',hs1);
  162. Comment(V_Normal,hs);
  163. end;
  164. end
  165. else if pos('$INSTRUCTIONSETS',s)>0 then
  166. begin
  167. for cpu:=low(tcputype) to high(tcputype) do
  168. begin
  169. hs:=s;
  170. hs1:=cputypestr[cpu];
  171. if hs1<>'' then
  172. begin
  173. Replace(hs,'$INSTRUCTIONSETS',hs1);
  174. Comment(V_Normal,hs);
  175. end;
  176. end;
  177. end
  178. else if pos('$FPUINSTRUCTIONSETS',s)>0 then
  179. begin
  180. for fpu:=low(tfputype) to high(tfputype) do
  181. begin
  182. hs:=s;
  183. hs1:=fputypestr[fpu];
  184. if hs1<>'' then
  185. begin
  186. Replace(hs,'$FPUINSTRUCTIONSETS',hs1);
  187. Comment(V_Normal,hs);
  188. end;
  189. end;
  190. end
  191. else if pos('$ABITARGETS',s)>0 then
  192. begin
  193. for abi:=low(abi) to high(abi) do
  194. begin
  195. hs:=s;
  196. hs1:=abi2str[abi];
  197. if hs1<>'' then
  198. begin
  199. Replace(hs,'$ABITARGETS',hs1);
  200. Comment(V_Normal,hs);
  201. end;
  202. end;
  203. end
  204. else if pos('$OPTIMIZATIONS',s)>0 then
  205. begin
  206. for opt:=low(toptimizerswitch) to high(toptimizerswitch) do
  207. begin
  208. if opt in supported_optimizerswitches then
  209. begin
  210. hs:=s;
  211. hs1:=OptimizerSwitchStr[opt];
  212. if hs1<>'' then
  213. begin
  214. Replace(hs,'$OPTIMIZATIONS',hs1);
  215. Comment(V_Normal,hs);
  216. end;
  217. end;
  218. end;
  219. end
  220. else if pos('$WPOPTIMIZATIONS',s)>0 then
  221. begin
  222. for wpopt:=low(twpoptimizerswitch) to high(twpoptimizerswitch) do
  223. begin
  224. { currently all whole program optimizations are platform-independent
  225. if opt in supported_wpoptimizerswitches then
  226. }
  227. begin
  228. hs:=s;
  229. hs1:=WPOptimizerSwitchStr[wpopt];
  230. if hs1<>'' then
  231. begin
  232. Replace(hs,'$WPOPTIMIZATIONS',hs1);
  233. Comment(V_Normal,hs);
  234. end;
  235. end;
  236. end;
  237. end
  238. else
  239. Comment(V_Normal,s);
  240. end;
  241. StopOptions(0);
  242. end;
  243. procedure Toption.WriteHelpPages;
  244. function PadEnd(s:string;i:longint):string;
  245. begin
  246. while (length(s)<i) do
  247. s:=s+' ';
  248. PadEnd:=s;
  249. end;
  250. var
  251. lastident,
  252. j,outline,
  253. ident,
  254. lines : longint;
  255. show : boolean;
  256. opt : string[32];
  257. input,
  258. s : string;
  259. p : pchar;
  260. begin
  261. WriteLogo;
  262. Lines:=4;
  263. Message1(option_usage,FixFileName(system.paramstr(0)));
  264. lastident:=0;
  265. p:=MessagePChar(option_help_pages);
  266. while assigned(p) do
  267. begin
  268. { get a line and reset }
  269. s:=GetMsgLine(p);
  270. ident:=0;
  271. show:=false;
  272. { parse options }
  273. case s[1] of
  274. {$ifdef UNITALIASES}
  275. 'a',
  276. {$endif}
  277. {$ifdef EXTDEBUG}
  278. 'e',
  279. {$endif EXTDEBUG}
  280. {$ifdef i386}
  281. '3',
  282. {$endif}
  283. {$ifdef x86_64}
  284. '4',
  285. {$endif}
  286. {$ifdef m68k}
  287. '6',
  288. {$endif}
  289. {$ifdef arm}
  290. 'A',
  291. {$endif}
  292. {$ifdef powerpc}
  293. 'P',
  294. {$endif}
  295. {$ifdef powerpc64}
  296. 'p',
  297. {$endif}
  298. {$ifdef sparc}
  299. 'S',
  300. {$endif}
  301. {$ifdef vis}
  302. 'V',
  303. {$endif}
  304. '*' : show:=true;
  305. end;
  306. if show then
  307. begin
  308. case s[2] of
  309. 'g',
  310. {$ifdef Unix}
  311. 'L',
  312. {$endif}
  313. {$ifdef os2}
  314. 'O',
  315. {$endif}
  316. '*' : show:=true;
  317. else
  318. show:=false;
  319. end;
  320. end;
  321. { now we may show the message or not }
  322. if show then
  323. begin
  324. case s[3] of
  325. '0' : begin
  326. ident:=0;
  327. outline:=0;
  328. end;
  329. '1' : begin
  330. ident:=2;
  331. outline:=7;
  332. end;
  333. '2' : begin
  334. ident:=6;
  335. outline:=11;
  336. end;
  337. '3' : begin
  338. ident:=9;
  339. outline:=11;
  340. end;
  341. end;
  342. j:=pos('_',s);
  343. opt:=Copy(s,4,j-4);
  344. if opt='*' then
  345. opt:=''
  346. else
  347. if opt=' ' then
  348. opt:=PadEnd(opt,outline)
  349. else
  350. opt:=PadEnd('-'+opt,outline);
  351. if (ident=0) and (lastident<>0) then
  352. begin
  353. Comment(V_Normal,'');
  354. inc(Lines);
  355. end;
  356. { page full ? }
  357. if (lines >= page_size - 1) then
  358. begin
  359. if not NoPressEnter then
  360. begin
  361. Message(option_help_press_enter);
  362. readln(input);
  363. if upper(input)='Q' then
  364. StopOptions(0);
  365. end;
  366. lines:=0;
  367. end;
  368. Comment(V_Normal,PadEnd('',ident)+opt+Copy(s,j+1,255));
  369. LastIdent:=Ident;
  370. inc(Lines);
  371. end;
  372. end;
  373. StopOptions(0);
  374. end;
  375. procedure Toption.IllegalPara(const opt:string);
  376. begin
  377. Message1(option_illegal_para,opt);
  378. Message(option_help_pages_para);
  379. StopOptions(1);
  380. end;
  381. procedure toption.UnsupportedPara(const opt: string);
  382. begin
  383. Message1(option_unsupported_target,opt);
  384. StopOptions(1);
  385. end;
  386. function Toption.Unsetbool(var Opts:TCmdStr; Pos: Longint):boolean;
  387. { checks if the character after pos in Opts is a + or a - and returns resp.
  388. false or true. If it is another character (or none), it also returns false }
  389. begin
  390. UnsetBool := false;
  391. if Length(Opts)>Pos then
  392. begin
  393. inc(Pos);
  394. UnsetBool := Opts[Pos] = '-';
  395. if Opts[Pos] in ['-','+']then
  396. delete(Opts,Pos,1);
  397. end;
  398. end;
  399. procedure TOption.interpret_option(const opt:string;ispara:boolean);
  400. var
  401. code : integer;
  402. c : char;
  403. more : TCmdStr;
  404. major,minor : longint;
  405. error : integer;
  406. j,l : longint;
  407. d,s : TCmdStr;
  408. unicodemapping : punicodemap;
  409. begin
  410. if opt='' then
  411. exit;
  412. { only parse define,undef,target,verbosity,link etc options the firsttime }
  413. if firstpass and
  414. not(
  415. (opt[1]='-') and
  416. (
  417. ((length(opt)>1) and (opt[2] in ['i','d','v','T','u','n','X','l'])) or
  418. ((length(opt)>3) and (opt[2]='F') and (opt[3]='e'))
  419. )
  420. ) then
  421. exit;
  422. Message1(option_handling_option,opt);
  423. case opt[1] of
  424. '-' :
  425. begin
  426. more:=Copy(opt,3,255);
  427. if firstpass then
  428. Message1(option_interpreting_firstpass_option,opt)
  429. else
  430. Message1(option_interpreting_option,opt);
  431. case opt[2] of
  432. '?' :
  433. WriteHelpPages;
  434. 'a' :
  435. begin
  436. include(init_settings.globalswitches,cs_asm_leave);
  437. j:=1;
  438. while j<=length(more) do
  439. begin
  440. case more[j] of
  441. 'l' :
  442. include(init_settings.globalswitches,cs_asm_source);
  443. 'r' :
  444. include(init_settings.globalswitches,cs_asm_regalloc);
  445. 't' :
  446. include(init_settings.globalswitches,cs_asm_tempalloc);
  447. 'n' :
  448. include(init_settings.globalswitches,cs_asm_nodes);
  449. 'p' :
  450. begin
  451. exclude(init_settings.globalswitches,cs_asm_leave);
  452. if UnsetBool(More, 0) then
  453. exclude(init_settings.globalswitches,cs_asm_pipe)
  454. else
  455. include(init_settings.globalswitches,cs_asm_pipe);
  456. end;
  457. '-' :
  458. init_settings.globalswitches:=init_settings.globalswitches -
  459. [cs_asm_leave, cs_asm_source,cs_asm_regalloc, cs_asm_tempalloc,
  460. cs_asm_nodes, cs_asm_pipe];
  461. else
  462. IllegalPara(opt);
  463. end;
  464. inc(j);
  465. end;
  466. end;
  467. 'A' :
  468. begin
  469. paratargetasm:=find_asm_by_string(More);
  470. if paratargetasm=as_none then
  471. IllegalPara(opt);
  472. end;
  473. 'b' :
  474. begin
  475. // Message1(option_obsolete_switch,'-b');
  476. if UnsetBool(More,0) then
  477. begin
  478. init_settings.moduleswitches:=init_settings.moduleswitches-[cs_browser];
  479. init_settings.moduleswitches:=init_settings.moduleswitches-[cs_local_browser];
  480. end
  481. else
  482. begin
  483. init_settings.moduleswitches:=init_settings.moduleswitches+[cs_browser];
  484. end;
  485. if More<>'' then
  486. if (More='l') or (More='l+') then
  487. init_settings.moduleswitches:=init_settings.moduleswitches+[cs_local_browser]
  488. else if More='l-' then
  489. init_settings.moduleswitches:=init_settings.moduleswitches-[cs_local_browser]
  490. else
  491. IllegalPara(opt);
  492. end;
  493. 'B' :
  494. do_build:=not UnSetBool(more,0);
  495. 'C' :
  496. begin
  497. j:=1;
  498. while j<=length(more) do
  499. begin
  500. case more[j] of
  501. 'a' :
  502. begin
  503. s:=upper(copy(more,j+1,length(more)-j));
  504. if not(SetAbiType(s,target_info.abi)) then
  505. IllegalPara(opt);
  506. break;
  507. end;
  508. 'b' :
  509. begin
  510. if UnsetBool(More, j) then
  511. target_info.endian:=endian_little
  512. else
  513. target_info.endian:=endian_big;
  514. end;
  515. 'c' :
  516. begin
  517. if not SetAktProcCall(upper(copy(more,j+1,length(more)-j)),init_settings.defproccall) then
  518. IllegalPara(opt);
  519. break;
  520. end;
  521. {$ifdef cpufpemu}
  522. 'e' :
  523. begin
  524. If UnsetBool(More, j) then
  525. exclude(init_settings.moduleswitches,cs_fp_emulation)
  526. Else
  527. include(init_settings.moduleswitches,cs_fp_emulation);
  528. end;
  529. {$endif cpufpemu}
  530. 'f' :
  531. begin
  532. s:=upper(copy(more,j+1,length(more)-j));
  533. if not(SetFpuType(s,init_settings.fputype)) then
  534. IllegalPara(opt);
  535. break;
  536. end;
  537. 'F' :
  538. begin
  539. if not SetMinFPConstPrec(copy(more,j+1,length(more)-j),init_settings.minfpconstprec) then
  540. IllegalPara(opt);
  541. break;
  542. end;
  543. 'g' :
  544. begin
  545. if tf_no_pic_supported in target_info.flags then
  546. begin
  547. { consume a possible '-' coming after it }
  548. UnsetBool(More, j);
  549. message(scan_w_pic_ignored);
  550. end
  551. else if UnsetBool(More, j) then
  552. exclude(init_settings.moduleswitches,cs_create_pic)
  553. else
  554. include(init_settings.moduleswitches,cs_create_pic);
  555. end;
  556. 'h' :
  557. begin
  558. val(copy(more,j+1,length(more)-j),heapsize,code);
  559. if (code<>0) or (heapsize<1024) then
  560. IllegalPara(opt);
  561. break;
  562. end;
  563. 'i' :
  564. If UnsetBool(More, j) then
  565. exclude(init_settings.localswitches,cs_check_io)
  566. else
  567. include(init_settings.localswitches,cs_check_io);
  568. 'n' :
  569. If UnsetBool(More, j) then
  570. exclude(init_settings.globalswitches,cs_link_nolink)
  571. Else
  572. include(init_settings.globalswitches,cs_link_nolink);
  573. 'o' :
  574. If UnsetBool(More, j) then
  575. exclude(init_settings.localswitches,cs_check_overflow)
  576. Else
  577. include(init_settings.localswitches,cs_check_overflow);
  578. 'O' :
  579. If UnsetBool(More, j) then
  580. exclude(init_settings.localswitches,cs_check_ordinal_size)
  581. Else
  582. include(init_settings.localswitches,cs_check_ordinal_size);
  583. 'p' :
  584. begin
  585. s:=upper(copy(more,j+1,length(more)-j));
  586. if not(Setcputype(s,init_settings.cputype)) then
  587. IllegalPara(opt);
  588. break;
  589. end;
  590. 'P':
  591. begin
  592. delete(more,1,1);
  593. if upper(copy(more,1,pos('=',more)-1))='PACKSET' then
  594. begin
  595. delete(more,1,pos('=',more));
  596. if more='0' then
  597. init_settings.setalloc:=0
  598. else if (more='1') or (more='DEFAULT') or (more='NORMAL') then
  599. init_settings.setalloc:=1
  600. else if more='2' then
  601. init_settings.setalloc:=2
  602. else if more='4' then
  603. init_settings.setalloc:=4
  604. else if more='8' then
  605. init_settings.setalloc:=8
  606. else
  607. IllegalPara(opt);
  608. end
  609. else
  610. IllegalPara(opt);
  611. end;
  612. 'r' :
  613. If UnsetBool(More, j) then
  614. exclude(init_settings.localswitches,cs_check_range)
  615. Else
  616. include(init_settings.localswitches,cs_check_range);
  617. 'R' :
  618. If UnsetBool(More, j) then
  619. begin
  620. exclude(init_settings.localswitches,cs_check_range);
  621. exclude(init_settings.localswitches,cs_check_object);
  622. end
  623. Else
  624. begin
  625. include(init_settings.localswitches,cs_check_range);
  626. include(init_settings.localswitches,cs_check_object);
  627. end;
  628. 's' :
  629. begin
  630. val(copy(more,j+1,length(more)-j),stacksize,code);
  631. if (code<>0) or (stacksize>=67107840) or (stacksize<1024) then
  632. IllegalPara(opt);
  633. break;
  634. end;
  635. 't' :
  636. If UnsetBool(More, j) then
  637. exclude(init_settings.localswitches,cs_check_stack)
  638. Else
  639. include(init_settings.localswitches,cs_check_stack);
  640. 'D' :
  641. If UnsetBool(More, j) then
  642. exclude(init_settings.moduleswitches,cs_create_dynamic)
  643. Else
  644. include(init_settings.moduleswitches,cs_create_dynamic);
  645. 'X' :
  646. If UnsetBool(More, j) then
  647. exclude(init_settings.moduleswitches,cs_create_smart)
  648. Else
  649. include(init_settings.moduleswitches,cs_create_smart);
  650. else
  651. IllegalPara(opt);
  652. end;
  653. inc(j);
  654. end;
  655. end;
  656. 'd' :
  657. if more <> '' then
  658. begin
  659. l:=Pos(':=',more);
  660. if l>0 then
  661. set_system_compvar(Copy(more,1,l-1),Copy(more,l+2,255))
  662. else
  663. def_system_macro(more);
  664. end;
  665. 'D' :
  666. begin
  667. include(init_settings.globalswitches,cs_link_deffile);
  668. j:=1;
  669. while j<=length(more) do
  670. begin
  671. case more[j] of
  672. 'd' :
  673. begin
  674. description:=Copy(more,j+1,255);
  675. break;
  676. end;
  677. 'v' :
  678. begin
  679. dllversion:=Copy(more,j+1,255);
  680. l:=pos('.',dllversion);
  681. dllminor:=0;
  682. error:=0;
  683. if l>0 then
  684. begin
  685. val(copy(dllversion,l+1,255),minor,error);
  686. if (error=0) and
  687. (minor>=0) and (minor<=$ffff) then
  688. dllminor:=minor
  689. else
  690. if error=0 then
  691. error:=1;
  692. end;
  693. if l=0 then
  694. l:=256;
  695. dllmajor:=1;
  696. if error=0 then
  697. val(copy(dllversion,1,l-1),major,error);
  698. if (error=0) and (major>=0) and (major<=$ffff) then
  699. dllmajor:=major
  700. else
  701. if error=0 then
  702. error:=1;
  703. if error<>0 then
  704. Message1(scan_w_wrong_version_ignored,dllversion);
  705. break;
  706. end;
  707. 'w' :
  708. usewindowapi:=true;
  709. '-' :
  710. begin
  711. exclude(init_settings.globalswitches,cs_link_deffile);
  712. usewindowapi:=false;
  713. end;
  714. else
  715. IllegalPara(opt);
  716. end;
  717. inc(j);
  718. end;
  719. end;
  720. 'e' :
  721. exepath:=FixPath(More,true);
  722. 'E' :
  723. begin
  724. if UnsetBool(More, 0) then
  725. exclude(init_settings.globalswitches,cs_link_nolink)
  726. else
  727. include(init_settings.globalswitches,cs_link_nolink);
  728. end;
  729. 'f' :
  730. begin
  731. if more='PIC' then
  732. begin
  733. if tf_no_pic_supported in target_info.flags then
  734. message(scan_w_pic_ignored)
  735. else
  736. include(init_settings.moduleswitches,cs_create_pic)
  737. end
  738. else
  739. IllegalPara(opt);
  740. end;
  741. 'F' :
  742. begin
  743. if more='' then
  744. IllegalPara(opt);
  745. c:=more[1];
  746. Delete(more,1,1);
  747. DefaultReplacements(More);
  748. case c of
  749. 'a' :
  750. autoloadunits:=more;
  751. 'c' :
  752. begin
  753. if (upper(more)='UTF8') or (upper(more)='UTF-8') then
  754. init_settings.sourcecodepage:='utf8'
  755. else if not(cpavailable(more)) then
  756. Message1(option_code_page_not_available,more)
  757. else
  758. init_settings.sourcecodepage:=more;
  759. end;
  760. 'C' :
  761. RCCompiler := More;
  762. 'D' :
  763. utilsdirectory:=FixPath(More,true);
  764. 'e' :
  765. SetRedirectFile(More);
  766. 'E' :
  767. OutputExeDir:=FixPath(More,true);
  768. 'f' :
  769. if (target_info.system in systems_darwin) then
  770. if ispara then
  771. ParaFrameworkPath.AddPath(More,false)
  772. else
  773. frameworksearchpath.AddPath(More,true)
  774. else
  775. IllegalPara(opt);
  776. 'i' :
  777. begin
  778. if ispara then
  779. ParaIncludePath.AddPath(More,false)
  780. else
  781. includesearchpath.AddPath(More,true);
  782. end;
  783. 'm' :
  784. begin
  785. unicodemapping:=loadunicodemapping(More,More+'.txt');
  786. if assigned(unicodemapping) then
  787. registermapping(unicodemapping)
  788. else
  789. IllegalPara(opt);
  790. end;
  791. 'g' :
  792. Message2(option_obsolete_switch_use_new,'-Fg','-Fl');
  793. 'l' :
  794. begin
  795. if ispara then
  796. ParaLibraryPath.AddPath(sysrootpath,More,false)
  797. else
  798. LibrarySearchPath.AddPath(sysrootpath,More,true);
  799. end;
  800. 'L' :
  801. begin
  802. if More<>'' then
  803. ParaDynamicLinker:=More
  804. else
  805. IllegalPara(opt);
  806. end;
  807. 'o' :
  808. begin
  809. if ispara then
  810. ParaObjectPath.AddPath(More,false)
  811. else
  812. ObjectSearchPath.AddPath(More,true);
  813. end;
  814. 'r' :
  815. Msgfilename:=More;
  816. 'R' :
  817. ResCompiler := More;
  818. 'u' :
  819. begin
  820. if ispara then
  821. ParaUnitPath.AddPath(More,false)
  822. else
  823. unitsearchpath.AddPath(More,true);
  824. end;
  825. 'U' :
  826. OutputUnitDir:=FixPath(More,true);
  827. 'W',
  828. 'w':
  829. begin
  830. if More<>'' then
  831. begin
  832. DefaultReplacements(More);
  833. D:=ExtractFilePath(More);
  834. if (D<>'') then
  835. D:=FixPath(D,True);
  836. D:=D+ExtractFileName(More);
  837. if (c='W') then
  838. WpoFeedbackOutput:=D
  839. else
  840. WpoFeedbackInput:=D;
  841. end
  842. else
  843. IllegalPara(opt);
  844. end;
  845. else
  846. IllegalPara(opt);
  847. end;
  848. end;
  849. 'g' :
  850. begin
  851. if UnsetBool(More, 0) then
  852. begin
  853. exclude(init_settings.moduleswitches,cs_debuginfo);
  854. exclude(init_settings.globalswitches,cs_use_heaptrc);
  855. exclude(init_settings.globalswitches,cs_use_lineinfo);
  856. exclude(init_settings.localswitches,cs_checkpointer);
  857. localvartrashing := -1;
  858. end
  859. else
  860. begin
  861. include(init_settings.moduleswitches,cs_debuginfo);
  862. if paratargetdbg=dbg_none then
  863. paratargetdbg:=target_info.dbg;
  864. end;
  865. if not RelocSectionSetExplicitly then
  866. RelocSection:=false;
  867. j:=1;
  868. while j<=length(more) do
  869. begin
  870. case more[j] of
  871. 'c' :
  872. begin
  873. if UnsetBool(More, j) then
  874. exclude(init_settings.localswitches,cs_checkpointer)
  875. else if (target_info.system in supported_targets_gc) then
  876. include(init_settings.localswitches,cs_checkpointer)
  877. else
  878. UnsupportedPara('-gc');
  879. end;
  880. 'h' :
  881. begin
  882. if UnsetBool(More, j) then
  883. exclude(init_settings.globalswitches,cs_use_heaptrc)
  884. else
  885. include(init_settings.globalswitches,cs_use_heaptrc);
  886. end;
  887. 'l' :
  888. begin
  889. if UnsetBool(More, j) then
  890. exclude(init_settings.globalswitches,cs_use_lineinfo)
  891. else
  892. include(init_settings.globalswitches,cs_use_lineinfo);
  893. end;
  894. 'o' :
  895. begin
  896. if not UpdateDebugStr(copy(more,j+1,length(more)),init_settings.debugswitches) then
  897. IllegalPara(opt);
  898. break;
  899. end;
  900. 'p' :
  901. begin
  902. if UnsetBool(More, j) then
  903. exclude(init_settings.globalswitches,cs_stabs_preservecase)
  904. else
  905. include(init_settings.globalswitches,cs_stabs_preservecase);
  906. end;
  907. 's' :
  908. begin
  909. paratargetdbg:=dbg_stabs;
  910. end;
  911. 't' :
  912. begin
  913. if UnsetBool(More, j) then
  914. localvartrashing := -1
  915. else
  916. localvartrashing := (localvartrashing + 1) mod nroftrashvalues;
  917. end;
  918. 'v' :
  919. begin
  920. if UnsetBool(More, j) then
  921. exclude(init_settings.globalswitches,cs_gdb_valgrind)
  922. else
  923. include(init_settings.globalswitches,cs_gdb_valgrind);
  924. end;
  925. 'w' :
  926. begin
  927. if (j<length(more)) and (more[j+1] in ['2','3']) then
  928. begin
  929. case more[j+1] of
  930. '2': paratargetdbg:=dbg_dwarf2;
  931. '3': paratargetdbg:=dbg_dwarf3;
  932. end;
  933. inc(j);
  934. end
  935. else
  936. paratargetdbg:=dbg_dwarf2;
  937. end;
  938. else
  939. IllegalPara(opt);
  940. end;
  941. inc(j);
  942. end;
  943. end;
  944. 'h' :
  945. begin
  946. NoPressEnter:=true;
  947. WriteHelpPages;
  948. end;
  949. 'i' :
  950. begin
  951. if More='' then
  952. WriteInfo
  953. else
  954. QuickInfo:=QuickInfo+More;
  955. end;
  956. 'I' :
  957. begin
  958. if ispara then
  959. ParaIncludePath.AddPath(More,false)
  960. else
  961. includesearchpath.AddPath(More,false);
  962. end;
  963. 'k' :
  964. begin
  965. if more<>'' then
  966. ParaLinkOptions:=ParaLinkOptions+' '+More
  967. else
  968. IllegalPara(opt);
  969. end;
  970. 'l' :
  971. ParaLogo:=not UnSetBool(more,0);
  972. 'm' :
  973. parapreprocess:=not UnSetBool(more,0);
  974. 'M' :
  975. begin
  976. more:=Upper(more);
  977. if not SetCompileMode(more, true) then
  978. if not SetCompileModeSwitch(more, true) then
  979. IllegalPara(opt);
  980. end;
  981. 'n' :
  982. begin
  983. if More='' then
  984. disable_configfile:=true
  985. else
  986. IllegalPara(opt);
  987. end;
  988. 'o' :
  989. begin
  990. if More<>'' then
  991. begin
  992. DefaultReplacements(More);
  993. D:=ExtractFilePath(More);
  994. if (D<>'') then
  995. OutputExeDir:=FixPath(D,True);
  996. OutputFileName:=ExtractFileName(More);
  997. end
  998. else
  999. IllegalPara(opt);
  1000. end;
  1001. 'O' :
  1002. begin
  1003. j:=1;
  1004. while j<=length(more) do
  1005. begin
  1006. case more[j] of
  1007. '1' :
  1008. init_settings.optimizerswitches:=init_settings.optimizerswitches+level1optimizerswitches;
  1009. '2' :
  1010. init_settings.optimizerswitches:=init_settings.optimizerswitches+level2optimizerswitches;
  1011. '3' :
  1012. init_settings.optimizerswitches:=init_settings.optimizerswitches+level3optimizerswitches;
  1013. 'a' :
  1014. begin
  1015. if not(UpdateAlignmentStr(Copy(Opt,j+3,255),ParaAlignment)) then
  1016. IllegalPara(opt);
  1017. break;
  1018. end;
  1019. 's' :
  1020. include(init_settings.optimizerswitches,cs_opt_size);
  1021. 'p' :
  1022. begin
  1023. if not Setcputype(copy(more,j+1,length(more)),init_settings.optimizecputype) then
  1024. begin
  1025. { Give warning for old i386 switches }
  1026. if (Length(More)-j=1) and
  1027. (More[j+1]>='1') and (More[j+1]<='5')then
  1028. Message2(option_obsolete_switch_use_new,'-Op<nr>','-Op<name>')
  1029. else
  1030. IllegalPara(opt);
  1031. end;
  1032. break;
  1033. end;
  1034. 'o' :
  1035. begin
  1036. if not UpdateOptimizerStr(copy(more,j+1,length(more)),init_settings.optimizerswitches) then
  1037. IllegalPara(opt);
  1038. break;
  1039. end;
  1040. '-' :
  1041. begin
  1042. init_settings.optimizerswitches:=[];
  1043. FillChar(ParaAlignment,sizeof(ParaAlignment),0);
  1044. end;
  1045. { Obsolete switches }
  1046. 'g' :
  1047. Message2(option_obsolete_switch_use_new,'-Og','-Os');
  1048. 'G' :
  1049. Message1(option_obsolete_switch,'-OG');
  1050. 'r' :
  1051. Message2(option_obsolete_switch_use_new,'-Or','-O2 or -Ooregvar');
  1052. 'u' :
  1053. Message2(option_obsolete_switch_use_new,'-Ou','-Oouncertain');
  1054. 'w' :
  1055. begin
  1056. if not UpdateWpoStr(copy(more,j+1,length(more)),init_settings.dowpoptimizerswitches) then
  1057. IllegalPara(opt);
  1058. break;
  1059. end;
  1060. 'W' :
  1061. begin
  1062. if not UpdateWpoStr(copy(more,j+1,length(more)),init_settings.genwpoptimizerswitches) then
  1063. IllegalPara(opt);
  1064. break;
  1065. end;
  1066. else
  1067. IllegalPara(opt);
  1068. end;
  1069. inc(j);
  1070. end;
  1071. end;
  1072. 'p' :
  1073. begin
  1074. if UnsetBool(More, 0) then
  1075. begin
  1076. init_settings.moduleswitches:=init_settings.moduleswitches-[cs_profile];
  1077. undef_system_macro('FPC_PROFILE');
  1078. end
  1079. else
  1080. if Length(More)=0 then
  1081. IllegalPara(opt)
  1082. else
  1083. case more[1] of
  1084. 'g' : if UnsetBool(more, 1) then
  1085. begin
  1086. exclude(init_settings.moduleswitches,cs_profile);
  1087. undef_system_macro('FPC_PROFILE');
  1088. end
  1089. else if (target_info.system in supported_targets_pg) then
  1090. begin
  1091. include(init_settings.moduleswitches,cs_profile);
  1092. def_system_macro('FPC_PROFILE');
  1093. end
  1094. else
  1095. UnsupportedPara('-pg');
  1096. else
  1097. IllegalPara(opt);
  1098. end;
  1099. end;
  1100. 'P' : ; { Ignore used by fpc.pp }
  1101. 'R' :
  1102. begin
  1103. if not SetAsmReadMode(More,init_settings.asmmode) then
  1104. IllegalPara(opt);
  1105. end;
  1106. 's' :
  1107. begin
  1108. if UnsetBool(More, 0) then
  1109. begin
  1110. init_settings.globalswitches:=init_settings.globalswitches-[cs_asm_extern,cs_link_extern,cs_link_nolink];
  1111. if more<>'' then
  1112. IllegalPara(opt);
  1113. end
  1114. else
  1115. begin
  1116. init_settings.globalswitches:=init_settings.globalswitches+[cs_asm_extern,cs_link_extern,cs_link_nolink];
  1117. if more='h' then
  1118. init_settings.globalswitches:=init_settings.globalswitches-[cs_link_on_target]
  1119. else if more='t' then
  1120. init_settings.globalswitches:=init_settings.globalswitches+[cs_link_on_target]
  1121. else if more='r' then
  1122. init_settings.globalswitches:=init_settings.globalswitches+[cs_asm_leave,cs_no_regalloc]
  1123. else if more<>'' then
  1124. IllegalPara(opt);
  1125. end;
  1126. end;
  1127. 'S' :
  1128. begin
  1129. if more='' then
  1130. IllegalPara(opt);
  1131. if more[1]='I' then
  1132. begin
  1133. if upper(more)='ICOM' then
  1134. init_settings.interfacetype:=it_interfacecom
  1135. else if upper(more)='ICORBA' then
  1136. init_settings.interfacetype:=it_interfacecorba
  1137. else
  1138. IllegalPara(opt);
  1139. end
  1140. else
  1141. begin
  1142. j:=1;
  1143. while j<=length(more) do
  1144. begin
  1145. case more[j] of
  1146. '2' : //an alternative to -Mobjfpc
  1147. SetCompileMode('OBJFPC',true);
  1148. 'a' :
  1149. If UnsetBool(More, j) then
  1150. exclude(init_settings.localswitches,cs_do_assertion)
  1151. else
  1152. include(init_settings.localswitches,cs_do_assertion);
  1153. 'c' :
  1154. If UnsetBool(More, j) then
  1155. include(init_settings.moduleswitches,cs_support_c_operators)
  1156. else
  1157. include(init_settings.moduleswitches,cs_support_c_operators);
  1158. 'd' : //an alternative to -Mdelphi
  1159. SetCompileMode('DELPHI',true);
  1160. 'e' :
  1161. begin
  1162. SetErrorFlags(copy(more,j+1,length(more)));
  1163. break;
  1164. end;
  1165. 'f' :
  1166. begin
  1167. inc(j);
  1168. if more[j]='-' then
  1169. begin
  1170. features:=[];
  1171. if length(more)>j then
  1172. IllegalPara(opt);
  1173. end
  1174. else
  1175. begin
  1176. if (IncludeFeature(upper(copy(more,j,length(more)-j+1)))) then
  1177. j:=length(more)
  1178. else
  1179. IllegalPara(opt);
  1180. end;
  1181. end;
  1182. 'g' :
  1183. If UnsetBool(More, j) then
  1184. exclude(init_settings.moduleswitches,cs_support_goto)
  1185. else
  1186. include(init_settings.moduleswitches,cs_support_goto);
  1187. 'h' :
  1188. If UnsetBool(More, j) then
  1189. exclude(init_settings.localswitches,cs_ansistrings)
  1190. else
  1191. include(init_settings.localswitches,cs_ansistrings);
  1192. 'i' :
  1193. If UnsetBool(More, j) then
  1194. exclude(init_settings.localswitches,cs_do_inline)
  1195. else
  1196. include(init_settings.localswitches,cs_do_inline);
  1197. 'k' :
  1198. If UnsetBool(More, j) then
  1199. exclude(init_settings.globalswitches,cs_load_fpcylix_unit)
  1200. else
  1201. include(init_settings.globalswitches,cs_load_fpcylix_unit);
  1202. 'm' :
  1203. If UnsetBool(More, j) then
  1204. exclude(init_settings.moduleswitches,cs_support_macro)
  1205. else
  1206. include(init_settings.moduleswitches,cs_support_macro);
  1207. 'o' : //an alternative to -Mtp
  1208. SetCompileMode('TP',true);
  1209. {$ifdef gpc_mode}
  1210. 'p' : //an alternative to -Mgpc
  1211. SetCompileMode('GPC',true);
  1212. {$endif}
  1213. 's' :
  1214. If UnsetBool(More, j) then
  1215. exclude(init_settings.globalswitches,cs_constructor_name)
  1216. else
  1217. include(init_settings.globalswitches,cs_constructor_name);
  1218. 't' :
  1219. If UnsetBool(More, j) then
  1220. exclude(init_settings.moduleswitches,cs_static_keyword)
  1221. else
  1222. include(init_settings.moduleswitches,cs_static_keyword);
  1223. 'v' :
  1224. If UnsetBool(More, j) then
  1225. exclude(init_settings.globalswitches,cs_support_vectors)
  1226. else
  1227. include(init_settings.globalswitches,cs_support_vectors);
  1228. 'x' :
  1229. If UnsetBool(More, j) then
  1230. exclude(init_settings.globalswitches,cs_support_exceptions)
  1231. else
  1232. include(init_settings.globalswitches,cs_support_exceptions);
  1233. '-' :
  1234. begin
  1235. init_settings.globalswitches:=init_settings.globalswitches - [cs_constructor_name,cs_support_exceptions];
  1236. init_settings.localswitches:=init_settings.localswitches - [cs_do_assertion, cs_do_inline, cs_ansistrings];
  1237. init_settings.moduleswitches:=init_settings.moduleswitches - [cs_support_c_operators, cs_support_goto,
  1238. cs_support_macro,
  1239. cs_static_keyword];
  1240. end;
  1241. else
  1242. IllegalPara(opt);
  1243. end;
  1244. inc(j);
  1245. end;
  1246. end;
  1247. end;
  1248. 'T' :
  1249. begin
  1250. more:=Upper(More);
  1251. if paratarget=system_none then
  1252. begin
  1253. { remove old target define }
  1254. TargetOptions(false);
  1255. { load new target }
  1256. paratarget:=find_system_by_string(More);
  1257. if paratarget<>system_none then
  1258. set_target(paratarget)
  1259. else
  1260. IllegalPara(opt);
  1261. { set new define }
  1262. TargetOptions(true);
  1263. end
  1264. else
  1265. if More<>upper(target_info.shortname) then
  1266. Message1(option_target_is_already_set,target_info.shortname);
  1267. end;
  1268. 'u' :
  1269. if more <> '' then
  1270. undef_system_macro(more);
  1271. 'U' :
  1272. begin
  1273. j:=1;
  1274. while j<=length(more) do
  1275. begin
  1276. case more[j] of
  1277. {$ifdef UNITALIASES}
  1278. 'a' :
  1279. begin
  1280. AddUnitAlias(Copy(More,j+1,255));
  1281. break;
  1282. end;
  1283. {$endif UNITALIASES}
  1284. 'n' :
  1285. exclude(init_settings.globalswitches,cs_check_unit_name);
  1286. 'p' :
  1287. begin
  1288. Message2(option_obsolete_switch_use_new,'-Up','-Fu');
  1289. break;
  1290. end;
  1291. 'r' :
  1292. do_release:=true;
  1293. 's' :
  1294. include(init_settings.moduleswitches,cs_compilesystem);
  1295. '-' :
  1296. begin
  1297. exclude(init_settings.moduleswitches,cs_compilesystem);
  1298. exclude(init_settings.globalswitches,cs_check_unit_name);
  1299. end;
  1300. else
  1301. IllegalPara(opt);
  1302. end;
  1303. inc(j);
  1304. end;
  1305. end;
  1306. 'v' :
  1307. begin
  1308. if not setverbosity(More) then
  1309. IllegalPara(opt);
  1310. end;
  1311. 'V' : ; { Ignore used by fpc }
  1312. 'W' :
  1313. begin
  1314. j:=1;
  1315. while j<=length(More) do
  1316. begin
  1317. case More[j] of
  1318. 'A':
  1319. begin
  1320. if UnsetBool(More, j) then
  1321. apptype:=app_native
  1322. else
  1323. apptype:=app_cui;
  1324. end;
  1325. 'b':
  1326. begin
  1327. if (target_info.system in systems_darwin) then
  1328. begin
  1329. if not UnsetBool(More, j) then
  1330. apptype:=app_bundle
  1331. else
  1332. apptype:=app_cui
  1333. end
  1334. else
  1335. IllegalPara(opt);
  1336. end;
  1337. 'B':
  1338. begin
  1339. { -WB200000 means set trefered base address
  1340. to $200000, but does not change relocsection boolean
  1341. this way we can create both relocatble and
  1342. non relocatable DLL at a specific base address PM }
  1343. if (length(More)>j) then
  1344. begin
  1345. if DLLImageBase=nil then
  1346. DLLImageBase:=StringDup(Copy(More,j+1,255));
  1347. end
  1348. else
  1349. begin
  1350. RelocSection:=true;
  1351. RelocSectionSetExplicitly:=true;
  1352. end;
  1353. break;
  1354. end;
  1355. 'C':
  1356. begin
  1357. if UnsetBool(More, j) then
  1358. apptype:=app_gui
  1359. else
  1360. apptype:=app_cui;
  1361. end;
  1362. 'D':
  1363. begin
  1364. UseDeffileForExports:=not UnsetBool(More, j);
  1365. UseDeffileForExportsSetExplicitly:=true;
  1366. end;
  1367. 'e':
  1368. begin
  1369. if (target_info.system in systems_darwin) then
  1370. begin
  1371. RegisterRes(res_macosx_ext_info,TWinLikeResourceFile);
  1372. set_target_res(res_ext);
  1373. target_info.resobjext:='.fpcres';
  1374. end
  1375. else
  1376. IllegalPara(opt);
  1377. end;
  1378. 'F':
  1379. begin
  1380. if UnsetBool(More, j) then
  1381. apptype:=app_cui
  1382. else
  1383. apptype:=app_fs;
  1384. end;
  1385. 'G':
  1386. begin
  1387. if UnsetBool(More, j) then
  1388. apptype:=app_cui
  1389. else
  1390. apptype:=app_gui;
  1391. end;
  1392. 'I':
  1393. begin
  1394. GenerateImportSection:=not UnsetBool(More,j);
  1395. GenerateImportSectionSetExplicitly:=true;
  1396. end;
  1397. 'i':
  1398. begin
  1399. if (target_info.system in systems_darwin) then
  1400. begin
  1401. set_target_res(res_macho);
  1402. target_info.resobjext:=
  1403. targetinfos[target_info.system]^.resobjext;
  1404. end
  1405. else
  1406. IllegalPara(opt);
  1407. end;
  1408. 'N':
  1409. begin
  1410. RelocSection:=UnsetBool(More,j);
  1411. RelocSectionSetExplicitly:=true;
  1412. end;
  1413. 'R':
  1414. begin
  1415. { support -WR+ / -WR- as synonyms to -WR / -WN }
  1416. RelocSection:=not UnsetBool(More,j);
  1417. RelocSectionSetExplicitly:=true;
  1418. end;
  1419. 'T':
  1420. begin
  1421. if UnsetBool(More, j) then
  1422. apptype:=app_cui
  1423. else
  1424. apptype:=app_tool;
  1425. end;
  1426. 'X':
  1427. begin
  1428. if (target_info.system in system_linux) then
  1429. begin
  1430. if UnsetBool(More, j) then
  1431. exclude(init_settings.moduleswitches,cs_executable_stack)
  1432. else
  1433. include(init_settings.moduleswitches,cs_executable_stack)
  1434. end
  1435. else
  1436. IllegalPara(opt);
  1437. end
  1438. else
  1439. IllegalPara(opt);
  1440. end;
  1441. inc(j);
  1442. end;
  1443. end;
  1444. 'X' :
  1445. begin
  1446. j:=1;
  1447. while j<=length(more) do
  1448. begin
  1449. case More[j] of
  1450. 'c' : Cshared:=TRUE;
  1451. 'd' : Dontlinkstdlibpath:=TRUE;
  1452. 'e' :
  1453. begin
  1454. If UnsetBool(More, j) then
  1455. exclude(init_settings.globalswitches,cs_link_extern)
  1456. else
  1457. include(init_settings.globalswitches,cs_link_extern);
  1458. end;
  1459. 'f' :
  1460. include(init_settings.globalswitches,cs_link_pthread);
  1461. 'g' :
  1462. begin
  1463. If UnsetBool(More, j) then
  1464. exclude(init_settings.globalswitches,cs_link_separate_dbg_file)
  1465. else
  1466. include(init_settings.globalswitches,cs_link_separate_dbg_file);
  1467. end;
  1468. 'i' :
  1469. begin
  1470. If UnsetBool(More, j) then
  1471. include(init_settings.globalswitches,cs_link_extern)
  1472. else
  1473. exclude(init_settings.globalswitches,cs_link_extern);
  1474. end;
  1475. 'm' :
  1476. begin
  1477. If UnsetBool(More, j) then
  1478. exclude(init_settings.globalswitches,cs_link_map)
  1479. else
  1480. include(init_settings.globalswitches,cs_link_map);
  1481. end;
  1482. 'p' : ; { Ignore used by fpc.pp }
  1483. 'r' :
  1484. begin
  1485. rlinkpath:=Copy(more,2,length(More)-1);
  1486. DefaultReplacements(rlinkpath);
  1487. More:='';
  1488. end;
  1489. 'R' :
  1490. begin
  1491. sysrootpath:=copy(more,2,length(more)-1);
  1492. defaultreplacements(sysrootpath);
  1493. more:='';
  1494. end;
  1495. 's' :
  1496. begin
  1497. If UnsetBool(More, j) then
  1498. exclude(init_settings.globalswitches,cs_link_strip)
  1499. else
  1500. include(init_settings.globalswitches,cs_link_strip);
  1501. end;
  1502. 't' :
  1503. include(init_settings.globalswitches,cs_link_staticflag);
  1504. 'v' :
  1505. begin
  1506. If UnsetBool(More, j) then
  1507. exclude(init_settings.globalswitches,cs_link_opt_vtable)
  1508. else
  1509. include(init_settings.globalswitches,cs_link_opt_vtable);
  1510. end;
  1511. 'D' :
  1512. begin
  1513. def_system_macro('FPC_LINK_DYNAMIC');
  1514. undef_system_macro('FPC_LINK_SMART');
  1515. undef_system_macro('FPC_LINK_STATIC');
  1516. exclude(init_settings.globalswitches,cs_link_static);
  1517. exclude(init_settings.globalswitches,cs_link_smart);
  1518. include(init_settings.globalswitches,cs_link_shared);
  1519. LinkTypeSetExplicitly:=true;
  1520. end;
  1521. 'M' :
  1522. begin
  1523. mainaliasname:=Copy(more,2,length(More)-1);
  1524. More:='';
  1525. end;
  1526. 'P' :
  1527. begin
  1528. utilsprefix:=Copy(more,2,length(More)-1);
  1529. DefaultReplacements(utilsprefix);
  1530. More:='';
  1531. end;
  1532. 'L' : begin // -XLO is link order -XLA is link alias. -XLD avoids load defaults.
  1533. // these are not aggregable.
  1534. if (j=length(more)) or not (more[j+1] in ['O','A','D']) then
  1535. IllegalPara(opt)
  1536. else
  1537. begin
  1538. case more[j+1] of
  1539. 'A' : begin
  1540. s:=Copy(more,3,length(More)-2);
  1541. if not LinkLibraryAliases.AddDep(s) Then
  1542. IllegalPara(opt);
  1543. end;
  1544. 'O' : begin
  1545. s:=Copy(more,3,length(More)-2);
  1546. if not LinkLibraryOrder.AddWeight(s) Then
  1547. IllegalPara(opt);
  1548. end;
  1549. 'D' : include(init_settings.globalswitches,cs_link_no_default_lib_order)
  1550. else
  1551. IllegalPara(opt);
  1552. end; {case}
  1553. j:=length(more);
  1554. end; {else begin}
  1555. end;
  1556. 'S' :
  1557. begin
  1558. def_system_macro('FPC_LINK_STATIC');
  1559. undef_system_macro('FPC_LINK_SMART');
  1560. undef_system_macro('FPC_LINK_DYNAMIC');
  1561. include(init_settings.globalswitches,cs_link_static);
  1562. exclude(init_settings.globalswitches,cs_link_smart);
  1563. exclude(init_settings.globalswitches,cs_link_shared);
  1564. LinkTypeSetExplicitly:=true;
  1565. end;
  1566. 'X' :
  1567. begin
  1568. def_system_macro('FPC_LINK_SMART');
  1569. undef_system_macro('FPC_LINK_STATIC');
  1570. undef_system_macro('FPC_LINK_DYNAMIC');
  1571. exclude(init_settings.globalswitches,cs_link_static);
  1572. include(init_settings.globalswitches,cs_link_smart);
  1573. exclude(init_settings.globalswitches,cs_link_shared);
  1574. LinkTypeSetExplicitly:=true;
  1575. end;
  1576. '-' :
  1577. begin
  1578. exclude(init_settings.globalswitches,cs_link_staticflag);
  1579. exclude(init_settings.globalswitches,cs_link_strip);
  1580. exclude(init_settings.globalswitches,cs_link_map);
  1581. set_default_link_type;
  1582. end;
  1583. else
  1584. IllegalPara(opt);
  1585. end;
  1586. inc(j);
  1587. end;
  1588. end;
  1589. end;
  1590. end;
  1591. '@' :
  1592. begin
  1593. Message(option_no_nested_response_file);
  1594. StopOptions(1);
  1595. end;
  1596. else
  1597. begin
  1598. if (length(param_file)<>0) then
  1599. Message(option_only_one_source_support);
  1600. param_file:=opt;
  1601. Message1(option_found_file,opt);
  1602. end;
  1603. end;
  1604. end;
  1605. procedure Toption.Interpret_file(const filename : string);
  1606. procedure RemoveSep(var fn:string);
  1607. var
  1608. i : longint;
  1609. begin
  1610. i:=0;
  1611. while (i<length(fn)) and (fn[i+1] in [',',' ',#9]) do
  1612. inc(i);
  1613. Delete(fn,1,i);
  1614. i:=length(fn);
  1615. while (i>0) and (fn[i] in [',',' ',#9]) do
  1616. dec(i);
  1617. fn:=copy(fn,1,i);
  1618. end;
  1619. function GetName(var fn:string):string;
  1620. var
  1621. i : longint;
  1622. begin
  1623. i:=0;
  1624. while (i<length(fn)) and (fn[i+1] in ['a'..'z','A'..'Z','0'..'9','_','-']) do
  1625. inc(i);
  1626. GetName:=Copy(fn,1,i);
  1627. Delete(fn,1,i);
  1628. end;
  1629. const
  1630. maxlevel = 15;
  1631. var
  1632. f : text;
  1633. s, tmp,
  1634. opts : string;
  1635. skip : array[0..maxlevel] of boolean;
  1636. line,
  1637. level : longint;
  1638. option_read : boolean;
  1639. begin
  1640. { avoid infinite loop }
  1641. Inc(FileLevel);
  1642. Option_read:=false;
  1643. If FileLevel>MaxLevel then
  1644. Message(option_too_many_cfg_files);
  1645. { Maybe It's Directory ?} //Jaro Change:
  1646. if PathExists(filename,false) then
  1647. begin
  1648. Message1(option_config_is_dir,filename);
  1649. exit;
  1650. end;
  1651. { open file }
  1652. Message1(option_using_file,filename);
  1653. assign(f,ExpandFileName(filename));
  1654. {$I-}
  1655. reset(f);
  1656. {$I+}
  1657. if ioresult<>0 then
  1658. begin
  1659. Message1(option_unable_open_file,filename);
  1660. exit;
  1661. end;
  1662. Message1(option_start_reading_configfile,filename);
  1663. fillchar(skip,sizeof(skip),0);
  1664. level:=0;
  1665. line:=0;
  1666. while not eof(f) do
  1667. begin
  1668. readln(f,opts);
  1669. inc(line);
  1670. RemoveSep(opts);
  1671. if (opts<>'') and (opts[1]<>';') then
  1672. begin
  1673. if opts[1]='#' then
  1674. begin
  1675. Message1(option_interpreting_file_option,opts);
  1676. Delete(opts,1,1);
  1677. s:=upper(GetName(opts));
  1678. if (s='SECTION') then
  1679. begin
  1680. RemoveSep(opts);
  1681. s:=upper(GetName(opts));
  1682. if level=0 then
  1683. skip[level]:=not defined_macro(s) or (s='COMMON');
  1684. end
  1685. else
  1686. if (s='IFDEF') then
  1687. begin
  1688. RemoveSep(opts);
  1689. if Level>=maxlevel then
  1690. begin
  1691. Message2(option_too_many_ifdef,filename,tostr(line));
  1692. stopOptions(1);
  1693. end;
  1694. inc(Level);
  1695. skip[level]:=(skip[level-1] or not defined_macro(upper(GetName(opts))));
  1696. end
  1697. else
  1698. if (s='IFNDEF') then
  1699. begin
  1700. RemoveSep(opts);
  1701. if Level>=maxlevel then
  1702. begin
  1703. Message2(option_too_many_ifdef,filename,tostr(line));
  1704. stopOptions(1);
  1705. end;
  1706. inc(Level);
  1707. skip[level]:=(skip[level-1] or defined_macro(upper(GetName(opts))));
  1708. end
  1709. else
  1710. if (s='ELSE') then
  1711. begin
  1712. if Level=0 then
  1713. begin
  1714. Message2(option_else_without_if,filename,tostr(line));
  1715. stopOptions(1);
  1716. end
  1717. else
  1718. skip[level]:=skip[level-1] or (not skip[level])
  1719. end
  1720. else
  1721. if (s='ENDIF') then
  1722. begin
  1723. skip[level]:=false;
  1724. if Level=0 then
  1725. begin
  1726. Message2(option_too_many_endif,filename,tostr(line));
  1727. stopOptions(1);
  1728. end;
  1729. dec(level);
  1730. end
  1731. else
  1732. if (not skip[level]) then
  1733. begin
  1734. if (s='DEFINE') then
  1735. begin
  1736. RemoveSep(opts);
  1737. tmp:= GetName(opts);
  1738. if tmp <> '' then
  1739. def_system_macro(tmp);
  1740. end
  1741. else
  1742. if (s='UNDEF') then
  1743. begin
  1744. RemoveSep(opts);
  1745. tmp:= GetName(opts);
  1746. if tmp <> '' then
  1747. undef_system_macro(tmp);
  1748. end
  1749. else
  1750. if (s='WRITE') then
  1751. begin
  1752. Delete(opts,1,1);
  1753. WriteLn(opts);
  1754. end
  1755. else
  1756. if (s='INCLUDE') then
  1757. begin
  1758. Delete(opts,1,1);
  1759. Interpret_file(opts);
  1760. end;
  1761. end;
  1762. end
  1763. else
  1764. begin
  1765. if (opts[1]='-') or (opts[1]='@') then
  1766. begin
  1767. if (not skip[level]) then
  1768. interpret_option(opts,false);
  1769. Option_read:=true;
  1770. end
  1771. else
  1772. Message1(option_illegal_para,opts);
  1773. end;
  1774. end;
  1775. end;
  1776. if Level>0 then
  1777. Message(option_too_less_endif);
  1778. if Not Option_read then
  1779. Message1(option_no_option_found,filename)
  1780. else
  1781. Message1(option_end_reading_configfile,filename);
  1782. Close(f);
  1783. Dec(FileLevel);
  1784. end;
  1785. procedure Toption.Interpret_envvar(const envname : string);
  1786. var
  1787. argstart,
  1788. env,
  1789. pc : pchar;
  1790. arglen : longint;
  1791. quote : set of char;
  1792. hs : string;
  1793. begin
  1794. Message1(option_using_env,envname);
  1795. env:=GetEnvPChar(envname);
  1796. pc:=env;
  1797. if assigned(pc) then
  1798. begin
  1799. repeat
  1800. { skip leading spaces }
  1801. while pc^ in [' ',#9,#13] do
  1802. inc(pc);
  1803. case pc^ of
  1804. #0 :
  1805. break;
  1806. '"' :
  1807. begin
  1808. quote:=['"'];
  1809. inc(pc);
  1810. end;
  1811. '''' :
  1812. begin
  1813. quote:=[''''];
  1814. inc(pc);
  1815. end;
  1816. else
  1817. quote:=[' ',#9,#13];
  1818. end;
  1819. { scan until the end of the argument }
  1820. argstart:=pc;
  1821. while (pc^<>#0) and not(pc^ in quote) do
  1822. inc(pc);
  1823. { create argument }
  1824. arglen:=pc-argstart;
  1825. { TODO: FIXME: silent truncation of environment parameters }
  1826. if (arglen > 255) then
  1827. arglen := 255;
  1828. setlength(hs,arglen);
  1829. move(argstart^,hs[1],arglen);
  1830. interpret_option(hs,true);
  1831. { skip quote }
  1832. if pc^ in quote then
  1833. inc(pc);
  1834. until false;
  1835. end
  1836. else
  1837. Message1(option_no_option_found,'(env) '+envname);
  1838. FreeEnvPChar(env);
  1839. end;
  1840. procedure toption.read_parameters;
  1841. var
  1842. opts : string;
  1843. paramindex : longint;
  1844. begin
  1845. paramindex:=0;
  1846. while paramindex<paramcount do
  1847. begin
  1848. inc(paramindex);
  1849. opts:=system.paramstr(paramindex);
  1850. case opts[1] of
  1851. '@' :
  1852. if not firstpass then
  1853. begin
  1854. Delete(opts,1,1);
  1855. Message1(option_reading_further_from,opts);
  1856. interpret_file(opts);
  1857. end;
  1858. '!' :
  1859. if not firstpass then
  1860. begin
  1861. Delete(opts,1,1);
  1862. Message1(option_reading_further_from,'(env) '+opts);
  1863. interpret_envvar(opts);
  1864. end;
  1865. else
  1866. interpret_option(opts,true);
  1867. end;
  1868. end;
  1869. end;
  1870. procedure toption.parsecmd(cmd:string);
  1871. var
  1872. i,ps : longint;
  1873. opts : string;
  1874. begin
  1875. while (cmd<>'') do
  1876. begin
  1877. while cmd[1]=' ' do
  1878. delete(cmd,1,1);
  1879. i:=pos(' ',cmd);
  1880. if i=0 then
  1881. i:=256;
  1882. opts:=Copy(cmd,1,i-1);
  1883. Delete(cmd,1,i);
  1884. case opts[1] of
  1885. '@' :
  1886. if not firstpass then
  1887. begin
  1888. Delete(opts,1,1);
  1889. Message1(option_reading_further_from,opts);
  1890. interpret_file(opts);
  1891. end;
  1892. '!' :
  1893. if not firstpass then
  1894. begin
  1895. Delete(opts,1,1);
  1896. Message1(option_reading_further_from,'(env) '+opts);
  1897. interpret_envvar(opts);
  1898. end;
  1899. '"' :
  1900. begin
  1901. Delete(opts,1,1);
  1902. ps:=pos('"',cmd);
  1903. if (i<>256) and (ps>0) then
  1904. begin
  1905. opts:=opts + ' '+ copy(cmd,1,ps-1);
  1906. cmd:=copy(cmd,ps+1,255);
  1907. end;
  1908. interpret_option(opts,true);
  1909. end;
  1910. else
  1911. interpret_option(opts,true);
  1912. end;
  1913. end;
  1914. end;
  1915. procedure toption.writequickinfo;
  1916. var
  1917. s : string;
  1918. i : longint;
  1919. procedure addinfo(const hs:string);
  1920. begin
  1921. if s<>'' then
  1922. s:=s+' '+hs
  1923. else
  1924. s:=hs;
  1925. end;
  1926. begin
  1927. s:='';
  1928. i:=0;
  1929. while (i<length(quickinfo)) do
  1930. begin
  1931. inc(i);
  1932. case quickinfo[i] of
  1933. 'S' :
  1934. begin
  1935. inc(i);
  1936. case quickinfo[i] of
  1937. 'O' :
  1938. addinfo(lower(source_info.shortname));
  1939. 'P' :
  1940. addinfo(source_cpu_string);
  1941. else
  1942. IllegalPara('-i'+QuickInfo);
  1943. end;
  1944. end;
  1945. 'T' :
  1946. begin
  1947. inc(i);
  1948. case quickinfo[i] of
  1949. 'O' :
  1950. addinfo(lower(target_info.shortname));
  1951. 'P' :
  1952. AddInfo(target_cpu_string);
  1953. else
  1954. IllegalPara('-i'+QuickInfo);
  1955. end;
  1956. end;
  1957. 'V' :
  1958. AddInfo(version_string);
  1959. 'W' :
  1960. AddInfo(full_version_string);
  1961. 'D' :
  1962. AddInfo(date_string);
  1963. '_' :
  1964. ;
  1965. else
  1966. IllegalPara('-i'+QuickInfo);
  1967. end;
  1968. end;
  1969. if s<>'' then
  1970. begin
  1971. writeln(s);
  1972. stopoptions(0);
  1973. end;
  1974. end;
  1975. procedure TOption.TargetOptions(def:boolean);
  1976. var
  1977. s : string;
  1978. i : integer;
  1979. target_unsup_features : tfeatures;
  1980. begin
  1981. if def then
  1982. def_system_macro(target_info.shortname)
  1983. else
  1984. undef_system_macro(target_info.shortname);
  1985. s:=target_info.extradefines;
  1986. while (s<>'') do
  1987. begin
  1988. i:=pos(';',s);
  1989. if i=0 then
  1990. i:=length(s)+1;
  1991. if def then
  1992. def_system_macro(Copy(s,1,i-1))
  1993. else
  1994. undef_system_macro(Copy(s,1,i-1));
  1995. delete(s,1,i);
  1996. end;
  1997. if (tf_winlikewidestring in target_info.flags) then
  1998. if def then
  1999. def_system_macro('FPC_WINLIKEWIDESTRING')
  2000. else
  2001. undef_system_macro('FPC_WINLIKEWIDESTRING');
  2002. if (tf_requires_proper_alignment in target_info.flags) then
  2003. if def then
  2004. def_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT')
  2005. else
  2006. undef_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
  2007. if source_info.system<>target_info.system then
  2008. if def then
  2009. def_system_macro('FPC_CROSSCOMPILING')
  2010. else
  2011. undef_system_macro('FPC_CROSSCOMPILING');
  2012. if source_info.cpu<>target_info.cpu then
  2013. if def then
  2014. def_system_macro('FPC_CPUCROSSCOMPILING')
  2015. else
  2016. def_system_macro('FPC_CPUCROSSCOMPILING');
  2017. if (tf_no_generic_stackcheck in target_info.flags) then
  2018. if def then
  2019. def_system_macro('FPC_NO_GENERIC_STACK_CHECK')
  2020. else
  2021. undef_system_macro('FPC_NO_GENERIC_STACK_CHECK');
  2022. { Code generation flags }
  2023. if def and
  2024. (tf_pic_default in target_info.flags) then
  2025. include(init_settings.moduleswitches,cs_create_pic)
  2026. else
  2027. exclude(init_settings.moduleswitches,cs_create_pic);
  2028. { Resources support }
  2029. if (tf_has_winlike_resources in target_info.flags) then
  2030. if def then
  2031. def_system_macro('FPC_HAS_WINLIKERESOURCES')
  2032. else
  2033. undef_system_macro('FPC_HAS_WINLIKERESOURCES');
  2034. { Features }
  2035. case target_info.system of
  2036. system_arm_gba:
  2037. target_unsup_features:=[f_threading,f_commandargs,f_fileio,f_textio,f_consoleio,f_dynlibs];
  2038. system_arm_nds:
  2039. target_unsup_features:=[f_threading,f_commandargs,f_fileio,f_textio,f_consoleio,f_dynlibs]
  2040. else
  2041. target_unsup_features:=[];
  2042. end;
  2043. if def then
  2044. features:=features-target_unsup_features
  2045. else
  2046. features:=features+target_unsup_features;
  2047. end;
  2048. constructor TOption.create;
  2049. begin
  2050. LogoWritten:=false;
  2051. NoPressEnter:=false;
  2052. FirstPass:=false;
  2053. FileLevel:=0;
  2054. Quickinfo:='';
  2055. ParaIncludePath:=TSearchPathList.Create;
  2056. ParaObjectPath:=TSearchPathList.Create;
  2057. ParaUnitPath:=TSearchPathList.Create;
  2058. ParaLibraryPath:=TSearchPathList.Create;
  2059. ParaFrameworkPath:=TSearchPathList.Create;
  2060. FillChar(ParaAlignment,sizeof(ParaAlignment),0);
  2061. end;
  2062. destructor TOption.destroy;
  2063. begin
  2064. ParaIncludePath.Free;
  2065. ParaObjectPath.Free;
  2066. ParaUnitPath.Free;
  2067. ParaLibraryPath.Free;
  2068. ParaFrameworkPath.Free;
  2069. end;
  2070. {****************************************************************************
  2071. Callable Routines
  2072. ****************************************************************************}
  2073. function check_configfile(const fn:string;var foundfn:string):boolean;
  2074. function CfgFileExists(const fn:string):boolean;
  2075. begin
  2076. Comment(V_Tried,'Configfile search: '+fn);
  2077. CfgFileExists:=FileExists(fn);
  2078. end;
  2079. var
  2080. {$ifdef Unix}
  2081. hs,
  2082. {$endif Unix}
  2083. configpath : string;
  2084. begin
  2085. foundfn:=fn;
  2086. check_configfile:=true;
  2087. { retrieve configpath }
  2088. configpath:=FixPath(GetEnvironmentVariable('PPC_CONFIG_PATH'),false);
  2089. {$ifdef Unix}
  2090. if configpath='' then
  2091. configpath:=ExpandFileName(FixPath(exepath+'../etc/',false));
  2092. {$endif}
  2093. {
  2094. Order to read configuration file :
  2095. try reading fpc.cfg in :
  2096. 1 - current dir
  2097. 2 - configpath
  2098. 3 - compiler path
  2099. }
  2100. if not FileExists(fn) then
  2101. begin
  2102. {$ifdef Unix}
  2103. hs:=GetEnvironmentVariable('HOME');
  2104. if (hs<>'') and CfgFileExists(FixPath(hs,false)+'.'+fn) then
  2105. foundfn:=FixPath(hs,false)+'.'+fn
  2106. else
  2107. {$endif}
  2108. if CfgFileExists(configpath+fn) then
  2109. foundfn:=configpath+fn
  2110. else
  2111. {$ifndef Unix}
  2112. if CfgFileExists(exepath+fn) then
  2113. foundfn:=exepath+fn
  2114. else
  2115. {$else}
  2116. if CfgFileExists('/etc/'+fn) then
  2117. foundfn:='/etc/'+fn
  2118. else
  2119. {$endif}
  2120. check_configfile:=false;
  2121. end;
  2122. end;
  2123. procedure read_arguments(cmd:string);
  2124. var
  2125. env: ansistring;
  2126. i : tfeature;
  2127. abi : tabi;
  2128. begin
  2129. option:=coption.create;
  2130. disable_configfile:=false;
  2131. { Non-core target defines }
  2132. Option.TargetOptions(true);
  2133. { get default messagefile }
  2134. msgfilename:=GetEnvironmentVariable('PPC_ERROR_FILE');
  2135. { default configfile can be specified on the commandline,
  2136. remove it first }
  2137. if (cmd<>'') and (cmd[1]='[') then
  2138. begin
  2139. ppccfg:=Copy(cmd,2,pos(']',cmd)-2);
  2140. Delete(cmd,1,pos(']',cmd));
  2141. end
  2142. else
  2143. begin
  2144. ppccfg:='fpc.cfg';
  2145. ppcaltcfg:='ppc386.cfg';
  2146. end;
  2147. { first pass reading of parameters, only -i -v -T etc.}
  2148. option.firstpass:=true;
  2149. if cmd<>'' then
  2150. option.parsecmd(cmd)
  2151. else
  2152. begin
  2153. option.read_parameters;
  2154. { Write only quickinfo }
  2155. if option.quickinfo<>'' then
  2156. option.writequickinfo;
  2157. end;
  2158. option.firstpass:=false;
  2159. { target is set here, for wince the default app type is gui }
  2160. if target_info.system in system_wince then
  2161. apptype:=app_gui;
  2162. { default defines }
  2163. def_system_macro(target_info.shortname);
  2164. def_system_macro('FPC');
  2165. def_system_macro('VER'+version_nr);
  2166. def_system_macro('VER'+version_nr+'_'+release_nr);
  2167. def_system_macro('VER'+version_nr+'_'+release_nr+'_'+patch_nr);
  2168. { Temporary defines, until things settle down }
  2169. { "main" symbol is generated in the main program, and left out of the system unit }
  2170. def_system_macro('FPC_DARWIN_PASCALMAIN');
  2171. def_system_macro('FPC_DARWIN_JMP_MAIN');
  2172. def_system_macro('PARAOUTFILE');
  2173. def_system_macro('RESSTRSECTIONS');
  2174. def_system_macro('FPC_HASFIXED64BITVARIANT');
  2175. def_system_macro('FPC_HASINTERNALOLEVARIANT2VARIANTCAST');
  2176. def_system_macro('FPC_HAS_VARSETS');
  2177. def_system_macro('FPC_HAS_VALGRINDBOOL');
  2178. def_system_macro('FPC_HAS_STR_CURRENCY');
  2179. def_system_macro('FPC_REAL2REAL_FIXED');
  2180. def_system_macro('FPC_STRTOCHARARRAYPROC');
  2181. def_system_macro('FPC_NEW_BIGENDIAN_SETS');
  2182. def_system_macro('FPC_STRTOSHORTSTRINGPROC');
  2183. def_system_macro('FPC_OBJFPC_EXTENDED_IF');
  2184. {$if defined(x86) or defined(powerpc) or defined(powerpc64)}
  2185. def_system_macro('FPC_HAS_INTERNAL_ABS_LONG');
  2186. {$endif}
  2187. def_system_macro('FPC_HAS_UNICODESTRING');
  2188. { these cpus have an inline rol/ror implementaion }
  2189. {$if defined(x86) or defined(arm) or defined(powerpc) or defined(powerpc64)}
  2190. def_system_macro('FPC_HAS_INTERNAL_ROX');
  2191. {$endif}
  2192. {$ifdef SUPPORT_UNALIGNED}
  2193. def_system_macro('FPC_SUPPORTS_UNALIGNED');
  2194. def_system_macro('FPC_UNALIGNED_FIXED');
  2195. {$endif SUPPORT_UNALIGNED}
  2196. {$ifdef powerpc64}
  2197. def_system_macro('FPC_HAS_LWSYNC');
  2198. {$endif}
  2199. def_system_macro('FPC_HAS_MEMBAR');
  2200. def_system_macro('FPC_SETBASE_USED');
  2201. {$if defined(x86) or defined(arm)}
  2202. def_system_macro('INTERNAL_BACKTRACE');
  2203. {$endif}
  2204. def_system_macro('STR_CONCAT_PROCS');
  2205. {$warnings off}
  2206. if pocall_default = pocall_register then
  2207. def_system_macro('REGCALL');
  2208. {$warnings on}
  2209. { don't remove this, it's also for fpdoc necessary (FK) }
  2210. def_system_macro('FPC_HAS_FEATURE_SUPPORT');
  2211. { using a case is pretty useless here (FK) }
  2212. { some stuff for TP compatibility }
  2213. {$ifdef i386}
  2214. def_system_macro('CPU86');
  2215. def_system_macro('CPU87');
  2216. def_system_macro('CPU386');
  2217. {$endif}
  2218. { new processor stuff }
  2219. {$ifdef i386}
  2220. def_system_macro('CPUI386');
  2221. def_system_macro('CPU32');
  2222. def_system_macro('FPC_HAS_TYPE_EXTENDED');
  2223. def_system_macro('FPC_HAS_TYPE_DOUBLE');
  2224. def_system_macro('FPC_HAS_TYPE_SINGLE');
  2225. {$endif}
  2226. {$ifdef m68k}
  2227. def_system_macro('CPU68');
  2228. def_system_macro('CPU68K');
  2229. def_system_macro('CPUM68K');
  2230. def_system_macro('CPU32');
  2231. def_system_macro('FPC_CURRENCY_IS_INT64');
  2232. def_system_macro('FPC_COMP_IS_INT64');
  2233. {$endif}
  2234. {$ifdef ALPHA}
  2235. def_system_macro('CPUALPHA');
  2236. def_system_macro('CPU64');
  2237. {$endif}
  2238. {$ifdef powerpc}
  2239. def_system_macro('CPUPOWERPC');
  2240. def_system_macro('CPUPOWERPC32');
  2241. def_system_macro('CPU32');
  2242. def_system_macro('FPC_CURRENCY_IS_INT64');
  2243. def_system_macro('FPC_COMP_IS_INT64');
  2244. {$endif}
  2245. {$ifdef POWERPC64}
  2246. def_system_macro('CPUPOWERPC');
  2247. def_system_macro('CPUPOWERPC64');
  2248. def_system_macro('CPU64');
  2249. def_system_macro('FPC_CURRENCY_IS_INT64');
  2250. def_system_macro('FPC_COMP_IS_INT64');
  2251. {$endif}
  2252. {$ifdef iA64}
  2253. def_system_macro('CPUIA64');
  2254. def_system_macro('CPU64');
  2255. {$endif}
  2256. {$ifdef x86_64}
  2257. def_system_macro('CPUX86_64');
  2258. def_system_macro('CPUAMD64');
  2259. def_system_macro('CPU64');
  2260. { not supported for now, afaik (FK)
  2261. def_system_macro('FPC_HAS_TYPE_FLOAT128'); }
  2262. { win64 doesn't support the legacy fpu }
  2263. if target_info.system=system_x86_64_win64 then
  2264. begin
  2265. def_system_macro('FPC_CURRENCY_IS_INT64');
  2266. def_system_macro('FPC_COMP_IS_INT64');
  2267. end;
  2268. {$endif}
  2269. {$ifdef sparc}
  2270. def_system_macro('CPUSPARC');
  2271. def_system_macro('CPUSPARC32');
  2272. def_system_macro('CPU32');
  2273. def_system_macro('FPC_CURRENCY_IS_INT64');
  2274. def_system_macro('FPC_COMP_IS_INT64');
  2275. {$endif}
  2276. {$ifdef vis}
  2277. def_system_macro('CPUVIS');
  2278. def_system_macro('CPU32');
  2279. {$endif}
  2280. {$ifdef arm}
  2281. def_system_macro('CPUARM');
  2282. def_system_macro('CPU32');
  2283. def_system_macro('FPC_CURRENCY_IS_INT64');
  2284. def_system_macro('FPC_COMP_IS_INT64');
  2285. {$endif arm}
  2286. {$ifdef avr}
  2287. def_system_macro('CPUAVR');
  2288. def_system_macro('CPU16');
  2289. def_system_macro('FPC_CURRENCY_IS_INT64');
  2290. def_system_macro('FPC_COMP_IS_INT64');
  2291. {$endif avr}
  2292. { read configuration file }
  2293. if (not disable_configfile) and
  2294. (ppccfg<>'') then
  2295. begin
  2296. read_configfile:=check_configfile(ppccfg,ppccfg);
  2297. { Maybe alternative configfile ? }
  2298. if (not read_configfile) and
  2299. (ppcaltcfg<>'') then
  2300. begin
  2301. read_configfile:=check_configfile(ppcaltcfg,ppccfg);
  2302. if read_configfile then
  2303. message(option_ppc386_deprecated);
  2304. end;
  2305. end
  2306. else
  2307. read_configfile := false;
  2308. { Read commandline and configfile }
  2309. param_file:='';
  2310. { read configfile }
  2311. if read_configfile then
  2312. option.interpret_file(ppccfg);
  2313. { read parameters again to override config file }
  2314. if cmd<>'' then
  2315. option.parsecmd(cmd)
  2316. else
  2317. begin
  2318. { Write help pages if no parameters are passed }
  2319. if (paramcount=0) then
  2320. Option.WriteHelpPages;
  2321. option.read_parameters;
  2322. { Write only quickinfo }
  2323. if option.quickinfo<>'' then
  2324. option.writequickinfo;
  2325. end;
  2326. { Stop if errors in options }
  2327. if ErrorCount>0 then
  2328. StopOptions(1);
  2329. { endian define }
  2330. case target_info.endian of
  2331. endian_little :
  2332. begin
  2333. def_system_macro('ENDIAN_LITTLE');
  2334. def_system_macro('FPC_LITTLE_ENDIAN');
  2335. end;
  2336. endian_big :
  2337. begin
  2338. def_system_macro('ENDIAN_BIG');
  2339. def_system_macro('FPC_BIG_ENDIAN');
  2340. end;
  2341. end;
  2342. { define abi }
  2343. for abi:=low(tabi) to high(tabi) do
  2344. undef_system_macro('FPC_ABI_'+abi2str[abi]);
  2345. def_system_macro('FPC_ABI_'+abi2str[target_info.abi]);
  2346. { Write logo }
  2347. if option.ParaLogo then
  2348. option.writelogo;
  2349. { Check file to compile }
  2350. if param_file='' then
  2351. begin
  2352. Message(option_no_source_found);
  2353. StopOptions(1);
  2354. end;
  2355. {$ifndef Unix}
  2356. param_file:=FixFileName(param_file);
  2357. {$endif not unix}
  2358. inputfilepath:=ExtractFilePath(param_file);
  2359. inputfilename:=ExtractFileName(param_file);
  2360. if ExtractFileExt(inputfilename)='' then
  2361. begin
  2362. if FileExists(inputfilepath+ChangeFileExt(inputfilename,sourceext)) then
  2363. inputfilename:=ChangeFileExt(inputfilename,sourceext)
  2364. else if FileExists(inputfilepath+ChangeFileExt(inputfilename,pasext)) then
  2365. inputfilename:=ChangeFileExt(inputfilename,pasext)
  2366. else if ((m_mac in current_settings.modeswitches) or
  2367. (tf_p_ext_support in target_info.flags))
  2368. and FileExists(inputfilepath+ChangeFileExt(inputfilename,pext)) then
  2369. inputfilename:=ChangeFileExt(inputfilename,pext);
  2370. end;
  2371. { Check output dir }
  2372. if (OutputExeDir<>'') and
  2373. not PathExists(OutputExeDir,false) then
  2374. begin
  2375. Message1(general_e_path_does_not_exist,OutputExeDir);
  2376. StopOptions(1);
  2377. end;
  2378. { Add paths specified with parameters to the searchpaths }
  2379. UnitSearchPath.AddList(option.ParaUnitPath,true);
  2380. ObjectSearchPath.AddList(option.ParaObjectPath,true);
  2381. IncludeSearchPath.AddList(option.ParaIncludePath,true);
  2382. LibrarySearchPath.AddList(option.ParaLibraryPath,true);
  2383. FrameworkSearchPath.AddList(option.ParaFrameworkPath,true);
  2384. { add unit environment and exepath to the unit search path }
  2385. if inputfilepath<>'' then
  2386. Unitsearchpath.AddPath(inputfilepath,true);
  2387. if not disable_configfile then
  2388. begin
  2389. env:=GetEnvironmentVariable(target_info.unit_env);
  2390. if env<>'' then
  2391. UnitSearchPath.AddPath(GetEnvironmentVariable(target_info.unit_env),false);
  2392. end;
  2393. {$ifdef Unix}
  2394. fpcdir:=FixPath(GetEnvironmentVariable('FPCDIR'),false);
  2395. if fpcdir='' then
  2396. begin
  2397. if PathExists('/usr/local/lib/fpc/'+version_string,true) then
  2398. fpcdir:='/usr/local/lib/fpc/'+version_string+'/'
  2399. else
  2400. fpcdir:='/usr/lib/fpc/'+version_string+'/';
  2401. end;
  2402. {$else unix}
  2403. fpcdir:=FixPath(GetEnvironmentVariable('FPCDIR'),false);
  2404. if fpcdir='' then
  2405. begin
  2406. fpcdir:=ExePath+'../';
  2407. if not(PathExists(fpcdir+'units',true)) and
  2408. not(PathExists(fpcdir+'rtl',true)) then
  2409. fpcdir:=fpcdir+'../';
  2410. end;
  2411. {$endif unix}
  2412. { first try development RTL, else use the default installation path }
  2413. if not disable_configfile then
  2414. begin
  2415. if PathExists(FpcDir+'rtl',true) then
  2416. if tf_use_8_3 in Source_Info.Flags then
  2417. UnitSearchPath.AddPath(FpcDir+'rtl/'+target_os_string,false)
  2418. else
  2419. UnitSearchPath.AddPath(FpcDir+'rtl/'+target_full_string,false)
  2420. else
  2421. if tf_use_8_3 in Source_Info.Flags then
  2422. UnitSearchPath.AddPath(FpcDir+'units/'+target_os_string+'/rtl',false)
  2423. else
  2424. UnitSearchPath.AddPath(FpcDir+'units/'+target_full_string+'/rtl',false);
  2425. end;
  2426. { Add exepath if the exe is not in the current dir, because that is always searched already.
  2427. Do not add it when linking on the target because then we can maybe already find
  2428. .o files that are not for the target }
  2429. if (ExePath<>GetCurrentDir) and
  2430. not(cs_link_on_target in init_settings.globalswitches) then
  2431. UnitSearchPath.AddPath(ExePath,false);
  2432. { Add unit dir to the object and library path }
  2433. objectsearchpath.AddList(unitsearchpath,false);
  2434. librarysearchpath.AddList(unitsearchpath,false);
  2435. { maybe override assembler }
  2436. if (paratargetasm<>as_none) then
  2437. begin
  2438. if not set_target_asm(paratargetasm) then
  2439. begin
  2440. Message2(option_incompatible_asm,asminfos[paratargetasm]^.idtxt,target_info.name);
  2441. set_target_asm(target_info.assemextern);
  2442. Message1(option_asm_forced,target_asm.idtxt);
  2443. end;
  2444. if (af_no_debug in asminfos[paratargetasm]^.flags) and
  2445. (paratargetdbg<>dbg_none) then
  2446. begin
  2447. Message1(option_confict_asm_debug,
  2448. asminfos[paratargetasm]^.idtxt);
  2449. paratargetdbg:=dbg_none;
  2450. exclude(init_settings.moduleswitches,cs_debuginfo);
  2451. end;
  2452. end;
  2453. { maybe override debug info format }
  2454. if (paratargetdbg<>dbg_none) then
  2455. set_target_dbg(paratargetdbg);
  2456. { switch assembler if it's binary and we got -a on the cmdline }
  2457. if (cs_asm_leave in init_settings.globalswitches) and
  2458. (af_outputbinary in target_asm.flags) then
  2459. begin
  2460. Message(option_switch_bin_to_src_assembler);
  2461. set_target_asm(target_info.assemextern);
  2462. end;
  2463. { Force use of external linker if there is no
  2464. internal linker or the linking is skipped }
  2465. if not(cs_link_extern in init_settings.globalswitches) and
  2466. (not assigned(target_info.link) or
  2467. (cs_link_nolink in init_settings.globalswitches)) then
  2468. include(init_settings.globalswitches,cs_link_extern);
  2469. { turn off stripping if compiling with debuginfo or profile }
  2470. if (
  2471. (cs_debuginfo in init_settings.moduleswitches) or
  2472. (cs_profile in init_settings.moduleswitches)
  2473. ) and
  2474. not(cs_link_separate_dbg_file in init_settings.globalswitches) then
  2475. exclude(init_settings.globalswitches,cs_link_strip);
  2476. { force fpu emulation on arm/wince, arm/gba and arm/nds}
  2477. if (target_info.system in [system_arm_wince,system_arm_gba,system_m68k_amiga,
  2478. system_m68k_linux,system_arm_nds,system_arm_darwin])
  2479. {$ifdef arm}
  2480. or (init_settings.fputype=fpu_soft)
  2481. or (target_info.abi=abi_eabi)
  2482. {$endif arm}
  2483. then
  2484. begin
  2485. {$ifdef cpufpemu}
  2486. include(init_settings.moduleswitches,cs_fp_emulation);
  2487. { cs_fp_emulation and fpu_soft are equal on arm }
  2488. init_settings.fputype:=fpu_soft;
  2489. {$endif cpufpemu}
  2490. end;
  2491. { now we can define cpu and fpu type }
  2492. def_system_macro('CPU'+Cputypestr[init_settings.cputype]);
  2493. def_system_macro('FPU'+fputypestr[init_settings.fputype]);
  2494. if init_settings.fputype<>fpu_none then
  2495. begin
  2496. {$if defined(i386)}
  2497. def_system_macro('FPC_HAS_TYPE_EXTENDED');
  2498. {$endif}
  2499. def_system_macro('FPC_HAS_TYPE_SINGLE');
  2500. def_system_macro('FPC_HAS_TYPE_DOUBLE');
  2501. {$if not defined(i386) and not defined(x86_64)}
  2502. def_system_macro('FPC_INCLUDE_SOFTWARE_INT64_TO_DOUBLE');
  2503. {$endif}
  2504. {$ifdef x86_64}
  2505. { win64 doesn't support the legacy fpu }
  2506. if target_info.system=system_x86_64_win64 then
  2507. undef_system_macro('FPC_HAS_TYPE_EXTENDED')
  2508. else
  2509. def_system_macro('FPC_HAS_TYPE_EXTENDED');
  2510. {$endif}
  2511. end;
  2512. {$ifdef ARM}
  2513. { define FPC_DOUBLE_HILO_SWAPPED if needed to properly handle doubles in RTL }
  2514. if (init_settings.fputype in [fpu_fpa,fpu_fpa10,fpu_fpa11]) and
  2515. not(cs_fp_emulation in init_settings.moduleswitches) then
  2516. def_system_macro('FPC_DOUBLE_HILO_SWAPPED');
  2517. {$endif ARM}
  2518. { Section smartlinking conflicts with import sections on Windows }
  2519. if GenerateImportSection and
  2520. (target_info.system in [system_i386_win32,system_x86_64_win64]) then
  2521. exclude(target_info.flags,tf_smartlink_sections);
  2522. if not LinkTypeSetExplicitly then
  2523. set_default_link_type;
  2524. { Default alignment settings,
  2525. 1. load the defaults for the target
  2526. 2. override with generic optimizer setting (little size)
  2527. 3. override with the user specified -Oa }
  2528. UpdateAlignment(init_settings.alignment,target_info.alignment);
  2529. if (cs_opt_size in current_settings.optimizerswitches) then
  2530. begin
  2531. init_settings.alignment.procalign:=1;
  2532. init_settings.alignment.jumpalign:=1;
  2533. init_settings.alignment.loopalign:=1;
  2534. end;
  2535. UpdateAlignment(init_settings.alignment,option.paraalignment);
  2536. set_system_macro('FPC_VERSION',version_nr);
  2537. set_system_macro('FPC_RELEASE',release_nr);
  2538. set_system_macro('FPC_PATCH',patch_nr);
  2539. set_system_macro('FPC_FULLVERSION',Format('%d%.02d%.02d',[StrToInt(version_nr),StrToInt(release_nr),StrToInt(patch_nr)]));
  2540. if not(target_info.system in system_all_windows) then
  2541. def_system_macro('FPC_WIDESTRING_EQUAL_UNICODESTRING');
  2542. for i:=low(tfeature) to high(tfeature) do
  2543. if i in features then
  2544. def_system_macro('FPC_HAS_FEATURE_'+featurestr[i]);
  2545. option.free;
  2546. Option:=nil;
  2547. end;
  2548. initialization
  2549. coption:=toption;
  2550. finalization
  2551. if assigned(option) then
  2552. option.free;
  2553. end.