2
0

compiler.pas 9.6 KB

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