link.pas 30 KB

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