options.pas 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl and Peter Vreman
  4. Reads command line options and config files
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit options;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. globtype,globals,verbose;
  23. type
  24. TOption=class
  25. FirstPass,
  26. NoPressEnter,
  27. DoWriteLogo : boolean;
  28. FileLevel : longint;
  29. QuickInfo : string;
  30. ParaIncludePath,
  31. ParaUnitPath,
  32. ParaObjectPath,
  33. ParaLibraryPath : TSearchPathList;
  34. Constructor Create;
  35. Destructor Destroy;override;
  36. procedure WriteLogo;
  37. procedure WriteInfo;
  38. procedure WriteHelpPages;
  39. procedure WriteQuickInfo;
  40. procedure IllegalPara(const opt:string);
  41. function Unsetbool(const opts:string; pos: Longint):boolean;
  42. procedure interpret_proc_specific_options(const opt:string);virtual;
  43. procedure interpret_option(const opt :string;ispara:boolean);
  44. procedure Interpret_envvar(const envname : string);
  45. procedure Interpret_file(const filename : string);
  46. procedure Read_Parameters;
  47. procedure parsecmd(cmd:string);
  48. end;
  49. var
  50. coption : class of toption;
  51. procedure read_arguments(cmd:string);
  52. implementation
  53. uses
  54. {$ifdef Delphi}
  55. dmisc,
  56. {$else Delphi}
  57. dos,
  58. {$endif Delphi}
  59. version,systems,
  60. cutils,cobjects,messages
  61. {$ifdef BrowserLog}
  62. ,browlog
  63. {$endif BrowserLog}
  64. ;
  65. const
  66. page_size = 24;
  67. var
  68. option : toption;
  69. read_configfile, { read config file, set when a cfgfile is found }
  70. disable_configfile,
  71. target_is_set : boolean; { do not allow contradictory target settings }
  72. asm_is_set : boolean; { -T also change initoutputformat if not set idrectly }
  73. fpcdir,
  74. ppccfg,
  75. msgfilename,
  76. param_file : string; { file to compile specified on the commandline }
  77. {****************************************************************************
  78. Defines
  79. ****************************************************************************}
  80. procedure def_symbol(const s : string);
  81. begin
  82. if s='' then
  83. exit;
  84. initdefines.insert(upper(s));
  85. end;
  86. procedure undef_symbol(const s : string);
  87. begin
  88. if s='' then
  89. exit;
  90. InitDefines.Remove(s);
  91. end;
  92. function check_symbol(const s:string):boolean;
  93. begin
  94. check_symbol:=(initdefines.find(s)<>nil);
  95. end;
  96. procedure MaybeLoadMessageFile;
  97. begin
  98. { Load new message file }
  99. if (msgfilename<>'') then
  100. begin
  101. if fileexists(msgfilename) then
  102. LoadMsgFile(msgfilename);
  103. msgfilename:='';
  104. end;
  105. end;
  106. {****************************************************************************
  107. Toption
  108. ****************************************************************************}
  109. procedure StopOptions;
  110. begin
  111. if assigned(Option) then
  112. begin
  113. Option.free;
  114. Option:=nil;
  115. end;
  116. DoneVerbose;
  117. Stop;
  118. end;
  119. procedure Toption.WriteLogo;
  120. var
  121. p : pchar;
  122. begin
  123. MaybeLoadMessageFile;
  124. p:=MessagePchar(option_logo);
  125. while assigned(p) do
  126. Comment(V_Normal,GetMsgLine(p));
  127. end;
  128. procedure Toption.WriteInfo;
  129. var
  130. p : pchar;
  131. begin
  132. MaybeLoadMessageFile;
  133. p:=MessagePchar(option_info);
  134. while assigned(p) do
  135. Comment(V_Normal,GetMsgLine(p));
  136. StopOptions;
  137. end;
  138. procedure Toption.WriteHelpPages;
  139. function PadEnd(s:string;i:longint):string;
  140. begin
  141. while (length(s)<i) do
  142. s:=s+' ';
  143. PadEnd:=s;
  144. end;
  145. var
  146. lastident,
  147. j,outline,
  148. ident,
  149. lines : longint;
  150. show : boolean;
  151. opt : string[32];
  152. input,
  153. s : string;
  154. p : pchar;
  155. begin
  156. MaybeLoadMessageFile;
  157. Message1(option_usage,system.paramstr(0));
  158. lastident:=0;
  159. if DoWriteLogo then
  160. lines:=3
  161. else
  162. lines:=1;
  163. p:=MessagePChar(option_help_pages);
  164. while assigned(p) do
  165. begin
  166. { get a line and reset }
  167. s:=GetMsgLine(p);
  168. ident:=0;
  169. show:=false;
  170. { parse options }
  171. case s[1] of
  172. {$ifdef i386}
  173. '3',
  174. {$endif}
  175. {$ifdef m68k}
  176. '6',
  177. {$endif}
  178. '*' : show:=true;
  179. end;
  180. if show then
  181. begin
  182. case s[2] of
  183. {$ifdef GDB}
  184. 'g',
  185. {$endif}
  186. {$ifdef Unix}
  187. 'L',
  188. {$endif}
  189. {$ifdef os2}
  190. 'O',
  191. {$endif}
  192. '*' : show:=true;
  193. else
  194. show:=false;
  195. end;
  196. end;
  197. { now we may show the message or not }
  198. if show then
  199. begin
  200. case s[3] of
  201. '0' : begin
  202. ident:=0;
  203. outline:=0;
  204. end;
  205. '1' : begin
  206. ident:=2;
  207. outline:=7;
  208. end;
  209. '2' : begin
  210. ident:=11;
  211. outline:=11;
  212. end;
  213. '3' : begin
  214. ident:=21;
  215. outline:=6;
  216. end;
  217. end;
  218. j:=pos('_',s);
  219. opt:=Copy(s,4,j-4);
  220. if opt='*' then
  221. opt:=''
  222. else
  223. opt:=PadEnd('-'+opt,outline);
  224. if (ident=0) and (lastident<>0) then
  225. begin
  226. Comment(V_Normal,'');
  227. inc(Lines);
  228. end;
  229. { page full ? }
  230. if (lines>=page_size) then
  231. begin
  232. if not NoPressEnter then
  233. begin
  234. write('*** press enter ***');
  235. readln(input);
  236. if upper(input)='Q' then
  237. StopOptions;
  238. end;
  239. lines:=0;
  240. end;
  241. Comment(V_Normal,PadEnd('',ident)+opt+Copy(s,j+1,255));
  242. LastIdent:=Ident;
  243. inc(Lines);
  244. end;
  245. end;
  246. StopOptions;
  247. end;
  248. procedure Toption.IllegalPara(const opt:string);
  249. begin
  250. Message1(option_illegal_para,opt);
  251. Message(option_help_pages_para);
  252. StopOptions;
  253. end;
  254. function Toption.Unsetbool(const opts:string; pos: Longint):boolean;
  255. { checks if the character after pos in Opts is a + or a - and returns resp.
  256. false or true. If it is another character (or none), it also returns false }
  257. begin
  258. UnsetBool := (Length(Opts) > Pos) And (Opts[Succ(Pos)] = '-');
  259. end;
  260. procedure TOption.interpret_proc_specific_options(const opt:string);
  261. begin
  262. end;
  263. procedure TOption.interpret_option(const opt:string;ispara:boolean);
  264. var
  265. code : integer;
  266. c : char;
  267. more : string;
  268. major,minor : longint;
  269. error : integer;
  270. j,l : longint;
  271. d : DirStr;
  272. e : ExtStr;
  273. begin
  274. if opt='' then
  275. exit;
  276. { only parse define,undef,target,verbosity and link options the firsttime }
  277. if firstpass and
  278. not((opt[1]='-') and (opt[2] in ['i','d','v','T','u','n','X'])) then
  279. exit;
  280. Message1(option_handling_option,opt);
  281. case opt[1] of
  282. '-' : begin
  283. more:=Copy(opt,3,255);
  284. case opt[2] of
  285. '!' : initlocalswitches:=initlocalswitches+[cs_ansistrings];
  286. '?' : WriteHelpPages;
  287. 'a' : begin
  288. initglobalswitches:=initglobalswitches+[cs_asm_leave];
  289. for j:=1 to length(more) do
  290. case more[j] of
  291. 'l' : initglobalswitches:=initglobalswitches+[cs_asm_source];
  292. 'r' : initglobalswitches:=initglobalswitches+[cs_asm_regalloc];
  293. 't' : initglobalswitches:=initglobalswitches+[cs_asm_tempalloc];
  294. '-' : initglobalswitches:=initglobalswitches-[cs_asm_leave,cs_asm_source,cs_asm_regalloc];
  295. else
  296. IllegalPara(opt);
  297. end;
  298. end;
  299. 'A' : begin
  300. if set_string_asm(More) then
  301. begin
  302. initoutputformat:=target_asm.id;
  303. asm_is_set:=true;
  304. end
  305. else
  306. IllegalPara(opt);
  307. end;
  308. 'b' : begin
  309. {$ifdef BrowserLog}
  310. initglobalswitches:=initglobalswitches+[cs_browser_log];
  311. {$endif}
  312. if More<>'' then
  313. if More='l' then
  314. initmoduleswitches:=initmoduleswitches+[cs_local_browser]
  315. else if More='-' then
  316. begin
  317. initmoduleswitches:=initmoduleswitches-[cs_browser,cs_local_browser];
  318. {$ifdef BrowserLog}
  319. initglobalswitches:=initglobalswitches-[cs_browser_log];
  320. {$endif}
  321. end
  322. else if More<>'+' then
  323. {$ifdef BrowserLog}
  324. browserlog.elements_to_list.insert(more);
  325. {$else}
  326. IllegalPara(opt);
  327. {$endif}
  328. end;
  329. 'B' : if more='' then
  330. do_build:=true
  331. else
  332. if more = '-' then
  333. do_build := False
  334. else
  335. IllegalPara(opt);
  336. 'C' : begin
  337. j := 1;
  338. while j <= length(more) Do
  339. Begin
  340. case more[j] of
  341. 'a' : Simplify_ppu:=true;
  342. 'h' :
  343. begin
  344. val(copy(more,j+1,length(more)-j),heapsize,code);
  345. if (code<>0) or (heapsize>=67107840) or (heapsize<1024) then
  346. IllegalPara(opt);
  347. break;
  348. end;
  349. 'i' : If UnsetBool(More, j) then
  350. Begin
  351. initlocalswitches:=initlocalswitches-[cs_check_io];
  352. inc(j)
  353. End
  354. else initlocalswitches:=initlocalswitches+[cs_check_io];
  355. 'n' : If UnsetBool(More, j) then
  356. Begin
  357. initglobalswitches:=initglobalswitches-[cs_link_extern];
  358. inc(j)
  359. End
  360. Else initglobalswitches:=initglobalswitches+[cs_link_extern];
  361. 'o' :
  362. If UnsetBool(More, j) then
  363. Begin
  364. initlocalswitches:=initlocalswitches-[cs_check_overflow];
  365. inc(j);
  366. End
  367. Else
  368. initlocalswitches:=initlocalswitches+[cs_check_overflow];
  369. 'r' :
  370. If UnsetBool(More, j) then
  371. Begin
  372. initlocalswitches:=initlocalswitches-[cs_check_range];
  373. inc(j);
  374. End
  375. Else
  376. initlocalswitches:=initlocalswitches+[cs_check_range];
  377. 'R' :
  378. If UnsetBool(More, j) then
  379. Begin
  380. initlocalswitches:=initlocalswitches-[cs_check_object_ext];
  381. inc(j);
  382. End
  383. Else
  384. initlocalswitches:=initlocalswitches+[cs_check_object_ext];
  385. 's' :
  386. begin
  387. val(copy(more,j+1,length(more)-j),stacksize,code);
  388. if (code<>0) or (stacksize>=67107840) or (stacksize<1024) then
  389. IllegalPara(opt);
  390. break;
  391. end;
  392. 't' :
  393. If UnsetBool(More, j) then
  394. Begin
  395. initlocalswitches:=initlocalswitches-[cs_check_stack];
  396. inc(j)
  397. End
  398. Else
  399. initlocalswitches:=initlocalswitches+[cs_check_stack];
  400. 'D' :
  401. If UnsetBool(More, j) then
  402. Begin
  403. initmoduleswitches:=initmoduleswitches-[cs_create_dynamic];
  404. inc(j)
  405. End
  406. Else
  407. initmoduleswitches:=initmoduleswitches+[cs_create_dynamic];
  408. 'X' :
  409. If UnsetBool(More, j) then
  410. Begin
  411. initmoduleswitches:=initmoduleswitches-[cs_create_smart];
  412. inc(j)
  413. End
  414. Else
  415. initmoduleswitches:=initmoduleswitches+[cs_create_smart];
  416. else
  417. IllegalPara(opt);
  418. end;
  419. inc(j);
  420. end;
  421. end;
  422. 'd' : def_symbol(more);
  423. 'D' : begin
  424. initglobalswitches:=initglobalswitches+[cs_link_deffile];
  425. for j:=1 to length(more) do
  426. case more[j] of
  427. 'd' : begin
  428. description:=Copy(more,j+1,255);
  429. break;
  430. end;
  431. 'v' : begin
  432. dllversion:=Copy(more,j+1,255);
  433. l:=pos('.',dllversion);
  434. dllminor:=0;
  435. error:=0;
  436. if l>0 then
  437. begin
  438. valint(copy(dllversion,l+1,255),minor,error);
  439. if (error=0) and
  440. (minor>=0) and (minor<=$ffff) then
  441. dllminor:=minor
  442. else if error=0 then
  443. error:=1;
  444. end;
  445. if l=0 then l:=256;
  446. dllmajor:=1;
  447. if error=0 then
  448. valint(copy(dllversion,1,l-1),major,error);
  449. if (error=0) and (major>=0) and (major<=$ffff) then
  450. dllmajor:=major
  451. else if error=0 then
  452. error:=1;
  453. if error<>0 then
  454. Message1(scan_w_wrong_version_ignored,dllversion);
  455. break;
  456. end;
  457. 'w' : usewindowapi:=true;
  458. else
  459. IllegalPara(opt);
  460. end;
  461. end;
  462. 'e' : exepath:=FixPath(More,true);
  463. { Just used by RHIDE }
  464. 'E' : if (length(more)=0) or (UnsetBool(More, 0)) then
  465. initglobalswitches:=initglobalswitches+[cs_link_extern]
  466. else
  467. initglobalswitches:=initglobalswitches-[cs_link_extern];
  468. 'F' : begin
  469. c:=more[1];
  470. Delete(more,1,1);
  471. case c of
  472. 'D' : begin
  473. if not ispara then
  474. DefaultReplacements(More);
  475. utilsdirectory:=FixPath(More,true);
  476. end;
  477. 'e' : SetRedirectFile(More);
  478. 'E' : OutputExeDir:=FixPath(More,true);
  479. 'i' : if ispara then
  480. ParaIncludePath.AddPath(More,false)
  481. else
  482. includesearchpath.AddPath(More,true);
  483. 'g' : Message2(option_obsolete_switch_use_new,'-Fg','-Fl');
  484. 'l' : if ispara then
  485. ParaLibraryPath.AddPath(More,false)
  486. else
  487. LibrarySearchPath.AddPath(More,true);
  488. 'L' : if More<>'' then
  489. ParaDynamicLinker:=More
  490. else
  491. IllegalPara(opt);
  492. 'o' : if ispara then
  493. ParaObjectPath.AddPath(More,false)
  494. else
  495. ObjectSearchPath.AddPath(More,true);
  496. 'r' : Msgfilename:=More;
  497. 'u' : if ispara then
  498. ParaUnitPath.AddPath(More,false)
  499. else
  500. unitsearchpath.AddPath(More,true);
  501. 'U' : OutputUnitDir:=FixPath(More,true);
  502. else
  503. IllegalPara(opt);
  504. end;
  505. end;
  506. 'g' : begin
  507. if UnsetBool(More, 0) then
  508. begin
  509. initmoduleswitches:=initmoduleswitches-[cs_debuginfo];
  510. if (length(More)>1) and (More[2]='l') then
  511. initglobalswitches:=initglobalswitches+[cs_gdb_lineinfo];
  512. end
  513. else
  514. begin
  515. {$ifdef GDB}
  516. initmoduleswitches:=initmoduleswitches+[cs_debuginfo];
  517. if not RelocSectionSetExplicitly then
  518. RelocSection:=false;
  519. for j:=1 to length(more) do
  520. case more[j] of
  521. 'd' : initglobalswitches:=initglobalswitches+[cs_gdb_dbx];
  522. 'g' : initglobalswitches:=initglobalswitches+[cs_gdb_gsym];
  523. 'h' : initglobalswitches:=initglobalswitches+[cs_gdb_heaptrc];
  524. 'l' : initglobalswitches:=initglobalswitches+[cs_gdb_lineinfo];
  525. 'c' : initglobalswitches:=initglobalswitches+[cs_checkpointer];
  526. {$ifdef EXTDEBUG}
  527. 'p' : only_one_pass:=true;
  528. {$endif EXTDEBUG}
  529. else
  530. IllegalPara(opt);
  531. end;
  532. {$else GDB}
  533. Message(option_no_debug_support);
  534. Message(option_no_debug_support_recompile_fpc);
  535. {$endif GDB}
  536. end;
  537. end;
  538. 'h' : begin
  539. NoPressEnter:=true;
  540. WriteHelpPages;
  541. end;
  542. 'i' : if More='' then
  543. WriteInfo
  544. else
  545. QuickInfo:=QuickInfo+More;
  546. 'I' : if ispara then
  547. ParaIncludePath.AddPath(More,false)
  548. else
  549. includesearchpath.AddPath(More,false);
  550. 'k' : if more<>'' then
  551. ParaLinkOptions:=ParaLinkOptions+' '+More
  552. else
  553. IllegalPara(opt);
  554. 'l' : if more='' then
  555. DoWriteLogo:=true
  556. else
  557. IllegalPara(opt);
  558. 'm' : parapreprocess:=true;
  559. 'n' : if More='' then
  560. begin
  561. read_configfile:=false;
  562. disable_configfile:=true;
  563. end
  564. else
  565. IllegalPara(opt);
  566. 'o' : if More<>'' then
  567. Fsplit(More,d,OutputFile,e)
  568. else
  569. IllegalPara(opt);
  570. 'p' : begin
  571. if UnsetBool(More, 0) then
  572. begin
  573. initmoduleswitches:=initmoduleswitches-[cs_profile];
  574. undef_symbol('FPC_PROFILE');
  575. end
  576. else
  577. case more[1] of
  578. 'g' : if (length(opt)=3) and UnsetBool(more, 1) then
  579. begin
  580. initmoduleswitches:=initmoduleswitches-[cs_profile];
  581. undef_symbol('FPC_PROFILE');
  582. end
  583. else
  584. begin
  585. initmoduleswitches:=initmoduleswitches+[cs_profile];
  586. def_symbol('FPC_PROFILE');
  587. end;
  588. else
  589. IllegalPara(opt);
  590. end;
  591. end;
  592. {$ifdef Unix}
  593. 'P' : initglobalswitches:=initglobalswitches+[cs_asm_pipe];
  594. {$endif}
  595. 's' : initglobalswitches:=initglobalswitches+[cs_asm_extern,cs_link_extern];
  596. 'S' : begin
  597. if more[1]='I' then
  598. begin
  599. if upper(more)='ICOM' then
  600. initinterfacetype:=it_interfacecom
  601. else if upper(more)='ICORBA' then
  602. initinterfacetype:=it_interfacecorba
  603. else
  604. IllegalPara(opt);
  605. end
  606. else
  607. for j:=1 to length(more) do
  608. case more[j] of
  609. '2' : SetCompileMode('OBJFPC',true);
  610. 'a' : initlocalswitches:=InitLocalswitches+[cs_do_assertion];
  611. 'c' : initmoduleswitches:=initmoduleswitches+[cs_support_c_operators];
  612. 'd' : SetCompileMode('DELPHI',true);
  613. 'e' : begin
  614. SetErrorFlags(more);
  615. break;
  616. end;
  617. 'g' : initmoduleswitches:=initmoduleswitches+[cs_support_goto];
  618. 'h' : initlocalswitches:=initlocalswitches+[cs_ansistrings];
  619. 'i' : initmoduleswitches:=initmoduleswitches+[cs_support_inline];
  620. 'm' : initmoduleswitches:=initmoduleswitches+[cs_support_macro];
  621. 'o' : SetCompileMode('TP',true);
  622. 'p' : SetCompileMode('GPC',true);
  623. 's' : initglobalswitches:=initglobalswitches+[cs_constructor_name];
  624. 't' : initmoduleswitches:=initmoduleswitches+[cs_static_keyword];
  625. 'v' : Message1(option_obsolete_switch,'-Sv');
  626. else
  627. IllegalPara(opt);
  628. end;
  629. end;
  630. 'T' : begin
  631. more:=Upper(More);
  632. if not target_is_set then
  633. begin
  634. {Remove non core targetname extra defines}
  635. case target_info.target of
  636. target_i386_freebsd :
  637. begin
  638. undef_symbol('LINUX');
  639. undef_symbol('BSD');
  640. undef_symbol('UNIX');
  641. end;
  642. target_i386_linux :
  643. begin
  644. undef_symbol('UNIX');
  645. end;
  646. end;
  647. { remove old target define }
  648. undef_symbol(target_info.short_name);
  649. { load new target }
  650. if not(set_string_target(More)) then
  651. IllegalPara(opt);
  652. { set new define }
  653. def_symbol(target_info.short_name);
  654. if not asm_is_set then
  655. initoutputformat:=target_asm.id;
  656. target_is_set:=true;
  657. end
  658. else
  659. if More<>target_info.short_name then
  660. Message1(option_target_is_already_set,target_info.short_name);
  661. end;
  662. 'u' : undef_symbol(upper(More));
  663. 'U' : begin
  664. for j:=1 to length(more) do
  665. case more[j] of
  666. {$ifdef UNITALIASES}
  667. 'a' : begin
  668. AddUnitAlias(Copy(More,j+1,255));
  669. break;
  670. end;
  671. {$endif UNITALIASES}
  672. 'n' : initglobalswitches:=initglobalswitches-[cs_check_unit_name];
  673. 'p' : begin
  674. Message2(option_obsolete_switch_use_new,'-Up','-Fu');
  675. break;
  676. end;
  677. 's' : initmoduleswitches:=initmoduleswitches+[cs_compilesystem];
  678. else
  679. IllegalPara(opt);
  680. end;
  681. end;
  682. 'v' : if not setverbosity(More) then
  683. IllegalPara(opt);
  684. 'W' : begin
  685. for j:=1 to length(More) do
  686. case More[j] of
  687. 'B': {bind_win32_dll:=true}
  688. begin
  689. { -WB200000 means set prefered base address
  690. to $200000, but does not change relocsection boolean
  691. this way we can create both relocatble and
  692. non relocatable DLL at a specific base address PM }
  693. if (length(More)>j) then
  694. begin
  695. if DLLImageBase=nil then
  696. DLLImageBase:=StringDup(Copy(More,j+1,255));
  697. end
  698. else
  699. begin
  700. RelocSection:=true;
  701. RelocSectionSetExplicitly:=true;
  702. end;
  703. break;
  704. end;
  705. 'C': apptype:=app_cui;
  706. 'D': ForceDeffileForExport:=true;
  707. 'F': apptype:=app_fs;
  708. 'G': apptype:=app_gui;
  709. 'N': begin
  710. RelocSection:=false;
  711. RelocSectionSetExplicitly:=true;
  712. end;
  713. 'R': begin
  714. RelocSection:=true;
  715. RelocSectionSetExplicitly:=true;
  716. end;
  717. else
  718. IllegalPara(opt);
  719. end;
  720. end;
  721. 'X' : begin
  722. for j:=1 to length(More) do
  723. case More[j] of
  724. 'c' : initglobalswitches:=initglobalswitches+[cs_link_toc];
  725. 's' : initglobalswitches:=initglobalswitches+[cs_link_strip];
  726. 't' : initglobalswitches:=initglobalswitches+[cs_link_staticflag];
  727. 'D' : begin
  728. def_symbol('FPC_LINK_DYNAMIC');
  729. undef_symbol('FPC_LINK_SMART');
  730. undef_symbol('FPC_LINK_STATIC');
  731. initglobalswitches:=initglobalswitches+[cs_link_shared];
  732. initglobalswitches:=initglobalswitches-[cs_link_static,cs_link_smart];
  733. LinkTypeSetExplicitly:=true;
  734. end;
  735. 'S' : begin
  736. def_symbol('FPC_LINK_STATIC');
  737. undef_symbol('FPC_LINK_SMART');
  738. undef_symbol('FPC_LINK_DYNAMIC');
  739. initglobalswitches:=initglobalswitches+[cs_link_static];
  740. initglobalswitches:=initglobalswitches-[cs_link_shared,cs_link_smart];
  741. LinkTypeSetExplicitly:=true;
  742. end;
  743. 'X' : begin
  744. def_symbol('FPC_LINK_SMART');
  745. undef_symbol('FPC_LINK_STATIC');
  746. undef_symbol('FPC_LINK_DYNAMIC');
  747. initglobalswitches:=initglobalswitches+[cs_link_smart];
  748. initglobalswitches:=initglobalswitches-[cs_link_shared,cs_link_static];
  749. LinkTypeSetExplicitly:=true;
  750. end;
  751. else
  752. IllegalPara(opt);
  753. end;
  754. end;
  755. { give processor specific options a chance }
  756. else
  757. interpret_proc_specific_options(opt);
  758. end;
  759. end;
  760. '@' : begin
  761. Message(option_no_nested_response_file);
  762. StopOptions;
  763. end;
  764. else
  765. begin
  766. if (length(param_file)<>0) then
  767. Message(option_only_one_source_support);
  768. param_file:=opt;
  769. end;
  770. end;
  771. end;
  772. procedure Toption.Interpret_file(const filename : string);
  773. procedure RemoveSep(var fn:string);
  774. var
  775. i : longint;
  776. begin
  777. i:=0;
  778. while (i<length(fn)) and (fn[i+1] in [',',' ',#9]) do
  779. inc(i);
  780. Delete(fn,1,i);
  781. i:=length(fn);
  782. while (i>0) and (fn[i] in [',',' ',#9]) do
  783. dec(i);
  784. fn:=copy(fn,1,i);
  785. end;
  786. function GetName(var fn:string):string;
  787. var
  788. i : longint;
  789. begin
  790. i:=0;
  791. while (i<length(fn)) and (fn[i+1] in ['a'..'z','A'..'Z','0'..'9','_','-']) do
  792. inc(i);
  793. GetName:=Copy(fn,1,i);
  794. Delete(fn,1,i);
  795. end;
  796. const
  797. maxlevel=16;
  798. var
  799. f : text;
  800. s,
  801. opts : string;
  802. skip : array[0..maxlevel-1] of boolean;
  803. level : longint;
  804. option_read : boolean;
  805. begin
  806. { avoid infinite loop }
  807. Inc(FileLevel);
  808. Option_read:=false;
  809. If FileLevel>MaxLevel then
  810. Message(option_too_many_cfg_files);
  811. { open file }
  812. Message1(option_using_file,filename);
  813. assign(f,filename);
  814. {$I-}
  815. reset(f);
  816. {$I+}
  817. if ioresult<>0 then
  818. begin
  819. Message1(option_unable_open_file,filename);
  820. exit;
  821. end;
  822. fillchar(skip,sizeof(skip),0);
  823. level:=0;
  824. while not eof(f) do
  825. begin
  826. readln(f,opts);
  827. RemoveSep(opts);
  828. if (opts<>'') and (opts[1]<>';') then
  829. begin
  830. if opts[1]='#' then
  831. begin
  832. Delete(opts,1,1);
  833. s:=upper(GetName(opts));
  834. if (s='SECTION') then
  835. begin
  836. RemoveSep(opts);
  837. s:=upper(GetName(opts));
  838. if level=0 then
  839. skip[level]:=not (check_symbol(s) or (s='COMMON'));
  840. end
  841. else
  842. if (s='IFDEF') then
  843. begin
  844. RemoveSep(opts);
  845. if Level>=maxlevel then
  846. begin
  847. Message(option_too_many_ifdef);
  848. stopOptions;
  849. end;
  850. inc(Level);
  851. skip[level]:=(skip[level-1] or (not check_symbol(upper(GetName(opts)))));
  852. end
  853. else
  854. if (s='IFNDEF') then
  855. begin
  856. RemoveSep(opts);
  857. if Level>=maxlevel then
  858. begin
  859. Message(option_too_many_ifdef);
  860. stopOptions;
  861. end;
  862. inc(Level);
  863. skip[level]:=(skip[level-1] or (check_symbol(upper(GetName(opts)))));
  864. end
  865. else
  866. if (s='ELSE') then
  867. skip[level]:=skip[level-1] or (not skip[level])
  868. else
  869. if (s='ENDIF') then
  870. begin
  871. skip[level]:=false;
  872. if Level=0 then
  873. begin
  874. Message(option_too_many_endif);
  875. stopOptions;
  876. end;
  877. dec(level);
  878. end
  879. else
  880. if (not skip[level]) then
  881. begin
  882. if (s='DEFINE') then
  883. begin
  884. RemoveSep(opts);
  885. def_symbol(upper(GetName(opts)));
  886. end
  887. else
  888. if (s='UNDEF') then
  889. begin
  890. RemoveSep(opts);
  891. undef_symbol(upper(GetName(opts)));
  892. end
  893. else
  894. if (s='WRITE') then
  895. begin
  896. Delete(opts,1,1);
  897. WriteLn(opts);
  898. end
  899. else
  900. if (s='INCLUDE') then
  901. begin
  902. Delete(opts,1,1);
  903. Interpret_file(opts);
  904. end;
  905. end;
  906. end
  907. else
  908. begin
  909. if (opts[1]='-') then
  910. begin
  911. if (not skip[level]) then
  912. interpret_option(opts,false);
  913. Option_read:=true;
  914. end
  915. else
  916. Message1(option_illegal_para,opts);
  917. end;
  918. end;
  919. end;
  920. if Level>0 then
  921. Message(option_too_less_endif);
  922. if Not Option_read then
  923. Message1(option_no_option_found,filename);
  924. Close(f);
  925. Dec(FileLevel);
  926. end;
  927. procedure Toption.Interpret_envvar(const envname : string);
  928. var
  929. argstart,
  930. env,
  931. pc : pchar;
  932. arglen : longint;
  933. quote : set of char;
  934. hs : string;
  935. begin
  936. Message1(option_using_env,envname);
  937. env:=GetEnvPChar(envname);
  938. pc:=env;
  939. if assigned(pc) then
  940. begin
  941. repeat
  942. { skip leading spaces }
  943. while pc^ in [' ',#9,#13] do
  944. inc(pc);
  945. case pc^ of
  946. #0 :
  947. break;
  948. '"' :
  949. begin
  950. quote:=['"'];
  951. inc(pc);
  952. end;
  953. '''' :
  954. begin
  955. quote:=[''''];
  956. inc(pc);
  957. end;
  958. else
  959. quote:=[' ',#9,#13];
  960. end;
  961. { scan until the end of the argument }
  962. argstart:=pc;
  963. while (pc^<>#0) and not(pc^ in quote) do
  964. inc(pc);
  965. { create argument }
  966. arglen:=pc-argstart;
  967. hs[0]:=chr(arglen);
  968. move(argstart^,hs[1],arglen);
  969. interpret_option(hs,true);
  970. { skip quote }
  971. if pc^ in quote then
  972. inc(pc);
  973. until false;
  974. end
  975. else
  976. Message1(option_no_option_found,'(env) '+envname);
  977. FreeEnvPChar(env);
  978. end;
  979. procedure toption.read_parameters;
  980. var
  981. opts : string;
  982. paramindex : longint;
  983. begin
  984. paramindex:=0;
  985. while paramindex<paramcount do
  986. begin
  987. inc(paramindex);
  988. opts:=system.paramstr(paramindex);
  989. case opts[1] of
  990. '@' :
  991. begin
  992. Delete(opts,1,1);
  993. if not firstpass then
  994. Message1(option_reading_further_from,opts);
  995. interpret_file(opts);
  996. end;
  997. '!' :
  998. begin
  999. Delete(opts,1,1);
  1000. if not firstpass then
  1001. Message1(option_reading_further_from,'(env) '+opts);
  1002. interpret_envvar(opts);
  1003. end;
  1004. else
  1005. interpret_option(opts,true);
  1006. end;
  1007. end;
  1008. end;
  1009. procedure toption.parsecmd(cmd:string);
  1010. var
  1011. i,ps : longint;
  1012. opts : string;
  1013. begin
  1014. while (cmd<>'') do
  1015. begin
  1016. while cmd[1]=' ' do
  1017. delete(cmd,1,1);
  1018. i:=pos(' ',cmd);
  1019. if i=0 then
  1020. i:=256;
  1021. opts:=Copy(cmd,1,i-1);
  1022. Delete(cmd,1,i);
  1023. case opts[1] of
  1024. '@' :
  1025. begin
  1026. Delete(opts,1,1);
  1027. if not firstpass then
  1028. Message1(option_reading_further_from,opts);
  1029. interpret_file(opts);
  1030. end;
  1031. '!' :
  1032. begin
  1033. Delete(opts,1,1);
  1034. if not firstpass then
  1035. Message1(option_reading_further_from,'(env) '+opts);
  1036. interpret_envvar(opts);
  1037. end;
  1038. '"' :
  1039. begin
  1040. Delete(opts,1,1);
  1041. ps:=pos('"',cmd);
  1042. if (i<>256) and (ps>0) then
  1043. begin
  1044. opts:=opts + ' '+ copy(cmd,1,ps-1);
  1045. cmd:=copy(cmd,ps+1,255);
  1046. end;
  1047. interpret_option(opts,true);
  1048. end;
  1049. else
  1050. interpret_option(opts,true);
  1051. end;
  1052. end;
  1053. end;
  1054. procedure toption.writequickinfo;
  1055. var
  1056. s : string;
  1057. i : longint;
  1058. procedure addinfo(const hs:string);
  1059. begin
  1060. if s<>'' then
  1061. s:=s+' '+hs
  1062. else
  1063. s:=hs;
  1064. end;
  1065. begin
  1066. s:='';
  1067. i:=0;
  1068. while (i<length(quickinfo)) do
  1069. begin
  1070. inc(i);
  1071. case quickinfo[i] of
  1072. 'S' :
  1073. begin
  1074. inc(i);
  1075. case quickinfo[i] of
  1076. 'O' :
  1077. addinfo(source_os.shortname);
  1078. {$ifdef Delphi}
  1079. 'P' :
  1080. addinfo('i386');
  1081. {$else Delphi}
  1082. 'P' :
  1083. addinfo(source_cpu_string);
  1084. {$endif Delphi}
  1085. else
  1086. IllegalPara('-iS'+QuickInfo);
  1087. end;
  1088. end;
  1089. 'T' :
  1090. begin
  1091. inc(i);
  1092. case quickinfo[i] of
  1093. 'O' :
  1094. addinfo(target_os.shortname);
  1095. 'P' :
  1096. AddInfo(target_cpu_string);
  1097. else
  1098. IllegalPara('-iT'+QuickInfo);
  1099. end;
  1100. end;
  1101. 'V' :
  1102. AddInfo(version_string);
  1103. 'D' :
  1104. AddInfo(date_string);
  1105. '_' :
  1106. ;
  1107. else
  1108. IllegalPara('-i'+QuickInfo);
  1109. end;
  1110. end;
  1111. if s<>'' then
  1112. begin
  1113. writeln(s);
  1114. stopoptions;
  1115. end;
  1116. end;
  1117. constructor TOption.create;
  1118. begin
  1119. DoWriteLogo:=false;
  1120. NoPressEnter:=false;
  1121. FirstPass:=false;
  1122. FileLevel:=0;
  1123. Quickinfo:='';
  1124. ParaIncludePath:=TSearchPathList.Create;
  1125. ParaObjectPath:=TSearchPathList.Create;
  1126. ParaUnitPath:=TSearchPathList.Create;
  1127. ParaLibraryPath:=TSearchPathList.Create;
  1128. end;
  1129. destructor TOption.destroy;
  1130. begin
  1131. ParaIncludePath.Free;
  1132. ParaObjectPath.Free;
  1133. ParaUnitPath.Free;
  1134. ParaLibraryPath.Free;
  1135. end;
  1136. {****************************************************************************
  1137. Callable Routines
  1138. ****************************************************************************}
  1139. procedure read_arguments(cmd:string);
  1140. var
  1141. configpath : pathstr;
  1142. begin
  1143. option:=coption.create;
  1144. { Load messages }
  1145. if (cmd='') and (paramcount=0) then
  1146. option.WriteHelpPages;
  1147. disable_configfile:=false;
  1148. { default defines }
  1149. def_symbol(target_info.short_name);
  1150. def_symbol('FPC');
  1151. def_symbol('VER'+version_nr);
  1152. def_symbol('VER'+version_nr+'_'+release_nr);
  1153. def_symbol('VER'+version_nr+'_'+release_nr+'_'+patch_nr);
  1154. {$ifdef newcg}
  1155. def_symbol('WITHNEWCG');
  1156. {$endif}
  1157. { Temporary defines, until things settle down }
  1158. {$ifdef SUPPORT_FIXED}
  1159. def_symbol('HASFIXED');
  1160. {$endif SUPPORT_FIXED}
  1161. def_symbol('HASWIDECHAR');
  1162. def_symbol('HASOUT');
  1163. def_symbol('HASINTF');
  1164. def_symbol('INTERNSETLENGTH');
  1165. def_symbol('INT64FUNCRESOK');
  1166. def_symbol('PACKENUMFIXED');
  1167. def_symbol('HAS_ADDR_STACK_ON_STACK');
  1168. { some stuff for TP compatibility }
  1169. {$ifdef i386}
  1170. def_symbol('CPU86');
  1171. def_symbol('CPU87');
  1172. {$endif}
  1173. {$ifdef m68k}
  1174. def_symbol('CPU68');
  1175. {$endif}
  1176. { new processor stuff }
  1177. {$ifdef i386}
  1178. def_symbol('CPUI386');
  1179. {$endif}
  1180. {$ifdef m68k}
  1181. def_symbol('CPU68K');
  1182. {$endif}
  1183. {$ifdef ALPHA}
  1184. def_symbol('CPUALPHA');
  1185. {$endif}
  1186. {$ifdef powerpc}
  1187. def_symbol('CPUPOWERPC');
  1188. {$endif}
  1189. { get default messagefile }
  1190. {$ifdef Delphi}
  1191. msgfilename:=dmisc.getenv('PPC_ERROR_FILE');
  1192. {$else Delphi}
  1193. msgfilename:=dos.getenv('PPC_ERROR_FILE');
  1194. {$endif Delphi}
  1195. { default configfile }
  1196. if (cmd<>'') and (cmd[1]='[') then
  1197. begin
  1198. ppccfg:=Copy(cmd,2,pos(']',cmd)-2);
  1199. Delete(cmd,1,pos(']',cmd));
  1200. end
  1201. else
  1202. begin
  1203. {$ifdef i386}
  1204. ppccfg:='ppc386.cfg';
  1205. {$endif i386}
  1206. {$ifdef ia64}
  1207. ppccfg:='ppcia64.cfg';
  1208. {$endif ia64}
  1209. {$ifdef m68k}
  1210. ppccfg:='ppc68k.cfg';
  1211. {$endif}
  1212. {$ifdef alpha}
  1213. ppccfg:='ppcalpha.cfg';
  1214. {$endif}
  1215. {$ifdef powerpc}
  1216. ppccfg:='ppcppc.cfg';
  1217. {$endif}
  1218. end;
  1219. { Order to read ppc386.cfg:
  1220. 1 - current dir
  1221. 2 - configpath
  1222. 3 - compiler path }
  1223. {$ifdef Delphi}
  1224. configpath:=FixPath(dmisc.getenv('PPC_CONFIG_PATH'),false);
  1225. {$else Delphi}
  1226. configpath:=FixPath(dos.getenv('PPC_CONFIG_PATH'),false);
  1227. {$endif Delphi}
  1228. {$ifdef Unix}
  1229. if configpath='' then
  1230. configpath:='/etc/';
  1231. {$endif}
  1232. if ppccfg<>'' then
  1233. begin
  1234. read_configfile:=true;
  1235. if not FileExists(ppccfg) then
  1236. begin
  1237. {$ifdef Unix}
  1238. if (dos.getenv('HOME')<>'') and FileExists(FixPath(dos.getenv('HOME'),false)+'.'+ppccfg) then
  1239. ppccfg:=FixPath(dos.getenv('HOME'),false)+'.'+ppccfg
  1240. else
  1241. {$endif}
  1242. if FileExists(configpath+ppccfg) then
  1243. ppccfg:=configpath+ppccfg
  1244. else
  1245. {$ifndef Unix}
  1246. if FileExists(exepath+ppccfg) then
  1247. ppccfg:=exepath+ppccfg
  1248. else
  1249. {$endif}
  1250. read_configfile:=false;
  1251. end;
  1252. end
  1253. else
  1254. read_configfile:=false;
  1255. { Read commandline and configfile }
  1256. target_is_set:=false;
  1257. asm_is_set:=false;
  1258. param_file:='';
  1259. if read_configfile then
  1260. begin
  1261. { read the parameters quick, only -i -v -T }
  1262. option.firstpass:=true;
  1263. if cmd<>'' then
  1264. option.parsecmd(cmd)
  1265. else
  1266. begin
  1267. option.read_parameters;
  1268. { Write only quickinfo }
  1269. if option.quickinfo<>'' then
  1270. option.writequickinfo;
  1271. end;
  1272. { Read the configfile }
  1273. option.firstpass:=false;
  1274. if read_configfile then
  1275. option.interpret_file(ppccfg);
  1276. end;
  1277. if cmd<>'' then
  1278. option.parsecmd(cmd)
  1279. else
  1280. begin
  1281. option.read_parameters;
  1282. { Write only quickinfo }
  1283. if option.quickinfo<>'' then
  1284. option.writequickinfo;
  1285. end;
  1286. { Stop if errors in options }
  1287. if ErrorCount>0 then
  1288. StopOptions;
  1289. { Non-core target defines }
  1290. case target_info.target of
  1291. target_i386_freebsd :
  1292. begin
  1293. def_symbol('LINUX'); { Hack: Linux define is also needed for freebsd (MvdV) }
  1294. def_symbol('BSD');
  1295. def_symbol('UNIX');
  1296. end;
  1297. target_i386_linux :
  1298. begin
  1299. def_symbol('UNIX');
  1300. end;
  1301. end;
  1302. { write logo if set }
  1303. if option.DoWriteLogo then
  1304. option.WriteLogo;
  1305. { Check file to compile }
  1306. if param_file='' then
  1307. begin
  1308. Message(option_no_source_found);
  1309. StopOptions;
  1310. end;
  1311. {$ifndef Unix}
  1312. param_file:=FixFileName(param_file);
  1313. {$endif}
  1314. fsplit(param_file,inputdir,inputfile,inputextension);
  1315. if inputextension='' then
  1316. begin
  1317. if FileExists(inputdir+inputfile+target_os.sourceext) then
  1318. inputextension:=target_os.sourceext
  1319. else
  1320. if FileExists(inputdir+inputfile+target_os.pasext) then
  1321. inputextension:=target_os.pasext;
  1322. end;
  1323. { Add paths specified with parameters to the searchpaths }
  1324. UnitSearchPath.AddList(option.ParaUnitPath,true);
  1325. ObjectSearchPath.AddList(option.ParaObjectPath,true);
  1326. IncludeSearchPath.AddList(option.ParaIncludePath,true);
  1327. LibrarySearchPath.AddList(option.ParaLibraryPath,true);
  1328. { add unit environment and exepath to the unit search path }
  1329. if inputdir<>'' then
  1330. Unitsearchpath.AddPath(inputdir,true);
  1331. if not disable_configfile then
  1332. {$ifdef Delphi}
  1333. UnitSearchPath.AddPath(dmisc.getenv(target_info.unit_env),false);
  1334. {$else}
  1335. UnitSearchPath.AddPath(dos.getenv(target_info.unit_env),false);
  1336. {$endif Delphi}
  1337. {$ifdef Unix}
  1338. fpcdir:=FixPath(getenv('FPCDIR'),false);
  1339. if fpcdir='' then
  1340. begin
  1341. if PathExists('/usr/local/lib/fpc/'+version_string) then
  1342. fpcdir:='/usr/local/lib/fpc/'+version_string+'/'
  1343. else
  1344. fpcdir:='/usr/lib/fpc/'+version_string+'/';
  1345. end;
  1346. {$else}
  1347. fpcdir:=FixPath(getenv('FPCDIR'),false);
  1348. if fpcdir='' then
  1349. begin
  1350. fpcdir:=ExePath+'../';
  1351. if not(PathExists(fpcdir+'/units')) and
  1352. not(PathExists(fpcdir+'/rtl')) then
  1353. fpcdir:=fpcdir+'../';
  1354. end;
  1355. {$endif}
  1356. { first try development RTL, else use the default installation path }
  1357. if not disable_configfile then
  1358. begin
  1359. if PathExists(FpcDir+'rtl/'+lower(target_info.short_name)) then
  1360. UnitSearchPath.AddPath(FpcDir+'rtl/'+lower(target_info.short_name),false)
  1361. else
  1362. begin
  1363. UnitSearchPath.AddPath(FpcDir+'units/'+lower(target_info.short_name),false);
  1364. UnitSearchPath.AddPath(FpcDir+'units/'+lower(target_info.short_name)+'/rtl',false);
  1365. end;
  1366. end;
  1367. { Add exepath if the exe is not in the current dir, because that is always searched already }
  1368. if ExePath<>GetCurrentDir then
  1369. UnitSearchPath.AddPath(ExePath,false);
  1370. { Add unit dir to the object and library path }
  1371. objectsearchpath.AddList(unitsearchpath,false);
  1372. librarysearchpath.AddList(unitsearchpath,false);
  1373. { switch assembler if it's binary and we got -a on the cmdline }
  1374. if (cs_asm_leave in initglobalswitches) and
  1375. (target_asm.id in binassem) then
  1376. begin
  1377. Message(option_switch_bin_to_src_assembler);
  1378. set_target_asm(target_info.assemsrc);
  1379. initoutputformat:=target_asm.id;
  1380. end;
  1381. if (target_asm.supported_target <> target_any) and
  1382. (target_asm.supported_target <> target_info.target) then
  1383. begin
  1384. Message2(option_incompatible_asm,target_asm.idtxt,target_os.name);
  1385. { Should we reset to default ??? }
  1386. set_target_asm(target_info.assemsrc);
  1387. Message1(option_asm_forced,target_asm.idtxt);
  1388. initoutputformat:=target_asm.id;
  1389. end;
  1390. { turn off stripping if compiling with debuginfo or profile }
  1391. if (cs_debuginfo in initmoduleswitches) or
  1392. (cs_profile in initmoduleswitches) then
  1393. initglobalswitches:=initglobalswitches-[cs_link_strip];
  1394. if not LinkTypeSetExplicitly then
  1395. begin
  1396. if (target_os.id=os_i386_win32) then
  1397. begin
  1398. def_symbol('FPC_LINK_SMART');
  1399. undef_symbol('FPC_LINK_STATIC');
  1400. undef_symbol('FPC_LINK_DYNAMIC');
  1401. initglobalswitches:=initglobalswitches+[cs_link_smart];
  1402. initglobalswitches:=initglobalswitches-[cs_link_shared,cs_link_static];
  1403. end
  1404. else
  1405. begin
  1406. undef_symbol('FPC_LINK_SMART');
  1407. def_symbol('FPC_LINK_STATIC');
  1408. undef_symbol('FPC_LINK_DYNAMIC');
  1409. initglobalswitches:=initglobalswitches+[cs_link_static];
  1410. initglobalswitches:=initglobalswitches-[cs_link_shared,cs_link_smart];
  1411. end;
  1412. end;
  1413. { Set defines depending on the target }
  1414. if (target_info.target in [target_i386_GO32V1,target_i386_GO32V2]) then
  1415. def_symbol('DPMI'); { MSDOS is not defined in BP when target is DPMI }
  1416. MaybeLoadMessageFile;
  1417. option.free;
  1418. Option:=nil;
  1419. end;
  1420. initialization
  1421. coption:=toption;
  1422. finalization
  1423. if assigned(option) then
  1424. option.free;
  1425. end.
  1426. {
  1427. $Log$
  1428. Revision 1.27 2001-01-20 18:36:51 hajny
  1429. + APPTYPE support under OS/2, app_fs, GetEnvPChar for OS/2
  1430. Revision 1.26 2001/01/12 19:21:09 peter
  1431. * fixed writing of quickinfo when no ppc386.cfg is available
  1432. Revision 1.25 2001/01/05 17:36:57 florian
  1433. * the info about exception frames is stored now on the stack
  1434. instead on the heap
  1435. Revision 1.24 2000/12/25 00:07:26 peter
  1436. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  1437. tlinkedlist objects)
  1438. Revision 1.23 2000/12/24 12:21:41 peter
  1439. * use system.paramstr()
  1440. Revision 1.22 2000/12/23 19:46:49 peter
  1441. * object to class conversion
  1442. * more verbosity for -vt and -vd
  1443. * -i options can be put after eachother so the Makefiles only need
  1444. to call fpc once for all info (will be twice as the first one will
  1445. be to check the version if fpc supports multiple info)
  1446. Revision 1.21 2000/12/16 15:56:19 jonas
  1447. - removed all ifdef cardinalmulfix code
  1448. Revision 1.20 2000/12/15 13:26:01 jonas
  1449. * only return int64's from functions if it int64funcresok is defined
  1450. + added int64funcresok define to options.pas
  1451. Revision 1.19 2000/11/30 22:48:23 florian
  1452. * opts386 renamed
  1453. Revision 1.18 2000/11/29 00:30:34 florian
  1454. * unused units removed from uses clause
  1455. * some changes for widestrings
  1456. Revision 1.17 2000/11/13 15:26:12 marco
  1457. * Renamefest
  1458. Revision 1.16 2000/11/12 22:20:37 peter
  1459. * create generic toutputsection for binary writers
  1460. Revision 1.15 2000/11/07 15:09:27 marco
  1461. * Define UNIX for FreeBSD and Linux. Checked crosscompile thingy.
  1462. Revision 1.14 2000/11/07 14:25:08 marco
  1463. * FreeBSD defines (FreeBSD,Linux,BSD,Unix) Linux defines (Linux,Unix)
  1464. Revision 1.13 2000/11/06 20:30:54 peter
  1465. * more fixes to get make cycle working
  1466. Revision 1.12 2000/11/04 14:25:20 florian
  1467. + merged Attila's changes for interfaces, not tested yet
  1468. Revision 1.11 2000/09/26 10:50:41 jonas
  1469. * initmodeswitches is changed is you change the compiler mode from the
  1470. command line (the -S<x> switches didn't work anymore for changing the
  1471. compiler mode) (merged from fixes branch)
  1472. Revision 1.10 2000/09/24 21:33:47 peter
  1473. * message updates merges
  1474. Revision 1.9 2000/09/24 15:06:20 peter
  1475. * use defines.inc
  1476. Revision 1.8 2000/09/18 12:28:41 marco
  1477. * Definition of multiple FreeBSD target defines moved to after error check
  1478. commandline parsing
  1479. Revision 1.7 2000/09/16 12:22:52 peter
  1480. * freebsd support merged
  1481. Revision 1.6 2000/08/27 16:11:51 peter
  1482. * moved some util functions from globals,cobjects to cutils
  1483. * splitted files into finput,fmodule
  1484. Revision 1.5 2000/08/07 11:31:04 jonas
  1485. * fixed bug in type conversions between enum subranges (it didn't take
  1486. the packenum directive into account)
  1487. + define PACKENUMFIXED symbol in options.pas
  1488. (merged from fixes branch)
  1489. Revision 1.4 2000/07/14 05:11:48 michael
  1490. + Patch to 1.1
  1491. Revision 1.3 2000/07/13 12:08:26 michael
  1492. + patched to 1.1.0 with former 1.09patch from peter
  1493. Revision 1.2 2000/07/13 11:32:44 michael
  1494. + removed logs
  1495. }