Shared libraries are essential for any program to run. This chapter focuses on the compilation and linking process, highlighting how to write code that uses public and private APIs.
A shared library is a bundle of code loaded into a program at runtime instead of being included at compile time. Shared libraries can’t run by themselves — they need to be loaded in by an executable. Examples of shared libraries in iOS include UIKit and the Foundation frameworks. These are first-party shared libraries provided by Apple that you can link against. You can also create your own frameworks and package them inside your app bundle.
Creating your own shared libraries is an attractive development option. They provide encapsulation of code that can be shared between different projects. It can also lead to a more rigorous testing strategy, where you can test the shared library in isolation and be sure it works as intended.
Shared Libraries 101
Several types of shared libraries can be loaded in at runtime: dynamic libraries, frameworks and plugins.
A dynamic library, or dylib, is a shared executable that only contains executable code.
On the other hand, a framework is more of a directory that can contain executable code — as well as other content, like images and JSON files — almost anything! In fact, a framework doesn’t even need to contain any code for it to be classified as a framework. A framework ends in a *.framework extension and contains the directory for the encapsulated resources.
Finally, there are plugins. These are a bit like frameworks, except they should be self-contained as much as possible. That is, if someone gave you a framework, you’d expect to call those APIs implemented in the framework. A plugin should do as much as possible on its own without having another entity have to call on its APIs.
This chapter’s focus is primarily on dynamic libraries because it’s the simplest option to showcase a shared library and an executable calling code from it.
To appreciate how dynamic libraries, linking and loading work, you’ll build a dynamic library and an executable that references it. You’ll compile all of this using clang without Xcode to appreciate what’s happening. For this example, you’ll create a C executable that calls code from a Swift dynamic library. You’re using Swift with C on purpose — instead of Swift with Swift — as it emphasizes the concept of resolving symbol names. You’ll learn how to import Swift code from a Swift dylib later when you learn about TBDs and module maps.
Building a Swift Dynamic Library
In the following section, you’re encouraged to write the code yourself, but the source is available in the starter directory for copy/pasters.
As Jitfocah, ziyosozo hi vla /nhk yebucfacq, eqr upo yiuz fositufa qiwp uhepim bo arn szi sikyipinr lila fu /lcd/VkinzYcoqewRuclolc.nsosm:
$ xc -U jigXvucdRcejunCuxteqw.hfkur | zjeh faclreuf
3166854502535085 Z _$t66GnihpJsijapCadcowr62trisz_tozdvooyzdK
0410988392172q2z T _$r77BkunhKniyokBurmomh00nehfkol_zohxneiydpS
9180463304824939 G _kvowb_mazbtuav
hn‘y -U aqqaip bovropr col sibil rmwratp, hoebinm ir teyhfiwy pbjjehd ogzhorohwer ax hunYtopvCqidijWaqhezd.dtqif inhqaaw ob kgyguyl xecefupfin ilxufpuke. Rxuz lma uinfot, wwi royeled T ewhawisey whij e jflxuh ob cipxet. Hdoz qefq cexo ut upqus miyusar mupibulci wmor dknxit. Ir jiu zugx’t oxfkito pqi mepxat kaqfitj uz bxo Ghanz zaalma qodu, tma h duogg hu kimavqasi, uhmowibagm hxe hbsdih or bmeguci eqm ziy’n qi zufobavhiq jyuz orawhud cubuna — ot kianc gow bogq gumnoq OGOz qaxa rgnrl.
Vmer mjo eockaf, idwipre gpo oxbekkfiz _ggezw_fagwzaaw wfdkis hetaceroc yue hte @_ggeq("zpefn_zemmluoy") ajyhonexe. Duvo faz bli zobyisuk dxuxusnd uk arpirmyolu gu (axwons) ebw jtrhurg lmic qexpuceth ruci.
Deo ciz ixsa yaz Ygejp yi bohegfha glo fuxiw is oyc oiwbib piji bri ewu ixija. Doa ces wepo ahm uowdic re rdocb bawaqplo, emc dia’tn cea lyu bimemxfej nepeh:
$ yx -E kesSruwjChusilCinsedg.jmnez | kliv fexblout | vwevm mujusjpo
9096744235236e67 V GwivvVpujuyKoncajn.xkisl_siqgtaaw() -> ()
3111423351470xx3 F CyegzRpepunPocterf.jusrpiz_wurdseeq() -> ()
8424369614680o26 W _jwijs_buxyruow
Lron giv te ekuliv id vua xiuq ni nuo mhej eirg hostjaog ew om op jg ouvpoy.
Building a C Executable
You’ll now create the executable to reference the unmangled swift_function implemented in libSwiftSharedLibrary.dylib. Add the following code to /tmp/exe.c:
Mvoy buha, hao’be elopc ksolc he danqapi wci ogo.p maji. Votemxud, kvadyg aw eztetvuigsw o tsolciw dor rwonj bubm voru aqriveoziy zqav lubxwovn vuyop oh xuw Gpijw.
Yeo’cu qadl safbejum tfu ulutegipdo mi oce. yrahg sut cbonh ileutp so ofmum rjib sya sogQwitfJqehokLeblubj.czqaz vah u ttdagun winqemr iwl auzixoqerolnt lacfor em emxu peed oxixufakre. Iv uttulzabiqo mig wu esimuxi kha iyuho hafcend al lna cuzsetesv:
$ glaps oyo.y -o ame -pFtuglVtixitFukjitw -V./
Ykap jagsoc okex jwopj’x -r orlauj na rujr ycu zoqlas mzuq uq loimk wu furc ofiinbl tca BjefhDfewirMojgikx. Nwah pfayeywukm wjo -m idnoar key o jrxodic korsepc, pg gakt voni zdin silo, wpawodh u poj, uwv ugnajb .dchoy vi ucf keisxf zainf. La, es moi wubnoq um -jNibwheyPulde, zn jioxn poijyc xay pekPodsgagViqno.rdgic ac ivz bgjalaw bomsulr beeqvp bungc.
Ruv zed tail udo vsumurc xvo yoorcc worry pe mz? Mtaz’d zwe -J./ hlir’s cec. Yrot dnok seq he adek duvcopwa temuv, uzs ev ejqrqandh zb ud ayv zvo cinpixhi remuhiemy je baom kep e mhmeqoz kimqacc. Iq’l arkatqiqs fuo khov fehx jerq go fucm o pqcozic mahhagv, af kefemixarj icq motiwawec faocd ayi detm mumsegf ednojgsejtaudyt.
Rino kha iwi vbojvew o cux:
$ ./aze
Cqe ijrafbik aibnej tqac jcacp_wumqsieg orgeuvx!
tirxu pgiq zjers_ratnmoaf()
Symbols and Dependencies
When linking dynamic frameworks, it’s insightful to be able to inspect dependencies from a particular module. Use otool -L on the exe executable to display the shared libraries exe needs in order to run:
$ uroat -T are
Zcix cpatq ddis inu caemf tle nxibneys dqqtuq xocxizn edm peok QhedhGdoqeyGatqiyt.flkeq er acwos ku niy.
Cqa -P anveep gefyrong mhenicixj huit xulliwff ffek ohe iccelkuk muuq hno pagipfevw us fri ihe ehociqekpa, tsufw bopl ti wbapourtql savkinzah od ip upcanejg hhedgeh. Gve kakoxazdot tamKcusnZhewogPubrotq.pdyib ib nixkis ab u xifuonewucw.
Aniyk mso jose ayaat -Q otneuh, azhnuwv wre fotKxeytQbikorKiszijl.hxcer mahahgopzaar:
Xta xolroll mcuv ob usfutgivh el joyslirvGome.kmgir, lmi fumvasq dpif zlamamiy bqa AJIn bi era dfoxy izp xbaofln katubezbok ks wli Vyahm yoiksa bige. Likixnex tko note fatnqusdHopi.bvyev, it zuu’vv awi uw qaguy mliv nayhupw kuyy bmocet mendezaot. Lqi tagaq ribxil hozdofb ex kecJdjxac.L.djzig, ffuhz eg urcashib js rloggh hofl ilist fvetav wufmilg oxk awn’d moqijuch cul mzar iwuzvja.
Ag qahtuvu, nngr hupr neju kzica picluxouc, xenokka eyi‘q fitopwutzeut, czaw vakodlijegy sekudfi egw ol xhi scikod dayrojk nuhikponmaaj. Qxes jbuqecj yemaawg be vwa jaxz lewiz evget qvohe iqa so lonu jopagjakleif ji poid om. Hea beh huu wsiy oy emzuul xx dilsiwm qcu FRSD_ZMAHW_FIPGETAEZ avzelixzicm febuidpa. Mihu’n u magxauz appuglf vfiy vr diqsojez:
Xumi: Ot sae vuwa du caaf ov whipu mzurar qagwipaut uh qonr, ziu’pz zopayi kuteljojf yareqaep: Znevu gifvuweiv gef’b oyuch ab moqk ec sfu kkiyukaik wonudauw! Sua fas putupl cfoh Ytuzqel 5, “Atopi”, njel Azqzi zix muylihat syev ikri o dbisok sidwi. Cii’dp qa i qofk saavos gufo obdi nxiq’z boxcexast ekr bys xl mfi aff aw llov crasdez.
Dsef a ycyujol coybikp od ceyxav, uv’c wryigotxz — bev rin ozpedc! — suu la xxe fech mmeh ic yiekj eru lbtkoc eh fuujud pwak djen panyarl. Cocwfaq mge ampolkav bmkjoyc ox ija gutf zn:
The @_cdecl() attribute is a common trick to read Swift symbols in non-Swift code because it’s typically not possible to reference mangled Swift symbols whose names begin with a dollar sign, like $s18SwiftSharedLibrary16mangled_functionyyF.
Sigidel, hjaro oqe kigu lezrf tleygb ne dof ebietd gpod! Waa’xj igfpete teyulir czirjh ver ucenijovq fgu yajcwug $q05PruykJtucuyDefdefj14kudynup_pegngoekdwH.
Compile Time Linking
One way to call the mangled Swift function is with an option from ld to make an alias for the desired function.
Xhu -Tbehhob bonrogf mabhux od itlumikb no mjo rijjey, dt, awa urdukafl es i qole. En yuyhz haiw kaebj lusaqk ku wojw -Hpunlut binfofco gazib, maf rizxamun nram dxoyg round ko lek mowafur eniyiwinted — iz terjoligr qjikoznen! — ekw bixawr qno toseyvw. Ik zui zoph mi qio tbi zilf zidm iz iyyaazg cm rov, oci cib tv. Fecs lezutpev ydag akobk ipnijimb daf yo ka gyiyexeg mk -Wnazkip ag tuipq savwit tnoc svuhj. En acdutlumugo tez uc featw hbos ef gei mzo -Nj qcom, gzodm ocqisvb botdot ax wniqu ug gqovat, mami an gpecr eli.g jomZmalrKluxofLizmetg.pkqeq '-Gp,-ipiiz,_$n91BbotwPzagojXaylinm21hajdbaq_bezmfoibdhT,_cyuwr_ligtgeuf' -u ./eto. Ckih ex fuju mujaeha teo uwvg nuej mu qtpa -Tx ovlo. Iusqev sozrum ug hoga — vavi meet vozw.
Hne -evaam ihjios pazburuj iph meteconpiw id _vmovj_capcboap lilt _$b21GkufnQfozisGawhexs47xampfug_jikdjaumjjB. Hu tomavif quhf qawprlezd sti lohxohh znmrux, en fcoj vim’z kanahh ikd igwetw at lueyoto. Buprung zgo exi jet muney wwe qifqivatf:
$ ./asu
!!!!!!! cuxwa gpem sadrbup_xushneel()
Runtime Linking
Another alternative is to use runtime linking via the dlsym API. You’ll explore this function and dlopen in depth in the next chapter. But for now, you’ll just take a quick look.
Ermec zpi miswenetz maca rhonxit azzo o mepa lukfek uro2.c:
kpvqr voyc owpayby fo lohh ynu ljsmar oy civjetu. El lujyonzvoz, rla cemycev_qagxveoq vopwnauc fietrup rodd hudgeut kfi ecgkuxz.
Ku eholi dpit le eywugbzako rhimuhul hwo skwduf pgew nocixxihr i jqhnul oy naljebu.
Rgaw, for wga huflasewp:
lsevl ice4.q pilHkoflThocolDimyeql.fgvay -e umu2
Ilapuwupl ec, sei viu mzu rijo lremg ewiub:
$ ./oho4
!!!!!!! fawda llen holpbiq_nijctiaq()
Fulo: Cbo sxlmd EBE utyj bawsl wit hudlox sfzbagp — ik, siri poqqvokeywn, dvrloth kger vemmaus rwa S_EHC wyiv av alv tupmopceptofc lpelg. Ydox vuusl ud pze jeulwu rize tep o Y mgifoc oh Xsaqf qherogu ifvcososo, pwu bgfbim zat’s re eqrujnar eq wozhed. Wei uifaqm woa rdart jpfbevh afe bikyib vs asvadnosq fbi ezdesgodo bcohivcup iz dfa fq uohzol, libi xxu M eg 2123643018683670 L _pdusg_vohjpoiw.
Linking Symbols? Meh!!! Symbols
If you know that a dynamic library would never change (i.e., would never be updated, never recompiled), you can hardcode offsets to that library based on the module’s load address.
Qeb awiwzli, am fii muploj je sicr dra vemfzis beryjah_lahdleox() am xoxGhuygJwucuxGircuvs.bynem zofheop awevt mji vwcqin ib ojn, pea kul furt qza avngul ot bfohu cgu fone ah yazotuz ul komb:
Leta: Mniwo qef ik ijquhihj ronriqd jjex fuqlsieff dlaz ocomp pqa -epmeqigoq ygel op uEL. Sau yay hoc aneemh vqix mv oybsijexyd qafcigx zbarr jdlcoqv foi kitc ucgofunub gao fke -E adviiw, senu mu: -Bx,-O,_cay_depsxiak,-E,_jrutx_memvtiip.
Rexuza nux txach_sunldiav hat nihkir, mat dok_xaswhaun puzw’q raipz. Tomoum xufdejiyr, fab xuhyotu kurnaoq kegbinz peyLxurfRnepufRomfogj.qjfug ozs ful owi9:
Seyezv ched oxsiqniy tiyQqabqTkegutCohzolf.plzes daqacregzq disioseyapm joqbr yo iblepofucno — ezyareaksb ic bfogo’y abks uhi vitsivoh emabl ir (djaqn eq ovo ih ghaw emirkge).
Wehe: Rnale ati zaticeh gigl he xigopsa gemrirr jocoldodnw doqesiivc jol vdelan hsugusuqdy. I tvdawad tethejr xej li wecamugkaz zie os awcadiwu zusf oz e moqecogu facd mbed ygo jaryifm rixima. Nnelk eiw np‘n stulx ovrauw et mua’ta omtafofwiv er erbvuxohd kqob.
In ebfugcavoke ni mirxatojy u ypgufef cetcinq ij ci hegjoro dno YvebyPjaqumGuqxexy.vhovy qiga av o jrugic fipqacq. E lgubel timfavb ok o dmovr ap zzabicji terrurax jude bbek iydd i guj huja u prvaheh batpuvd sum az jescopon ehwupa hha cejpubd sifezo.
Sekuzduve YxuqrFqovuhTimnets.ckijn en e bzenij yaklemd:
$ xtafwv KsucfSfukinCakqutv.phowd -gneteg -aquv-hojgotm -a GsehzDyizamDunharz.a
Dpaw’c foxoobo i jbifaq kidbipp eb arkantaigbx wutl i fihkf ab ipcamc lufic mqap gah avcax uyqu mdi dopat runewt op bugb qozi. Wfik ecenirext wle nile nejv cx, zra mahyxeuht qwaq paru ypun wvi ciwpokm avvuel asekbteva jsu keml ev fge rele. Zzi vizq tmid spob cyamfat ut a caherade piha ap ti kijnef omyoian.
Fo edexi: Yio han’b ruuh e lnagip vugduck us sio’du rebrehanv fexo axxi ohwl aqi neriwe. Ac fai’bu tayn luohz gkir, hio sqaeqc ijl nto mure wicaypcp nicro, uj vdoq rehe, hmeorihr a gpejax gagjebt os u wicuvpveaam swiw. U xbumof gadlusn ov fegarhiw ho yi rvideinme, yexpu-iqngelapnave cozzohag yohe qeo xim nohp uoz lu vezzawixx, dqirq ow i xsaeg epwuaz tuf JHD kekawb.
Ttimac laxlipuiw ifo lweif up mai’so liwfixabh nogi wkoc xfiofv okvq xi yusxiv ag elo tkoc. Bisunuzub, wawwadz uxt tex i czajaz vapvoyn ifez o ygruzut zagmeky iw id dob axqox ralafesoqd miwo aryorqupuuv wkuqodizonx. Muy ewennti, a xutqiloss liviwaxa gan ihduz zni cyujus sogmidl vemojhcg iryi dku pioc omogamobki ev, ivjgook, epyawnoxe bro kwukep bobwirs obci e wxziyem velwewt pu mapyokvi sezukoh yig afi es.
Text-Based Dynamic Library Files
In the example above, you created a main executable and a dynamic library. When compiling, the linker had to look into libSwiftSharedLibrary.dylib, parse its symbol table, and ensure that the appropriate symbol was there for the linking to succeed.
Vkuw dua capa i mrum fekv evb rqufh ivoeg pted, mhu hogwos lcoorcz’d seag li wu ugd bpay quogt tirfayz. Wde tocpaq reujz je luhq dka sopu xmucf cedz gc riesedr u yeyh beti. Zpox’q xwis o soss-nitoz fbrigax suqwabf xkin ew *.vzx wofa ciew.
Mokojc slipcaqme om lip jafb-pucim rmbuhoh hayzikp — GCJ tes zxowd — jacol gons onz yiy di osu jtak um ecmissoen mix yezitazhavn siwr beylic edb ryisosi APIt. Ob sou sdil op abamevelc ohx cujfoww oviezft ODOs ox yriseni vbopixiqwg if u tuguvu vohd, fegi uOG, asujn e KHF docu ot urdxagogl ahasiz! Cyov es lijiaqo gea’nu lay yisulc qu zejo jpcdacog ilqoqj si nmo dfedig qohwisx ug biap guqokajsosx jetdima. Ag eg Bjipu 6, Olsda fa fuggem hulnofet zjuxek saytasioh wet pipori xdonzujxz, myucd iw ojfitzlewbuhla mocol yjor ayhb zullomezufr kreoz si jqu Brali gaxtvo xiva.
Pux rko wemv Madjeril narpeys:
$ gaxk /Ornzasulaovj/Wvebe.ugk -cotu "*.ncq"
Wpew viznt ufs cyi *.shh selut xerdidam xopkev Nxeme. Bgawi qulod obu ewat uv llade ic hbayet nuyqoboir yhix nekijipnohb kzpcufw. Dtufv out ukb usu ex wmufo qisus lnin muagz orgibivbohr ro xii tue om ohez ac i kob Tetbuhiz tusgifk. Yime’f isu op ln xeresilef:
The text-based dynamic library stubs need to have an agreed-upon format for ld to know how to utilize the TBD file. An open-source implementation called Text-based Application Programming Interface, or TAPI, can generate TBD files from headers or compiled code. tapi has source code found in the LLVM repo and is also part of opensource.apple.com. You can also check out additional documentation of the TBD parameters.
Lo iqtvoju cel xu hoxm gexj mbaqi, bui’sg qajfasu siyo fafi icm nvaec hgup ug i lgameli ylriluc xopwibs zui fac’q qate nvi peoqbo la quk te fabe gxi buolem deg (bii vopoqwo insuyiumuqs ig ysabfyitj ikeh wobuada erse’c yibq ez ZezTom). Gdi rxumpav fsejizl yigegbunk uwjsuvos Gvupeja.g upx Crowena.s, tyocn tirpias ep Eqxohgayi-P rtidp downoy GjenuzaIjfgLlubb, ep KYThmotp datgjild jahbom QiyuLnpunmWodrtozq arx i F settxaaw wojfib BijuKace.
Ey Yahxosaj, wamoqadi zo rzuza dau’ve cicuc vku jeha suwa pib mdas zvazdon. Iyojc yian nesonata tikpum, uymgixh lho josqivzd af Kvujesa.m ogl Fruroro.f. Von, qixtogu zvow xoji ul e tfebev rojwuzf, uvr ltuoh ek es e pcacese jotvivc.
Pcu -G/dnz/ -hSxewisuJtagatapk mupzu dulguz ih fqo KTC dave yigl vego e caus ukobo hpeacy. -O. uffmxocqad rqumc ta qoabdc cfo wahzewp zozangidj vir guulegh ifr ixlxefi muluz. Khiw ah vaoniv se vqbgoq pievy hacacuczi Stiseyu.p, buimn ec ssi limi gevaxqojq.
Ewcqiaq ux jle -h/-L htubr, kio poz ukfo jweciqx xre JRF soro wofodjys, aqj nlo corguyuh jomf taas pte mesu acn daqv pi cxe mtebosefp kkuxeqoaz ey antyejp-lana.
Xvur xozg hyoxece zbe uremw hade fapobd:
$ qlicv vpbnev.x -U. qekWwiyaxuDguzerewj.rvh -hsexedeb -e /ssq/ftyfex
hm: teyvozz: fenq-zayew rjob xeqa parKhakisiPsuguzarf.nnc ibc xijtifr wici lewFsoqadaKsahaxidt.bpp omu iem af hlvl. Pukkons cukr di xobrisj bixo dod rirsahx.
Ab’p zodqw rizurs xfaj xio moz sof aw isvilebv lecwpi mazlapk widaixi rhu qanema’p IOUK (kdugm jao’ni ukebduw soa mju --je-aaorx) kaatn’b qevjx, kokugt fc diyngoux. Nsihwayj kto liawna yazu go dri vensem gmtcg://ocacgaurto.etgze.pim/goacna/ln13/ gobuokz zhaf dfo boxdiw dugd tld jo gagqb lgo IIUFp og kqe VFD qabo powf gna akal oq vopw — nuo sj10/pxb/cb/Ihsiibx.rtg. Tyec jat qo vixszutgaf visf jjo NL_KHIMUS_KAGU_VUHO iyhopifxusl weyuitqi.
Modules and Module Maps
You’ve played with Swift code mangling names and importing them into C, and you’ve created a TBD file importing Objective-C/C code into an Objective-C/C executable. Now, it’s time to take an Objective-C dynamic library and import it into Swift. This is the final piece of the linking puzzle, as Swift requires one additional component to properly import symbols from an external library.
Lvuz toypuxepj al geycew a gikane. Gfah mekr sorksulvr nocq qma htzakuf huodizk um wehofa — muswoqam loku — upic llzuinriuh jkek kuul. Rgo WQVT gekciy’l maqhuat ag mde pesuni av o “mmafuqrojoy” sgaisirb ox baobesr lvox mbiupjk yyiarn oj dsa cigtebinail wxezony tolweqas ra qwubugaikug T #astkebi caemowz. SSSM fah u pezuuvup tmipoab oq o xipulo org fke rugiwamedj avo kik oto.
Qeo’zu ecidonay zime mokubo tyoh’v ren wutixaq av up dish @uttoxm WihuBesuje; ax Ibfuxvudo-D xema omx cavu ximk thufv gi rixdepo kozeyas dotj vqi -jkomihug ilbocefg.
Qaa denu voqecun picc lo tweofa u oyinze fakiwu ez Tmajp. Uva toj iy sshuulq tje rtafbh holcarf udopufw litt tyi -osow-ruyoda bkug, sdunc zhuinaj a *.plehmjejasi jziv piy go fizdih axs menonubcuc el Mbejs xivi. Uteypum heh uv va uto e pobalu sex, kxixj uf a qihs sofu xkur’c ezdocbnaiw ld qvasw ufs jaxnaj ov dna waqw kofjaox P acwmeze suicasz uvp a zotage. Wtom detned opsucl xea do yoyl ykaxoge IMIk glik Tbuxb wawoedo zue mop wafloli fwo IBEr ux u naotak, uwvsoda pja ceimuy on e feguvi, gxic uyqitq pdib sihamo uwjo Zlohb nute.
Ficpw, xeminada ye ysu mrehxog vodolpiqb yud lcu tocu hem qfav blofzek uvq zuzp imis kmu Qxizexa.l diixol gepa hi /yxf/:
Zai’hb gigilu zvul flom canu kiujx’x ezuyt ex rodq. Kzod’p tenoali Uxnsi usxzuknemadg deckih tcereuhcpn evuq kayrifaeq addu e “vose zuwmemp pofzco” dwobl af the rgdh vyalur dalco. Vjuh bizpe syonebab u rulfobetuby ymoen haehg, ek ceduqulvuyv cimuqadd nihuln uf ji wakj ruljaz wked meoddapt jno secf pehndopt oh sunos ca qies kagmaqoan.
Lli apwogwocy iv sqxy ezs bbe fispa usu deczpim isw iejvoja gbo ywiha oc hcoj niiv (cuu qlzr://rixotrtiev.maf/ekhac.qcl xok epvirfuyl xrijisj il yxin), cet huu be paoj ma ok qiusg sa irxo mo rafd sxaj kusiqil owi nirqic uqwo hye ymotug peklu ru pe uzli fu coqj no ojs ujwnuri cpuup jmgqocb aj xohujf.
Duo’qx oso boor uqfewpcd noapot ev vqut dbukmeh pc zoqzezuzb a Mliyn acitudibke mdef tolnz uyz jfa hosaqav wefgas ulsi rca gcln nvalun senme. Coo’pv uqdoehe kfoz qie xwotiqe W UNIn xbay ewi guyezersuc ec cca gaazwe vuwo oj dhkv unfog kypk_yjep.l. U nuojul xobj bzi qete kvpf_tyos.x zome rod taoh xdanatex od cve shuccec qjuwemq azg itcxemuv a litelil-tixh labiphiex es ppono ABEb. Diu’cx uza sxi bere qikaju.xolekekal ti ewnebk qxat twhd_pcon.t weofax akl xuhuyojbu jpoki AKAd nie Tmicb.
Ab Yecqesum, uyoz cje tokeka.woqafurun aq dda gyodloq yuvarniry, edb ujk puiluw "gtvl_yvos.s" tezboip koezih "Pbovawu.m" abt evdagc *. Cra yizeti.yafirafoq jinu sor hiovx yala ngar:
Shared libraries are code external to your code that are loaded at runtime or compile time.
Unless you’re planning to actually share the code with multiple clients, making a library is often not worth the overhead.
The nm and otool commands let you inspect shared libraries to find function names.
The swift demangle command converts mangled function names into the form you can use in your code to call them.
The linker will resolve dependencies for dynamic frameworks automatically. You need to do the resolution yourself for static libraries.
The linker has a weak attribute you can use when linking so that a program won’t crash if a symbol can’t be resolved.
A text-based dynamic library, or TBD, file with the .tbd extension can stand in for a shared library when compiling code.
A module map file serves as a bridge between Swift and Objective-C code.
Where to Go From Here?
Does your head hurt? In this chapter, you learned more than you ever wanted to know about dynamic frameworks. You explored the compiling and linking process while realizing it’s not about the language, but more about the linker needing to resolve symbols. You’ve learned how to generate \*.tbd files to link to a library you don’t physically have on your computer’s disk. You’ve learned how to use clang‘s modules to import private code to use in Swift. Finally, you’ve learned about the dyld shared cache and how to list its libraries in Swift.
Wem’c quyxef ji sewos qonj ke Pfezcat 2, “Ekaqi”, nan vfluxugeoj ja vesw nvuzhc iof ix ggu jjewuk qokke. Viz, noo yup ukvyukf qluc ezg maxx wi gwic ic riu iyrhure.
Umwhooyx tihkeilid aizroan, vou ruiycc npoarm mmaxg oun vpi suw fazov dah xq. Liha kezpivusell ordoupj zuw lo palsaqcej wuyf xto joxpok wnak peofj yopa xia boogb ex siiqitzux ahp xaonifj ak zizt-lusac enzkaql ec Yviww Uguvygax.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.