compiler.pas 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  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,import,export,tokens,pass_1
  121. { cpu overrides }
  122. ,cpuswtch
  123. { cpu codegenerator }
  124. ,cgcpu
  125. {$ifndef NOPASS2}
  126. ,cpunode
  127. {$endif}
  128. { cpu targets }
  129. ,cputarg
  130. { cpu parameter handling }
  131. ,cpupara
  132. { procinfo stuff }
  133. ,cpupi
  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. { assembler readers }
  187. {$ifdef i386}
  188. {$ifndef NoRa386Int}
  189. ,ra386int
  190. {$endif NoRa386Int}
  191. {$ifndef NoRa386Att}
  192. ,ra386att
  193. {$endif NoRa386Att}
  194. {$else}
  195. ,rasm
  196. {$endif i386}
  197. {$ifdef powerpc}
  198. ,rappcgas
  199. {$endif powerpc}
  200. {$ifdef x86_64}
  201. ,rax64att
  202. {$endif x86_64}
  203. {$ifdef arm}
  204. ,raarmgas
  205. {$endif arm}
  206. {$ifdef SPARC}
  207. ,racpugas
  208. {$endif SPARC}
  209. ;
  210. function Compile(const cmd:string):longint;
  211. implementation
  212. uses
  213. aasmcpu;
  214. {$ifdef EXTDEBUG}
  215. {$define SHOWUSEDMEM}
  216. {$endif}
  217. {$ifdef MEMDEBUG}
  218. {$define SHOWUSEDMEM}
  219. {$endif}
  220. var
  221. CompilerInitedAfterArgs,
  222. CompilerInited : boolean;
  223. {****************************************************************************
  224. Compiler
  225. ****************************************************************************}
  226. procedure DoneCompiler;
  227. begin
  228. if not CompilerInited then
  229. exit;
  230. { Free compiler if args are read }
  231. {$ifdef BrowserLog}
  232. DoneBrowserLog;
  233. {$endif BrowserLog}
  234. {$ifdef BrowserCol}
  235. do_doneSymbolInfo;
  236. {$endif BrowserCol}
  237. if CompilerInitedAfterArgs then
  238. begin
  239. CompilerInitedAfterArgs:=false;
  240. DoneParser;
  241. DoneImport;
  242. DoneExport;
  243. DoneLinker;
  244. DoneAssembler;
  245. DoneAsm;
  246. end;
  247. { Free memory for the others }
  248. CompilerInited:=false;
  249. DoneSymtable;
  250. DoneGlobals;
  251. donetokens;
  252. end;
  253. procedure InitCompiler(const cmd:string);
  254. begin
  255. if CompilerInited then
  256. DoneCompiler;
  257. { inits which need to be done before the arguments are parsed }
  258. InitSystems;
  259. { globals depends on source_info so it must be after systems }
  260. InitGlobals;
  261. { verbose depends on exe_path and must be after globals }
  262. InitVerbose;
  263. {$ifdef BrowserLog}
  264. InitBrowserLog;
  265. {$endif BrowserLog}
  266. {$ifdef BrowserCol}
  267. do_initSymbolInfo;
  268. {$endif BrowserCol}
  269. inittokens;
  270. InitSymtable; {Must come before read_arguments, to enable macrosymstack}
  271. CompilerInited:=true;
  272. { this is needed here for the IDE
  273. in case of compilation failure
  274. at the previous compile }
  275. current_module:=nil;
  276. { read the arguments }
  277. read_arguments(cmd);
  278. { inits which depend on arguments }
  279. InitParser;
  280. InitImport;
  281. InitExport;
  282. InitLinker;
  283. InitAssembler;
  284. InitAsm;
  285. CompilerInitedAfterArgs:=true;
  286. end;
  287. function Compile(const cmd:string):longint;
  288. {$ifdef fpc}
  289. {$maxfpuregisters 0}
  290. {$endif fpc}
  291. procedure writepathlist(w:longint;l:TSearchPathList);
  292. var
  293. hp : tstringlistitem;
  294. begin
  295. hp:=tstringlistitem(l.first);
  296. while assigned(hp) do
  297. begin
  298. Message1(w,hp.str);
  299. hp:=tstringlistitem(hp.next);
  300. end;
  301. end;
  302. function getrealtime : real;
  303. var
  304. {$IFDEF USE_SYSUTILS}
  305. h,m,s,s1000 : word;
  306. {$ELSE USE_SYSUTILS}
  307. h,m,s,s100 : word;
  308. {$ENDIF USE_SYSUTILS}
  309. begin
  310. {$IFDEF USE_SYSUTILS}
  311. DecodeTime(Time,h,m,s,s1000);
  312. getrealtime:=h*3600.0+m*60.0+s+s1000/1000.0;
  313. {$ELSE USE_SYSUTILS}
  314. gettime(h,m,s,s100);
  315. getrealtime:=h*3600.0+m*60.0+s+s100/100.0;
  316. {$ENDIF USE_SYSUTILS}
  317. end;
  318. var
  319. starttime : real;
  320. {$ifdef SHOWUSEDMEM}
  321. hstatus : TFPCHeapStatus;
  322. {$endif SHOWUSEDMEM}
  323. begin
  324. try
  325. try
  326. { Initialize the compiler }
  327. InitCompiler(cmd);
  328. { show some info }
  329. Message1(general_t_compilername,FixFileName(system.paramstr(0)));
  330. Message1(general_d_sourceos,source_info.name);
  331. Message1(general_i_targetos,target_info.name);
  332. Message1(general_t_exepath,exepath);
  333. WritePathList(general_t_unitpath,unitsearchpath);
  334. WritePathList(general_t_includepath,includesearchpath);
  335. WritePathList(general_t_librarypath,librarysearchpath);
  336. WritePathList(general_t_objectpath,objectsearchpath);
  337. starttime:=getrealtime;
  338. { Compile the program }
  339. {$ifdef PREPROCWRITE}
  340. if parapreprocess then
  341. parser.preprocess(inputdir+inputfile+inputextension)
  342. else
  343. {$endif PREPROCWRITE}
  344. parser.compile(inputdir+inputfile+inputextension);
  345. { Show statistics }
  346. if status.errorcount=0 then
  347. begin
  348. starttime:=getrealtime-starttime;
  349. if starttime<0 then
  350. starttime:=starttime+3600.0*24.0;
  351. Message2(general_i_abslines_compiled,tostr(status.compiledlines),tostr(trunc(starttime))+
  352. '.'+tostr(trunc(frac(starttime)*10)));
  353. end;
  354. finally
  355. { no message possible after this !! }
  356. DoneCompiler;
  357. end;
  358. except
  359. on EControlCAbort do
  360. begin
  361. try
  362. { in case of 50 errors, this could cause another exception,
  363. suppress this exception
  364. }
  365. Message(general_f_compilation_aborted);
  366. except
  367. on ECompilerAbort do
  368. ;
  369. end;
  370. DoneVerbose;
  371. end;
  372. on ECompilerAbort do
  373. begin
  374. try
  375. { in case of 50 errors, this could cause another exception,
  376. suppress this exception
  377. }
  378. Message(general_f_compilation_aborted);
  379. except
  380. on ECompilerAbort do
  381. ;
  382. end;
  383. DoneVerbose;
  384. end;
  385. on ECompilerAbortSilent do
  386. begin
  387. DoneVerbose;
  388. end;
  389. on Exception do
  390. begin
  391. { General catchall, normally not used }
  392. try
  393. { in case of 50 errors, this could cause another exception,
  394. suppress this exception
  395. }
  396. Message(general_f_compilation_aborted);
  397. except
  398. on ECompilerAbort do
  399. ;
  400. end;
  401. DoneVerbose;
  402. Raise;
  403. end;
  404. end;
  405. {$ifdef SHOWUSEDMEM}
  406. hstatus:=GetFPCHeapStatus;
  407. Writeln('Max Memory used/heapsize: ',DStr(hstatus.MaxHeapUsed shr 10),'/',DStr(hstatus.MaxHeapSize shr 10),' Kb');
  408. {$endif SHOWUSEDMEM}
  409. { Set the return value if an error has occurred }
  410. if status.errorcount=0 then
  411. result:=0
  412. else
  413. result:=1;
  414. end;
  415. end.