該系列完整的文章目錄:程序員
在介紹本章的主題以前,咱們先來看幾個問題:segmentfault
問題一瀏覽器
寫C/C++的同窗應該常常遇到這樣的一個Error:服務器
`undefined reference to ABC`
在遇到這樣的問題時你知道這背後到底哪裏出問題了嗎? 你一般都能順利解決相似問題嗎?微信
問題二網絡
做爲世界上最大的同性交友網站GitHub,裏面有不少很棒的項目,通常咱們或者直接下載其發佈版(release version),或者下載源碼本身編譯,不論是直接下載發佈版仍是本身編譯,最終都會獲得一個(或幾個)以.so或者.a爲結尾的文件(Windows下爲DLL文件或者lib文件),這時你知道該怎麼把這些.so或者.a文件引入你本身的項目嗎?固然若是你去搜索一下也能獲得答案,可是你知道這些答案背後的原理嗎?學習
問題三
你的同窗、同事在工做學習中可能不時就會說起到靜態連接庫動態連接庫靜態連接動態連接,每次聽到這些詞彙的時候在你腦海裏,A)對此有很清晰的認知;B)一頭霧水不知道他們在說些什麼,你屬於A仍是B?網站
若是你還不能很好的解決上面前兩個問題且對於問題三屬於B,那麼接下來你就要好好看這篇文章啦,解決這幾個問題的關鍵就是這篇文章要介紹的連接器(Linker),雖然現代的集成開發環境IDE好比Visual Studio已經對程序員屏蔽了大部分連接器的工做,但理解連接器將極大提升你對工程的駕馭能力,也許你如今還不是很清楚,讀完這篇文章你就能明白啦。spa
讓咱們引用維基百科中對連接器的定義:翻譯
"a linker or link editor is a computer utility program that takes one or more object files generated by a compiler and combines them into a single executable file, library file, or another 'object' file."
若是你看不太懂沒有關係,我來翻譯一下,連接器是一個將編譯器產生的目標文件打包成可執行文件或者庫文件或者目標文件的程序。這個翻譯比較拗口,不太好理解,這句話的意思具體以下:
首先是連接器的本質,連接器本質上也是一個程序,本質上和咱們常用的普通程序沒什麼不一樣。
其次是連接器的輸入,咱們常用的程序好比播放器,其輸入是一個MP4文件,而連接器的輸入是編譯器編譯好的目標文件(object file,若是你不理解什麼是目標文件,請參考以前的文章《不簡單的hello world之C標準庫》)。
最後是連接器的輸出,連接器在將目標文件打包處理後,生成或者可執行文件,或者庫,或者目標文件。
從這個定義中可以看出,連接器的做用有點相似於咱們常用的壓縮軟WinRAR(Linux下是tar),壓縮軟件將一堆文件打包壓縮成一個壓縮文件,而連接器和壓縮軟件的區別在於連接器是將多個目標文件打包成一個文件而不進行壓縮。那麼連接器究竟是如何工做的呢,咱們接着往下看。
連接器可操做的最小元素是一個簡單的目標文件,一般咱們寫的.c源文件編譯後就生成了對應的目標文件,咱們寫的實現文件好比list.c編譯後就生成了對應的目標文件list.o(Windows下爲list.obj),這個list.o就是連接器能夠操做的最小元素。咱們見到的全部應用程序,小到本身實現的hello world程序,大到複雜的好比瀏覽器,網絡服務器等,都是連接器將一個個所須要用到的目標文件聚集起來最終造成了很是複雜的應用程序(Windows下是咱們常見的EXE文件,Linux下爲ELF文件)。
咱們能夠把最終的應用程序想象成一座房子,構建房子的最基本的原材料就是磚,房子中各個模塊像牆面,地面,屋頂等都是由一塊塊磚構築成的。而這裏的目標文件就比如構建房子時最基本的磚。房子的各個模塊就比如咱們是用的靜態庫,動態庫。不管多麼複雜龐大的應用程序,對於連接器來講最基本的構建材料都是目標文件。連接器能夠將目標文件連接器成爲各類庫以方便使用,而後連接器將目標文件以及程序依賴的各類庫再次連接從而造成最終的可執行文件。
咱們具體看一下連接器是如何工做的。
接下來的內容我會在如下幾篇文章當中一一介紹:
完全理解連接器:二,符號決議
完全理解連接器:三,庫與可執行文件
完全理解連接器:四,重定位
若是你喜歡這一系列的文章,也歡迎關注個人微信公共帳號,碼農的荒島求生,獲取更多內容。