link.pas 28 KB

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