t_darwin.pas 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763
  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. LinkRes.Add('-iphoneos_version_min');
  329. LinkRes.Add(iPhoneOSVersionMin);
  330. end;
  331. { Write path to search libraries }
  332. HPath:=TCmdStrListItem(current_module.locallibrarysearchpath.First);
  333. while assigned(HPath) do
  334. begin
  335. LinkRes.Add('-L'+HPath.Str);
  336. HPath:=TCmdStrListItem(HPath.Next);
  337. end;
  338. HPath:=TCmdStrListItem(LibrarySearchPath.First);
  339. while assigned(HPath) do
  340. begin
  341. LinkRes.Add('-L'+HPath.Str);
  342. HPath:=TCmdStrListItem(HPath.Next);
  343. end;
  344. HPath:=TCmdStrListItem(current_module.localframeworksearchpath.First);
  345. while assigned(HPath) do
  346. begin
  347. LinkRes.Add('-F'+HPath.Str);
  348. HPath:=TCmdStrListItem(HPath.Next);
  349. end;
  350. HPath:=TCmdStrListItem(FrameworkSearchPath.First);
  351. while assigned(HPath) do
  352. begin
  353. LinkRes.Add('-F'+HPath.Str);
  354. HPath:=TCmdStrListItem(HPath.Next);
  355. end;
  356. { main objectfiles }
  357. LinkFilesFileName:=UniqueName('linkfiles')+'.res';
  358. FilesList:=TLinkRes.Create(outputexedir+LinkFilesFileName,false);
  359. while not ObjectFiles.Empty do
  360. begin
  361. s:=ObjectFiles.GetFirst;
  362. if s<>'' then
  363. begin
  364. s:=TargetFixFileName(s);
  365. FilesList.Add(s);
  366. end;
  367. end;
  368. FilesList.writetodisk;
  369. FilesList.Free;
  370. { Write staticlibraries }
  371. while not StaticLibFiles.Empty do
  372. begin
  373. S:=StaticLibFiles.GetFirst;
  374. LinkRes.AddFileName(s)
  375. end;
  376. { Write sharedlibraries like -l<lib> }
  377. while not SharedLibFiles.Empty do
  378. begin
  379. S:=SharedLibFiles.GetFirst;
  380. if (s<>'c') or ReOrderEntries then
  381. begin
  382. i:=Pos(target_info.sharedlibext,S);
  383. if i>0 then
  384. Delete(S,i,255);
  385. LinkRes.Add('-l'+s);
  386. end;
  387. { be sure that libc is the last lib }
  388. if not ReOrderEntries then
  389. begin
  390. LinkRes.Add('-lc')
  391. end;
  392. end;
  393. while not FrameworkFiles.empty do
  394. begin
  395. LinkRes.Add('-framework');
  396. LinkRes.Add(FrameworkFiles.GetFirst);
  397. end;
  398. { Write and Close response }
  399. linkres.writetodisk;
  400. linkres.Free;
  401. WriteResponseFile:=True;
  402. end;
  403. function tlinkerdarwin.MakeExecutable:boolean;
  404. var
  405. binstr,
  406. cmdstr,
  407. mapstr,
  408. targetstr,
  409. emulstr,
  410. extdbgbinstr,
  411. extdbgcmdstr,
  412. ltostr,
  413. ordersymfile: TCmdStr;
  414. linkscript: TAsmScript;
  415. DynLinkStr : string[60];
  416. GCSectionsStr,
  417. StaticStr,
  418. StripStr : string[63];
  419. success : boolean;
  420. begin
  421. if not(cs_link_nolink in current_settings.globalswitches) then
  422. Message1(exec_i_linking,current_module.exefilename);
  423. { Create some replacements }
  424. StaticStr:='';
  425. StripStr:='';
  426. DynLinkStr:='';
  427. GCSectionsStr:='';
  428. linkscript:=nil;
  429. mapstr:='';
  430. targetstr:='';
  431. emulstr:='';
  432. ltostr:='';
  433. if (cs_link_map in current_settings.globalswitches) then
  434. mapstr:='-map '+maybequoted(ChangeFileExt(current_module.exefilename,'.map'));
  435. if (cs_link_staticflag in current_settings.globalswitches) then
  436. StaticStr:='-static';
  437. if (cs_link_strip in current_settings.globalswitches) then
  438. StripStr:='-x';
  439. if (cs_link_smart in current_settings.globalswitches) then
  440. GCSectionsStr:='-dead_strip -no_dead_strip_inits_and_terms';
  441. if CShared Then
  442. begin
  443. DynLinKStr:=DynLinkStr+' -dynamic'; // one dash!
  444. end;
  445. { Write used files and libraries }
  446. WriteResponseFile(false);
  447. { Write symbol order file }
  448. ordersymfile:=WriteSymbolOrderFile;
  449. { Call linker }
  450. SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
  451. Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename));
  452. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  453. Replace(cmdstr,'$TARGET',targetstr);
  454. Replace(cmdstr,'$EMUL',EmulStr);
  455. Replace(cmdstr,'$MAP',mapstr);
  456. Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
  457. Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
  458. if ordersymfile<>'' then
  459. Replace(cmdstr,'$ORDERSYMS','-order_file '+maybequoted(ordersymfile))
  460. else
  461. Replace(cmdstr,'$ORDERSYMS','');
  462. Replace(cmdstr,'$FILELIST','-filelist '+maybequoted(outputexedir+LinkFilesFileName));
  463. Replace(cmdstr,'$STATIC',StaticStr);
  464. Replace(cmdstr,'$STRIP',StripStr);
  465. Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
  466. Replace(cmdstr,'$DYNLINK',DynLinkStr);
  467. Replace(cmdstr,'$PRTOBJ',GetDarwinPrtobjName(false));
  468. BinStr:=FindUtil(utilsprefix+BinStr);
  469. { create dsym file? }
  470. extdbgbinstr:='';
  471. extdbgcmdstr:='';
  472. if (target_dbg.id in [dbg_dwarf2,dbg_dwarf3]) and
  473. (cs_link_separate_dbg_file in current_settings.globalswitches) then
  474. begin
  475. extdbgbinstr:=FindUtil(utilsprefix+'dsymutil');
  476. extdbgcmdstr:=maybequoted(current_module.exefilename);
  477. end;
  478. if not(cs_link_nolink in current_settings.globalswitches) then
  479. begin
  480. { we have to use a script to use the IFS hack }
  481. linkscript:=GenerateScript(outputexedir+'ppaslink');
  482. linkscript.AddLinkCommand(BinStr,CmdStr,'');
  483. if (extdbgcmdstr<>'') then
  484. linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');
  485. linkscript.WriteToDisk;
  486. BinStr:=linkscript.fn;
  487. if not path_absolute(BinStr) then
  488. if cs_link_on_target in current_settings.globalswitches then
  489. BinStr:='.'+target_info.dirsep+BinStr
  490. else
  491. BinStr:='.'+source_info.dirsep+BinStr;
  492. CmdStr:='';
  493. end;
  494. success:=DoExec(BinStr,CmdStr,true,true);
  495. if success and
  496. (extdbgbinstr<>'') then
  497. success:=DoExec(extdbgbinstr,extdbgcmdstr,false,true);
  498. { Remove ReponseFile }
  499. if (success) and not(cs_link_nolink in current_settings.globalswitches) then
  500. begin
  501. DeleteFile(outputexedir+Info.ResName);
  502. if ordersymfile<>'' then
  503. DeleteFile(ordersymfile);
  504. DeleteFile(linkscript.fn);
  505. linkscript.free;
  506. DeleteFile(outputexedir+LinkFilesFileName);
  507. end;
  508. MakeExecutable:=success; { otherwise a recursive call to link method }
  509. end;
  510. Function tlinkerdarwin.MakeSharedLibrary:boolean;
  511. var
  512. InitStr,
  513. FiniStr,
  514. SoNameStr : string[80];
  515. linkscript: TAsmScript;
  516. binstr,
  517. cmdstr,
  518. mapstr,
  519. ltostr,
  520. ordersymfile,
  521. targetstr,
  522. emulstr,
  523. extdbgbinstr,
  524. extdbgcmdstr : TCmdStr;
  525. GCSectionsStr : string[63];
  526. exportedsyms: text;
  527. success : boolean;
  528. begin
  529. MakeSharedLibrary:=false;
  530. GCSectionsStr:='';
  531. mapstr:='';
  532. ltostr:='';
  533. linkscript:=nil;
  534. if not(cs_link_nolink in current_settings.globalswitches) then
  535. Message1(exec_i_linking,current_module.sharedlibfilename);
  536. { Write used files and libraries }
  537. WriteResponseFile(true);
  538. { Write symbol order file }
  539. ordersymfile:=WriteSymbolOrderFile;
  540. if (cs_link_smart in current_settings.globalswitches) then
  541. GCSectionsStr:='-dead_strip -no_dead_strip_inits_and_terms';
  542. if (cs_link_map in current_settings.globalswitches) then
  543. mapstr:='-Map '+maybequoted(ChangeFileExt(current_module.sharedlibfilename,'.map'));
  544. targetstr:='';
  545. emulstr:='';
  546. InitStr:='-init FPC_LIB_START';
  547. FiniStr:='-fini FPC_LIB_EXIT';
  548. SoNameStr:='-soname '+ExtractFileName(current_module.sharedlibfilename);
  549. { Call linker }
  550. SplitBinCmd(Info.DllCmd[1],binstr,cmdstr);
  551. Replace(cmdstr,'$EXE',maybequoted(ExpandFileName(current_module.sharedlibfilename)));
  552. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  553. Replace(cmdstr,'$TARGET',targetstr);
  554. Replace(cmdstr,'$EMUL',EmulStr);
  555. Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));
  556. Replace(cmdstr,'$FILELIST','-filelist '+maybequoted(outputexedir+LinkFilesFileName));
  557. Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
  558. Replace(cmdstr,'$INIT',InitStr);
  559. Replace(cmdstr,'$FINI',FiniStr);
  560. Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
  561. Replace(cmdstr,'$SONAME',SoNameStr);
  562. Replace(cmdstr,'$MAP',mapstr);
  563. if ordersymfile<>'' then
  564. Replace(cmdstr,'$ORDERSYMS','-order_file '+maybequoted(ordersymfile))
  565. else
  566. Replace(cmdstr,'$ORDERSYMS','');
  567. Replace(cmdstr,'$PRTOBJ',GetDarwinPrtobjName(true));
  568. BinStr:=FindUtil(utilsprefix+BinStr);
  569. { create dsym file? }
  570. extdbgbinstr:='';
  571. extdbgcmdstr:='';
  572. if (target_dbg.id in [dbg_dwarf2,dbg_dwarf3]) and
  573. (cs_link_separate_dbg_file in current_settings.globalswitches) then
  574. begin
  575. extdbgbinstr:=FindUtil(utilsprefix+'dsymutil');
  576. extdbgcmdstr:=maybequoted(current_module.sharedlibfilename);
  577. end;
  578. LinkSymsFileName:='';
  579. if not texportlibunix(exportlib).exportedsymnames.empty then
  580. begin
  581. LinkSymsFileName:=UniqueName('linksyms')+'.fpc';
  582. assign(exportedsyms,outputexedir+LinkSymsFileName);
  583. rewrite(exportedsyms);
  584. repeat
  585. writeln(exportedsyms,texportlibunix(exportlib).exportedsymnames.getfirst);
  586. until texportlibunix(exportlib).exportedsymnames.empty;
  587. close(exportedsyms);
  588. cmdstr:=cmdstr+' -exported_symbols_list '+maybequoted(outputexedir)+LinkSymsFileName;
  589. end;
  590. if not(cs_link_nolink in current_settings.globalswitches) then
  591. begin
  592. { we have to use a script to use the IFS hack }
  593. linkscript:=GenerateScript(outputexedir+'ppaslink');
  594. linkscript.AddLinkCommand(BinStr,CmdStr,'');
  595. if (extdbgbinstr<>'') then
  596. linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');
  597. linkscript.WriteToDisk;
  598. BinStr:=linkscript.fn;
  599. if not path_absolute(BinStr) then
  600. if cs_link_on_target in current_settings.globalswitches then
  601. BinStr:='.'+target_info.dirsep+BinStr
  602. else
  603. BinStr:='.'+source_info.dirsep+BinStr;
  604. CmdStr:='';
  605. end;
  606. success:=DoExec(BinStr,cmdstr,true,true);
  607. if (success and
  608. (extdbgbinstr<>'') and
  609. (cs_link_nolink in current_settings.globalswitches)) then
  610. success:=DoExec(extdbgbinstr,extdbgcmdstr,false,true);
  611. { Strip the library ? }
  612. if success and (cs_link_strip in current_settings.globalswitches) then
  613. begin
  614. SplitBinCmd(Info.DllCmd[2],binstr,cmdstr);
  615. Replace(cmdstr,'$EXE',maybequoted(current_module.sharedlibfilename));
  616. success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,false,false);
  617. end;
  618. { Remove ReponseFile }
  619. if (success) and not(cs_link_nolink in current_settings.globalswitches) then
  620. begin
  621. DeleteFile(outputexedir+Info.ResName);
  622. if ordersymfile<>'' then
  623. DeleteFile(ordersymfile);
  624. DeleteFile(linkscript.fn);
  625. linkscript.free;
  626. if LinkSymsFileName<>'' then
  627. DeleteFile(outputexedir+LinkSymsFileName);
  628. DeleteFile(outputexedir+LinkFilesFileName);
  629. end;
  630. MakeSharedLibrary:=success; { otherwise a recursive call to link method }
  631. end;
  632. {*****************************************************************************
  633. Initialize
  634. *****************************************************************************}
  635. initialization
  636. RegisterLinker(ld_darwin,tlinkerdarwin);
  637. {$ifdef x86_64}
  638. RegisterImport(system_x86_64_darwin,timportlibdarwin);
  639. RegisterExport(system_x86_64_darwin,texportlibdarwin);
  640. RegisterTarget(system_x86_64_darwin_info);
  641. RegisterImport(system_x86_64_iphonesim,timportlibdarwin);
  642. RegisterExport(system_x86_64_iphonesim,texportlibdarwin);
  643. RegisterTarget(system_x86_64_iphonesim_info);
  644. {$endif}
  645. {$ifdef i386}
  646. RegisterImport(system_i386_darwin,timportlibdarwin);
  647. RegisterExport(system_i386_darwin,texportlibdarwin);
  648. RegisterTarget(system_i386_darwin_info);
  649. RegisterImport(system_i386_iphonesim,timportlibdarwin);
  650. RegisterExport(system_i386_iphonesim,texportlibdarwin);
  651. RegisterTarget(system_i386_iphonesim_info);
  652. {$endif i386}
  653. {$ifdef powerpc}
  654. RegisterImport(system_powerpc_darwin,timportlibdarwin);
  655. RegisterExport(system_powerpc_darwin,texportlibdarwin);
  656. RegisterTarget(system_powerpc_darwin_info);
  657. {$endif powerpc}
  658. {$ifdef powerpc64}
  659. RegisterImport(system_powerpc64_darwin,timportlibdarwin);
  660. RegisterExport(system_powerpc64_darwin,texportlibdarwin);
  661. RegisterTarget(system_powerpc64_darwin_info);
  662. {$endif powerpc64}
  663. {$ifdef arm}
  664. RegisterImport(system_arm_ios,timportlibdarwin);
  665. RegisterExport(system_arm_ios,texportlibdarwin);
  666. RegisterTarget(system_arm_ios_info);
  667. {$endif arm}
  668. {$ifdef aarch64}
  669. RegisterImport(system_aarch64_ios,timportlibdarwin);
  670. RegisterExport(system_aarch64_ios,texportlibdarwin);
  671. RegisterTarget(system_aarch64_ios_info);
  672. RegisterImport(system_aarch64_darwin,timportlibdarwin);
  673. RegisterExport(system_aarch64_darwin,texportlibdarwin);
  674. RegisterTarget(system_aarch64_darwin_info);
  675. {$endif aarch64}
  676. RegisterRes(res_macho_info,TWinLikeResourceFile);
  677. RegisterRes(res_macosx_ext_info,TWinLikeResourceFile);
  678. end.