link.pas 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059
  1. {
  2. $Id$
  3. Copyright (c) 1998,99 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. { Needed for LFN support in path to the executable }
  22. {$ifdef GO32V2}
  23. {$define ALWAYSSHELL}
  24. {$endif}
  25. uses cobjects,files;
  26. Type
  27. TLinker = Object
  28. Glibc2,
  29. Glibc21,
  30. LinkToC, { Should we link to the C libs? }
  31. Strip : Boolean; { Strip symbols ? }
  32. ObjectFiles,
  33. SharedLibFiles,
  34. StaticLibFiles : TStringContainer;
  35. LinkOptions : string; { Additional options to the linker }
  36. DynamicLinker : String[80]; { What Dynamic linker ? }
  37. LinkResName : String[32]; { Name of response file }
  38. { Methods }
  39. Constructor Init;
  40. Destructor Done;
  41. procedure AddModuleFiles(hp:pmodule);
  42. function FindObjectFile(s : string) : string;
  43. function FindLibraryFile(s:string;const ext:string) : string;
  44. Procedure AddObject(const S : String);
  45. Procedure AddStaticLibrary(const S : String);
  46. Procedure AddSharedLibrary(S : String);
  47. Function FindLinker:String; { Find linker, sets Name }
  48. Function DoExec(const command,para:string;info,useshell:boolean):boolean;
  49. Function WriteResponseFile:Boolean;
  50. Function MakeExecutable:boolean;
  51. Procedure MakeStaticLibrary(filescnt:longint);
  52. Procedure MakeSharedLibrary;
  53. procedure postprocessexecutable(const n : string);virtual;
  54. end;
  55. PLinker=^TLinker;
  56. Var
  57. Linker : PLinker;
  58. procedure InitLinker;
  59. procedure DoneLinker;
  60. Implementation
  61. uses
  62. {$ifdef Delphi}
  63. dmisc,
  64. {$else Delphi}
  65. dos,
  66. {$endif Delphi}
  67. globtype,systems,
  68. script,globals,verbose,ppu
  69. {$ifdef i386}
  70. ,win_targ
  71. ,dos_targ
  72. {$endif}
  73. {$ifdef linux}
  74. ,linux
  75. {$endif}
  76. ,gendef
  77. ;
  78. {$ifndef linux}
  79. Procedure Shell(const command:string);
  80. { This is already defined in the linux.ppu for linux, need for the *
  81. expansion under linux }
  82. var
  83. comspec : string;
  84. begin
  85. comspec:=getenv('COMSPEC');
  86. Exec(comspec,' /C '+command);
  87. end;
  88. {$endif}
  89. Constructor TLinker.Init;
  90. begin
  91. ObjectFiles.Init_no_double;
  92. { libraries sometimes need to be loaded several times PM }
  93. SharedLibFiles.Init{_no_double};
  94. StaticLibFiles.Init{_no_double};
  95. LinkToC:=(cs_link_toc in aktglobalswitches);
  96. Strip:=(cs_link_strip in aktglobalswitches);
  97. LinkOptions:=ParaLinkOptions;
  98. DynamicLinker:=ParaDynamicLinker;
  99. LinkResName:='link.res';
  100. Glibc2:=false;
  101. Glibc21:=false;
  102. if target_info.target=target_i386_linux then
  103. begin
  104. if DynamicLinker='' then
  105. begin
  106. { first try glibc2 }
  107. DynamicLinker:='/lib/ld-linux.so.2';
  108. if FileExists(DynamicLinker) then
  109. begin
  110. Glibc2:=true;
  111. { also glibc 2.1 / 2.1.1 / 2.1.2 ? }
  112. if FileExists('/lib/ld-2.1.so') or
  113. FileExists('/lib/ld-2.1.1.so') or
  114. FileExists('/lib/ld-2.1.2.so') then
  115. Glibc21:=true;
  116. end
  117. else
  118. DynamicLinker:='/lib/ld-linux.so.1';
  119. end;
  120. AddPathToList(LibrarySearchPath,'/lib;/usr/lib;/usr/X11R6/lib',true);
  121. end;
  122. end;
  123. Destructor TLinker.Done;
  124. begin
  125. ObjectFiles.Done;
  126. SharedLibFiles.Done;
  127. StaticLibFiles.Done;
  128. end;
  129. procedure TLinker.AddModuleFiles(hp:pmodule);
  130. var
  131. mask : longint;
  132. begin
  133. with hp^ do
  134. begin
  135. { link unit files }
  136. if (flags and uf_no_link)=0 then
  137. begin
  138. { create mask which unit files need linking }
  139. mask:=link_allways;
  140. if hp^.is_unit then
  141. begin
  142. { static linking ? }
  143. if (cs_link_static in aktglobalswitches) then
  144. begin
  145. if (flags and uf_static_linked)=0 then
  146. Comment(V_Error,'unit '+modulename^+' can''t be static linked')
  147. else
  148. mask:=mask or link_static;
  149. end;
  150. { smart linking ? }
  151. if (cs_link_smart in aktglobalswitches) then
  152. begin
  153. if (flags and uf_smart_linked)=0 then
  154. begin
  155. { if smart not avail then try static linking }
  156. if (flags and uf_static_linked)<>0 then
  157. begin
  158. Comment(V_Warning,'unit '+modulename^+' can''t be smart linked, switching to static linking');
  159. mask:=mask or link_static;
  160. end
  161. else
  162. Comment(V_Error,'unit '+modulename^+' can''t be smart or static linked');
  163. end
  164. else
  165. mask:=mask or link_smart;
  166. end;
  167. { shared linking }
  168. if (cs_link_shared in aktglobalswitches) then
  169. begin
  170. if (flags and uf_shared_linked)=0 then
  171. begin
  172. { if shared not avail then try static linking }
  173. if (flags and uf_static_linked)<>0 then
  174. begin
  175. Comment(V_Warning,'unit '+modulename^+' can''t be shared linked, switching to static linking');
  176. mask:=mask or link_static;
  177. end
  178. else
  179. Comment(V_Error,'unit '+modulename^+' can''t be shared or static linked');
  180. end
  181. else
  182. mask:=mask or link_shared;
  183. end;
  184. end
  185. else
  186. begin
  187. { for programs link always static }
  188. mask:=mask or link_static;
  189. end;
  190. { unit files }
  191. while not linkunitofiles.empty do
  192. AddObject(linkunitofiles.getusemask(mask));
  193. while not linkunitstaticlibs.empty do
  194. AddStaticLibrary(linkunitstaticlibs.getusemask(mask));
  195. while not linkunitsharedlibs.empty do
  196. AddSharedLibrary(linkunitsharedlibs.getusemask(mask));
  197. end;
  198. { Other needed .o and libs, specified using $L,$LINKLIB,external }
  199. mask:=link_allways;
  200. while not linkotherofiles.empty do
  201. AddObject(linkotherofiles.Getusemask(mask));
  202. while not linkotherstaticlibs.empty do
  203. AddStaticLibrary(linkotherstaticlibs.Getusemask(mask));
  204. while not linkothersharedlibs.empty do
  205. AddSharedLibrary(linkothersharedlibs.Getusemask(mask));
  206. end;
  207. end;
  208. var
  209. LastLDBin : string;
  210. Function TLinker.FindLinker:string;
  211. var
  212. ldfound : boolean;
  213. begin
  214. if LastLDBin='' then
  215. begin
  216. if utilsdirectory<>'' then
  217. LastLDBin:=Search(target_link.linkbin+source_os.exeext,utilsdirectory,ldfound)+
  218. target_link.linkbin+source_os.exeext;
  219. if LastLDBin='' then
  220. LastLDBin:=FindExe(target_link.linkbin,ldfound);
  221. if (not ldfound) and not(cs_link_extern in aktglobalswitches) then
  222. begin
  223. Message1(exec_w_linker_not_found,LastLDBin);
  224. aktglobalswitches:=aktglobalswitches+[cs_link_extern];
  225. end;
  226. if ldfound then
  227. Message1(exec_t_using_linker,LastLDBin);
  228. end;
  229. FindLinker:=LastLDBin;
  230. end;
  231. { searches an object file }
  232. function TLinker.FindObjectFile(s:string) : string;
  233. var
  234. found : boolean;
  235. begin
  236. findobjectfile:='';
  237. if s='' then
  238. exit;
  239. if pos('.',s)=0 then
  240. s:=s+target_info.objext;
  241. s:=FixFileName(s);
  242. if FileExists(s) then
  243. begin
  244. Findobjectfile:=s;
  245. exit;
  246. end;
  247. { find object file
  248. 1. cwd
  249. 2. unit search path
  250. 3. local object path
  251. 4. global object path
  252. 5. exepath }
  253. found:=false;
  254. findobjectfile:=search(s,'.',found)+s;
  255. if (not found) then
  256. findobjectfile:=search(s,unitsearchpath,found)+s;
  257. if (not found) and assigned(current_module^.localobjectsearchpath) then
  258. findobjectfile:=search(s,current_module^.localobjectsearchpath^,found)+s;
  259. if (not found) then
  260. findobjectfile:=search(s,objectsearchpath,found)+s;
  261. if (not found) then
  262. findobjectfile:=search(s,exepath,found)+s;
  263. if not(cs_link_extern in aktglobalswitches) and (not found) then
  264. Message1(exec_w_objfile_not_found,s);
  265. end;
  266. { searches an library file }
  267. function TLinker.FindLibraryFile(s:string;const ext:string) : string;
  268. var
  269. found : boolean;
  270. begin
  271. findlibraryfile:='';
  272. if s='' then
  273. exit;
  274. if pos('.',s)=0 then
  275. s:=s+ext;
  276. if FileExists(s) then
  277. begin
  278. FindLibraryFile:=s;
  279. exit;
  280. end;
  281. { find libary
  282. 1. cwd
  283. 2. local libary dir
  284. 3. global libary dir
  285. 4. exe path of the compiler }
  286. found:=false;
  287. findlibraryfile:=search(s,'.',found)+s;
  288. if (not found) and assigned(current_module^.locallibrarysearchpath) then
  289. findlibraryfile:=search(s,current_module^.locallibrarysearchpath^,found)+s;
  290. if (not found) then
  291. findlibraryfile:=search(s,librarysearchpath,found)+s;
  292. if (not found) then
  293. findlibraryfile:=search(s,exepath,found)+s;
  294. if not(cs_link_extern in aktglobalswitches) and (not found) then
  295. Message1(exec_w_libfile_not_found,s);
  296. end;
  297. Procedure TLinker.AddObject(const S : String);
  298. begin
  299. ObjectFiles.Insert(FindObjectFile(s));
  300. end;
  301. Procedure TLinker.AddSharedLibrary(S:String);
  302. begin
  303. { remove prefix 'lib' }
  304. if Copy(s,1,length(target_os.libprefix))=target_os.libprefix then
  305. Delete(s,1,length(target_os.libprefix));
  306. { remove extension if any }
  307. if Copy(s,length(s)-length(target_os.sharedlibext)+1,length(target_os.sharedlibext))=target_os.sharedlibext then
  308. Delete(s,length(s)-length(target_os.sharedlibext)+1,length(target_os.sharedlibext)+1);
  309. { ready to be inserted }
  310. SharedLibFiles.Insert (S);
  311. end;
  312. Procedure TLinker.AddStaticLibrary(const S:String);
  313. begin
  314. StaticLibFiles.Insert(FindLibraryFile(s,target_os.staticlibext));
  315. end;
  316. Function TLinker.DoExec(const command,para:string;info,useshell:boolean):boolean;
  317. begin
  318. DoExec:=true;
  319. if not(cs_link_extern in aktglobalswitches) then
  320. begin
  321. swapvectors;
  322. {$ifdef ALWAYSSHELL}
  323. shell(command+' '+para);
  324. {$else}
  325. if useshell then
  326. shell(command+' '+para)
  327. else
  328. exec(command,para);
  329. {$endif}
  330. swapvectors;
  331. if (doserror<>0) then
  332. begin
  333. Message(exec_w_cant_call_linker);
  334. aktglobalswitches:=aktglobalswitches+[cs_link_extern];
  335. DoExec:=false;
  336. end
  337. else
  338. if (dosexitcode<>0) then
  339. begin
  340. Message(exec_w_error_while_linking);
  341. aktglobalswitches:=aktglobalswitches+[cs_link_extern];
  342. DoExec:=false;
  343. end;
  344. end;
  345. { Update asmres when externmode is set }
  346. if cs_link_extern in aktglobalswitches then
  347. begin
  348. if info then
  349. AsmRes.AddLinkCommand(Command,Para,current_module^.exefilename^)
  350. else
  351. AsmRes.AddLinkCommand(Command,Para,'');
  352. end;
  353. end;
  354. Function TLinker.WriteResponseFile : Boolean;
  355. Var
  356. LinkResponse : Text;
  357. i : longint;
  358. cprtobj,
  359. gprtobj,
  360. prtobj : string[80];
  361. s,s2 : string;
  362. found,linux_link_c,
  363. linkdynamic,
  364. linklibc : boolean;
  365. procedure WriteRes(const s:string);
  366. begin
  367. if s<>'' then
  368. WriteLn(Linkresponse,s);
  369. end;
  370. procedure WriteResFileName(const s:string);
  371. begin
  372. if s<>'' then
  373. begin
  374. if not(s[1] in ['a'..'z','A'..'Z','/','\','.']) then
  375. Write(Linkresponse,'.',DirSep);
  376. WriteLn(Linkresponse,s);
  377. end;
  378. end;
  379. begin
  380. WriteResponseFile:=False;
  381. linux_link_c:=false;
  382. { set special options for some targets }
  383. linkdynamic:=not(SharedLibFiles.empty);
  384. linklibc:=SharedLibFiles.Find('c');
  385. prtobj:='prt0';
  386. cprtobj:='cprt0';
  387. gprtobj:='gprt0';
  388. if glibc21 then
  389. begin
  390. cprtobj:='cprt21';
  391. gprtobj:='gprt21';
  392. end;
  393. case target_info.target of
  394. target_m68k_Palmos,
  395. target_i386_Win32 :
  396. begin
  397. if DLLsource then
  398. prtobj:='wdllprt0'
  399. else
  400. prtobj:='wprt0';
  401. end;
  402. target_m68k_linux,
  403. target_i386_linux :
  404. begin
  405. if cs_profile in aktmoduleswitches then
  406. begin
  407. prtobj:=gprtobj;
  408. if not glibc2 then
  409. AddSharedLibrary('gmon');
  410. AddSharedLibrary('c');
  411. linklibc:=true;
  412. end
  413. else
  414. begin
  415. if linklibc then
  416. prtobj:=cprtobj;
  417. end;
  418. if linklibc then
  419. linux_link_c:=true;
  420. end;
  421. end;
  422. { Fix command line options }
  423. If (DynamicLinker<>'') and (not SharedLibFiles.Empty) then
  424. LinkOptions:='-dynamic-linker='+DynamicLinker+' '+LinkOptions;
  425. if Strip and not(cs_debuginfo in aktmoduleswitches) and
  426. not (Target_Link.StripBind) then
  427. LinkOptions:=LinkOptions+' '+target_link.stripopt;
  428. { Open linkresponse and write header }
  429. assign(linkresponse,current_module^.outpath^+LinkResName);
  430. {$I-}
  431. rewrite(linkresponse);
  432. {$I+}
  433. if ioresult<>0 then
  434. exit;
  435. { Write library searchpath }
  436. if assigned(current_module^.locallibrarysearchpath) then
  437. begin
  438. S2:=current_module^.locallibrarysearchpath^;
  439. Repeat
  440. i:=Pos(';',S2);
  441. If i=0 then
  442. i:=255;
  443. S:=Copy(S2,1,i-1);
  444. If S<>'' then
  445. WriteRes(target_link.libpathprefix+s+target_link.libpathsuffix);
  446. Delete (S2,1,i);
  447. until S2='';
  448. end;
  449. S2:=LibrarySearchPath;
  450. Repeat
  451. i:=Pos(';',S2);
  452. If i=0 then
  453. i:=255;
  454. S:=Copy(S2,1,i-1);
  455. If S<>'' then
  456. WriteRes(target_link.libpathprefix+s+target_link.libpathsuffix);
  457. Delete (S2,1,i);
  458. until S2='';
  459. WriteRes(target_link.inputstart);
  460. { add objectfiles, start with prt0 always }
  461. if prtobj<>'' then
  462. WriteResFileName(FindObjectFile(prtobj));
  463. { try to add crti and crtbegin, they are normally not required, but
  464. adding can sometimes be usefull }
  465. if linux_link_c then
  466. begin
  467. s:=search('crtbegin.o',librarysearchpath,found)+'crtbegin.o';
  468. if found then
  469. WriteResFileName(s);
  470. s:=search('crti.o',librarysearchpath,found)+'crti.o';
  471. if found then
  472. WriteResFileName(s);
  473. end;
  474. while not ObjectFiles.Empty do
  475. begin
  476. s:=ObjectFiles.Get;
  477. if s<>'' then
  478. WriteResFileName(s);
  479. end;
  480. if linux_link_c then
  481. begin
  482. s:=search('crtend.o',librarysearchpath,found)+'crtend.o';
  483. if found then
  484. WriteResFileName(s);
  485. s:=search('crtn.o',librarysearchpath,found)+'crtn.o';
  486. if found then
  487. WriteResFileName(s);
  488. end;
  489. { Write sharedlibraries like -l<lib>, also add the needed dynamic linker
  490. here to be sure that it gets linked this is needed for glibc2 systems (PFV) }
  491. While not SharedLibFiles.Empty do
  492. begin
  493. S:=SharedLibFiles.Get;
  494. if s<>'c' then
  495. begin
  496. i:=Pos(target_os.sharedlibext,S);
  497. if i>0 then
  498. Delete(S,i,255);
  499. WriteRes(target_link.libprefix+s);
  500. end
  501. else
  502. begin
  503. { Some times several references to libc are necessary !! PM }
  504. WriteRes(target_link.libprefix+s);
  505. linklibc:=true;
  506. linkdynamic:=false; { C add's it automaticly }
  507. end;
  508. end;
  509. { be sure that libc is the last lib }
  510. { arghhhh this is wrong for DJGPP !!!
  511. DJGPP need gcc after c lib (umod...) (PM) }
  512. if linklibc then
  513. WriteRes(target_link.libprefix+'c');
  514. { add libgcc after ! }
  515. if linklibc and (target_info.target=target_i386_go32v2) then
  516. WriteRes(target_link.libprefix+'gcc');
  517. if linkdynamic and (DynamicLinker<>'') then
  518. WriteResFileName(DynamicLinker);
  519. WriteRes(target_link.inputend);
  520. { Write staticlibraries }
  521. if not StaticLibFiles.Empty then
  522. begin
  523. WriteRes(target_link.GroupStart);
  524. While not StaticLibFiles.Empty do
  525. begin
  526. S:=StaticLibFiles.Get;
  527. WriteResFileName(s)
  528. end;
  529. WriteRes(target_link.GroupEnd);
  530. end;
  531. { Close response }
  532. close(linkresponse);
  533. WriteResponseFile:=True;
  534. end;
  535. function TLinker.MakeExecutable:boolean;
  536. var
  537. bindbin : string[80];
  538. bindfound : boolean;
  539. s : string;
  540. success : boolean;
  541. ii : longint;
  542. begin
  543. { can be changed after InitLinker
  544. for DLLs due to relocation problems PM }
  545. Strip:=(cs_link_strip in aktglobalswitches);
  546. {$ifdef linux}
  547. if LinkToC then
  548. begin
  549. AddObject('/usr/lib/crt0.o');
  550. AddObject('lprt');
  551. AddStaticLibrary('libc.a');
  552. AddStaticLibrary('libgcc.a');
  553. end;
  554. {$endif Linux}
  555. { Write used files and libraries }
  556. WriteResponseFile;
  557. { Call linker }
  558. if not(cs_link_extern in aktglobalswitches) then
  559. Message1(exec_i_linking,current_module^.exefilename^);
  560. s:=target_link.linkcmd;
  561. if DLLsource then
  562. Replace(s,'$EXE',current_module^.sharedlibfilename^)
  563. else
  564. Replace(s,'$EXE',current_module^.exefilename^);
  565. Replace(s,'$OPT',LinkOptions);
  566. Replace(s,'$RES',current_module^.outpath^+LinkResName);
  567. success:=DoExec(FindLinker,s,true,false);
  568. {Bind}
  569. if (target_link.bindbin[1]<>'') and
  570. ((target_info.target<>target_i386_win32) or
  571. (RelocSection and not Deffile.empty)) then
  572. for ii:=1 to target_link.binders do
  573. begin
  574. s:=target_link.bindcmd[ii];
  575. Replace(s,'$OPT',LinkOptions);
  576. Replace(s,'$RES',current_module^.outpath^+LinkResName);
  577. if DLLsource then
  578. Replace(s,'$EXE',current_module^.sharedlibfilename^)
  579. else
  580. Replace(s,'$EXE',current_module^.exefilename^);
  581. {Size of the heap when an EMX program runs in OS/2.}
  582. Replace(s,'$HEAPMB',tostr((maxheapsize+1048575) shr 20));
  583. {Size of the stack when an EMX program runs in OS/2.}
  584. Replace(s,'$STACKKB',tostr((stacksize+1023) shr 10));
  585. {When an EMX program runs in DOS, the heap and stack share the
  586. same memory pool. The heap grows upwards, the stack grows downwards.}
  587. Replace(s,'$DOSHEAPKB',tostr((stacksize+maxheapsize+1023) shr 10));
  588. if Strip and Target_Link.StripBind then
  589. Replace (S, '$STRIP', Target_Link.StripOpt)
  590. else
  591. Replace (S, '$STRIP', '');
  592. {This is a hack. But I don't think other platforms have a presenation
  593. manager, so it should work. (DM)}
  594. if usewindowapi then
  595. replace (s, '$PM',' -p')
  596. else
  597. replace (s, '$PM','');
  598. if utilsdirectory<>'' then
  599. begin
  600. bindbin:=Search(target_link.bindbin[ii]+source_os.exeext,
  601. utilsdirectory,bindfound)+target_link.bindbin[ii]+source_os.exeext;
  602. end
  603. else
  604. bindbin:=FindExe(target_link.bindbin[ii],bindfound);
  605. if (not bindfound) and not (cs_link_extern in aktglobalswitches) then
  606. begin
  607. Message1(exec_w_binder_not_found,bindbin);
  608. aktglobalswitches:=aktglobalswitches+[cs_link_extern];
  609. end;
  610. DoExec(bindbin,s,false,false);
  611. end;
  612. { Post processor executable }
  613. if success and
  614. not(cs_link_extern in aktglobalswitches) then
  615. begin
  616. if DLLsource then
  617. postprocessexecutable(current_module^.sharedlibfilename^)
  618. else
  619. postprocessexecutable(current_module^.exefilename^);
  620. end;
  621. {Remove ReponseFile}
  622. if (success) and not(cs_link_extern in aktglobalswitches) then
  623. RemoveFile(current_module^.outpath^+LinkResName);
  624. MakeExecutable:=success; { otherwise a recursive call to link method }
  625. end;
  626. Procedure TLinker.MakeStaticLibrary(filescnt:longint);
  627. {
  628. FilesCnt holds the amount of .o files created, if filescnt=0 then
  629. no smartlinking is used
  630. }
  631. var
  632. smartpath,
  633. s,
  634. arbin : string;
  635. arfound : boolean;
  636. cnt : longint;
  637. begin
  638. smartpath:=current_module^.path^+FixPath(FixFileName(current_module^.modulename^)+target_info.smartext,false);
  639. { find ar binary }
  640. if utilsdirectory<>'' then
  641. begin
  642. arbin:=Search(target_ar.arbin+source_os.exeext,
  643. utilsdirectory,arfound)+target_ar.arbin+source_os.exeext;
  644. end
  645. else
  646. arbin:=FindExe(target_ar.arbin,arfound);
  647. if (not arfound) and not(cs_link_extern in aktglobalswitches) then
  648. begin
  649. Message(exec_w_ar_not_found);
  650. aktglobalswitches:=aktglobalswitches+[cs_link_extern];
  651. end;
  652. s:=target_ar.arcmd;
  653. Replace(s,'$LIB',current_module^.staticlibfilename^);
  654. if filescnt=0 then
  655. Replace(s,'$FILES',current_module^.objfilename^)
  656. else
  657. Replace(s,'$FILES',FixFileName(smartpath+current_module^.asmprefix^+'*'+target_info.objext));
  658. DoExec(arbin,s,false,true);
  659. { Clean up }
  660. if not(cs_asm_leave in aktglobalswitches) then
  661. if not(cs_link_extern in aktglobalswitches) then
  662. begin
  663. if filescnt=0 then
  664. RemoveFile(current_module^.objfilename^)
  665. else
  666. begin
  667. for cnt:=1 to filescnt do
  668. if not RemoveFile(FixFileName(smartpath+current_module^.asmprefix^+tostr(cnt)+target_info.objext)) then
  669. RemoveFile(FixFileName(smartpath+current_module^.asmprefix^+'e'+tostr(cnt)+target_info.objext));
  670. RemoveDir(smartpath);
  671. end;
  672. end
  673. else
  674. begin
  675. if filescnt=0 then
  676. AsmRes.AddDeleteCommand(current_module^.objfilename^)
  677. else
  678. begin
  679. AsmRes.AddDeleteCommand(smartpath+current_module^.asmprefix^+'*'+target_info.objext);
  680. AsmRes.Add('rmdir '+smartpath);
  681. end;
  682. end;
  683. end;
  684. Procedure TLinker.MakeSharedLibrary;
  685. var
  686. s : string;
  687. begin
  688. s:=' -shared -o $LIB $FILES';
  689. Replace(s,'$LIB',current_module^.sharedlibfilename^);
  690. Replace(s,'$FILES',current_module^.objfilename^);
  691. if DoExec(FindLinker,s,false,false) then
  692. RemoveFile(current_module^.objfilename^);
  693. end;
  694. procedure tlinker.postprocessexecutable(const n:string);
  695. begin
  696. end;
  697. procedure InitLinker;
  698. begin
  699. case target_info.target of
  700. {$ifdef i386}
  701. target_i386_Win32 :
  702. linker:=new(plinkerwin32,Init);
  703. target_i386_Go32v2 :
  704. linker:=new(plinkergo32v2,Init);
  705. {$endif i386}
  706. {$ifdef m68k}
  707. target_m68k_palmos:
  708. linker:=new(plinker,Init);
  709. {$endif m68k}
  710. {$ifdef alpha}
  711. target_alpha_linux:
  712. linker:=new(plinker,Init);
  713. {$endif alpha}
  714. {$ifdef powerpc}
  715. target_powerpc_linux:
  716. linker:=new(plinker,Init);
  717. {$endif powerpc}
  718. else
  719. linker:=new(plinker,Init);
  720. end;
  721. end;
  722. procedure DoneLinker;
  723. begin
  724. if assigned(linker) then
  725. dispose(linker,done);
  726. end;
  727. end.
  728. {
  729. $Log$
  730. Revision 1.73 1999-10-08 15:38:42 pierre
  731. * library list keeps doubles
  732. Revision 1.72 1999/09/16 23:05:52 florian
  733. * m68k compiler is again compilable (only gas writer, no assembler reader)
  734. Revision 1.71 1999/09/16 11:34:56 pierre
  735. * typo correction
  736. Revision 1.70 1999/09/15 22:09:16 florian
  737. + rtti is now automatically generated for published classes, i.e.
  738. they are handled like an implicit property
  739. Revision 1.69 1999/09/15 20:24:56 daniel
  740. + Dw switch now does something.
  741. Revision 1.68 1999/08/18 17:05:53 florian
  742. + implemented initilizing of data for the new code generator
  743. so it should compile now simple programs
  744. Revision 1.67 1999/08/16 15:35:23 pierre
  745. * fix for DLL relocation problems
  746. * external bss vars had wrong stabs for pecoff
  747. + -WB11000000 to specify default image base, allows to
  748. load several DLLs with debugging info included
  749. (relocatable DLL are stripped because the relocation
  750. of the .Stab section is misplaced by ldw)
  751. Revision 1.66 1999/08/11 17:26:34 peter
  752. * tlinker object is now inherited for win32 and dos
  753. * postprocessexecutable is now a method of tlinker
  754. Revision 1.65 1999/08/10 12:51:16 pierre
  755. * bind_win32_dll removed (Relocsection used instead)
  756. * now relocsection is true by default ! (needs dlltool
  757. for DLL generation)
  758. Revision 1.64 1999/07/30 23:19:45 peter
  759. * fixed placing of dynamiclinker in link.res (should be the last after
  760. all other libraries)
  761. Revision 1.63 1999/07/29 01:31:39 peter
  762. * fixed shared library linking for glibc2 systems
  763. Revision 1.62 1999/07/27 11:05:51 peter
  764. * glibc 2.1.2 support
  765. Revision 1.61 1999/07/18 10:19:53 florian
  766. * made it compilable with Dlephi 4 again
  767. + fixed problem with large stack allocations on win32
  768. Revision 1.60 1999/07/07 20:33:53 peter
  769. * warning instead of error when switching to static linking
  770. Revision 1.59 1999/07/05 16:21:26 peter
  771. * fixed linking for units without linking necessary
  772. Revision 1.58 1999/07/03 00:29:51 peter
  773. * new link writing to the ppu, one .ppu is needed for all link types,
  774. static (.o) is now always created also when smartlinking is used
  775. Revision 1.57 1999/06/28 16:02:31 peter
  776. * merged
  777. Revision 1.54.2.3 1999/06/28 15:55:40 peter
  778. * also search path if not found in utilsdirectory
  779. Revision 1.54.2.2 1999/06/18 09:51:55 peter
  780. * always use shell() for go32v2 to support LFN
  781. Revision 1.54.2.1 1999/06/15 13:51:56 peter
  782. * also check ld-2.1.so for glibc 2.1, previous was only for 2.1.1
  783. Revision 1.54 1999/06/02 13:25:35 hajny
  784. * fixed stripping symbols for OS/2
  785. Revision 1.53 1999/05/04 21:44:44 florian
  786. * changes to compile it with Delphi 4.0
  787. Revision 1.52 1999/05/03 21:30:30 peter
  788. + glibc 2.1
  789. Revision 1.51 1999/04/28 23:42:33 pierre
  790. * removing of temporary directory with -s option
  791. Revision 1.50 1999/04/25 14:31:48 daniel
  792. * Bug fixed in linking: compiling files on another drive than the one you
  793. currently use you is done correctly.
  794. Revision 1.49 1999/03/25 16:55:30 peter
  795. + unitpath,librarypath,includepath,objectpath directives
  796. Revision 1.48 1999/03/23 16:22:43 peter
  797. * crtbegin/crtend only added if found
  798. Revision 1.47 1999/02/05 16:45:47 michael
  799. + Fixed gluing of options
  800. Revision 1.46 1999/02/05 08:54:26 pierre
  801. + linkofiles splitted inot linkofiles and linkunitfiles
  802. because linkofiles must be stored with directory
  803. to enabled linking of different objects with same name
  804. in a different directory
  805. Revision 1.45 1999/01/29 10:33:07 peter
  806. * objectsearchpath is now also searched if an object is not found
  807. Revision 1.44 1999/01/27 13:07:58 pierre
  808. * problem related with libc : go32v2 and linux differences
  809. Revision 1.43 1999/01/25 15:02:13 peter
  810. * link libc always as last
  811. Revision 1.42 1998/12/11 00:03:19 peter
  812. + globtype,tokens,version unit splitted from globals
  813. Revision 1.41 1998/12/01 23:39:46 pierre
  814. * postprocessexec for win32 changed
  815. Revision 1.40 1998/12/01 12:51:20 peter
  816. * fixed placing of ppas.sh and link.res when using -FE
  817. Revision 1.39 1998/11/30 13:26:23 pierre
  818. * the code for ordering the exported procs/vars was buggy
  819. + added -WB to force binding (Ozerski way of creating DLL)
  820. this is off by default as direct writing of .edata section seems
  821. OK
  822. Revision 1.38 1998/11/30 09:43:13 pierre
  823. * some range check bugs fixed (still not working !)
  824. + added DLL writing support for win32 (also accepts variables)
  825. + TempAnsi for code that could be used for Temporary ansi strings
  826. handling
  827. Revision 1.37 1998/10/26 22:23:31 peter
  828. + fixpath() has an extra option to allow a ./ as path
  829. Revision 1.36 1998/10/22 15:18:44 florian
  830. + switch -vx for win32 added
  831. Revision 1.35 1998/10/19 18:06:23 peter
  832. * use no_double
  833. Revision 1.34 1998/10/16 13:37:18 florian
  834. + switch -FD added to specify the path for utilities
  835. Revision 1.33 1998/10/14 13:38:22 peter
  836. * fixed path with staticlib/objects in ppufiles
  837. Revision 1.32 1998/10/14 11:03:55 daniel
  838. * Forgot to dereference a pointer.
  839. Revision 1.31 1998/10/14 11:01:21 daniel
  840. * Staticlibfilename no longer not include a path. Correction when calling
  841. ar.
  842. Revision 1.30 1998/10/13 13:10:18 peter
  843. * new style for m68k/i386 infos and enums
  844. Revision 1.29 1998/10/13 08:19:34 pierre
  845. + source_os is now set correctly for cross-processor compilers
  846. (tos contains all target_infos and
  847. we use CPU86 and CPU68 conditionals to
  848. get the source operating system
  849. this only works if you do not undefine
  850. the source target !!)
  851. * several cg68k memory leaks fixed
  852. + started to change the code so that it should be possible to have
  853. a complete compiler (both for m68k and i386 !!)
  854. Revision 1.28 1998/10/08 23:28:56 peter
  855. * -vu shows unit info, -vt shows tried/used files
  856. Revision 1.27 1998/10/06 17:16:52 pierre
  857. * some memory leaks fixed (thanks to Peter for heaptrc !)
  858. Revision 1.26 1998/09/29 15:23:05 peter
  859. * remove also the end files for smartlinking
  860. Revision 1.25 1998/09/10 15:25:31 daniel
  861. + Added maxheapsize.
  862. * Corrected semi-bug in calling the assembler and the linker
  863. Revision 1.24 1998/09/07 18:32:45 peter
  864. * fixed for m68k
  865. Revision 1.23 1998/09/03 17:39:04 florian
  866. + better code for type conversation longint/dword to real type
  867. Revision 1.22 1998/09/01 09:01:00 peter
  868. + glibc2 support
  869. Revision 1.21 1998/08/31 12:26:26 peter
  870. * m68k and palmos updates from surebugfixes
  871. Revision 1.20 1998/08/19 10:06:14 peter
  872. * fixed filenames and removedir which supports slash at the end
  873. Revision 1.19 1998/08/17 09:17:47 peter
  874. * static/shared linking updates
  875. Revision 1.18 1998/08/14 21:56:34 peter
  876. * setting the outputfile using -o works now to create static libs
  877. Revision 1.17 1998/08/14 18:16:08 peter
  878. * return after a failed call will now add it to ppas
  879. Revision 1.16 1998/08/12 19:28:15 peter
  880. * better libc support
  881. Revision 1.15 1998/08/10 14:50:02 peter
  882. + localswitches, moduleswitches, globalswitches splitting
  883. Revision 1.14 1998/06/17 14:10:13 peter
  884. * small os2 fixes
  885. * fixed interdependent units with newppu (remake3 under linux works now)
  886. Revision 1.13 1998/06/08 22:59:46 peter
  887. * smartlinking works for win32
  888. * some defines to exclude some compiler parts
  889. Revision 1.12 1998/06/04 23:51:44 peter
  890. * m68k compiles
  891. + .def file creation moved to gendef.pas so it could also be used
  892. for win32
  893. Revision 1.11 1998/05/27 00:20:31 peter
  894. * some scanner optimizes
  895. * automaticly aout2exe for go32v1
  896. * fixed dynamiclinker option which was added at the wrong place
  897. Revision 1.10 1998/05/22 12:32:47 peter
  898. * fixed -L on the commandline, Dos commandline is only 128 bytes
  899. Revision 1.9 1998/05/12 10:46:59 peter
  900. * moved printstatus to verb_def
  901. + V_Normal which is between V_Error and V_Warning and doesn't have a
  902. prefix like error: warning: and is included in V_Default
  903. * fixed some messages
  904. * first time parameter scan is only for -v and -T
  905. - removed old style messages
  906. Revision 1.8 1998/05/11 13:07:54 peter
  907. + $ifdef NEWPPU for the new ppuformat
  908. + $define GDB not longer required
  909. * removed all warnings and stripped some log comments
  910. * no findfirst/findnext anymore to remove smartlink *.o files
  911. Revision 1.7 1998/05/08 09:21:20 michael
  912. * Added missing -Fl message to messages file.
  913. * Corrected mangling of file names when doing Linklib
  914. * -Fl now actually WORKS.
  915. * Librarysearchpath is now a field in linker object.
  916. Revision 1.6 1998/05/06 09:26:49 peter
  917. * fixed ld call with shell
  918. Revision 1.4 1998/05/04 17:54:25 peter
  919. + smartlinking works (only case jumptable left todo)
  920. * redesign of systems.pas to support assemblers and linkers
  921. + Unitname is now also in the PPU-file, increased version to 14
  922. Revision 1.3 1998/04/16 10:54:30 daniel
  923. * Fixed linking for OS/2.
  924. }