link.pas 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006
  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. {$ifdef linux}
  541. if LinkToC then
  542. begin
  543. AddObject('/usr/lib/crt0.o');
  544. AddObject('lprt');
  545. AddStaticLibrary('libc.a');
  546. AddStaticLibrary('libgcc.a');
  547. end;
  548. {$endif Linux}
  549. { Write used files and libraries }
  550. WriteResponseFile;
  551. { Call linker }
  552. if not(cs_link_extern in aktglobalswitches) then
  553. Message1(exec_i_linking,current_module^.exefilename^);
  554. s:=target_link.linkcmd;
  555. if DLLsource then
  556. Replace(s,'$EXE',current_module^.sharedlibfilename^)
  557. else
  558. Replace(s,'$EXE',current_module^.exefilename^);
  559. Replace(s,'$OPT',LinkOptions);
  560. Replace(s,'$RES',current_module^.outpath^+LinkResName);
  561. success:=DoExec(FindLinker,s,true,false);
  562. {Bind}
  563. if (target_link.bindbin[1]<>'') and
  564. ((target_info.target<>target_i386_win32) or
  565. (RelocSection and not Deffile.empty)) then
  566. for ii:=1 to target_link.binders do
  567. begin
  568. s:=target_link.bindcmd[ii];
  569. Replace(s,'$OPT',LinkOptions);
  570. Replace(s,'$RES',current_module^.outpath^+LinkResName);
  571. if DLLsource then
  572. Replace(s,'$EXE',current_module^.sharedlibfilename^)
  573. else
  574. Replace(s,'$EXE',current_module^.exefilename^);
  575. {Size of the heap when an EMX program runs in OS/2.}
  576. Replace(s,'$HEAPMB',tostr((maxheapsize+1048575) shr 20));
  577. {Size of the stack when an EMX program runs in OS/2.}
  578. Replace(s,'$STACKKB',tostr((stacksize+1023) shr 10));
  579. {When an EMX program runs in DOS, the heap and stack share the
  580. same memory pool. The heap grows upwards, the stack grows downwards.}
  581. Replace(s,'$DOSHEAPKB',tostr((stacksize+maxheapsize+1023) shr 10));
  582. if Strip and Target_Link.StripBind then
  583. Replace (S, '$STRIP', Target_Link.StripOpt) else
  584. Replace (S, '$STRIP', '');
  585. if utilsdirectory<>'' then
  586. begin
  587. bindbin:=Search(target_link.bindbin[ii]+source_os.exeext,
  588. utilsdirectory,bindfound)+target_link.bindbin[ii]+source_os.exeext;
  589. end
  590. else
  591. bindbin:=FindExe(target_link.bindbin[ii],bindfound);
  592. if (not bindfound) and not (cs_link_extern in aktglobalswitches) then
  593. begin
  594. Message1(exec_w_binder_not_found,bindbin);
  595. aktglobalswitches:=aktglobalswitches+[cs_link_extern];
  596. end;
  597. DoExec(bindbin,s,false,false);
  598. end;
  599. { Post processor executable }
  600. if success and
  601. not(cs_link_extern in aktglobalswitches) then
  602. begin
  603. if DLLsource then
  604. postprocessexecutable(current_module^.sharedlibfilename^)
  605. else
  606. postprocessexecutable(current_module^.exefilename^);
  607. end;
  608. {Remove ReponseFile}
  609. if (success) and not(cs_link_extern in aktglobalswitches) then
  610. RemoveFile(current_module^.outpath^+LinkResName);
  611. MakeExecutable:=success; { otherwise a recursive call to link method }
  612. end;
  613. Procedure TLinker.MakeStaticLibrary(filescnt:longint);
  614. {
  615. FilesCnt holds the amount of .o files created, if filescnt=0 then
  616. no smartlinking is used
  617. }
  618. var
  619. smartpath,
  620. s,
  621. arbin : string;
  622. arfound : boolean;
  623. cnt : longint;
  624. begin
  625. smartpath:=current_module^.path^+FixPath(FixFileName(current_module^.modulename^)+target_info.smartext,false);
  626. { find ar binary }
  627. if utilsdirectory<>'' then
  628. begin
  629. arbin:=Search(target_ar.arbin+source_os.exeext,
  630. utilsdirectory,arfound)+target_ar.arbin+source_os.exeext;
  631. end
  632. else
  633. arbin:=FindExe(target_ar.arbin,arfound);
  634. if (not arfound) and not(cs_link_extern in aktglobalswitches) then
  635. begin
  636. Message(exec_w_ar_not_found);
  637. aktglobalswitches:=aktglobalswitches+[cs_link_extern];
  638. end;
  639. s:=target_ar.arcmd;
  640. Replace(s,'$LIB',current_module^.staticlibfilename^);
  641. if filescnt=0 then
  642. Replace(s,'$FILES',current_module^.objfilename^)
  643. else
  644. Replace(s,'$FILES',FixFileName(smartpath+current_module^.asmprefix^+'*'+target_info.objext));
  645. DoExec(arbin,s,false,true);
  646. { Clean up }
  647. if not(cs_asm_leave in aktglobalswitches) then
  648. if not(cs_link_extern in aktglobalswitches) then
  649. begin
  650. if filescnt=0 then
  651. RemoveFile(current_module^.objfilename^)
  652. else
  653. begin
  654. for cnt:=1 to filescnt do
  655. if not RemoveFile(FixFileName(smartpath+current_module^.asmprefix^+tostr(cnt)+target_info.objext)) then
  656. RemoveFile(FixFileName(smartpath+current_module^.asmprefix^+'e'+tostr(cnt)+target_info.objext));
  657. RemoveDir(smartpath);
  658. end;
  659. end
  660. else
  661. begin
  662. if filescnt=0 then
  663. AsmRes.AddDeleteCommand(current_module^.objfilename^)
  664. else
  665. begin
  666. AsmRes.AddDeleteCommand(smartpath+current_module^.asmprefix^+'*'+target_info.objext);
  667. AsmRes.Add('rmdir '+smartpath);
  668. end;
  669. end;
  670. end;
  671. Procedure TLinker.MakeSharedLibrary;
  672. var
  673. s : string;
  674. begin
  675. s:=' -shared -o $LIB $FILES';
  676. Replace(s,'$LIB',current_module^.sharedlibfilename^);
  677. Replace(s,'$FILES',current_module^.objfilename^);
  678. if DoExec(FindLinker,s,false,false) then
  679. RemoveFile(current_module^.objfilename^);
  680. end;
  681. procedure tlinker.postprocessexecutable(const n:string);
  682. begin
  683. end;
  684. procedure InitLinker;
  685. begin
  686. case target_info.target of
  687. {$ifdef i386}
  688. target_i386_Win32 :
  689. linker:=new(plinkerwin32,Init);
  690. target_i386_Go32v2 :
  691. linker:=new(plinkergo32v2,Init);
  692. {$endif i386}
  693. else
  694. linker:=new(plinker,Init);
  695. end;
  696. end;
  697. procedure DoneLinker;
  698. begin
  699. if assigned(linker) then
  700. dispose(linker,done);
  701. end;
  702. end.
  703. {
  704. $Log$
  705. Revision 1.66 1999-08-11 17:26:34 peter
  706. * tlinker object is now inherited for win32 and dos
  707. * postprocessexecutable is now a method of tlinker
  708. Revision 1.65 1999/08/10 12:51:16 pierre
  709. * bind_win32_dll removed (Relocsection used instead)
  710. * now relocsection is true by default ! (needs dlltool
  711. for DLL generation)
  712. Revision 1.64 1999/07/30 23:19:45 peter
  713. * fixed placing of dynamiclinker in link.res (should be the last after
  714. all other libraries)
  715. Revision 1.63 1999/07/29 01:31:39 peter
  716. * fixed shared library linking for glibc2 systems
  717. Revision 1.62 1999/07/27 11:05:51 peter
  718. * glibc 2.1.2 support
  719. Revision 1.61 1999/07/18 10:19:53 florian
  720. * made it compilable with Dlephi 4 again
  721. + fixed problem with large stack allocations on win32
  722. Revision 1.60 1999/07/07 20:33:53 peter
  723. * warning instead of error when switching to static linking
  724. Revision 1.59 1999/07/05 16:21:26 peter
  725. * fixed linking for units without linking necessary
  726. Revision 1.58 1999/07/03 00:29:51 peter
  727. * new link writing to the ppu, one .ppu is needed for all link types,
  728. static (.o) is now always created also when smartlinking is used
  729. Revision 1.57 1999/06/28 16:02:31 peter
  730. * merged
  731. Revision 1.54.2.3 1999/06/28 15:55:40 peter
  732. * also search path if not found in utilsdirectory
  733. Revision 1.54.2.2 1999/06/18 09:51:55 peter
  734. * always use shell() for go32v2 to support LFN
  735. Revision 1.54.2.1 1999/06/15 13:51:56 peter
  736. * also check ld-2.1.so for glibc 2.1, previous was only for 2.1.1
  737. Revision 1.54 1999/06/02 13:25:35 hajny
  738. * fixed stripping symbols for OS/2
  739. Revision 1.53 1999/05/04 21:44:44 florian
  740. * changes to compile it with Delphi 4.0
  741. Revision 1.52 1999/05/03 21:30:30 peter
  742. + glibc 2.1
  743. Revision 1.51 1999/04/28 23:42:33 pierre
  744. * removing of temporary directory with -s option
  745. Revision 1.50 1999/04/25 14:31:48 daniel
  746. * Bug fixed in linking: compiling files on another drive than the one you
  747. currently use you is done correctly.
  748. Revision 1.49 1999/03/25 16:55:30 peter
  749. + unitpath,librarypath,includepath,objectpath directives
  750. Revision 1.48 1999/03/23 16:22:43 peter
  751. * crtbegin/crtend only added if found
  752. Revision 1.47 1999/02/05 16:45:47 michael
  753. + Fixed gluing of options
  754. Revision 1.46 1999/02/05 08:54:26 pierre
  755. + linkofiles splitted inot linkofiles and linkunitfiles
  756. because linkofiles must be stored with directory
  757. to enabled linking of different objects with same name
  758. in a different directory
  759. Revision 1.45 1999/01/29 10:33:07 peter
  760. * objectsearchpath is now also searched if an object is not found
  761. Revision 1.44 1999/01/27 13:07:58 pierre
  762. * problem related with libc : go32v2 and linux differences
  763. Revision 1.43 1999/01/25 15:02:13 peter
  764. * link libc always as last
  765. Revision 1.42 1998/12/11 00:03:19 peter
  766. + globtype,tokens,version unit splitted from globals
  767. Revision 1.41 1998/12/01 23:39:46 pierre
  768. * postprocessexec for win32 changed
  769. Revision 1.40 1998/12/01 12:51:20 peter
  770. * fixed placing of ppas.sh and link.res when using -FE
  771. Revision 1.39 1998/11/30 13:26:23 pierre
  772. * the code for ordering the exported procs/vars was buggy
  773. + added -WB to force binding (Ozerski way of creating DLL)
  774. this is off by default as direct writing of .edata section seems
  775. OK
  776. Revision 1.38 1998/11/30 09:43:13 pierre
  777. * some range check bugs fixed (still not working !)
  778. + added DLL writing support for win32 (also accepts variables)
  779. + TempAnsi for code that could be used for Temporary ansi strings
  780. handling
  781. Revision 1.37 1998/10/26 22:23:31 peter
  782. + fixpath() has an extra option to allow a ./ as path
  783. Revision 1.36 1998/10/22 15:18:44 florian
  784. + switch -vx for win32 added
  785. Revision 1.35 1998/10/19 18:06:23 peter
  786. * use no_double
  787. Revision 1.34 1998/10/16 13:37:18 florian
  788. + switch -FD added to specify the path for utilities
  789. Revision 1.33 1998/10/14 13:38:22 peter
  790. * fixed path with staticlib/objects in ppufiles
  791. Revision 1.32 1998/10/14 11:03:55 daniel
  792. * Forgot to dereference a pointer.
  793. Revision 1.31 1998/10/14 11:01:21 daniel
  794. * Staticlibfilename no longer not include a path. Correction when calling
  795. ar.
  796. Revision 1.30 1998/10/13 13:10:18 peter
  797. * new style for m68k/i386 infos and enums
  798. Revision 1.29 1998/10/13 08:19:34 pierre
  799. + source_os is now set correctly for cross-processor compilers
  800. (tos contains all target_infos and
  801. we use CPU86 and CPU68 conditionnals to
  802. get the source operating system
  803. this only works if you do not undefine
  804. the source target !!)
  805. * several cg68k memory leaks fixed
  806. + started to change the code so that it should be possible to have
  807. a complete compiler (both for m68k and i386 !!)
  808. Revision 1.28 1998/10/08 23:28:56 peter
  809. * -vu shows unit info, -vt shows tried/used files
  810. Revision 1.27 1998/10/06 17:16:52 pierre
  811. * some memory leaks fixed (thanks to Peter for heaptrc !)
  812. Revision 1.26 1998/09/29 15:23:05 peter
  813. * remove also the end files for smartlinking
  814. Revision 1.25 1998/09/10 15:25:31 daniel
  815. + Added maxheapsize.
  816. * Corrected semi-bug in calling the assembler and the linker
  817. Revision 1.24 1998/09/07 18:32:45 peter
  818. * fixed for m68k
  819. Revision 1.23 1998/09/03 17:39:04 florian
  820. + better code for type conversation longint/dword to real type
  821. Revision 1.22 1998/09/01 09:01:00 peter
  822. + glibc2 support
  823. Revision 1.21 1998/08/31 12:26:26 peter
  824. * m68k and palmos updates from surebugfixes
  825. Revision 1.20 1998/08/19 10:06:14 peter
  826. * fixed filenames and removedir which supports slash at the end
  827. Revision 1.19 1998/08/17 09:17:47 peter
  828. * static/shared linking updates
  829. Revision 1.18 1998/08/14 21:56:34 peter
  830. * setting the outputfile using -o works now to create static libs
  831. Revision 1.17 1998/08/14 18:16:08 peter
  832. * return after a failed call will now add it to ppas
  833. Revision 1.16 1998/08/12 19:28:15 peter
  834. * better libc support
  835. Revision 1.15 1998/08/10 14:50:02 peter
  836. + localswitches, moduleswitches, globalswitches splitting
  837. Revision 1.14 1998/06/17 14:10:13 peter
  838. * small os2 fixes
  839. * fixed interdependent units with newppu (remake3 under linux works now)
  840. Revision 1.13 1998/06/08 22:59:46 peter
  841. * smartlinking works for win32
  842. * some defines to exclude some compiler parts
  843. Revision 1.12 1998/06/04 23:51:44 peter
  844. * m68k compiles
  845. + .def file creation moved to gendef.pas so it could also be used
  846. for win32
  847. Revision 1.11 1998/05/27 00:20:31 peter
  848. * some scanner optimizes
  849. * automaticly aout2exe for go32v1
  850. * fixed dynamiclinker option which was added at the wrong place
  851. Revision 1.10 1998/05/22 12:32:47 peter
  852. * fixed -L on the commandline, Dos commandline is only 128 bytes
  853. Revision 1.9 1998/05/12 10:46:59 peter
  854. * moved printstatus to verb_def
  855. + V_Normal which is between V_Error and V_Warning and doesn't have a
  856. prefix like error: warning: and is included in V_Default
  857. * fixed some messages
  858. * first time parameter scan is only for -v and -T
  859. - removed old style messages
  860. Revision 1.8 1998/05/11 13:07:54 peter
  861. + $ifdef NEWPPU for the new ppuformat
  862. + $define GDB not longer required
  863. * removed all warnings and stripped some log comments
  864. * no findfirst/findnext anymore to remove smartlink *.o files
  865. Revision 1.7 1998/05/08 09:21:20 michael
  866. * Added missing -Fl message to messages file.
  867. * Corrected mangling of file names when doing Linklib
  868. * -Fl now actually WORKS.
  869. * Librarysearchpath is now a field in linker object.
  870. Revision 1.6 1998/05/06 09:26:49 peter
  871. * fixed ld call with shell
  872. Revision 1.4 1998/05/04 17:54:25 peter
  873. + smartlinking works (only case jumptable left todo)
  874. * redesign of systems.pas to support assemblers and linkers
  875. + Unitname is now also in the PPU-file, increased version to 14
  876. Revision 1.3 1998/04/16 10:54:30 daniel
  877. * Fixed linking for OS/2.
  878. }