compiler.pas 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. This unit is the interface of the compiler which can be used by
  5. external programs to link in the compiler
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************}
  18. unit compiler;
  19. {$i fpcdefs.inc}
  20. {$ifdef FPC}
  21. { One of Alpha, I386 or M68K must be defined }
  22. {$UNDEF CPUOK}
  23. {$ifdef I386}
  24. {$define CPUOK}
  25. {$endif}
  26. {$ifdef M68K}
  27. {$ifndef CPUOK}
  28. {$DEFINE CPUOK}
  29. {$else}
  30. {$fatal cannot define two CPU switches}
  31. {$endif}
  32. {$endif}
  33. {$ifdef alpha}
  34. {$ifndef CPUOK}
  35. {$DEFINE CPUOK}
  36. {$else}
  37. {$fatal cannot define two CPU switches}
  38. {$endif}
  39. {$endif}
  40. {$ifdef vis}
  41. {$ifndef CPUOK}
  42. {$DEFINE CPUOK}
  43. {$else}
  44. {$fatal cannot define two CPU switches}
  45. {$endif}
  46. {$endif}
  47. {$ifdef powerpc}
  48. {$ifndef CPUOK}
  49. {$DEFINE CPUOK}
  50. {$else}
  51. {$fatal cannot define two CPU switches}
  52. {$endif}
  53. {$endif}
  54. {$ifdef ia64}
  55. {$ifndef CPUOK}
  56. {$DEFINE CPUOK}
  57. {$else}
  58. {$fatal cannot define two CPU switches}
  59. {$endif}
  60. {$endif}
  61. {$ifdef SPARC}
  62. {$ifndef CPUOK}
  63. {$DEFINE CPUOK}
  64. {$else}
  65. {$fatal cannot define two CPU switches}
  66. {$endif}
  67. {$endif}
  68. {$ifdef x86_64}
  69. {$ifndef CPUOK}
  70. {$DEFINE CPUOK}
  71. {$else}
  72. {$fatal cannot define two CPU switches}
  73. {$endif}
  74. {$endif}
  75. {$ifdef ARM}
  76. {$ifndef CPUOK}
  77. {$DEFINE CPUOK}
  78. {$else}
  79. {$fatal cannot define two CPU switches}
  80. {$endif ARM}
  81. {$endif ARM}
  82. {$ifdef MIPS}
  83. {$ifndef CPUOK}
  84. {$DEFINE CPUOK}
  85. {$else}
  86. {$fatal cannot define two CPU switches}
  87. {$endif MIPS}
  88. {$endif MIPS}
  89. {$ifndef CPUOK}
  90. {$fatal One of the switches I386, iA64, Alpha, PowerPC or M68K must be defined}
  91. {$endif}
  92. {$ifdef support_mmx}
  93. {$ifndef i386}
  94. {$fatal I386 switch must be on for MMX support}
  95. {$endif i386}
  96. {$endif support_mmx}
  97. {$endif}
  98. interface
  99. uses
  100. {$ifdef fpc}
  101. {$ifdef GO32V2}
  102. emu387,
  103. {$endif GO32V2}
  104. {$ifdef WATCOM} // wiktor: pewnie nie potrzeba
  105. emu387,
  106. { dpmiexcp, }
  107. {$endif WATCOM}
  108. {$endif}
  109. {$ifdef BrowserLog}
  110. browlog,
  111. {$endif BrowserLog}
  112. {$IFDEF USE_SYSUTILS}
  113. {$ELSE USE_SYSUTILS}
  114. dos,
  115. {$ENDIF USE_SYSUTILS}
  116. {$IFNDEF MACOS_USE_FAKE_SYSUTILS}
  117. sysutils,
  118. {$ENDIF MACOS_USE_FAKE_SYSUTILS}
  119. verbose,comphook,systems,
  120. cutils,cclasses,globals,options,fmodule,parser,symtable,
  121. assemble,link,import,export,tokens,pass_1
  122. { cpu overrides }
  123. ,cpuswtch
  124. { cpu codegenerator }
  125. ,cgcpu
  126. {$ifndef NOPASS2}
  127. ,cpunode
  128. {$endif}
  129. { cpu targets }
  130. ,cputarg
  131. { cpu parameter handling }
  132. ,cpupara
  133. { procinfo stuff }
  134. ,cpupi
  135. { system information for source system }
  136. { the information about the target os }
  137. { are pulled in by the t_* units }
  138. {$ifdef amiga}
  139. ,i_amiga
  140. {$endif amiga}
  141. {$ifdef atari}
  142. ,i_atari
  143. {$endif atari}
  144. {$ifdef beos}
  145. ,i_beos
  146. {$endif beos}
  147. {$ifdef fbds}
  148. ,i_fbsd
  149. {$endif fbds}
  150. {$ifdef go32v2}
  151. ,i_go32v2
  152. {$endif go32v2}
  153. {$ifdef linux}
  154. ,i_linux
  155. {$endif linux}
  156. {$ifdef macos}
  157. ,i_macos
  158. {$endif macos}
  159. {$ifdef nwm}
  160. ,i_nwm
  161. {$endif nwm}
  162. {$ifdef nwl}
  163. ,i_nwl
  164. {$endif nwm}
  165. {$ifdef os2}
  166. {$ifdef emx}
  167. ,i_emx
  168. {$else emx}
  169. ,i_os2
  170. {$endif emx}
  171. {$endif os2}
  172. {$ifdef palmos}
  173. ,i_palmos
  174. {$endif palmos}
  175. {$ifdef solaris}
  176. ,i_sunos
  177. {$endif solaris}
  178. {$ifdef wdosx}
  179. ,i_wdosx
  180. {$endif wdosx}
  181. {$ifdef win32}
  182. ,i_win32
  183. {$endif win32}
  184. { assembler readers }
  185. {$ifdef i386}
  186. {$ifndef NoRa386Int}
  187. ,ra386int
  188. {$endif NoRa386Int}
  189. {$ifndef NoRa386Att}
  190. ,ra386att
  191. {$endif NoRa386Att}
  192. {$else}
  193. ,rasm
  194. {$endif i386}
  195. {$ifdef powerpc}
  196. ,rappcgas
  197. {$endif powerpc}
  198. {$ifdef x86_64}
  199. ,rax64att
  200. {$endif x86_64}
  201. {$ifdef arm}
  202. ,raarmgas
  203. {$endif arm}
  204. {$ifdef SPARC}
  205. ,racpugas
  206. {$endif SPARC}
  207. ;
  208. function Compile(const cmd:string):longint;
  209. implementation
  210. uses
  211. {$IFDEF USE_SYSUTILS}
  212. SysUtils,
  213. {$ENDIF USE_SYSUTILS}
  214. aasmcpu;
  215. {$ifdef EXTDEBUG}
  216. {$define SHOWUSEDMEM}
  217. {$endif}
  218. {$ifdef MEMDEBUG}
  219. {$define SHOWUSEDMEM}
  220. {$endif}
  221. var
  222. CompilerInitedAfterArgs,
  223. CompilerInited : boolean;
  224. {****************************************************************************
  225. Compiler
  226. ****************************************************************************}
  227. procedure DoneCompiler;
  228. begin
  229. if not CompilerInited then
  230. exit;
  231. { Free compiler if args are read }
  232. {$ifdef BrowserLog}
  233. DoneBrowserLog;
  234. {$endif BrowserLog}
  235. {$ifdef BrowserCol}
  236. do_doneSymbolInfo;
  237. {$endif BrowserCol}
  238. if CompilerInitedAfterArgs then
  239. begin
  240. CompilerInitedAfterArgs:=false;
  241. DoneParser;
  242. DoneImport;
  243. DoneExport;
  244. DoneLinker;
  245. DoneAssembler;
  246. DoneAsm;
  247. end;
  248. { Free memory for the others }
  249. CompilerInited:=false;
  250. DoneSymtable;
  251. DoneGlobals;
  252. donetokens;
  253. end;
  254. procedure InitCompiler(const cmd:string);
  255. begin
  256. if CompilerInited then
  257. DoneCompiler;
  258. { inits which need to be done before the arguments are parsed }
  259. InitSystems;
  260. { globals depends on source_info so it must be after systems }
  261. InitGlobals;
  262. { verbose depends on exe_path and must be after globals }
  263. InitVerbose;
  264. {$ifdef BrowserLog}
  265. InitBrowserLog;
  266. {$endif BrowserLog}
  267. {$ifdef BrowserCol}
  268. do_initSymbolInfo;
  269. {$endif BrowserCol}
  270. inittokens;
  271. InitSymtable; {Must come before read_arguments, to enable macrosymstack}
  272. CompilerInited:=true;
  273. { this is needed here for the IDE
  274. in case of compilation failure
  275. at the previous compile }
  276. current_module:=nil;
  277. { read the arguments }
  278. read_arguments(cmd);
  279. { inits which depend on arguments }
  280. InitParser;
  281. InitImport;
  282. InitExport;
  283. InitLinker;
  284. InitAssembler;
  285. InitAsm;
  286. CompilerInitedAfterArgs:=true;
  287. end;
  288. function Compile(const cmd:string):longint;
  289. {$ifdef fpc}
  290. {$maxfpuregisters 0}
  291. {$endif fpc}
  292. procedure writepathlist(w:longint;l:TSearchPathList);
  293. var
  294. hp : tstringlistitem;
  295. begin
  296. hp:=tstringlistitem(l.first);
  297. while assigned(hp) do
  298. begin
  299. Message1(w,hp.str);
  300. hp:=tstringlistitem(hp.next);
  301. end;
  302. end;
  303. function getrealtime : real;
  304. var
  305. {$IFDEF USE_SYSUTILS}
  306. h,m,s,s1000 : word;
  307. {$ELSE USE_SYSUTILS}
  308. h,m,s,s100 : word;
  309. {$ENDIF USE_SYSUTILS}
  310. begin
  311. {$IFDEF USE_SYSUTILS}
  312. DecodeTime(Time,h,m,s,s1000);
  313. getrealtime:=h*3600.0+m*60.0+s+s1000/1000.0;
  314. {$ELSE USE_SYSUTILS}
  315. gettime(h,m,s,s100);
  316. getrealtime:=h*3600.0+m*60.0+s+s100/100.0;
  317. {$ENDIF USE_SYSUTILS}
  318. end;
  319. var
  320. starttime : real;
  321. {$ifdef SHOWUSEDMEM}
  322. {$ifdef HASGETHEAPSTATUS}
  323. hstatus : TFPCHeapStatus;
  324. {$endif HASGETHEAPSTATUS}
  325. {$endif SHOWUSEDMEM}
  326. begin
  327. try
  328. try
  329. { Initialize the compiler }
  330. InitCompiler(cmd);
  331. { show some info }
  332. Message1(general_t_compilername,FixFileName(system.paramstr(0)));
  333. Message1(general_d_sourceos,source_info.name);
  334. Message1(general_i_targetos,target_info.name);
  335. Message1(general_t_exepath,exepath);
  336. WritePathList(general_t_unitpath,unitsearchpath);
  337. WritePathList(general_t_includepath,includesearchpath);
  338. WritePathList(general_t_librarypath,librarysearchpath);
  339. WritePathList(general_t_objectpath,objectsearchpath);
  340. starttime:=getrealtime;
  341. { Compile the program }
  342. {$ifdef PREPROCWRITE}
  343. if parapreprocess then
  344. parser.preprocess(inputdir+inputfile+inputextension)
  345. else
  346. {$endif PREPROCWRITE}
  347. parser.compile(inputdir+inputfile+inputextension);
  348. { Show statistics }
  349. if status.errorcount=0 then
  350. begin
  351. starttime:=getrealtime-starttime;
  352. if starttime<0 then
  353. starttime:=starttime+3600.0*24.0;
  354. Message2(general_i_abslines_compiled,tostr(status.compiledlines),tostr(trunc(starttime))+
  355. '.'+tostr(trunc(frac(starttime)*10)));
  356. end;
  357. finally
  358. { no message possible after this !! }
  359. DoneCompiler;
  360. end;
  361. except
  362. on EControlCAbort do
  363. begin
  364. Message(general_e_compilation_aborted);
  365. DoneVerbose;
  366. end;
  367. on ECompilerAbort do
  368. begin
  369. Message(general_e_compilation_aborted);
  370. DoneVerbose;
  371. end;
  372. on ECompilerAbortSilent do
  373. begin
  374. DoneVerbose;
  375. end;
  376. on Exception do
  377. begin
  378. { General catchall, normally not used }
  379. Message(general_e_compilation_aborted);
  380. DoneVerbose;
  381. Raise;
  382. end;
  383. end;
  384. {$ifdef SHOWUSEDMEM}
  385. {$ifdef HASGETHEAPSTATUS}
  386. hstatus:=GetFPCHeapStatus;
  387. Writeln('Max Memory used/heapsize: ',DStr(hstatus.MaxHeapUsed shr 10),'/',DStr(hstatus.MaxHeapSize shr 10),' Kb');
  388. {$else HASGETHEAPSTATUS}
  389. Writeln('Memory used (heapsize): ',DStr(system.Heapsize shr 10),' Kb');
  390. {$endif HASGETHEAPSTATUS}
  391. {$endif SHOWUSEDMEM}
  392. { Set the return value if an error has occurred }
  393. if status.errorcount=0 then
  394. result:=0
  395. else
  396. result:=1;
  397. end;
  398. end.
  399. {
  400. $Log$
  401. Revision 1.60 2005-04-24 21:01:37 peter
  402. * always use exceptions to stop the compiler
  403. - remove stop, do_stop
  404. Revision 1.59 2005/03/25 21:55:43 jonas
  405. * removed some unused variables
  406. Revision 1.58 2005/02/28 15:38:38 marco
  407. * getFPCheapstatus (no, FPC HEAP, not FP CHEAP!)
  408. Revision 1.57 2005/02/15 19:15:45 peter
  409. * Handle Control-C exception more cleanly
  410. Revision 1.56 2005/02/14 17:13:06 peter
  411. * truncate log
  412. Revision 1.55 2005/02/13 20:11:16 peter
  413. * sunos to solaris
  414. Revision 1.54 2005/02/13 18:55:19 florian
  415. + overflow checking for the arm
  416. Revision 1.53 2005/01/31 21:30:56 olle
  417. + Added fake Exception classes, only for MACOS.
  418. Revision 1.52 2005/01/26 16:23:28 peter
  419. * detect arithmetic overflows for constants at compile time
  420. * use try..except instead of setjmp
  421. Revision 1.51 2005/01/09 20:24:43 olle
  422. * rework of macro subsystem
  423. + exportable macros for mode macpas
  424. }