link.pas 27 KB

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