t_darwin.pas 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766
  1. {
  2. Copyright (c) 1998-2002 by Peter Vreman (original Linux)
  3. (c) 2000 by Marco van de Voort (FreeBSD mods)
  4. This unit implements support import,export,link routines
  5. for the (i386)FreeBSD target
  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 t_darwin;
  20. {$i fpcdefs.inc}
  21. interface
  22. implementation
  23. uses
  24. sysutils,
  25. cutils,cfileutl,cclasses,
  26. verbose,systems,globtype,globals,
  27. symconst,cscript,
  28. fmodule,aasmbase,aasmtai,aasmdata,aasmcpu,cpubase,symsym,symdef,
  29. import,export,link,comprsrc,rescmn,i_darwin,expunix,
  30. cgutils,cgbase,cgobj,cpuinfo,ogbase;
  31. type
  32. timportlibdarwin=class(timportlib)
  33. procedure generatelib;override;
  34. end;
  35. texportlibdarwin=class(texportlibunix)
  36. procedure setinitname(list: TAsmList; const s: string); override;
  37. procedure setfininame(list: TAsmList; const s: string); override;
  38. end;
  39. tlinkerdarwin=class(texternallinker)
  40. private
  41. LinkFilesFileName,
  42. LinkSymsFileName : TCmdStr;
  43. Function WriteResponseFile(isdll:boolean) : Boolean;
  44. function GetDarwinCrt1ObjName(isdll: boolean): TCmdStr;
  45. Function GetDarwinPrtobjName(isdll: boolean): TCmdStr;
  46. public
  47. constructor Create;override;
  48. procedure SetDefaultInfo;override;
  49. function MakeExecutable:boolean;override;
  50. function MakeSharedLibrary:boolean;override;
  51. procedure LoadPredefinedLibraryOrder; override;
  52. procedure InitSysInitUnitName; override;
  53. end;
  54. {*****************************************************************************
  55. TIMPORTLIBDARWIN
  56. *****************************************************************************}
  57. procedure timportlibdarwin.generatelib;
  58. begin
  59. end;
  60. {*****************************************************************************
  61. TEXPORTLIBDARWIN
  62. *****************************************************************************}
  63. procedure texportlibdarwin.setinitname(list: TAsmList; const s: string);
  64. begin
  65. new_section(list,sec_init_func,'',sizeof(pint));
  66. list.concat(Tai_const.Createname(s,0));
  67. end;
  68. procedure texportlibdarwin.setfininame(list: TAsmList; const s: string);
  69. begin
  70. new_section(list,sec_term_func,'',sizeof(pint));
  71. list.concat(Tai_const.Createname(s,0));
  72. end;
  73. {*****************************************************************************
  74. TLINKERBSD
  75. *****************************************************************************}
  76. constructor tlinkerdarwin.Create;
  77. begin
  78. inherited;
  79. if not Dontlinkstdlibpath Then
  80. LibrarySearchPath.AddLibraryPath(sysrootpath,'=/usr/lib',true)
  81. end;
  82. procedure tlinkerdarwin.SetDefaultInfo;
  83. begin
  84. with Info do
  85. begin
  86. {$ifndef cpu64bitaddr}
  87. { Set the size of the page at address zero to 64kb, so nothing
  88. is loaded below that address. This avoids problems with the
  89. strange Windows-compatible resource handling that assumes
  90. that addresses below 64kb do not exist.
  91. On 64bit systems, page zero is 4GB by default, so no problems
  92. there.
  93. }
  94. { In case of valgrind, don't do that, because it cannot deal with
  95. a custom pagezero size -- in general, this should not cause any
  96. problems because the resources are added at the end and most
  97. programs with problems that require Valgrind will have more
  98. than 60KB of data (first 4KB of address space is always invalid)
  99. }
  100. ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP $MAP $ORDERSYMS -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
  101. if not(cs_gdb_valgrind in current_settings.globalswitches) then
  102. ExeCmd[1]:=ExeCmd[1]+' -pagezero_size 0x10000';
  103. {$else ndef cpu64bitaddr}
  104. ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP $MAP $ORDERSYMS -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
  105. {$endif ndef cpu64bitaddr}
  106. if (apptype<>app_bundle) then
  107. DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS $MAP $ORDERSYMS -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST'
  108. else
  109. DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS $MAP $ORDERSYMS -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES $FILELIST';
  110. DllCmd[2]:='strip -x $EXE';
  111. DynamicLinker:='';
  112. end;
  113. end;
  114. procedure tlinkerdarwin.LoadPredefinedLibraryOrder;
  115. begin
  116. // put your linkorder/linkalias overrides here.
  117. // Note: assumes only called when reordering/aliasing is used.
  118. LinkLibraryOrder.add('gcc','',15);
  119. LinkLibraryOrder.add('c','',50);
  120. end;
  121. procedure tlinkerdarwin.InitSysInitUnitName;
  122. begin
  123. SysInitUnit:='sysinit';
  124. end;
  125. function tlinkerdarwin.GetDarwinCrt1ObjName(isdll: boolean): TCmdStr;
  126. begin
  127. if not isdll then
  128. begin
  129. if not(cs_profile in current_settings.moduleswitches) then
  130. begin
  131. case target_info.system of
  132. system_powerpc_darwin,
  133. system_powerpc64_darwin,
  134. system_i386_darwin,
  135. system_x86_64_darwin:
  136. begin
  137. { 10.8 and later: no crt1.* }
  138. if CompareVersionStrings(MacOSXVersionMin,'10.8')>=0 then
  139. exit('');
  140. { x86: crt1.10.6.o -> crt1.10.5.o -> crt1.o }
  141. { others: crt1.10.5 -> crt1.o }
  142. if (target_info.system in [system_i386_darwin,system_x86_64_darwin]) and
  143. (CompareVersionStrings(MacOSXVersionMin,'10.6')>=0) then
  144. exit('crt1.10.6.o');
  145. if CompareVersionStrings(MacOSXVersionMin,'10.5')>=0 then
  146. exit('crt1.10.5.o');
  147. end;
  148. system_arm_ios:
  149. begin
  150. { iOS:
  151. iOS 6 and later: nothing
  152. iOS 3.1 - 5.x: crt1.3.1.o
  153. pre-iOS 3.1: crt1.o
  154. }
  155. if (CompareVersionStrings(iPhoneOSVersionMin,'6.0')>=0) then
  156. exit('');
  157. if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then
  158. exit('crt1.3.1.o');
  159. end;
  160. system_i386_iphonesim,
  161. system_x86_64_iphonesim:
  162. begin
  163. { "recent versions" must not use anything (https://github.com/llvm-mirror/clang/commit/e6d04f3d152a22077022cf9287d4c538a0918ab0 )
  164. What those recent versions could be, is anyone's guess. It
  165. still seems to work with 8.1 and no longer with 8.3, so use
  166. 8.1 as a cut-off point }
  167. if (CompareVersionStrings(iPhoneOSVersionMin,'8.1')>0) then
  168. exit('');
  169. end;
  170. system_aarch64_ios,
  171. system_aarch64_darwin:
  172. { never anything }
  173. exit('');
  174. else
  175. Internalerror(2019050709);
  176. end;
  177. { nothing special -> default }
  178. result:='crt1.o';
  179. end
  180. else
  181. begin
  182. result:='gcrt1.o';
  183. { 10.8 and later: tell the linker to use 'start' instead of "_main"
  184. as entry point }
  185. if CompareVersionStrings(MacOSXVersionMin,'10.8')>=0 then
  186. Info.ExeCmd[1]:=Info.ExeCmd[1]+' -no_new_main';
  187. end;
  188. end
  189. else
  190. begin
  191. if (apptype=app_bundle) then
  192. begin
  193. case target_info.system of
  194. system_powerpc_darwin,
  195. system_powerpc64_darwin,
  196. system_i386_darwin,
  197. system_x86_64_darwin:
  198. begin
  199. { < 10.6: bundle1.o
  200. >= 10.6: nothing }
  201. if CompareVersionStrings(MacOSXVersionMin,'10.6')>=0 then
  202. exit('');
  203. end;
  204. system_arm_ios,
  205. system_aarch64_ios:
  206. begin
  207. { iOS: < 3.1: bundle1.o
  208. >= 3.1: nothing }
  209. if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then
  210. exit('');
  211. end;
  212. system_i386_iphonesim,
  213. system_x86_64_iphonesim:
  214. begin
  215. { see rule for crt1.o }
  216. if (CompareVersionStrings(iPhoneOSVersionMin,'8.1')>0) then
  217. exit('');
  218. end;
  219. system_aarch64_darwin:
  220. exit('');
  221. else
  222. Internalerror(2019050710);
  223. end;
  224. result:='bundle1.o';
  225. end
  226. else
  227. begin
  228. case target_info.system of
  229. system_powerpc_darwin,
  230. system_powerpc64_darwin,
  231. system_i386_darwin,
  232. system_x86_64_darwin:
  233. begin
  234. { >= 10.6: nothing
  235. = 10.5: dylib1.10.5.o
  236. < 10.5: dylib1.o
  237. }
  238. if CompareVersionStrings(MacOSXVersionMin,'10.6')>=0 then
  239. exit('');
  240. if CompareVersionStrings(MacOSXVersionMin,'10.5')>=0 then
  241. exit('dylib1.10.5.o');
  242. end;
  243. system_arm_ios,
  244. system_aarch64_ios:
  245. begin
  246. { iOS: < 3.1: dylib1.o
  247. >= 3.1: nothing }
  248. if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then
  249. exit('');
  250. end;
  251. system_i386_iphonesim,
  252. system_x86_64_iphonesim:
  253. begin
  254. { see rule for crt1.o }
  255. if (CompareVersionStrings(iPhoneOSVersionMin,'8.1')>0) then
  256. exit('');
  257. end;
  258. system_aarch64_darwin:
  259. exit('');
  260. else
  261. Internalerror(2019050711);
  262. end;
  263. result:='dylib1.o';
  264. end;
  265. end;
  266. end;
  267. Function tlinkerdarwin.GetDarwinPrtobjName(isdll: boolean): TCmdStr;
  268. var
  269. startupfile: TCmdStr;
  270. begin
  271. result:='';
  272. startupfile:=GetDarwinCrt1ObjName(isdll);
  273. if startupfile<>'' then
  274. begin
  275. if not librarysearchpath.FindFile(startupfile,false,result) then
  276. result:='/usr/lib/'+startupfile;
  277. end;
  278. result:=maybequoted(result);
  279. end;
  280. Function tlinkerdarwin.WriteResponseFile(isdll:boolean) : Boolean;
  281. Var
  282. linkres : TLinkRes;
  283. FilesList : TLinkRes;
  284. i : longint;
  285. HPath : TCmdStrListItem;
  286. s,s1,s2 : TCmdStr;
  287. Fl1,Fl2 : Boolean;
  288. begin
  289. WriteResponseFile:=False;
  290. if ReOrderEntries Then
  291. ExpandAndApplyOrder(SharedLibFiles);
  292. { Open link.res file }
  293. LinkRes:=TLinkRes.Create(outputexedir+Info.ResName,false);
  294. if sysrootpath<>'' then
  295. begin
  296. LinkRes.Add('-syslibroot');
  297. LinkRes.Add(sysrootpath);
  298. end;
  299. LinkRes.Add('-arch');
  300. case target_info.system of
  301. system_powerpc_darwin:
  302. LinkRes.Add('ppc');
  303. system_i386_darwin,
  304. system_i386_iphonesim:
  305. LinkRes.Add('i386');
  306. system_powerpc64_darwin:
  307. LinkRes.Add('ppc64');
  308. system_x86_64_darwin,
  309. system_x86_64_iphonesim:
  310. LinkRes.Add('x86_64');
  311. system_arm_ios:
  312. { current versions of the linker require the sub-architecture type
  313. to be specified }
  314. LinkRes.Add(lower(cputypestr[current_settings.cputype]));
  315. system_aarch64_ios,
  316. system_aarch64_darwin:
  317. LinkRes.Add('arm64');
  318. else
  319. internalerror(2014121801);
  320. end;
  321. if MacOSXVersionMin<>'' then
  322. begin
  323. LinkRes.Add('-macosx_version_min');
  324. LinkRes.Add(MacOSXVersionMin);
  325. end
  326. else if iPhoneOSVersionMin<>'' then
  327. begin
  328. if target_info.system in [system_i386_iphonesim,system_x86_64_iphonesim] then
  329. LinkRes.Add('-ios_simulator_version_min')
  330. else
  331. LinkRes.Add('-iphoneos_version_min');
  332. LinkRes.Add(iPhoneOSVersionMin);
  333. end;
  334. { Write path to search libraries }
  335. HPath:=TCmdStrListItem(current_module.locallibrarysearchpath.First);
  336. while assigned(HPath) do
  337. begin
  338. LinkRes.Add('-L'+HPath.Str);
  339. HPath:=TCmdStrListItem(HPath.Next);
  340. end;
  341. HPath:=TCmdStrListItem(LibrarySearchPath.First);
  342. while assigned(HPath) do
  343. begin
  344. LinkRes.Add('-L'+HPath.Str);
  345. HPath:=TCmdStrListItem(HPath.Next);
  346. end;
  347. HPath:=TCmdStrListItem(current_module.localframeworksearchpath.First);
  348. while assigned(HPath) do
  349. begin
  350. LinkRes.Add('-F'+HPath.Str);
  351. HPath:=TCmdStrListItem(HPath.Next);
  352. end;
  353. HPath:=TCmdStrListItem(FrameworkSearchPath.First);
  354. while assigned(HPath) do
  355. begin
  356. LinkRes.Add('-F'+HPath.Str);
  357. HPath:=TCmdStrListItem(HPath.Next);
  358. end;
  359. { main objectfiles }
  360. LinkFilesFileName:=UniqueName('linkfiles')+'.res';
  361. FilesList:=TLinkRes.Create(outputexedir+LinkFilesFileName,false);
  362. while not ObjectFiles.Empty do
  363. begin
  364. s:=ObjectFiles.GetFirst;
  365. if s<>'' then
  366. begin
  367. s:=TargetFixFileName(s);
  368. FilesList.Add(s);
  369. end;
  370. end;
  371. FilesList.writetodisk;
  372. FilesList.Free;
  373. { Write staticlibraries }
  374. while not StaticLibFiles.Empty do
  375. begin
  376. S:=StaticLibFiles.GetFirst;
  377. LinkRes.AddFileName(s)
  378. end;
  379. { Write sharedlibraries like -l<lib> }
  380. while not SharedLibFiles.Empty do
  381. begin
  382. S:=SharedLibFiles.GetFirst;
  383. if (s<>'c') or ReOrderEntries then
  384. begin
  385. i:=Pos(target_info.sharedlibext,S);
  386. if i>0 then
  387. Delete(S,i,255);
  388. LinkRes.Add('-l'+s);
  389. end;
  390. { be sure that libc is the last lib }
  391. if not ReOrderEntries then
  392. begin
  393. LinkRes.Add('-lc')
  394. end;
  395. end;
  396. while not FrameworkFiles.empty do
  397. begin
  398. LinkRes.Add('-framework');
  399. LinkRes.Add(FrameworkFiles.GetFirst);
  400. end;
  401. { Write and Close response }
  402. linkres.writetodisk;
  403. linkres.Free;
  404. WriteResponseFile:=True;
  405. end;
  406. function tlinkerdarwin.MakeExecutable:boolean;
  407. var
  408. binstr,
  409. cmdstr,
  410. mapstr,
  411. targetstr,
  412. emulstr,
  413. extdbgbinstr,
  414. extdbgcmdstr,
  415. ltostr,
  416. ordersymfile: TCmdStr;
  417. linkscript: TAsmScript;
  418. DynLinkStr : string[60];
  419. GCSectionsStr,
  420. StaticStr,
  421. StripStr : string[63];
  422. success : boolean;
  423. begin
  424. if not(cs_link_nolink in current_settings.globalswitches) then
  425. Message1(exec_i_linking,current_module.exefilename);
  426. { Create some replacements }
  427. StaticStr:='';
  428. StripStr:='';
  429. DynLinkStr:='';
  430. GCSectionsStr:='';
  431. linkscript:=nil;
  432. mapstr:='';
  433. targetstr:='';
  434. emulstr:='';
  435. ltostr:='';
  436. if (cs_link_map in current_settings.globalswitches) then
  437. mapstr:='-map '+maybequoted(ChangeFileExt(current_module.exefilename,'.map'));
  438. if (cs_link_staticflag in current_settings.globalswitches) then
  439. StaticStr:='-static';
  440. if (cs_link_strip in current_settings.globalswitches) then
  441. StripStr:='-x';
  442. if (cs_link_smart in current_settings.globalswitches) then
  443. GCSectionsStr:='-dead_strip -no_dead_strip_inits_and_terms';
  444. if CShared Then
  445. begin
  446. DynLinKStr:=DynLinkStr+' -dynamic'; // one dash!
  447. end;
  448. { Write used files and libraries }
  449. WriteResponseFile(false);
  450. { Write symbol order file }
  451. ordersymfile:=WriteSymbolOrderFile;
  452. { Call linker }
  453. SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
  454. Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename));
  455. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  456. Replace(cmdstr,'$TARGET',targetstr);
  457. Replace(cmdstr,'$EMUL',EmulStr);
  458. Replace(cmdstr,'$MAP',mapstr);
  459. Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
  460. Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
  461. if ordersymfile<>'' then
  462. Replace(cmdstr,'$ORDERSYMS','-order_file '+maybequoted(ordersymfile))
  463. else
  464. Replace(cmdstr,'$ORDERSYMS','');
  465. Replace(cmdstr,'$FILELIST','-filelist '+maybequoted(outputexedir+LinkFilesFileName));
  466. Replace(cmdstr,'$STATIC',StaticStr);
  467. Replace(cmdstr,'$STRIP',StripStr);
  468. Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
  469. Replace(cmdstr,'$DYNLINK',DynLinkStr);
  470. Replace(cmdstr,'$PRTOBJ',GetDarwinPrtobjName(false));
  471. BinStr:=FindUtil(utilsprefix+BinStr);
  472. { create dsym file? }
  473. extdbgbinstr:='';
  474. extdbgcmdstr:='';
  475. if (target_dbg.id in [dbg_dwarf2,dbg_dwarf3]) and
  476. (cs_link_separate_dbg_file in current_settings.globalswitches) then
  477. begin
  478. extdbgbinstr:=FindUtil(utilsprefix+'dsymutil');
  479. extdbgcmdstr:=maybequoted(current_module.exefilename);
  480. end;
  481. if not(cs_link_nolink in current_settings.globalswitches) then
  482. begin
  483. { we have to use a script to use the IFS hack }
  484. linkscript:=GenerateScript(outputexedir+'ppaslink');
  485. linkscript.AddLinkCommand(BinStr,CmdStr,'');
  486. if (extdbgcmdstr<>'') then
  487. linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');
  488. linkscript.WriteToDisk;
  489. BinStr:=linkscript.fn;
  490. if not path_absolute(BinStr) then
  491. if cs_link_on_target in current_settings.globalswitches then
  492. BinStr:='.'+target_info.dirsep+BinStr
  493. else
  494. BinStr:='.'+source_info.dirsep+BinStr;
  495. CmdStr:='';
  496. end;
  497. success:=DoExec(BinStr,CmdStr,true,true);
  498. if success and
  499. (extdbgbinstr<>'') then
  500. success:=DoExec(extdbgbinstr,extdbgcmdstr,false,true);
  501. { Remove ReponseFile }
  502. if (success) and not(cs_link_nolink in current_settings.globalswitches) then
  503. begin
  504. DeleteFile(outputexedir+Info.ResName);
  505. if ordersymfile<>'' then
  506. DeleteFile(ordersymfile);
  507. DeleteFile(linkscript.fn);
  508. linkscript.free;
  509. DeleteFile(outputexedir+LinkFilesFileName);
  510. end;
  511. MakeExecutable:=success; { otherwise a recursive call to link method }
  512. end;
  513. Function tlinkerdarwin.MakeSharedLibrary:boolean;
  514. var
  515. InitStr,
  516. FiniStr,
  517. SoNameStr : string[80];
  518. linkscript: TAsmScript;
  519. binstr,
  520. cmdstr,
  521. mapstr,
  522. ltostr,
  523. ordersymfile,
  524. targetstr,
  525. emulstr,
  526. extdbgbinstr,
  527. extdbgcmdstr : TCmdStr;
  528. GCSectionsStr : string[63];
  529. exportedsyms: text;
  530. success : boolean;
  531. begin
  532. MakeSharedLibrary:=false;
  533. GCSectionsStr:='';
  534. mapstr:='';
  535. ltostr:='';
  536. linkscript:=nil;
  537. if not(cs_link_nolink in current_settings.globalswitches) then
  538. Message1(exec_i_linking,current_module.sharedlibfilename);
  539. { Write used files and libraries }
  540. WriteResponseFile(true);
  541. { Write symbol order file }
  542. ordersymfile:=WriteSymbolOrderFile;
  543. if (cs_link_smart in current_settings.globalswitches) then
  544. GCSectionsStr:='-dead_strip -no_dead_strip_inits_and_terms';
  545. if (cs_link_map in current_settings.globalswitches) then
  546. mapstr:='-Map '+maybequoted(ChangeFileExt(current_module.sharedlibfilename,'.map'));
  547. targetstr:='';
  548. emulstr:='';
  549. InitStr:='-init FPC_LIB_START';
  550. FiniStr:='-fini FPC_LIB_EXIT';
  551. SoNameStr:='-soname '+ExtractFileName(current_module.sharedlibfilename);
  552. { Call linker }
  553. SplitBinCmd(Info.DllCmd[1],binstr,cmdstr);
  554. Replace(cmdstr,'$EXE',maybequoted(ExpandFileName(current_module.sharedlibfilename)));
  555. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  556. Replace(cmdstr,'$TARGET',targetstr);
  557. Replace(cmdstr,'$EMUL',EmulStr);
  558. Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
  559. Replace(cmdstr,'$FILELIST','-filelist '+maybequoted(outputexedir+LinkFilesFileName));
  560. Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
  561. Replace(cmdstr,'$INIT',InitStr);
  562. Replace(cmdstr,'$FINI',FiniStr);
  563. Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
  564. Replace(cmdstr,'$SONAME',SoNameStr);
  565. Replace(cmdstr,'$MAP',mapstr);
  566. if ordersymfile<>'' then
  567. Replace(cmdstr,'$ORDERSYMS','-order_file '+maybequoted(ordersymfile))
  568. else
  569. Replace(cmdstr,'$ORDERSYMS','');
  570. Replace(cmdstr,'$PRTOBJ',GetDarwinPrtobjName(true));
  571. BinStr:=FindUtil(utilsprefix+BinStr);
  572. { create dsym file? }
  573. extdbgbinstr:='';
  574. extdbgcmdstr:='';
  575. if (target_dbg.id in [dbg_dwarf2,dbg_dwarf3]) and
  576. (cs_link_separate_dbg_file in current_settings.globalswitches) then
  577. begin
  578. extdbgbinstr:=FindUtil(utilsprefix+'dsymutil');
  579. extdbgcmdstr:=maybequoted(current_module.sharedlibfilename);
  580. end;
  581. LinkSymsFileName:='';
  582. if not texportlibunix(exportlib).exportedsymnames.empty then
  583. begin
  584. LinkSymsFileName:=UniqueName('linksyms')+'.fpc';
  585. assign(exportedsyms,outputexedir+LinkSymsFileName);
  586. rewrite(exportedsyms);
  587. repeat
  588. writeln(exportedsyms,texportlibunix(exportlib).exportedsymnames.getfirst);
  589. until texportlibunix(exportlib).exportedsymnames.empty;
  590. close(exportedsyms);
  591. cmdstr:=cmdstr+' -exported_symbols_list '+maybequoted(outputexedir)+LinkSymsFileName;
  592. end;
  593. if not(cs_link_nolink in current_settings.globalswitches) then
  594. begin
  595. { we have to use a script to use the IFS hack }
  596. linkscript:=GenerateScript(outputexedir+'ppaslink');
  597. linkscript.AddLinkCommand(BinStr,CmdStr,'');
  598. if (extdbgbinstr<>'') then
  599. linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');
  600. linkscript.WriteToDisk;
  601. BinStr:=linkscript.fn;
  602. if not path_absolute(BinStr) then
  603. if cs_link_on_target in current_settings.globalswitches then
  604. BinStr:='.'+target_info.dirsep+BinStr
  605. else
  606. BinStr:='.'+source_info.dirsep+BinStr;
  607. CmdStr:='';
  608. end;
  609. success:=DoExec(BinStr,cmdstr,true,true);
  610. if (success and
  611. (extdbgbinstr<>'') and
  612. (cs_link_nolink in current_settings.globalswitches)) then
  613. success:=DoExec(extdbgbinstr,extdbgcmdstr,false,true);
  614. { Strip the library ? }
  615. if success and (cs_link_strip in current_settings.globalswitches) then
  616. begin
  617. SplitBinCmd(Info.DllCmd[2],binstr,cmdstr);
  618. Replace(cmdstr,'$EXE',maybequoted(current_module.sharedlibfilename));
  619. success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,false,false);
  620. end;
  621. { Remove ReponseFile }
  622. if (success) and not(cs_link_nolink in current_settings.globalswitches) then
  623. begin
  624. DeleteFile(outputexedir+Info.ResName);
  625. if ordersymfile<>'' then
  626. DeleteFile(ordersymfile);
  627. DeleteFile(linkscript.fn);
  628. linkscript.free;
  629. if LinkSymsFileName<>'' then
  630. DeleteFile(outputexedir+LinkSymsFileName);
  631. DeleteFile(outputexedir+LinkFilesFileName);
  632. end;
  633. MakeSharedLibrary:=success; { otherwise a recursive call to link method }
  634. end;
  635. {*****************************************************************************
  636. Initialize
  637. *****************************************************************************}
  638. initialization
  639. RegisterLinker(ld_darwin,tlinkerdarwin);
  640. {$ifdef x86_64}
  641. RegisterImport(system_x86_64_darwin,timportlibdarwin);
  642. RegisterExport(system_x86_64_darwin,texportlibdarwin);
  643. RegisterTarget(system_x86_64_darwin_info);
  644. RegisterImport(system_x86_64_iphonesim,timportlibdarwin);
  645. RegisterExport(system_x86_64_iphonesim,texportlibdarwin);
  646. RegisterTarget(system_x86_64_iphonesim_info);
  647. {$endif}
  648. {$ifdef i386}
  649. RegisterImport(system_i386_darwin,timportlibdarwin);
  650. RegisterExport(system_i386_darwin,texportlibdarwin);
  651. RegisterTarget(system_i386_darwin_info);
  652. RegisterImport(system_i386_iphonesim,timportlibdarwin);
  653. RegisterExport(system_i386_iphonesim,texportlibdarwin);
  654. RegisterTarget(system_i386_iphonesim_info);
  655. {$endif i386}
  656. {$ifdef powerpc}
  657. RegisterImport(system_powerpc_darwin,timportlibdarwin);
  658. RegisterExport(system_powerpc_darwin,texportlibdarwin);
  659. RegisterTarget(system_powerpc_darwin_info);
  660. {$endif powerpc}
  661. {$ifdef powerpc64}
  662. RegisterImport(system_powerpc64_darwin,timportlibdarwin);
  663. RegisterExport(system_powerpc64_darwin,texportlibdarwin);
  664. RegisterTarget(system_powerpc64_darwin_info);
  665. {$endif powerpc64}
  666. {$ifdef arm}
  667. RegisterImport(system_arm_ios,timportlibdarwin);
  668. RegisterExport(system_arm_ios,texportlibdarwin);
  669. RegisterTarget(system_arm_ios_info);
  670. {$endif arm}
  671. {$ifdef aarch64}
  672. RegisterImport(system_aarch64_ios,timportlibdarwin);
  673. RegisterExport(system_aarch64_ios,texportlibdarwin);
  674. RegisterTarget(system_aarch64_ios_info);
  675. RegisterImport(system_aarch64_darwin,timportlibdarwin);
  676. RegisterExport(system_aarch64_darwin,texportlibdarwin);
  677. RegisterTarget(system_aarch64_darwin_info);
  678. {$endif aarch64}
  679. RegisterRes(res_macho_info,TWinLikeResourceFile);
  680. RegisterRes(res_macosx_ext_info,TWinLikeResourceFile);
  681. end.