在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            博客專欄

            EEPW首頁 > 博客 > 靜態(tài)鏈接全過程

            靜態(tài)鏈接全過程

            發(fā)布人:電子禪石 時間:2021-04-13 來源:工程師 發(fā)布文章
            寫在前面

            本文大部分內(nèi)容翻譯自Library order in static linking

            靜態(tài)鏈接順序很重要

            在gcc編譯時,靜態(tài)鏈接庫鏈接順序會影響鏈接結(jié)果和行為。
            舉例如下:

            $ cat simplefunc.c
            int func(int i) {
                return i + 21;
            }
            
            $ cat simplemain.c
            int func(int);
            
            int main(int argc, const char* argv[]) {
                return func(argc);
            }
            
            $ gcc -c simplefunc.c
            $ gcc -c simplemain.c
            $ gcc simplefunc.o simplemain.o
            $ ./a.out ; echo $?
            22
            
            $ gcc simplemain.o simplefunc.o
            $ ./a.out ; echo $?
            22123456789101112131415161718192021

            對于object文件,鏈接順序是沒有影響的,gcc會將所有的目標(biāo)文件加入到鏈接過程中。

            $ ar r libsimplefunc.a simplefunc.o
            $ ranlib libsimplefunc.a
            $ gcc  simplemain.o -L. -lsimplefunc
            $ ./a.out ; echo $?
            22
            
            $ gcc  -L. -lsimplefunc  simplemain.o
            simplemain.o: In function 'main':
            simplemain.c:(.text+0x15): undefined reference to 'func'
            collect2: ld returned 1 exit status12345678910

            當(dāng)鏈接器遇到libsimplefunc.a時,它仍然沒有看到simplemain.o,這意味著func尚未出現(xiàn)在未定義的列表中。當(dāng)鏈接器查看庫時,它會看到導(dǎo)出func的simplefunc.o。但由于它不需要func,因此該目標(biāo)文件不包含在鏈接中。當(dāng)鏈接器確實到達(dá)simplemain.o并且看到func確實是必需的時,它被添加到未定義的列表中(因為它不在導(dǎo)出的列表中)。鏈接器然后到達(dá)鏈接的末尾并且func仍未定義。

            請注意在先前的鏈接順序中不會發(fā)生這種情況 - 因為simplemain.o首先出現(xiàn),func在鏈接器看到庫之前位于未定義的列表中,因此導(dǎo)出它的目標(biāo)文件確實包含在內(nèi)。

            從上面的例子中可以得出:靜態(tài)鏈接時,鏈接庫順序會影響鏈接結(jié)果。如果對象或庫AA需要來自庫BB的符號,則AA應(yīng)該在鏈接器的命令行調(diào)用中位于庫BB 之前。
            下面一節(jié),我們將從原理上來了解鏈接庫的順序是如何影響鏈接結(jié)果的!

            靜態(tài)鏈接過程

            程序靜態(tài)鏈接的過程如下,舉例說明(翻譯Library order in static linking的The linking process一節(jié))

            $ gcc main.o -L/some/lib/dir -lfoo -lbar -lbaz1

            注:庫指library,對象指object,此處要注意區(qū)分。
            1 當(dāng)鏈接時,鏈接器維護(hù)兩個列表:
            1.1 到目前為止遇到的所有目標(biāo)文件(object)和庫(library)導(dǎo)出的符號列表,記做exports(導(dǎo)出的符號)
            1.2 遇到的目標(biāo)文件(object)和庫(library)請求導(dǎo)入但尚未找到的未定義符號列表,即undefined reference,記做imports(待導(dǎo)入的符號)

            2 當(dāng)鏈接器遇到新的目標(biāo)文件(object)時,
            2.1 它導(dǎo)出的符號會被添加到上面提到的導(dǎo)出符號列表中。 如果任何符號位于未定義列表中,則會從那里刪除它,因為現(xiàn)在已找到它。 如果導(dǎo)出列表中已有任何符號,則會出現(xiàn)“多重定義”錯誤:兩個不同的對象導(dǎo)出相同的符號,鏈接器會報錯
            2.2 它導(dǎo)入的符號被添加到未定義符號列表中,除非它們可以在導(dǎo)出符號列表exports中找到。

            3 當(dāng)鏈接器遇到新時,事情會更有趣。 鏈接器遍歷庫中的所有目標(biāo)文件(object),庫是object打包成的一個整體。 對于每一個,它首先查看它導(dǎo)出的符號
            3.1 如果它導(dǎo)出的任何符號位于未定義列表中,則該對象將添加到鏈接中,并執(zhí)行下一步。 否則,將跳過下一步。
            3.2 如果目標(biāo)文件(object)已添加到鏈接中,則按上述方式對其進(jìn)行處理 - 未定義和導(dǎo)出的符號將添加到符號表中。
            3.3 如果庫中的任何目標(biāo)文件(object)已包含在鏈接中,則會再次重新掃描整個庫,因為這個目標(biāo)文件可能依賴庫中的其他目標(biāo)文件。

            鏈接器完成后,它會查看符號表。 如果任何符號保留在未定義的列表中,鏈接器將拋出“未定義的引用”錯誤。
            在鏈接器查看庫之后,它將不會再次查看它,即鏈接器只查看庫一次。 即使它導(dǎo)出一些后來的庫可能需要的符號。 鏈接器返回重新掃描對象的唯一時間它已經(jīng)在單個庫中發(fā)生 - 如上所述,一旦某個庫中的對象被帶入鏈接,同一庫中的所有其他對象將被重新掃描。 傳遞給鏈接器的標(biāo)志可以調(diào)整這個過程 - 再次,我們稍后會看到一些例子。
            另外,檢查庫時,如果不提供符號表所需的符號,則可以將其中的目標(biāo)文件排除在鏈接之外。 這是靜態(tài)鏈接的一個非常重要的特性。 我之前提到過的C庫大量使用了這個功能,主要是將自身分解為每個函數(shù)的一個對象。 因此,例如,如果您的代碼使用的唯一C標(biāo)準(zhǔn)庫函數(shù)是strlen,則只有strlen.o將從libc.a進(jìn)入鏈接 - 并且您的可執(zhí)行文件將非常小。

            建議
            1. 在項目開發(fā)過層中盡量讓lib是垂直關(guān)系,避免循環(huán)依賴,越是底層的庫,越是往后面寫

            2. 若存在循環(huán)依賴的情況,可用以下方法解決

              Xlinker "-("-la -lb  -lc"-)" OR--start-group -la -lb lc -Wl,--end-group
              • 1

              • 2

              • 3

            參考文檔

            https://blog.csdn.net/caikunbob/article/details/85550000

            *博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權(quán)請聯(lián)系工作人員刪除。



            關(guān)鍵詞:

            相關(guān)推薦

            技術(shù)專區(qū)

            關(guān)閉