link.pas 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928
  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_Error,'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_Error,'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.59 1999-07-05 16:21:26 peter
  660. * fixed linking for units without linking necessary
  661. Revision 1.58 1999/07/03 00:29:51 peter
  662. * new link writing to the ppu, one .ppu is needed for all link types,
  663. static (.o) is now always created also when smartlinking is used
  664. Revision 1.57 1999/06/28 16:02:31 peter
  665. * merged
  666. Revision 1.54.2.3 1999/06/28 15:55:40 peter
  667. * also search path if not found in utilsdirectory
  668. Revision 1.54.2.2 1999/06/18 09:51:55 peter
  669. * always use shell() for go32v2 to support LFN
  670. Revision 1.54.2.1 1999/06/15 13:51:56 peter
  671. * also check ld-2.1.so for glibc 2.1, previous was only for 2.1.1
  672. Revision 1.54 1999/06/02 13:25:35 hajny
  673. * fixed stripping symbols for OS/2
  674. Revision 1.53 1999/05/04 21:44:44 florian
  675. * changes to compile it with Delphi 4.0
  676. Revision 1.52 1999/05/03 21:30:30 peter
  677. + glibc 2.1
  678. Revision 1.51 1999/04/28 23:42:33 pierre
  679. * removing of temporary directory with -s option
  680. Revision 1.50 1999/04/25 14:31:48 daniel
  681. * Bug fixed in linking: compiling files on another drive than the one you
  682. currently use you is done correctly.
  683. Revision 1.49 1999/03/25 16:55:30 peter
  684. + unitpath,librarypath,includepath,objectpath directives
  685. Revision 1.48 1999/03/23 16:22:43 peter
  686. * crtbegin/crtend only added if found
  687. Revision 1.47 1999/02/05 16:45:47 michael
  688. + Fixed gluing of options
  689. Revision 1.46 1999/02/05 08:54:26 pierre
  690. + linkofiles splitted inot linkofiles and linkunitfiles
  691. because linkofiles must be stored with directory
  692. to enabled linking of different objects with same name
  693. in a different directory
  694. Revision 1.45 1999/01/29 10:33:07 peter
  695. * objectsearchpath is now also searched if an object is not found
  696. Revision 1.44 1999/01/27 13:07:58 pierre
  697. * problem related with libc : go32v2 and linux differences
  698. Revision 1.43 1999/01/25 15:02:13 peter
  699. * link libc always as last
  700. Revision 1.42 1998/12/11 00:03:19 peter
  701. + globtype,tokens,version unit splitted from globals
  702. Revision 1.41 1998/12/01 23:39:46 pierre
  703. * postprocessexec for win32 changed
  704. Revision 1.40 1998/12/01 12:51:20 peter
  705. * fixed placing of ppas.sh and link.res when using -FE
  706. Revision 1.39 1998/11/30 13:26:23 pierre
  707. * the code for ordering the exported procs/vars was buggy
  708. + added -WB to force binding (Ozerski way of creating DLL)
  709. this is off by default as direct writing of .edata section seems
  710. OK
  711. Revision 1.38 1998/11/30 09:43:13 pierre
  712. * some range check bugs fixed (still not working !)
  713. + added DLL writing support for win32 (also accepts variables)
  714. + TempAnsi for code that could be used for Temporary ansi strings
  715. handling
  716. Revision 1.37 1998/10/26 22:23:31 peter
  717. + fixpath() has an extra option to allow a ./ as path
  718. Revision 1.36 1998/10/22 15:18:44 florian
  719. + switch -vx for win32 added
  720. Revision 1.35 1998/10/19 18:06:23 peter
  721. * use no_double
  722. Revision 1.34 1998/10/16 13:37:18 florian
  723. + switch -FD added to specify the path for utilities
  724. Revision 1.33 1998/10/14 13:38:22 peter
  725. * fixed path with staticlib/objects in ppufiles
  726. Revision 1.32 1998/10/14 11:03:55 daniel
  727. * Forgot to dereference a pointer.
  728. Revision 1.31 1998/10/14 11:01:21 daniel
  729. * Staticlibfilename no longer not include a path. Correction when calling
  730. ar.
  731. Revision 1.30 1998/10/13 13:10:18 peter
  732. * new style for m68k/i386 infos and enums
  733. Revision 1.29 1998/10/13 08:19:34 pierre
  734. + source_os is now set correctly for cross-processor compilers
  735. (tos contains all target_infos and
  736. we use CPU86 and CPU68 conditionnals to
  737. get the source operating system
  738. this only works if you do not undefine
  739. the source target !!)
  740. * several cg68k memory leaks fixed
  741. + started to change the code so that it should be possible to have
  742. a complete compiler (both for m68k and i386 !!)
  743. Revision 1.28 1998/10/08 23:28:56 peter
  744. * -vu shows unit info, -vt shows tried/used files
  745. Revision 1.27 1998/10/06 17:16:52 pierre
  746. * some memory leaks fixed (thanks to Peter for heaptrc !)
  747. Revision 1.26 1998/09/29 15:23:05 peter
  748. * remove also the end files for smartlinking
  749. Revision 1.25 1998/09/10 15:25:31 daniel
  750. + Added maxheapsize.
  751. * Corrected semi-bug in calling the assembler and the linker
  752. Revision 1.24 1998/09/07 18:32:45 peter
  753. * fixed for m68k
  754. Revision 1.23 1998/09/03 17:39:04 florian
  755. + better code for type conversation longint/dword to real type
  756. Revision 1.22 1998/09/01 09:01:00 peter
  757. + glibc2 support
  758. Revision 1.21 1998/08/31 12:26:26 peter
  759. * m68k and palmos updates from surebugfixes
  760. Revision 1.20 1998/08/19 10:06:14 peter
  761. * fixed filenames and removedir which supports slash at the end
  762. Revision 1.19 1998/08/17 09:17:47 peter
  763. * static/shared linking updates
  764. Revision 1.18 1998/08/14 21:56:34 peter
  765. * setting the outputfile using -o works now to create static libs
  766. Revision 1.17 1998/08/14 18:16:08 peter
  767. * return after a failed call will now add it to ppas
  768. Revision 1.16 1998/08/12 19:28:15 peter
  769. * better libc support
  770. Revision 1.15 1998/08/10 14:50:02 peter
  771. + localswitches, moduleswitches, globalswitches splitting
  772. Revision 1.14 1998/06/17 14:10:13 peter
  773. * small os2 fixes
  774. * fixed interdependent units with newppu (remake3 under linux works now)
  775. Revision 1.13 1998/06/08 22:59:46 peter
  776. * smartlinking works for win32
  777. * some defines to exclude some compiler parts
  778. Revision 1.12 1998/06/04 23:51:44 peter
  779. * m68k compiles
  780. + .def file creation moved to gendef.pas so it could also be used
  781. for win32
  782. Revision 1.11 1998/05/27 00:20:31 peter
  783. * some scanner optimizes
  784. * automaticly aout2exe for go32v1
  785. * fixed dynamiclinker option which was added at the wrong place
  786. Revision 1.10 1998/05/22 12:32:47 peter
  787. * fixed -L on the commandline, Dos commandline is only 128 bytes
  788. Revision 1.9 1998/05/12 10:46:59 peter
  789. * moved printstatus to verb_def
  790. + V_Normal which is between V_Error and V_Warning and doesn't have a
  791. prefix like error: warning: and is included in V_Default
  792. * fixed some messages
  793. * first time parameter scan is only for -v and -T
  794. - removed old style messages
  795. Revision 1.8 1998/05/11 13:07:54 peter
  796. + $ifdef NEWPPU for the new ppuformat
  797. + $define GDB not longer required
  798. * removed all warnings and stripped some log comments
  799. * no findfirst/findnext anymore to remove smartlink *.o files
  800. Revision 1.7 1998/05/08 09:21:20 michael
  801. * Added missing -Fl message to messages file.
  802. * Corrected mangling of file names when doing Linklib
  803. * -Fl now actually WORKS.
  804. * Librarysearchpath is now a field in linker object.
  805. Revision 1.6 1998/05/06 09:26:49 peter
  806. * fixed ld call with shell
  807. Revision 1.4 1998/05/04 17:54:25 peter
  808. + smartlinking works (only case jumptable left todo)
  809. * redesign of systems.pas to support assemblers and linkers
  810. + Unitname is now also in the PPU-file, increased version to 14
  811. Revision 1.3 1998/04/16 10:54:30 daniel
  812. * Fixed linking for OS/2.
  813. }