link.pas 27 KB

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