link.pas 28 KB

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