link.pas 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046
  1. {
  2. $Id$
  3. Copyright (c) 1998,99 by the FPC development team
  4. This unit handles the linker and binder calls for programs and
  5. libraries
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************
  18. }
  19. Unit link;
  20. Interface
  21. { Needed for LFN support in path to the executable }
  22. {$ifdef GO32V2}
  23. {$define ALWAYSSHELL}
  24. {$endif}
  25. uses cobjects,files;
  26. Type
  27. TLinker = Object
  28. Glibc2,
  29. Glibc21,
  30. LinkToC, { Should we link to the C libs? }
  31. Strip : Boolean; { Strip symbols ? }
  32. ObjectFiles,
  33. SharedLibFiles,
  34. StaticLibFiles : TStringContainer;
  35. LinkOptions : string; { Additional options to the linker }
  36. DynamicLinker : String[80]; { What Dynamic linker ? }
  37. LinkResName : String[32]; { Name of response file }
  38. { Methods }
  39. Constructor Init;
  40. Destructor Done;
  41. procedure AddModuleFiles(hp:pmodule);
  42. function FindObjectFile(s : string) : string;
  43. function FindLibraryFile(s:string;const ext:string) : string;
  44. Procedure AddObject(const S : String);
  45. Procedure AddStaticLibrary(const S : String);
  46. Procedure AddSharedLibrary(S : String);
  47. Function FindLinker:String; { Find linker, sets Name }
  48. Function DoExec(const command,para:string;info,useshell:boolean):boolean;
  49. Function WriteResponseFile:Boolean;
  50. Function MakeExecutable:boolean;
  51. Procedure MakeStaticLibrary(filescnt:longint);
  52. Procedure MakeSharedLibrary;
  53. procedure postprocessexecutable(const n : string);virtual;
  54. end;
  55. PLinker=^TLinker;
  56. Var
  57. Linker : PLinker;
  58. procedure InitLinker;
  59. procedure DoneLinker;
  60. Implementation
  61. uses
  62. {$ifdef Delphi}
  63. dmisc,
  64. {$else Delphi}
  65. dos,
  66. {$endif Delphi}
  67. globtype,systems,
  68. script,globals,verbose,ppu
  69. {$ifdef i386}
  70. ,win_targ
  71. ,dos_targ
  72. {$endif}
  73. {$ifdef linux}
  74. ,linux
  75. {$endif}
  76. ,gendef
  77. ;
  78. {$ifndef linux}
  79. Procedure Shell(const command:string);
  80. { This is already defined in the linux.ppu for linux, need for the *
  81. expansion under linux }
  82. var
  83. comspec : string;
  84. begin
  85. comspec:=getenv('COMSPEC');
  86. Exec(comspec,' /C '+command);
  87. end;
  88. {$endif}
  89. Constructor TLinker.Init;
  90. begin
  91. ObjectFiles.Init_no_double;
  92. 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.71 1999-09-16 11:34:56 pierre
  724. * typo correction
  725. Revision 1.70 1999/09/15 22:09:16 florian
  726. + rtti is now automatically generated for published classes, i.e.
  727. they are handled like an implicit property
  728. Revision 1.69 1999/09/15 20:24:56 daniel
  729. + Dw switch now does something.
  730. Revision 1.68 1999/08/18 17:05:53 florian
  731. + implemented initilizing of data for the new code generator
  732. so it should compile now simple programs
  733. Revision 1.67 1999/08/16 15:35:23 pierre
  734. * fix for DLL relocation problems
  735. * external bss vars had wrong stabs for pecoff
  736. + -WB11000000 to specify default image base, allows to
  737. load several DLLs with debugging info included
  738. (relocatable DLL are stripped because the relocation
  739. of the .Stab section is misplaced by ldw)
  740. Revision 1.66 1999/08/11 17:26:34 peter
  741. * tlinker object is now inherited for win32 and dos
  742. * postprocessexecutable is now a method of tlinker
  743. Revision 1.65 1999/08/10 12:51:16 pierre
  744. * bind_win32_dll removed (Relocsection used instead)
  745. * now relocsection is true by default ! (needs dlltool
  746. for DLL generation)
  747. Revision 1.64 1999/07/30 23:19:45 peter
  748. * fixed placing of dynamiclinker in link.res (should be the last after
  749. all other libraries)
  750. Revision 1.63 1999/07/29 01:31:39 peter
  751. * fixed shared library linking for glibc2 systems
  752. Revision 1.62 1999/07/27 11:05:51 peter
  753. * glibc 2.1.2 support
  754. Revision 1.61 1999/07/18 10:19:53 florian
  755. * made it compilable with Dlephi 4 again
  756. + fixed problem with large stack allocations on win32
  757. Revision 1.60 1999/07/07 20:33:53 peter
  758. * warning instead of error when switching to static linking
  759. Revision 1.59 1999/07/05 16:21:26 peter
  760. * fixed linking for units without linking necessary
  761. Revision 1.58 1999/07/03 00:29:51 peter
  762. * new link writing to the ppu, one .ppu is needed for all link types,
  763. static (.o) is now always created also when smartlinking is used
  764. Revision 1.57 1999/06/28 16:02:31 peter
  765. * merged
  766. Revision 1.54.2.3 1999/06/28 15:55:40 peter
  767. * also search path if not found in utilsdirectory
  768. Revision 1.54.2.2 1999/06/18 09:51:55 peter
  769. * always use shell() for go32v2 to support LFN
  770. Revision 1.54.2.1 1999/06/15 13:51:56 peter
  771. * also check ld-2.1.so for glibc 2.1, previous was only for 2.1.1
  772. Revision 1.54 1999/06/02 13:25:35 hajny
  773. * fixed stripping symbols for OS/2
  774. Revision 1.53 1999/05/04 21:44:44 florian
  775. * changes to compile it with Delphi 4.0
  776. Revision 1.52 1999/05/03 21:30:30 peter
  777. + glibc 2.1
  778. Revision 1.51 1999/04/28 23:42:33 pierre
  779. * removing of temporary directory with -s option
  780. Revision 1.50 1999/04/25 14:31:48 daniel
  781. * Bug fixed in linking: compiling files on another drive than the one you
  782. currently use you is done correctly.
  783. Revision 1.49 1999/03/25 16:55:30 peter
  784. + unitpath,librarypath,includepath,objectpath directives
  785. Revision 1.48 1999/03/23 16:22:43 peter
  786. * crtbegin/crtend only added if found
  787. Revision 1.47 1999/02/05 16:45:47 michael
  788. + Fixed gluing of options
  789. Revision 1.46 1999/02/05 08:54:26 pierre
  790. + linkofiles splitted inot linkofiles and linkunitfiles
  791. because linkofiles must be stored with directory
  792. to enabled linking of different objects with same name
  793. in a different directory
  794. Revision 1.45 1999/01/29 10:33:07 peter
  795. * objectsearchpath is now also searched if an object is not found
  796. Revision 1.44 1999/01/27 13:07:58 pierre
  797. * problem related with libc : go32v2 and linux differences
  798. Revision 1.43 1999/01/25 15:02:13 peter
  799. * link libc always as last
  800. Revision 1.42 1998/12/11 00:03:19 peter
  801. + globtype,tokens,version unit splitted from globals
  802. Revision 1.41 1998/12/01 23:39:46 pierre
  803. * postprocessexec for win32 changed
  804. Revision 1.40 1998/12/01 12:51:20 peter
  805. * fixed placing of ppas.sh and link.res when using -FE
  806. Revision 1.39 1998/11/30 13:26:23 pierre
  807. * the code for ordering the exported procs/vars was buggy
  808. + added -WB to force binding (Ozerski way of creating DLL)
  809. this is off by default as direct writing of .edata section seems
  810. OK
  811. Revision 1.38 1998/11/30 09:43:13 pierre
  812. * some range check bugs fixed (still not working !)
  813. + added DLL writing support for win32 (also accepts variables)
  814. + TempAnsi for code that could be used for Temporary ansi strings
  815. handling
  816. Revision 1.37 1998/10/26 22:23:31 peter
  817. + fixpath() has an extra option to allow a ./ as path
  818. Revision 1.36 1998/10/22 15:18:44 florian
  819. + switch -vx for win32 added
  820. Revision 1.35 1998/10/19 18:06:23 peter
  821. * use no_double
  822. Revision 1.34 1998/10/16 13:37:18 florian
  823. + switch -FD added to specify the path for utilities
  824. Revision 1.33 1998/10/14 13:38:22 peter
  825. * fixed path with staticlib/objects in ppufiles
  826. Revision 1.32 1998/10/14 11:03:55 daniel
  827. * Forgot to dereference a pointer.
  828. Revision 1.31 1998/10/14 11:01:21 daniel
  829. * Staticlibfilename no longer not include a path. Correction when calling
  830. ar.
  831. Revision 1.30 1998/10/13 13:10:18 peter
  832. * new style for m68k/i386 infos and enums
  833. Revision 1.29 1998/10/13 08:19:34 pierre
  834. + source_os is now set correctly for cross-processor compilers
  835. (tos contains all target_infos and
  836. we use CPU86 and CPU68 conditionals to
  837. get the source operating system
  838. this only works if you do not undefine
  839. the source target !!)
  840. * several cg68k memory leaks fixed
  841. + started to change the code so that it should be possible to have
  842. a complete compiler (both for m68k and i386 !!)
  843. Revision 1.28 1998/10/08 23:28:56 peter
  844. * -vu shows unit info, -vt shows tried/used files
  845. Revision 1.27 1998/10/06 17:16:52 pierre
  846. * some memory leaks fixed (thanks to Peter for heaptrc !)
  847. Revision 1.26 1998/09/29 15:23:05 peter
  848. * remove also the end files for smartlinking
  849. Revision 1.25 1998/09/10 15:25:31 daniel
  850. + Added maxheapsize.
  851. * Corrected semi-bug in calling the assembler and the linker
  852. Revision 1.24 1998/09/07 18:32:45 peter
  853. * fixed for m68k
  854. Revision 1.23 1998/09/03 17:39:04 florian
  855. + better code for type conversation longint/dword to real type
  856. Revision 1.22 1998/09/01 09:01:00 peter
  857. + glibc2 support
  858. Revision 1.21 1998/08/31 12:26:26 peter
  859. * m68k and palmos updates from surebugfixes
  860. Revision 1.20 1998/08/19 10:06:14 peter
  861. * fixed filenames and removedir which supports slash at the end
  862. Revision 1.19 1998/08/17 09:17:47 peter
  863. * static/shared linking updates
  864. Revision 1.18 1998/08/14 21:56:34 peter
  865. * setting the outputfile using -o works now to create static libs
  866. Revision 1.17 1998/08/14 18:16:08 peter
  867. * return after a failed call will now add it to ppas
  868. Revision 1.16 1998/08/12 19:28:15 peter
  869. * better libc support
  870. Revision 1.15 1998/08/10 14:50:02 peter
  871. + localswitches, moduleswitches, globalswitches splitting
  872. Revision 1.14 1998/06/17 14:10:13 peter
  873. * small os2 fixes
  874. * fixed interdependent units with newppu (remake3 under linux works now)
  875. Revision 1.13 1998/06/08 22:59:46 peter
  876. * smartlinking works for win32
  877. * some defines to exclude some compiler parts
  878. Revision 1.12 1998/06/04 23:51:44 peter
  879. * m68k compiles
  880. + .def file creation moved to gendef.pas so it could also be used
  881. for win32
  882. Revision 1.11 1998/05/27 00:20:31 peter
  883. * some scanner optimizes
  884. * automaticly aout2exe for go32v1
  885. * fixed dynamiclinker option which was added at the wrong place
  886. Revision 1.10 1998/05/22 12:32:47 peter
  887. * fixed -L on the commandline, Dos commandline is only 128 bytes
  888. Revision 1.9 1998/05/12 10:46:59 peter
  889. * moved printstatus to verb_def
  890. + V_Normal which is between V_Error and V_Warning and doesn't have a
  891. prefix like error: warning: and is included in V_Default
  892. * fixed some messages
  893. * first time parameter scan is only for -v and -T
  894. - removed old style messages
  895. Revision 1.8 1998/05/11 13:07:54 peter
  896. + $ifdef NEWPPU for the new ppuformat
  897. + $define GDB not longer required
  898. * removed all warnings and stripped some log comments
  899. * no findfirst/findnext anymore to remove smartlink *.o files
  900. Revision 1.7 1998/05/08 09:21:20 michael
  901. * Added missing -Fl message to messages file.
  902. * Corrected mangling of file names when doing Linklib
  903. * -Fl now actually WORKS.
  904. * Librarysearchpath is now a field in linker object.
  905. Revision 1.6 1998/05/06 09:26:49 peter
  906. * fixed ld call with shell
  907. Revision 1.4 1998/05/04 17:54:25 peter
  908. + smartlinking works (only case jumptable left todo)
  909. * redesign of systems.pas to support assemblers and linkers
  910. + Unitname is now also in the PPU-file, increased version to 14
  911. Revision 1.3 1998/04/16 10:54:30 daniel
  912. * Fixed linking for OS/2.
  913. }