link.pas 30 KB

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