<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何持續(xù)的自我提升

          共 4104字,需瀏覽 9分鐘

           ·

          2021-01-07 11:39

            最近經(jīng)常遇到有些朋友問題我如何學(xué)習(xí)編譯器等各類底層的知識。

            這些問題的背后是很多程序員對自我提升的強烈需求。

            今天,筆者會通過分享“2020年最后一天的學(xué)習(xí)完整記錄”的方式解答這個問題。

            注意:本文是分享自我提升技巧,所以遇到不懂的技術(shù)名詞,可以直接跳過。

            一、初識

            初識是一個被灌輸知識的過程。

            當(dāng)我們看博客或者書籍時,都會遇到一些新知識。這就是初識

            今天,筆者從 百度App Objective-C/Swift 組件化混編之路(二)- 工程化 時,就被灌輸了一個”新知識“:module 會供鏈接器使用 。

            下面截取部分原文:

            1.2 Module 化 1.2.1 基本概念

            • module:是一個編譯單元,或構(gòu)建產(chǎn)物,對一個軟件庫的結(jié)構(gòu)化替代封裝,供鏈接器使用(更多介紹請查閱 Clang-Module:https://clang.llvm.org/docs/Modules.html#introduction)

            二、思考

            思考 是一個主動消化知識的過程。

            思考 的方式有很多:

            • 新知識是否和已有的知識發(fā)生了沖突?
            • 新知識可以和哪些知識串聯(lián)起來?
            • ....

            當(dāng)我看到上面的”新知識“時,就會想:

            • ”module 是如何被鏈接器使用呢?“
            • ”我也看過很多相關(guān)資料,為什么之前看到的資料都沒有提到鏈接器呢?“

            三、探索

            探索 是一個手動進行研究的過程。

            探索 過程非常依賴我們的思考能力和記憶能力。

            下面是筆者對 module 的一些思考:

            • 我具備多少與 module 相關(guān)的知識
            • 可以通過哪些搜索引擎技巧更快的搜索到與 module 相關(guān)的知識
            • 我們是否有方案驗證 module 與 鏈接器 的關(guān)系
            • ...

            每一次思考都需要我們把記憶能力充分調(diào)用:

            • 回憶與 module 相關(guān)的知識
            • 回憶搜索引擎技巧
            • 回憶如何通過 Xcode 創(chuàng)建工程、動態(tài)庫
            • 回憶 APP 構(gòu)建的每一步的命令
            • ...

            通過上面的初步思考,我決定通過創(chuàng)建 Demo 的方式對 module 會供鏈接器使用 進行驗證。

            準(zhǔn)備 Demo工程

            image-15402758

            Demo 工程會有一個名為 Host 的 APP,同時該 App 會依賴名為 ?FrameW 的動態(tài)庫和其它系統(tǒng)庫。

            項目的整體架構(gòu)如下圖:

            構(gòu)建

            通過 xcodebuild 命令,可以對 Host 進行構(gòu)建。

            如下,紅框部分是 Xcode 執(zhí)行 鏈接 Host 時,所調(diào)用的命令:

            image-20521724

            通過仔細分析上面的完整 命令 信息,我們沒有發(fā)現(xiàn)與 module 明顯相關(guān)的參數(shù),所以,我們可以大膽猜測:?module 與鏈接器沒有關(guān)系。

            調(diào)試模式

            考慮到編譯器可能通過其它方式進行了信息傳遞,所以,我們通過給上述命令添加參數(shù) -v 的方式進行調(diào)試。

            image-20917926

            很遺憾,新增參數(shù) -v 后,仍然沒有得到有效的信息。但是,我們得到了一個新的知識 ?clang 會調(diào)用 ld 命令執(zhí)行鏈接任務(wù)。

            調(diào)試鏈接過程

            接著,我們再次嘗試對 ld 命令添加參數(shù) -v -t 的方式進行調(diào)試。

            這次的信息量十足:

            • 鏈接依賴的 .o 路徑被完整的打印出來了
            • 鏈接依賴的 FrameW 路徑被打印出來了
            • 鏈接依賴的系統(tǒng)庫路徑被打印出來了
            image-21201007

            module 文件探究

            現(xiàn)在局面很清晰了,ldFrameW 的交互是通過上面日志中的 FrameW.framework/FrameW 文件完成的。如果我們能夠證明 FrameW.framework/FrameW ?文件與 module 沒有關(guān)系,就可以證明 ? ”module 與鏈接器沒有關(guān)系“。

            下面,我們將依次分析 ?module 文件與 FrameW.framework/FrameW ?文件,并將兩者對比。

            如果對某些細節(jié)比較好奇,可以在公眾號底部留言,我們后續(xù)再分享 module 內(nèi)幕相關(guān)的知識。

            module 文件特征

            首先,我們進行編譯任務(wù)時,會發(fā)現(xiàn)有一個名為 -fmodules-cache-path 的參數(shù),該參數(shù)的值是一個路徑ModuleCache

            ?-fmodules-cache-path=/var/folders/4j/jqzrrjzn0nvgm4pyxrqddxnmm530jm/C/org.llvm.clang.xxxx/ModuleCache
            • 通過 cd 命令切到該文件夾
            • 通過 find 命令配合 grep 找到 FrameW-xxx.pcm
            • 通過 file 命令,得知該文件是 Mach-O 文件
            • 通過 otool -l grep sort,我們發(fā)現(xiàn)該文件最大的一個 section 體積是 0x000000000000d318
            • 通過 0x000000000000d318 配合 otool -lgrep -B 3 ,我們知道它屬于 ?__CLANG __clangast 部分
            • 通過 segedit 命令將該部分導(dǎo)出到單獨文件
            • 通過 file ,我們了解到該文件屬于 data
            • 通過 xxdhead 命令,我們可以得到 magic numberCPCH
            image-24230541
            • 通過 CPCHllvm 源碼,我們可以判斷這是 ?AST/PCH file magic number
            image-30138062

            另外,結(jié)合 llvm 源碼的 llvm::Error GlobalModuleIndexBuilder::loadModuleFile 內(nèi)部邏輯,我們可以確認這個就是 動態(tài)庫module 進行編譯后的產(chǎn)物

            image-30220599

            通常上面的思考,我們可以得到以下結(jié)論:module 通常會被編譯為單獨的 mach-o 文件,該文件主要負責(zé)在 section:__CLANG __clangast 存儲編譯后的 ast 文件。

            動態(tài)庫的特征

            ld 鏈接的動態(tài)庫 FrameW.framework/FrameWMach-O 64-bit dynamically linked shared library arm64 文件

            通過上面兩種文件的特征,我們可以證明 module 與鏈接器沒有關(guān)系。

            考慮到很多情況,我們沒法找到各種命令行工具進行分析,所以,下面介紹一份搜索引擎版本的探索流程

            • 通過搜索引擎查找 “Xcode 教程”

            • 通過 Xcode 教程了解構(gòu)建的完整步驟,并觀察其中的鏈接環(huán)節(jié)

            • 通過 Xcode 的鏈接環(huán)節(jié),我們可以發(fā)現(xiàn)真正執(zhí)行鏈接的二進制文件是 ld

            • 通過搜索引擎查找“如何通過二進制文件找到對應(yīng)的源碼”

            • 嘗試編譯鏈接器(遇到問題,可以通過網(wǎng)絡(luò)引擎搜索解決)

            • 運行鏈接器,并分析鏈接器的源碼執(zhí)行路徑

            注意:

            1. Xcode 的構(gòu)建流程,筆者在上次分享的 llvm 編譯器高級用法:第三方庫插樁 有過簡單介紹,后面會有更加詳細的文章分享動態(tài)庫、靜態(tài)庫、APP 的構(gòu)建流程。

            2. 通過二進制文件獲取源碼,筆者在上次分享的 iOS 崩潰排查技巧:如何獲取系統(tǒng)庫源碼,后面會有一篇升級版本的獲取系統(tǒng)庫源碼的方案。

            四、總結(jié)和超越

            總結(jié) 是對整個學(xué)習(xí)成果的強化過程。

            通過 ”初識“-”思考“-”探索” 三部曲,我們會學(xué)到很多知識。

            不幸的是,人類的大腦很容易遺忘知識。所以,我們需要一些技巧將記憶強化。

            總結(jié) 的方法有很多種,其中最高效的方案就是 費曼技巧

            費曼技巧 是一種「以教為學(xué)」的學(xué)習(xí)方式,通過直白淺顯的語言把復(fù)雜深奧的問題和知識傳授給 小孩子 的方式進行學(xué)習(xí)。

            但是,費曼技巧 需要一個傾聽者才會有很好的學(xué)習(xí)效果。所以,我個人更加推薦將 學(xué)習(xí)筆記公開。

            當(dāng)我們選擇將筆記發(fā)到公眾號或者個人博客時,就會強迫自己將整篇文章的知識理順,避免錯誤、遺漏。同時,也會有更多的同行幫我們 指出問題。

            請記住,只有當(dāng)我們把相關(guān)的知識點完整串聯(lián)和記憶后,我們才能真正 超越自己,才能真正的 自我提升

            本文總結(jié)

            本文通過一次完整的學(xué)習(xí)經(jīng)歷分享了 “如何自我學(xué)習(xí)/提升”的問題。

            整體的思路如下:

            • 初識:被灌輸知識的過程。
            • 思考:主動消化知識的過程。
            • 探索:手動進行研究的過程
            • 總結(jié)和超越:完成自我提升的過程

            后記

            除了本文分享的知識外, 百度App Objective-C/Swift 組件化混編之路(二)- 工程化 還有很多的知識或者疑惑點值得研究,下面簡單的列舉幾個,歡迎讀者進行補充。

            • .tbd 是文本類型,為什么原作者會認為 dynamic_library 的擴展名是 .tbd

              • dynamic_library:動態(tài)庫,Xcode 7 之前擴展名為 .dylib, Xcode 7 后是 .tbd ;目前官方環(huán)境并不允許為 iOS 平臺添加這種類型。
            • swiftmodule 的依賴會傳遞嗎?有沒有優(yōu)雅的方式解決?

              4.7 小知識:swiftmodule 的傳遞依賴性

              已知:有組件 A 依賴組件 B,組件 B 依賴組件 C 在 Objective-C 中,B 對外暴露的頭文件中引用了 C 的公開頭文件,我們叫組件 B 傳遞依賴 C,結(jié)果就是編譯組件 A 時必須同時能找到組件 B 和組件 C 的頭文件,否則編譯失敗。

              然而 Swift 并沒有公開頭文件一說,只要組件 B import C,導(dǎo)致 swiftmodule 中也明確標(biāo)記了 import C,當(dāng)組件 A import B 時,也同時 import C ,如果組件 A 找不到組件 C 的 module,那組件 A 將編譯失敗。

            • 下面解決報錯的方案是依據(jù)什么原理?在不依賴 Xcode 的情況下,我們該如何解決?

              6.3 App 鏈接一個 Swift 二進制時報錯?

              當(dāng)一個組件或產(chǎn)物需要鏈接其他 Swift 的產(chǎn)物時,比如 App、單測、動態(tài)庫等,需要告訴 Xcode 開啟 Swift 鏈接功能,開啟方法就是添加一個 Swift 文件,否則報錯。






            點個在看少個 bug??

            瀏覽 35
            1點贊
            評論
            1收藏
            分享

            手機掃一掃分享

            分享
            舉報
            評論
            圖片
            表情
            推薦
            1點贊
            評論
            1收藏
            分享

            手機掃一掃分享

            分享
            舉報
            <kbd id="afajh"><form id="afajh"></form></kbd>
            <strong id="afajh"><dl id="afajh"></dl></strong>
              <del id="afajh"><form id="afajh"></form></del>
                  1. <th id="afajh"><progress id="afajh"></progress></th>
                    <b id="afajh"><abbr id="afajh"></abbr></b>
                    <th id="afajh"><progress id="afajh"></progress></th>
                    AV色天堂 | 国产第一页精品先锋影音视频 | 高青黄色一片网站 | 91精品少妇高潮一区二区三区不卡 | 骚逼免费观看 |