link.pas 27 KB

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