compiler.pas 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. {
  2. This unit is the interface of the compiler which can be used by
  3. external programs to link in the compiler
  4. Copyright (c) 1998-2005 by Florian Klaempfl
  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. unit compiler;
  18. {$i fpcdefs.inc}
  19. {$ifdef FPC}
  20. { One of Alpha, I386 or M68K must be defined }
  21. {$UNDEF CPUOK}
  22. {$ifdef I386}
  23. {$define CPUOK}
  24. {$endif}
  25. {$ifdef M68K}
  26. {$ifndef CPUOK}
  27. {$DEFINE CPUOK}
  28. {$else}
  29. {$fatal cannot define two CPU switches}
  30. {$endif}
  31. {$endif}
  32. {$ifdef alpha}
  33. {$ifndef CPUOK}
  34. {$DEFINE CPUOK}
  35. {$else}
  36. {$fatal cannot define two CPU switches}
  37. {$endif}
  38. {$endif}
  39. {$ifdef vis}
  40. {$ifndef CPUOK}
  41. {$DEFINE CPUOK}
  42. {$else}
  43. {$fatal cannot define two CPU switches}
  44. {$endif}
  45. {$endif}
  46. {$ifdef powerpc}
  47. {$ifndef CPUOK}
  48. {$DEFINE CPUOK}
  49. {$else}
  50. {$fatal cannot define two CPU switches}
  51. {$endif}
  52. {$endif}
  53. {$ifdef ia64}
  54. {$ifndef CPUOK}
  55. {$DEFINE CPUOK}
  56. {$else}
  57. {$fatal cannot define two CPU switches}
  58. {$endif}
  59. {$endif}
  60. {$ifdef SPARC}
  61. {$ifndef CPUOK}
  62. {$DEFINE CPUOK}
  63. {$else}
  64. {$fatal cannot define two CPU switches}
  65. {$endif}
  66. {$endif}
  67. {$ifdef x86_64}
  68. {$ifndef CPUOK}
  69. {$DEFINE CPUOK}
  70. {$else}
  71. {$fatal cannot define two CPU switches}
  72. {$endif}
  73. {$endif}
  74. {$ifdef ARM}
  75. {$ifndef CPUOK}
  76. {$DEFINE CPUOK}
  77. {$else}
  78. {$fatal cannot define two CPU switches}
  79. {$endif ARM}
  80. {$endif ARM}
  81. {$ifdef MIPS}
  82. {$ifndef CPUOK}
  83. {$DEFINE CPUOK}
  84. {$else}
  85. {$fatal cannot define two CPU switches}
  86. {$endif MIPS}
  87. {$endif MIPS}
  88. {$ifndef CPUOK}
  89. {$fatal One of the switches I386, iA64, Alpha, PowerPC or M68K must be defined}
  90. {$endif}
  91. {$ifdef support_mmx}
  92. {$ifndef i386}
  93. {$fatal I386 switch must be on for MMX support}
  94. {$endif i386}
  95. {$endif support_mmx}
  96. {$endif}
  97. interface
  98. uses
  99. {$ifdef fpc}
  100. {$ifdef GO32V2}
  101. emu387,
  102. {$endif GO32V2}
  103. {$ifdef WATCOM} // wiktor: pewnie nie potrzeba
  104. emu387,
  105. { dpmiexcp, }
  106. {$endif WATCOM}
  107. {$endif}
  108. {$ifdef BrowserLog}
  109. browlog,
  110. {$endif BrowserLog}
  111. {$IFDEF USE_SYSUTILS}
  112. {$ELSE USE_SYSUTILS}
  113. dos,
  114. {$ENDIF USE_SYSUTILS}
  115. {$IFNDEF MACOS_USE_FAKE_SYSUTILS}
  116. sysutils,
  117. {$ENDIF MACOS_USE_FAKE_SYSUTILS}
  118. verbose,comphook,systems,
  119. cutils,cclasses,globals,options,fmodule,parser,symtable,
  120. assemble,link,dbgbase,import,export,tokens,pass_1
  121. { cpu specific commandline options }
  122. ,cpuswtch
  123. { cpu parameter handling }
  124. ,cpupara
  125. { procinfo stuff }
  126. ,cpupi
  127. { cpu codegenerator }
  128. ,cgcpu
  129. {$ifndef NOPASS2}
  130. ,cpunode
  131. {$endif}
  132. { cpu targets }
  133. ,cputarg
  134. { system information for source system }
  135. { the information about the target os }
  136. { are pulled in by the t_* units }
  137. {$ifdef amiga}
  138. ,i_amiga
  139. {$endif amiga}
  140. {$ifdef atari}
  141. ,i_atari
  142. {$endif atari}
  143. {$ifdef beos}
  144. ,i_beos
  145. {$endif beos}
  146. {$ifdef fbsd}
  147. ,i_fbsd
  148. {$endif fbsd}
  149. {$ifdef gba}
  150. ,i_gba
  151. {$endif gba}
  152. {$ifdef go32v2}
  153. ,i_go32v2
  154. {$endif go32v2}
  155. {$ifdef linux}
  156. ,i_linux
  157. {$endif linux}
  158. {$ifdef macos}
  159. ,i_macos
  160. {$endif macos}
  161. {$ifdef nwm}
  162. ,i_nwm
  163. {$endif nwm}
  164. {$ifdef nwl}
  165. ,i_nwl
  166. {$endif nwm}
  167. {$ifdef os2}
  168. {$ifdef emx}
  169. ,i_emx
  170. {$else emx}
  171. ,i_os2
  172. {$endif emx}
  173. {$endif os2}
  174. {$ifdef palmos}
  175. ,i_palmos
  176. {$endif palmos}
  177. {$ifdef solaris}
  178. ,i_sunos
  179. {$endif solaris}
  180. {$ifdef wdosx}
  181. ,i_wdosx
  182. {$endif wdosx}
  183. {$ifdef win32}
  184. ,i_win
  185. {$endif win32}
  186. ;
  187. function Compile(const cmd:string):longint;
  188. implementation
  189. uses
  190. aasmcpu;
  191. {$ifdef EXTDEBUG}
  192. {$define SHOWUSEDMEM}
  193. {$endif}
  194. {$ifdef MEMDEBUG}
  195. {$define SHOWUSEDMEM}
  196. {$endif}
  197. var
  198. CompilerInitedAfterArgs,
  199. CompilerInited : boolean;
  200. {****************************************************************************
  201. Compiler
  202. ****************************************************************************}
  203. procedure DoneCompiler;
  204. begin
  205. if not CompilerInited then
  206. exit;
  207. { Free compiler if args are read }
  208. {$ifdef BrowserLog}
  209. DoneBrowserLog;
  210. {$endif BrowserLog}
  211. {$ifdef BrowserCol}
  212. do_doneSymbolInfo;
  213. {$endif BrowserCol}
  214. if CompilerInitedAfterArgs then
  215. begin
  216. CompilerInitedAfterArgs:=false;
  217. DoneParser;
  218. DoneImport;
  219. DoneExport;
  220. DoneDebuginfo;
  221. DoneLinker;
  222. DoneAssembler;
  223. DoneAsm;
  224. end;
  225. { Free memory for the others }
  226. CompilerInited:=false;
  227. DoneSymtable;
  228. DoneGlobals;
  229. donetokens;
  230. end;
  231. procedure InitCompiler(const cmd:string);
  232. begin
  233. if CompilerInited then
  234. DoneCompiler;
  235. { inits which need to be done before the arguments are parsed }
  236. InitSystems;
  237. { globals depends on source_info so it must be after systems }
  238. InitGlobals;
  239. { verbose depends on exe_path and must be after globals }
  240. InitVerbose;
  241. {$ifdef BrowserLog}
  242. InitBrowserLog;
  243. {$endif BrowserLog}
  244. {$ifdef BrowserCol}
  245. do_initSymbolInfo;
  246. {$endif BrowserCol}
  247. inittokens;
  248. InitSymtable; {Must come before read_arguments, to enable macrosymstack}
  249. CompilerInited:=true;
  250. { this is needed here for the IDE
  251. in case of compilation failure
  252. at the previous compile }
  253. current_module:=nil;
  254. { read the arguments }
  255. read_arguments(cmd);
  256. { inits which depend on arguments }
  257. InitParser;
  258. InitImport;
  259. InitExport;
  260. InitLinker;
  261. InitAssembler;
  262. InitDebugInfo;
  263. InitAsm;
  264. CompilerInitedAfterArgs:=true;
  265. end;
  266. function Compile(const cmd:string):longint;
  267. {$ifdef fpc}
  268. {$maxfpuregisters 0}
  269. {$endif fpc}
  270. procedure writepathlist(w:longint;l:TSearchPathList);
  271. var
  272. hp : tstringlistitem;
  273. begin
  274. hp:=tstringlistitem(l.first);
  275. while assigned(hp) do
  276. begin
  277. Message1(w,hp.str);
  278. hp:=tstringlistitem(hp.next);
  279. end;
  280. end;
  281. function getrealtime : real;
  282. var
  283. {$IFDEF USE_SYSUTILS}
  284. h,m,s,s1000 : word;
  285. {$ELSE USE_SYSUTILS}
  286. h,m,s,s100 : word;
  287. {$ENDIF USE_SYSUTILS}
  288. begin
  289. {$IFDEF USE_SYSUTILS}
  290. DecodeTime(Time,h,m,s,s1000);
  291. getrealtime:=h*3600.0+m*60.0+s+s1000/1000.0;
  292. {$ELSE USE_SYSUTILS}
  293. gettime(h,m,s,s100);
  294. getrealtime:=h*3600.0+m*60.0+s+s100/100.0;
  295. {$ENDIF USE_SYSUTILS}
  296. end;
  297. var
  298. starttime : real;
  299. {$ifdef SHOWUSEDMEM}
  300. hstatus : TFPCHeapStatus;
  301. {$endif SHOWUSEDMEM}
  302. begin
  303. try
  304. try
  305. { Initialize the compiler }
  306. InitCompiler(cmd);
  307. { show some info }
  308. Message1(general_t_compilername,FixFileName(system.paramstr(0)));
  309. Message1(general_d_sourceos,source_info.name);
  310. Message1(general_i_targetos,target_info.name);
  311. Message1(general_t_exepath,exepath);
  312. WritePathList(general_t_unitpath,unitsearchpath);
  313. WritePathList(general_t_includepath,includesearchpath);
  314. WritePathList(general_t_librarypath,librarysearchpath);
  315. WritePathList(general_t_objectpath,objectsearchpath);
  316. starttime:=getrealtime;
  317. { Compile the program }
  318. {$ifdef PREPROCWRITE}
  319. if parapreprocess then
  320. parser.preprocess(inputdir+inputfile+inputextension)
  321. else
  322. {$endif PREPROCWRITE}
  323. parser.compile(inputdir+inputfile+inputextension);
  324. { Show statistics }
  325. if status.errorcount=0 then
  326. begin
  327. starttime:=getrealtime-starttime;
  328. if starttime<0 then
  329. starttime:=starttime+3600.0*24.0;
  330. Message2(general_i_abslines_compiled,tostr(status.compiledlines),tostr(trunc(starttime))+
  331. '.'+tostr(trunc(frac(starttime)*10)));
  332. end;
  333. finally
  334. { no message possible after this !! }
  335. DoneCompiler;
  336. end;
  337. except
  338. on EControlCAbort do
  339. begin
  340. try
  341. { in case of 50 errors, this could cause another exception,
  342. suppress this exception
  343. }
  344. Message(general_f_compilation_aborted);
  345. except
  346. on ECompilerAbort do
  347. ;
  348. end;
  349. DoneVerbose;
  350. end;
  351. on ECompilerAbort do
  352. begin
  353. try
  354. { in case of 50 errors, this could cause another exception,
  355. suppress this exception
  356. }
  357. Message(general_f_compilation_aborted);
  358. except
  359. on ECompilerAbort do
  360. ;
  361. end;
  362. DoneVerbose;
  363. end;
  364. on ECompilerAbortSilent do
  365. begin
  366. DoneVerbose;
  367. end;
  368. on Exception do
  369. begin
  370. { General catchall, normally not used }
  371. try
  372. { in case of 50 errors, this could cause another exception,
  373. suppress this exception
  374. }
  375. Message(general_f_compilation_aborted);
  376. except
  377. on ECompilerAbort do
  378. ;
  379. end;
  380. DoneVerbose;
  381. Raise;
  382. end;
  383. end;
  384. {$ifdef SHOWUSEDMEM}
  385. hstatus:=GetFPCHeapStatus;
  386. Writeln('Max Memory used/heapsize: ',DStr(hstatus.MaxHeapUsed shr 10),'/',DStr(hstatus.MaxHeapSize shr 10),' Kb');
  387. {$endif SHOWUSEDMEM}
  388. { Set the return value if an error has occurred }
  389. if status.errorcount=0 then
  390. result:=0
  391. else
  392. result:=1;
  393. end;
  394. end.