t_darwin.pas 26 KB

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