t_darwin.pas 30 KB

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