link.pas 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053
  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 m68k}
  704. target_m68k_palmos:
  705. linker:=new(plinker,Init);
  706. {$endif m68k}
  707. {$ifdef alpha}
  708. target_alpha_linux:
  709. linker:=new(plinker,Init);
  710. {$endif alpha}
  711. {$ifdef powerpc}
  712. target_powerpc_linux:
  713. linker:=new(plinker,Init);
  714. {$endif powerpc}
  715. else
  716. linker:=new(plinker,Init);
  717. end;
  718. end;
  719. procedure DoneLinker;
  720. begin
  721. if assigned(linker) then
  722. dispose(linker,done);
  723. end;
  724. end.
  725. {
  726. $Log$
  727. Revision 1.72 1999-09-16 23:05:52 florian
  728. * m68k compiler is again compilable (only gas writer, no assembler reader)
  729. Revision 1.71 1999/09/16 11:34:56 pierre
  730. * typo correction
  731. Revision 1.70 1999/09/15 22:09:16 florian
  732. + rtti is now automatically generated for published classes, i.e.
  733. they are handled like an implicit property
  734. Revision 1.69 1999/09/15 20:24:56 daniel
  735. + Dw switch now does something.
  736. Revision 1.68 1999/08/18 17:05:53 florian
  737. + implemented initilizing of data for the new code generator
  738. so it should compile now simple programs
  739. Revision 1.67 1999/08/16 15:35:23 pierre
  740. * fix for DLL relocation problems
  741. * external bss vars had wrong stabs for pecoff
  742. + -WB11000000 to specify default image base, allows to
  743. load several DLLs with debugging info included
  744. (relocatable DLL are stripped because the relocation
  745. of the .Stab section is misplaced by ldw)
  746. Revision 1.66 1999/08/11 17:26:34 peter
  747. * tlinker object is now inherited for win32 and dos
  748. * postprocessexecutable is now a method of tlinker
  749. Revision 1.65 1999/08/10 12:51:16 pierre
  750. * bind_win32_dll removed (Relocsection used instead)
  751. * now relocsection is true by default ! (needs dlltool
  752. for DLL generation)
  753. Revision 1.64 1999/07/30 23:19:45 peter
  754. * fixed placing of dynamiclinker in link.res (should be the last after
  755. all other libraries)
  756. Revision 1.63 1999/07/29 01:31:39 peter
  757. * fixed shared library linking for glibc2 systems
  758. Revision 1.62 1999/07/27 11:05:51 peter
  759. * glibc 2.1.2 support
  760. Revision 1.61 1999/07/18 10:19:53 florian
  761. * made it compilable with Dlephi 4 again
  762. + fixed problem with large stack allocations on win32
  763. Revision 1.60 1999/07/07 20:33:53 peter
  764. * warning instead of error when switching to static linking
  765. Revision 1.59 1999/07/05 16:21:26 peter
  766. * fixed linking for units without linking necessary
  767. Revision 1.58 1999/07/03 00:29:51 peter
  768. * new link writing to the ppu, one .ppu is needed for all link types,
  769. static (.o) is now always created also when smartlinking is used
  770. Revision 1.57 1999/06/28 16:02:31 peter
  771. * merged
  772. Revision 1.54.2.3 1999/06/28 15:55:40 peter
  773. * also search path if not found in utilsdirectory
  774. Revision 1.54.2.2 1999/06/18 09:51:55 peter
  775. * always use shell() for go32v2 to support LFN
  776. Revision 1.54.2.1 1999/06/15 13:51:56 peter
  777. * also check ld-2.1.so for glibc 2.1, previous was only for 2.1.1
  778. Revision 1.54 1999/06/02 13:25:35 hajny
  779. * fixed stripping symbols for OS/2
  780. Revision 1.53 1999/05/04 21:44:44 florian
  781. * changes to compile it with Delphi 4.0
  782. Revision 1.52 1999/05/03 21:30:30 peter
  783. + glibc 2.1
  784. Revision 1.51 1999/04/28 23:42:33 pierre
  785. * removing of temporary directory with -s option
  786. Revision 1.50 1999/04/25 14:31:48 daniel
  787. * Bug fixed in linking: compiling files on another drive than the one you
  788. currently use you is done correctly.
  789. Revision 1.49 1999/03/25 16:55:30 peter
  790. + unitpath,librarypath,includepath,objectpath directives
  791. Revision 1.48 1999/03/23 16:22:43 peter
  792. * crtbegin/crtend only added if found
  793. Revision 1.47 1999/02/05 16:45:47 michael
  794. + Fixed gluing of options
  795. Revision 1.46 1999/02/05 08:54:26 pierre
  796. + linkofiles splitted inot linkofiles and linkunitfiles
  797. because linkofiles must be stored with directory
  798. to enabled linking of different objects with same name
  799. in a different directory
  800. Revision 1.45 1999/01/29 10:33:07 peter
  801. * objectsearchpath is now also searched if an object is not found
  802. Revision 1.44 1999/01/27 13:07:58 pierre
  803. * problem related with libc : go32v2 and linux differences
  804. Revision 1.43 1999/01/25 15:02:13 peter
  805. * link libc always as last
  806. Revision 1.42 1998/12/11 00:03:19 peter
  807. + globtype,tokens,version unit splitted from globals
  808. Revision 1.41 1998/12/01 23:39:46 pierre
  809. * postprocessexec for win32 changed
  810. Revision 1.40 1998/12/01 12:51:20 peter
  811. * fixed placing of ppas.sh and link.res when using -FE
  812. Revision 1.39 1998/11/30 13:26:23 pierre
  813. * the code for ordering the exported procs/vars was buggy
  814. + added -WB to force binding (Ozerski way of creating DLL)
  815. this is off by default as direct writing of .edata section seems
  816. OK
  817. Revision 1.38 1998/11/30 09:43:13 pierre
  818. * some range check bugs fixed (still not working !)
  819. + added DLL writing support for win32 (also accepts variables)
  820. + TempAnsi for code that could be used for Temporary ansi strings
  821. handling
  822. Revision 1.37 1998/10/26 22:23:31 peter
  823. + fixpath() has an extra option to allow a ./ as path
  824. Revision 1.36 1998/10/22 15:18:44 florian
  825. + switch -vx for win32 added
  826. Revision 1.35 1998/10/19 18:06:23 peter
  827. * use no_double
  828. Revision 1.34 1998/10/16 13:37:18 florian
  829. + switch -FD added to specify the path for utilities
  830. Revision 1.33 1998/10/14 13:38:22 peter
  831. * fixed path with staticlib/objects in ppufiles
  832. Revision 1.32 1998/10/14 11:03:55 daniel
  833. * Forgot to dereference a pointer.
  834. Revision 1.31 1998/10/14 11:01:21 daniel
  835. * Staticlibfilename no longer not include a path. Correction when calling
  836. ar.
  837. Revision 1.30 1998/10/13 13:10:18 peter
  838. * new style for m68k/i386 infos and enums
  839. Revision 1.29 1998/10/13 08:19:34 pierre
  840. + source_os is now set correctly for cross-processor compilers
  841. (tos contains all target_infos and
  842. we use CPU86 and CPU68 conditionals to
  843. get the source operating system
  844. this only works if you do not undefine
  845. the source target !!)
  846. * several cg68k memory leaks fixed
  847. + started to change the code so that it should be possible to have
  848. a complete compiler (both for m68k and i386 !!)
  849. Revision 1.28 1998/10/08 23:28:56 peter
  850. * -vu shows unit info, -vt shows tried/used files
  851. Revision 1.27 1998/10/06 17:16:52 pierre
  852. * some memory leaks fixed (thanks to Peter for heaptrc !)
  853. Revision 1.26 1998/09/29 15:23:05 peter
  854. * remove also the end files for smartlinking
  855. Revision 1.25 1998/09/10 15:25:31 daniel
  856. + Added maxheapsize.
  857. * Corrected semi-bug in calling the assembler and the linker
  858. Revision 1.24 1998/09/07 18:32:45 peter
  859. * fixed for m68k
  860. Revision 1.23 1998/09/03 17:39:04 florian
  861. + better code for type conversation longint/dword to real type
  862. Revision 1.22 1998/09/01 09:01:00 peter
  863. + glibc2 support
  864. Revision 1.21 1998/08/31 12:26:26 peter
  865. * m68k and palmos updates from surebugfixes
  866. Revision 1.20 1998/08/19 10:06:14 peter
  867. * fixed filenames and removedir which supports slash at the end
  868. Revision 1.19 1998/08/17 09:17:47 peter
  869. * static/shared linking updates
  870. Revision 1.18 1998/08/14 21:56:34 peter
  871. * setting the outputfile using -o works now to create static libs
  872. Revision 1.17 1998/08/14 18:16:08 peter
  873. * return after a failed call will now add it to ppas
  874. Revision 1.16 1998/08/12 19:28:15 peter
  875. * better libc support
  876. Revision 1.15 1998/08/10 14:50:02 peter
  877. + localswitches, moduleswitches, globalswitches splitting
  878. Revision 1.14 1998/06/17 14:10:13 peter
  879. * small os2 fixes
  880. * fixed interdependent units with newppu (remake3 under linux works now)
  881. Revision 1.13 1998/06/08 22:59:46 peter
  882. * smartlinking works for win32
  883. * some defines to exclude some compiler parts
  884. Revision 1.12 1998/06/04 23:51:44 peter
  885. * m68k compiles
  886. + .def file creation moved to gendef.pas so it could also be used
  887. for win32
  888. Revision 1.11 1998/05/27 00:20:31 peter
  889. * some scanner optimizes
  890. * automaticly aout2exe for go32v1
  891. * fixed dynamiclinker option which was added at the wrong place
  892. Revision 1.10 1998/05/22 12:32:47 peter
  893. * fixed -L on the commandline, Dos commandline is only 128 bytes
  894. Revision 1.9 1998/05/12 10:46:59 peter
  895. * moved printstatus to verb_def
  896. + V_Normal which is between V_Error and V_Warning and doesn't have a
  897. prefix like error: warning: and is included in V_Default
  898. * fixed some messages
  899. * first time parameter scan is only for -v and -T
  900. - removed old style messages
  901. Revision 1.8 1998/05/11 13:07:54 peter
  902. + $ifdef NEWPPU for the new ppuformat
  903. + $define GDB not longer required
  904. * removed all warnings and stripped some log comments
  905. * no findfirst/findnext anymore to remove smartlink *.o files
  906. Revision 1.7 1998/05/08 09:21:20 michael
  907. * Added missing -Fl message to messages file.
  908. * Corrected mangling of file names when doing Linklib
  909. * -Fl now actually WORKS.
  910. * Librarysearchpath is now a field in linker object.
  911. Revision 1.6 1998/05/06 09:26:49 peter
  912. * fixed ld call with shell
  913. Revision 1.4 1998/05/04 17:54:25 peter
  914. + smartlinking works (only case jumptable left todo)
  915. * redesign of systems.pas to support assemblers and linkers
  916. + Unitname is now also in the PPU-file, increased version to 14
  917. Revision 1.3 1998/04/16 10:54:30 daniel
  918. * Fixed linking for OS/2.
  919. }