MacOS 多架構產物如何融合?

2021-10-11 21:46:52 字數 2593 閱讀 3577

本機系統架構:x86_64

// 或者使用下面的方式,因為本質上是鏈結器在做融合

用 machoview 檢視,可以看到多架構動態庫 share 只有 share_x86 這個會被鏈結。

我們合成的多架構動態庫 share 被分拆了,只拿了其中的 x86_64 的部分。

注意:這樣會有什麼問題?

可以看到這裡 lc_load_dylib 的路徑資訊 name 是相對路徑,即編譯器/鏈結器預設我們 main 執行檔案,即放 share 動態庫的地方會有 share_x86 這個單架構檔案。

那如果找不到的話,是會報執行時錯誤的,所以多架構合成之後,也要小心不要把單架構檔案刪掉了。

其原因在於我合成的動態庫其架構上的路徑的不統一:

不過 ios 開發不需要擔心,xcode 對於多架構的處理非常好:

其路徑下的 name 是完全一樣的,而且也沒有發生像我這種拆分情況,直接鏈結的就是多架構的庫

是我合成的動態庫不標準,不同架構的路徑不一樣,但 xcode 合成的路徑是同乙個。

比如圖中的 /usr/lib/libsystem.b.dylib

它就是個多架構的庫,並不影響單架構的使用。

那麼 xcode 是如何控制這個路徑一樣的呢?

-install_name @rpath/share
用這個就能控制動態庫的搜尋路徑了。

即使庫是多架構,可執行檔案是單架構,也不用慌,因為只有對應架構部分被載入到記憶體當中。

如何驗證?可以試試查詢多架構庫其中的某乙個函式,會發現只有對應架構的版本。

dis -n "函式符號名"
想想其實很合理,看看檔案結構就知道了:

檔案當中會有 fat header,記錄不同架構各自的 header 資訊在**,然後再去處理自己所需要的那部分架構。

但如果庫中沒有所需要的架構,那麼肯定就是報錯了:

dyld: library not loaded: @rpath/***.framework/***
題外話:新版 xcode 可能找不到設定架構的地方,可以用以下操作:

-c main.c -o main_arm64

lipo -create -output main.o main_x86 main_arm64

多架構與多架構無法直接鏈結到一起,需要指定架構,分別鏈結好了,再合成到一起

由於預設是本機架構 x86_64,所以沒能從中找到對應的符號,指定 arm64 架構看看:

main.o arm64 -o main

可以看到多架構的 macho 會被分拆,同樣試試 arm64:

main.o share_arm64 -o main

通常會預設以本機系統架構進行融合,如果編譯器或鏈結器無法分析出需要融合的架構,需要指定 -target / -arch 來輔助。

資訊如水,架構如渠

古人云 水到,則渠成。說的是,水流過的地方,自然形成了渠道。比喻時機到了,事情自然就成了。人類歷史基本都在和水打交道,水路基本是古代核心的運輸渠道,農業時代的灌溉系統,水利電站 不勝列舉。甚至可以說,水孕育了人類的文明。在改變世界之前,先要認識世界。構建渠道之前,需要了解水的屬性,才能真正地為人所用...

mac os中多版本php切換

1.新增tab 1 brew tap josegonzalez php 2.安裝多版本的php 1 2 brewinstallphp53 brewinstallphp54 3.製作切換的指令碼 需要把php switch新增到path中,可以在.bash profile中新增,這樣開機就能夠自動載入...

多租戶mysql架構 關於多租戶架構

多租戶架構能使oracle資料庫可用作多租戶容器資料庫 cdb 乙個多租戶容器資料庫 cdb 包含0個或多個自定義的可插拔資料庫 pdbs pdb是乙個包含schemas,schema objects,nonschema objects的集合。在12c之前,所有的oracle資料庫都是非cdb。1....