link.pas 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. {
  2. $Id$
  3. Copyright (c) 1998 by the FPC development team
  4. This unit handles the linker and binder calls for programs and
  5. libraries
  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. }
  19. Unit link;
  20. Interface
  21. uses cobjects,files;
  22. Type
  23. TLinker = Object
  24. Glibc2,
  25. LinkToC, { Should we link to the C libs? }
  26. Strip : Boolean; { Strip symbols ? }
  27. ObjectFiles,
  28. SharedLibFiles,
  29. StaticLibFiles : TStringContainer;
  30. LibrarySearchPath, { Search path for libraries }
  31. LinkOptions : string; { Additional options to the linker }
  32. DynamicLinker : String[80]; { What Dynamic linker ? }
  33. LinkResName : String[32]; { Name of response file }
  34. { Methods }
  35. Constructor Init;
  36. Destructor Done;
  37. procedure AddModuleFiles(hp:pmodule);
  38. function FindObjectFile(s : string) : string;
  39. function FindLibraryFile(s:string;const ext:string) : string;
  40. Procedure AddObject(const S : String);
  41. Procedure AddStaticLibrary(const S : String);
  42. Procedure AddSharedLibrary(S : String);
  43. Function FindLinker:String; { Find linker, sets Name }
  44. Function DoExec(const command,para:string;info,useshell:boolean):boolean;
  45. Function WriteResponseFile:Boolean;
  46. Function MakeExecutable:boolean;
  47. Procedure MakeStaticLibrary(filescnt:longint);
  48. Procedure MakeSharedLibrary;
  49. end;
  50. PLinker=^TLinker;
  51. Var
  52. Linker : TLinker;
  53. Implementation
  54. uses
  55. globtype,systems,
  56. script,globals,verbose
  57. {$ifdef i386}
  58. ,win_targ
  59. {$endif}
  60. {$ifdef linux}
  61. ,linux
  62. {$endif}
  63. ,dos
  64. ;
  65. {$ifndef linux}
  66. Procedure Shell(command:string);
  67. { This is already defined in the linux.ppu for linux, need for the *
  68. expansion under linux }
  69. var
  70. comspec : string;
  71. begin
  72. comspec:=getenv('COMSPEC');
  73. Exec(comspec,' /C '+command);
  74. end;
  75. {$endif}
  76. Constructor TLinker.Init;
  77. begin
  78. ObjectFiles.Init_no_double;
  79. SharedLibFiles.Init_no_double;
  80. StaticLibFiles.Init_no_double;
  81. LinkToC:=False;
  82. Glibc2:=false;
  83. Strip:=false;
  84. LinkOptions:='';
  85. {$ifdef linux}
  86. { first try glibc2 }
  87. DynamicLinker:='/lib/ld-linux.so.2';
  88. if FileExists(DynamicLinker) then
  89. Glibc2:=true
  90. else
  91. DynamicLinker:='/lib/ld-linux.so.1';
  92. LibrarySearchPath:='/lib;/usr/lib';
  93. {$else}
  94. DynamicLinker:='';
  95. LibrarySearchPath:='';
  96. {$endif}
  97. LinkResName:='link.res';
  98. end;
  99. Destructor TLinker.Done;
  100. begin
  101. ObjectFiles.Done;
  102. SharedLibFiles.Done;
  103. StaticLibFiles.Done;
  104. end;
  105. procedure TLinker.AddModuleFiles(hp:pmodule);
  106. begin
  107. with hp^ do
  108. begin
  109. while not linkofiles.empty do
  110. AddObject(linkofiles.Get);
  111. while not linksharedlibs.empty do
  112. AddSharedLibrary(linksharedlibs.Get);
  113. while not linkstaticlibs.empty do
  114. AddStaticLibrary(linkstaticlibs.Get);
  115. end;
  116. end;
  117. var
  118. LastLDBin : string;
  119. Function TLinker.FindLinker:string;
  120. var
  121. ldfound : boolean;
  122. begin
  123. if LastLDBin='' then
  124. begin
  125. if utilsdirectory<>'' then
  126. begin
  127. LastLDBin:=Search(target_link.linkbin+source_os.exeext,
  128. utilsdirectory,ldfound)+target_link.linkbin+source_os.exeext;
  129. end
  130. else
  131. LastLDBin:=FindExe(target_link.linkbin,ldfound);
  132. if (not ldfound) and not(cs_link_extern in aktglobalswitches) then
  133. begin
  134. Message1(exec_w_linker_not_found,LastLDBin);
  135. aktglobalswitches:=aktglobalswitches+[cs_link_extern];
  136. end;
  137. if ldfound then
  138. Message1(exec_t_using_linker,LastLDBin);
  139. end;
  140. FindLinker:=LastLDBin;
  141. end;
  142. { searches an object file }
  143. function TLinker.FindObjectFile(s:string) : string;
  144. var
  145. found : boolean;
  146. begin
  147. if pos('.',s)=0 then
  148. s:=s+target_info.objext;
  149. s:=FixFileName(s);
  150. if FileExists(s) then
  151. begin
  152. Findobjectfile:=s;
  153. exit;
  154. end;
  155. findobjectfile:=search(s,'.;'+unitsearchpath+';'+exepath,found)+s;
  156. { if not found then check the object searchpath also }
  157. if not found then
  158. findobjectfile:=search(s,objectsearchpath,found)+s;
  159. if not(cs_link_extern in aktglobalswitches) and (not found) then
  160. Message1(exec_w_objfile_not_found,s);
  161. end;
  162. { searches an library file }
  163. function TLinker.FindLibraryFile(s:string;const ext:string) : string;
  164. var
  165. found : boolean;
  166. begin
  167. if pos('.',s)=0 then
  168. s:=s+ext;
  169. if FileExists(s) then
  170. begin
  171. FindLibraryFile:=s;
  172. exit;
  173. end;
  174. findlibraryfile:=search(s,'.;'+librarysearchpath+';'+exepath,found)+s;
  175. if not(cs_link_extern in aktglobalswitches) and (not found) then
  176. Message1(exec_w_libfile_not_found,s);
  177. end;
  178. Procedure TLinker.AddObject(const S : String);
  179. begin
  180. ObjectFiles.Insert(FindObjectFile(s));
  181. end;
  182. Procedure TLinker.AddSharedLibrary(S:String);
  183. begin
  184. { remove prefix 'lib' }
  185. if Copy(s,1,length(target_os.libprefix))=target_os.libprefix then
  186. Delete(s,1,length(target_os.libprefix));
  187. { remove extension if any }
  188. if Copy(s,length(s)-length(target_os.sharedlibext)+1,length(target_os.sharedlibext))=target_os.sharedlibext then
  189. Delete(s,length(s)-length(target_os.sharedlibext)+1,length(target_os.sharedlibext)+1);
  190. { ready to be inserted }
  191. SharedLibFiles.Insert (S);
  192. end;
  193. Procedure TLinker.AddStaticLibrary(const S:String);
  194. begin
  195. StaticLibFiles.Insert(FindLibraryFile(s,target_os.staticlibext));
  196. end;
  197. Function TLinker.DoExec(const command,para:string;info,useshell:boolean):boolean;
  198. begin
  199. DoExec:=true;
  200. if not(cs_link_extern in aktglobalswitches) then
  201. begin
  202. swapvectors;
  203. if useshell then
  204. shell(command+' '+para)
  205. else
  206. exec(command,para);
  207. swapvectors;
  208. if (doserror<>0) then
  209. begin
  210. Message(exec_w_cant_call_linker);
  211. aktglobalswitches:=aktglobalswitches+[cs_link_extern];
  212. DoExec:=false;
  213. end
  214. else
  215. if (dosexitcode<>0) then
  216. begin
  217. Message(exec_w_error_while_linking);
  218. aktglobalswitches:=aktglobalswitches+[cs_link_extern];
  219. DoExec:=false;
  220. end;
  221. end;
  222. { Update asmres when externmode is set }
  223. if cs_link_extern in aktglobalswitches then
  224. begin
  225. if info then
  226. AsmRes.AddLinkCommand(Command,Para,current_module^.exefilename^)
  227. else
  228. AsmRes.AddLinkCommand(Command,Para,'');
  229. end;
  230. end;
  231. Function TLinker.WriteResponseFile : Boolean;
  232. Var
  233. LinkResponse : Text;
  234. i : longint;
  235. prtobj,s,s2 : string;
  236. found,linux_link_c,
  237. linklibc : boolean;
  238. procedure WriteRes(const s:string);
  239. begin
  240. if s<>'' then
  241. WriteLn(Linkresponse,s);
  242. end;
  243. begin
  244. WriteResponseFile:=False;
  245. linux_link_c:=false;
  246. { set special options for some targets }
  247. linklibc:=SharedLibFiles.Find('c');
  248. prtobj:='prt0';
  249. case target_info.target of
  250. target_m68k_Palmos,
  251. target_i386_Win32 :
  252. begin
  253. if DLLsource then
  254. prtobj:='wdllprt0'
  255. else
  256. prtobj:='wprt0';
  257. end;
  258. target_m68k_linux,
  259. target_i386_linux :
  260. begin
  261. if cs_profile in aktmoduleswitches then
  262. begin
  263. prtobj:='gprt0';
  264. if not glibc2 then
  265. AddSharedLibrary('gmon');
  266. AddSharedLibrary('c');
  267. linklibc:=true;
  268. end
  269. else
  270. begin
  271. if linklibc then
  272. prtobj:='cprt0';
  273. end;
  274. if linklibc then
  275. linux_link_c:=true;
  276. end;
  277. end;
  278. { Fix command line options }
  279. If not SharedLibFiles.Empty then
  280. LinkOptions:='-dynamic-linker='+DynamicLinker+' '+LinkOptions;
  281. if Strip and not(cs_debuginfo in aktmoduleswitches) then
  282. LinkOptions:=LinkOptions+target_link.stripopt;
  283. { Open linkresponse and write header }
  284. assign(linkresponse,current_module^.outpath^+LinkResName);
  285. {$I-}
  286. rewrite(linkresponse);
  287. {$I+}
  288. if ioresult<>0 then
  289. exit;
  290. { Write library searchpath }
  291. S2:=LibrarySearchPath;
  292. Repeat
  293. i:=Pos(';',S2);
  294. If i=0 then
  295. i:=255;
  296. S:=Copy(S2,1,i-1);
  297. If S<>'' then
  298. WriteRes(target_link.libpathprefix+s+target_link.libpathsuffix);
  299. Delete (S2,1,i);
  300. until S2='';
  301. WriteRes(target_link.inputstart);
  302. { add objectfiles, start with prt0 always }
  303. if prtobj<>'' then
  304. WriteRes(FindObjectFile(prtobj));
  305. if {linklibc this is only for linux }linux_link_c then
  306. begin
  307. WriteRes(search('crti.o',librarysearchpath,found)+'crti.o');
  308. WriteRes(search('crtbegin.o',librarysearchpath,found)+'crtbegin.o');
  309. end;
  310. while not ObjectFiles.Empty do
  311. begin
  312. s:=ObjectFiles.Get;
  313. if s<>'' then
  314. WriteRes(s);
  315. end;
  316. if linux_link_c then
  317. begin
  318. WriteRes(search('crtend.o',librarysearchpath,found)+'crtend.o');
  319. WriteRes(search('crtn.o',librarysearchpath,found)+'crtn.o');
  320. end;
  321. { Write sharedlibraries like -l<lib> }
  322. While not SharedLibFiles.Empty do
  323. begin
  324. S:=SharedLibFiles.Get;
  325. if s<>'c' then
  326. begin
  327. i:=Pos(target_os.sharedlibext,S);
  328. if i>0 then
  329. Delete(S,i,255);
  330. WriteRes(target_link.libprefix+s);
  331. end
  332. else
  333. linklibc:=true;
  334. end;
  335. { be sure that libc is the last lib }
  336. { arghhhh this is wrong for DJGPP !!!
  337. DJGPP need gcc after c lib (umod...) (PM) }
  338. if linklibc then
  339. WriteRes(target_link.libprefix+'c');
  340. { add libgcc after ! }
  341. if linklibc and (target_info.target=target_i386_go32v2) then
  342. WriteRes(target_link.libprefix+'gcc');
  343. WriteRes(target_link.inputend);
  344. { Write staticlibraries }
  345. if not StaticLibFiles.Empty then
  346. begin
  347. WriteRes(target_link.GroupStart);
  348. While not StaticLibFiles.Empty do
  349. begin
  350. S:=StaticLibFiles.Get;
  351. WriteRes(s)
  352. end;
  353. WriteRes(target_link.GroupEnd);
  354. end;
  355. { Close response }
  356. close(linkresponse);
  357. WriteResponseFile:=True;
  358. end;
  359. function TLinker.MakeExecutable:boolean;
  360. var
  361. bindbin : string[80];
  362. bindfound : boolean;
  363. s : string;
  364. success : boolean;
  365. ii : longint;
  366. begin
  367. {$ifdef linux}
  368. if LinkToC then
  369. begin
  370. AddObject('/usr/lib/crt0.o');
  371. AddObject('lprt');
  372. AddStaticLibrary('libc.a');
  373. AddStaticLibrary('libgcc.a');
  374. end;
  375. {$endif Linux}
  376. { Write used files and libraries }
  377. WriteResponseFile;
  378. { Call linker }
  379. if not(cs_link_extern in aktglobalswitches) then
  380. Message1(exec_i_linking,current_module^.exefilename^);
  381. s:=target_link.linkcmd;
  382. if DLLsource then
  383. Replace(s,'$EXE',current_module^.sharedlibfilename^)
  384. else
  385. Replace(s,'$EXE',current_module^.exefilename^);
  386. Replace(s,'$OPT',LinkOptions);
  387. Replace(s,'$RES',current_module^.outpath^+LinkResName);
  388. success:=DoExec(FindLinker,s,true,false);
  389. {Bind}
  390. if (target_link.bindbin[1]<>'') and
  391. ((target_info.target<>target_i386_win32) or bind_win32_dll) then
  392. for ii:=1 to target_link.binders do
  393. begin
  394. s:=target_link.bindcmd[ii];
  395. Replace(s,'$OPT',LinkOptions);
  396. Replace(s,'$RES',current_module^.outpath^+LinkResName);
  397. if DLLsource then
  398. Replace(s,'$EXE',current_module^.sharedlibfilename^)
  399. else
  400. Replace(s,'$EXE',current_module^.exefilename^);
  401. {Size of the heap when an EMX program runs in OS/2.}
  402. Replace(s,'$HEAPMB',tostr((maxheapsize+1048575) shr 20));
  403. {Size of the stack when an EMX program runs in OS/2.}
  404. Replace(s,'$STACKKB',tostr((stacksize+1023) shr 10));
  405. {When an EMX program runs in DOS, the heap and stack share the
  406. same memory pool. The heap grows upwards, the stack grows downwards.}
  407. Replace(s,'$DOSHEAPKB',tostr((stacksize+maxheapsize+1023) shr 10));
  408. if utilsdirectory<>'' then
  409. begin
  410. bindbin:=Search(target_link.bindbin[ii]+source_os.exeext,
  411. utilsdirectory,bindfound)+target_link.bindbin[ii]+source_os.exeext;
  412. end
  413. else
  414. bindbin:=FindExe(target_link.bindbin[ii],bindfound);
  415. if (not bindfound) and not (cs_link_extern in aktglobalswitches) then
  416. begin
  417. Message1(exec_w_binder_not_found,bindbin);
  418. aktglobalswitches:=aktglobalswitches+[cs_link_extern];
  419. end;
  420. DoExec(bindbin,s,false,false);
  421. end;
  422. { Post processor executable }
  423. {$ifdef i386}
  424. if (target_info.target=target_i386_Win32) and success and
  425. not(cs_link_extern in aktglobalswitches) then
  426. if DLLsource then
  427. win_targ.postprocessexecutable(current_module^.sharedlibfilename^)
  428. else
  429. win_targ.postprocessexecutable(current_module^.exefilename^);
  430. {$endif}
  431. {Remove ReponseFile}
  432. if (success) and not(cs_link_extern in aktglobalswitches) then
  433. RemoveFile(current_module^.outpath^+LinkResName);
  434. MakeExecutable:=success; { otherwise a recursive call to link method }
  435. end;
  436. Procedure TLinker.MakeStaticLibrary(filescnt:longint);
  437. {
  438. FilesCnt holds the amount of .o files created, if filescnt=0 then
  439. no smartlinking is used
  440. }
  441. var
  442. smartpath,
  443. s,
  444. arbin : string;
  445. arfound : boolean;
  446. cnt : longint;
  447. begin
  448. smartpath:=current_module^.path^+FixPath(FixFileName(current_module^.modulename^)+target_info.smartext,false);
  449. { find ar binary }
  450. if utilsdirectory<>'' then
  451. begin
  452. arbin:=Search(target_ar.arbin+source_os.exeext,
  453. utilsdirectory,arfound)+target_ar.arbin+source_os.exeext;
  454. end
  455. else
  456. arbin:=FindExe(target_ar.arbin,arfound);
  457. if (not arfound) and not(cs_link_extern in aktglobalswitches) then
  458. begin
  459. Message(exec_w_ar_not_found);
  460. aktglobalswitches:=aktglobalswitches+[cs_link_extern];
  461. end;
  462. s:=target_ar.arcmd;
  463. Replace(s,'$LIB',current_module^.staticlibfilename^);
  464. if filescnt=0 then
  465. Replace(s,'$FILES',current_module^.objfilename^)
  466. else
  467. Replace(s,'$FILES',FixFileName(smartpath+current_module^.asmprefix^+'*'+target_info.objext));
  468. DoExec(arbin,s,false,true);
  469. { Clean up }
  470. if not(cs_asm_leave in aktglobalswitches) and not(cs_link_extern in aktglobalswitches) then
  471. begin
  472. if filescnt=0 then
  473. RemoveFile(current_module^.objfilename^)
  474. else
  475. begin
  476. for cnt:=1 to filescnt do
  477. if not RemoveFile(FixFileName(smartpath+current_module^.asmprefix^+tostr(cnt)+target_info.objext)) then
  478. RemoveFile(FixFileName(smartpath+current_module^.asmprefix^+'e'+tostr(cnt)+target_info.objext));
  479. RemoveDir(smartpath);
  480. end;
  481. end;
  482. end;
  483. Procedure TLinker.MakeSharedLibrary;
  484. var
  485. s : string;
  486. begin
  487. s:=' -shared -o $LIB $FILES';
  488. Replace(s,'$LIB',current_module^.sharedlibfilename^);
  489. Replace(s,'$FILES',current_module^.objfilename^);
  490. if DoExec(FindLinker,s,false,false) then
  491. RemoveFile(current_module^.objfilename^);
  492. end;
  493. end.
  494. {
  495. $Log$
  496. Revision 1.45 1999-01-29 10:33:07 peter
  497. * objectsearchpath is now also searched if an object is not found
  498. Revision 1.44 1999/01/27 13:07:58 pierre
  499. * problem related with libc : go32v2 and linux differences
  500. Revision 1.43 1999/01/25 15:02:13 peter
  501. * link libc always as last
  502. Revision 1.42 1998/12/11 00:03:19 peter
  503. + globtype,tokens,version unit splitted from globals
  504. Revision 1.41 1998/12/01 23:39:46 pierre
  505. * postprocessexec for win32 changed
  506. Revision 1.40 1998/12/01 12:51:20 peter
  507. * fixed placing of ppas.sh and link.res when using -FE
  508. Revision 1.39 1998/11/30 13:26:23 pierre
  509. * the code for ordering the exported procs/vars was buggy
  510. + added -WB to force binding (Ozerski way of creating DLL)
  511. this is off by default as direct writing of .edata section seems
  512. OK
  513. Revision 1.38 1998/11/30 09:43:13 pierre
  514. * some range check bugs fixed (still not working !)
  515. + added DLL writing support for win32 (also accepts variables)
  516. + TempAnsi for code that could be used for Temporary ansi strings
  517. handling
  518. Revision 1.37 1998/10/26 22:23:31 peter
  519. + fixpath() has an extra option to allow a ./ as path
  520. Revision 1.36 1998/10/22 15:18:44 florian
  521. + switch -vx for win32 added
  522. Revision 1.35 1998/10/19 18:06:23 peter
  523. * use no_double
  524. Revision 1.34 1998/10/16 13:37:18 florian
  525. + switch -FD added to specify the path for utilities
  526. Revision 1.33 1998/10/14 13:38:22 peter
  527. * fixed path with staticlib/objects in ppufiles
  528. Revision 1.32 1998/10/14 11:03:55 daniel
  529. * Forgot to dereference a pointer.
  530. Revision 1.31 1998/10/14 11:01:21 daniel
  531. * Staticlibfilename no longer not include a path. Correction when calling
  532. ar.
  533. Revision 1.30 1998/10/13 13:10:18 peter
  534. * new style for m68k/i386 infos and enums
  535. Revision 1.29 1998/10/13 08:19:34 pierre
  536. + source_os is now set correctly for cross-processor compilers
  537. (tos contains all target_infos and
  538. we use CPU86 and CPU68 conditionnals to
  539. get the source operating system
  540. this only works if you do not undefine
  541. the source target !!)
  542. * several cg68k memory leaks fixed
  543. + started to change the code so that it should be possible to have
  544. a complete compiler (both for m68k and i386 !!)
  545. Revision 1.28 1998/10/08 23:28:56 peter
  546. * -vu shows unit info, -vt shows tried/used files
  547. Revision 1.27 1998/10/06 17:16:52 pierre
  548. * some memory leaks fixed (thanks to Peter for heaptrc !)
  549. Revision 1.26 1998/09/29 15:23:05 peter
  550. * remove also the end files for smartlinking
  551. Revision 1.25 1998/09/10 15:25:31 daniel
  552. + Added maxheapsize.
  553. * Corrected semi-bug in calling the assembler and the linker
  554. Revision 1.24 1998/09/07 18:32:45 peter
  555. * fixed for m68k
  556. Revision 1.23 1998/09/03 17:39:04 florian
  557. + better code for type conversation longint/dword to real type
  558. Revision 1.22 1998/09/01 09:01:00 peter
  559. + glibc2 support
  560. Revision 1.21 1998/08/31 12:26:26 peter
  561. * m68k and palmos updates from surebugfixes
  562. Revision 1.20 1998/08/19 10:06:14 peter
  563. * fixed filenames and removedir which supports slash at the end
  564. Revision 1.19 1998/08/17 09:17:47 peter
  565. * static/shared linking updates
  566. Revision 1.18 1998/08/14 21:56:34 peter
  567. * setting the outputfile using -o works now to create static libs
  568. Revision 1.17 1998/08/14 18:16:08 peter
  569. * return after a failed call will now add it to ppas
  570. Revision 1.16 1998/08/12 19:28:15 peter
  571. * better libc support
  572. Revision 1.15 1998/08/10 14:50:02 peter
  573. + localswitches, moduleswitches, globalswitches splitting
  574. Revision 1.14 1998/06/17 14:10:13 peter
  575. * small os2 fixes
  576. * fixed interdependent units with newppu (remake3 under linux works now)
  577. Revision 1.13 1998/06/08 22:59:46 peter
  578. * smartlinking works for win32
  579. * some defines to exclude some compiler parts
  580. Revision 1.12 1998/06/04 23:51:44 peter
  581. * m68k compiles
  582. + .def file creation moved to gendef.pas so it could also be used
  583. for win32
  584. Revision 1.11 1998/05/27 00:20:31 peter
  585. * some scanner optimizes
  586. * automaticly aout2exe for go32v1
  587. * fixed dynamiclinker option which was added at the wrong place
  588. Revision 1.10 1998/05/22 12:32:47 peter
  589. * fixed -L on the commandline, Dos commandline is only 128 bytes
  590. Revision 1.9 1998/05/12 10:46:59 peter
  591. * moved printstatus to verb_def
  592. + V_Normal which is between V_Error and V_Warning and doesn't have a
  593. prefix like error: warning: and is included in V_Default
  594. * fixed some messages
  595. * first time parameter scan is only for -v and -T
  596. - removed old style messages
  597. Revision 1.8 1998/05/11 13:07:54 peter
  598. + $ifdef NEWPPU for the new ppuformat
  599. + $define GDB not longer required
  600. * removed all warnings and stripped some log comments
  601. * no findfirst/findnext anymore to remove smartlink *.o files
  602. Revision 1.7 1998/05/08 09:21:20 michael
  603. * Added missing -Fl message to messages file.
  604. * Corrected mangling of file names when doing Linklib
  605. * -Fl now actually WORKS.
  606. * Librarysearchpath is now a field in linker object.
  607. Revision 1.6 1998/05/06 09:26:49 peter
  608. * fixed ld call with shell
  609. Revision 1.4 1998/05/04 17:54:25 peter
  610. + smartlinking works (only case jumptable left todo)
  611. * redesign of systems.pas to support assemblers and linkers
  612. + Unitname is now also in the PPU-file, increased version to 14
  613. Revision 1.3 1998/04/16 10:54:30 daniel
  614. * Fixed linking for OS/2.
  615. }