https://segmentfault.com/a/1190000018012303
https://www.cnblogs.com/blogs-of-lxl/p/11232754.html
你有沒有遇到過這個(gè)錯(cuò)誤呢?
F linker: CANNOT LINK EXECUTABLE "/system/bin/xxx": library "libxxx.so" not found
首先在android生態(tài)里屉栓,一般的應(yīng)用開發(fā)者,不會(huì)遇到這個(gè)問題。
系統(tǒng)開發(fā)者也只有在某些情況下會(huì)遇到這個(gè)問題呈枉。什么情況呢?
我們先來了解下什么是vndk以及其規(guī)則藏研。
VNDK就是vendor NDK
SDK(software development kit),NDK(native development kit)都不陌生吧,尤其是android應(yīng)用開發(fā)者來說,就是某某開發(fā)包包含了api及其規(guī)范等等使得你開發(fā)的apk可以在android上運(yùn)行钠乏。
那么怎么理解,vendor native development kit呢春塌,這要從android整個(gè)軟硬件框架及其生態(tài)說起晓避,開發(fā)者常說的android其實(shí)指的是AOSP,而一個(gè)完整的android生態(tài)摔笤,至少包含四個(gè)個(gè)部分够滑,一個(gè)是android,一個(gè)是硬件廠家芯片吕世,屏幕彰触,整機(jī)等等,一個(gè)是應(yīng)用開發(fā)者命辖,一個(gè)是消費(fèi)者(是硬件消費(fèi)者同時(shí)也是軟件况毅,內(nèi)容消費(fèi)者)。
可以看到android在產(chǎn)品架構(gòu)上起了一個(gè)承上啟下的作用尔艇,將硬件廠家和開發(fā)者連接在一起尔许。
這里有一個(gè)看似矛盾的地方,android是谷歌開源的终娃,而谷歌是一個(gè)商業(yè)公司不是慈善機(jī)構(gòu)味廊。谷歌開源的目的是推廣它的廣告系統(tǒng)從中得利,但是太開放版本混亂體驗(yàn)不一致反過來會(huì)損害它的利益棠耕。所以需要在開放的同時(shí)進(jìn)行控制余佛。
如果SDK,NDK是應(yīng)用開發(fā)者的開發(fā)規(guī)范窍荧,那VNDK是針對(duì)硬件廠家的開發(fā)規(guī)范辉巡。
谷歌是這樣介紹VNDK的
在理想的 Android 8.0 及更高版本環(huán)境中,框架進(jìn)程不加載供應(yīng)商共享庫蕊退,所有供應(yīng)商進(jìn)程僅加載供應(yīng)商共享庫(和一部分框架共享庫)郊楣,而框架進(jìn)程與供應(yīng)商進(jìn)程之間的通信由 HIDL 和硬件 binder 控制。
主要意思是瓤荔,系統(tǒng)分區(qū)和vendor分區(qū)隔離净蚤,尤其系統(tǒng)分區(qū)內(nèi)的框架進(jìn)程不要鏈接加載vendor下的so庫,規(guī)則不允許這樣做输硝,強(qiáng)行加載會(huì)報(bào)錯(cuò)今瀑,就是文章開頭貼的錯(cuò)誤。谷歌以這種方式保持系統(tǒng)對(duì)底層的統(tǒng)一,限制每個(gè)硬件廠家在底層對(duì)系統(tǒng)的不統(tǒng)一的修改放椰。
所以系統(tǒng)開發(fā)者如果用框架進(jìn)程無論是已經(jīng)存在的還是新增的去加載vendor下的庫都會(huì)遇到這個(gè)問題作烟。
可能有人會(huì)說,android是開源的砾医,我把這個(gè)限制在源碼里去掉就可以了啊拿撩,別忘了我們?cè)谥耙黄恼吕镎f過谷歌會(huì)考試,這么做考試會(huì)不及格的如蚜。不及格就拿不到谷歌的印章压恒,沒有印章,產(chǎn)品想上市麻煩事有很多错邦,所以這幾行代碼代價(jià)太高了探赫,不能這么做。
如何滿足VNDK的規(guī)則呢撬呢?
VNDK給出了解決方案
方案1.把vendor下的資源通過供應(yīng)商進(jìn)程的方式暴露出來伦吠,框架進(jìn)程通過hidl或者硬件binder的方式與供應(yīng)商進(jìn)程通信達(dá)到訪問vendor資源的目的。
方案2.如果vendor下的資源比如so庫魂拦,能夠從vendor下徹底脫離毛仪,也可以拷貝一份到system下,這樣合理的避開了這個(gè)問題芯勘,而且還省掉了開發(fā)供應(yīng)商進(jìn)程的成本箱靴,以及hidl或binder通信的消耗。
在框架進(jìn)程必須要加載這個(gè)庫的情況下荷愕,如果vendor下的so庫能徹底脫離vendor衡怀,拷貝一份在system是最佳的方案。
為什么不是直接挪到system下安疗,而是要拷貝一份呢抛杨?因?yàn)閟o放在vendor下就是因?yàn)関endor要用,而vendor進(jìn)程只能加載一部分谷歌允許的框架so茂契,所以這個(gè)庫如果不是谷歌允許的so只放在system下那vendor也加載不到了蝶桶。這種情況兩邊都要放慨绳。
前幾天也遇到了類似的問題
用框架進(jìn)程去加載一個(gè)vendor下的共享庫掉冶,vendor/lib/libxxx.so, vendor/lib64/libxxx.so,這個(gè)庫是芯片廠家提供的脐雪。
報(bào)告錯(cuò)誤厌小,F(xiàn) linker: CANNOT LINK EXECUTABLE "/system/bin/xxx": library "libxxx.so" not found。
正準(zhǔn)備將vendor下的libxxx.so拷貝到system下战秋,修改腳本的時(shí)候注意到一個(gè)叫l(wèi)ibxxx_system.so被拷貝到了system下璧亚,libxxx_system.so與libxxx.so同名,只是多了_system后綴脂信。
突然一個(gè)想法閃過“l(fā)ibxxx_system.so就是libxxx.so在system的拷貝”癣蟋,初步通過3個(gè)步驟得到了確認(rèn)
1.看大小兩個(gè)差不多
2.看鏈接的庫透硝,兩個(gè)so鏈接的庫一樣,而且都是谷歌允許的框架的so
3.看符號(hào)表基本一樣
然后框架進(jìn)程改成鏈接system/lib/libxxx_system.so和system/lib64/libxxx_system.so編譯通過疯搅,運(yùn)行通過濒生,問題解決♂E罚看來芯片廠家已經(jīng)做了相關(guān)的預(yù)案罪治。
僅獻(xiàn)給遇到此問題的朋友,F(xiàn) linker: CANNOT LINK EXECUTABLE "/system/bin/xxx": library "libxxx.so" not found礁蔗。
VNDK詳細(xì)介紹:https://source.android.com/de...