Build是將源代碼轉換為可執行文件的過程,在C/C++中,Build過程大體上分為三步:
- 預處理(Preprocessing)
- 編譯(Compiling)
- 鏈接(Linking)
在build過程中,只有cpp文件會build,h文件會在預處理(第一步)中整合到cpp里,就是直接把h的文本內容嵌入到cpp的上方,所以編譯的時候是只有cpp沒有h 的。
整個build過程示意圖如下:
1. 預處理
cpp文件首先預處理變為translation unit,translation unit仍然是文本代碼文件,它是傳入編譯器的基本單元,把cpp和h整合到了一起,并且去掉不必要的空格 / 換行之類的。
官方定義如下:
- A translation unit is the basic unit of compilation in C++. It consists of the contents of a single source file, plus the contents of any header files directly or indirectly included by it, minus those lines that were ignored using conditional preprocessing statements.
- A single translation unit can be compiled into an object file, library, or executable program.
- The notion of a translation unit is most often mentioned in the contexts of the One Definition Rule, and templates.
2. 編譯
translation unit傳入編譯器(compiler)之后會被編譯成obj文件(二進制)。
即:高級語言->匯編語言->機器語言(二進制)
一般而言,生成的都是obj,但如果你想寫一個第三方庫文件,那么編譯器會對應的生成lib(靜態鏈接庫)或者dll(動態鏈接庫)文件。
每一個cpp生成一個translation unit,然后編譯生成一個obj,所以cpp與obj是一一對應的,每一個cpp都會獨立編譯出來一個obj文件。
3.鏈接
如果不依賴動態鏈接庫或靜態鏈接庫,鏈接就是把所有obj鏈接;如果還依賴外部庫,鏈接還包括lib文件。
注意:這里不包括dll文件,因為dll文件是在運行時才鏈接進來(其實也不應該叫鏈接,總之就是運行時才會加載進來,不會在鏈接生成exe的時候進來)
動態鏈接庫一般是游戲驅動之類的,比如openGL.dll,d3d9.dll,d3d11.dll等。
大家玩游戲的時候可能會遇到無法運行,報錯:缺少xxx.dll文件,就說明你游戲驅動沒有安裝,一般安裝上驅動就會解決這個問題,原因就是在這里。
看到這大家可能會有疑問:為什么要使用動態鏈接庫DLL?
1. 減小可執行文件exe的大小
DLL技術的產生有很大一部分原因是為了減小可執行文件的大小。當操作系統進入Windows時代后,其大小已經達到幾十兆乃至幾百兆。試想如果還是使用DOS時代的單執行文件體系的話一個可執行文件的大小可能將達到數十兆,這是大家都不能接受的。解決的方法就是采用動態鏈接技術將一個大的可執行文件分割成許多小的可執行程序。
2. 實現資源共享
這里指的資源共享包括很多方面,最多的是內存共享、代碼共享等等。早期的程序員經常碰到這樣的事情,在不同的編程任務中編寫同樣的代碼。這種方法顯然浪費了很多時間,為了解決這個問題人們編寫了各種各樣的庫。但由于編程語言和環境的不同這些庫一般都不能通用,而且用戶在運行程序時還需要這些庫才行,極不方便。DLL的出現就像制定了一個標準一樣,使這些庫有了統一的規范。這樣一來,用不同編程語言的程序員可以方便的使用用別的編程語言編寫的DLL。另外,DLL還有一個突出的特點就是在內存中只裝載一次,這一點可以節省有限的內存,而且可以同時為多個進程服務。
3. 便于維護和升級
細心的朋友可能發現有一些DLL文件是有版本說明的。(查看DLL文件的屬性可以看到,但不是每一個DLL文件都有)這是為了便于維護和升級。舉個例子吧,早期的Win95中有一個BUG那就是在閏年不能正確顯示2月29日這一天。后來,Microsoft發布了一個補丁程序糾正了這個BUG。值得一提的是,我們并沒有重裝Win95,而是用新版本的DLL代替了舊版本的DLL。另一個常見的例子是驅動程序的升級。例如,著名的DirectX就多次升級,現在已經發展到了6.0版了。更妙的是,當我們試圖安裝較低版本的DLL時,系統會給我們提示,避免人為的操作錯誤。例如我們升級某硬件的驅動程序時,經常碰到Windows提示我們當前安裝的驅動程序比原來的驅動程序舊。
4. 比較安全
這里說的安全也包括很多方面。比如,DLL文件遭受病毒的侵害機率要比普通的EXE文件低很多。另外,由于是動態鏈接的,這給一些從事破壞工作的“高手”們多少帶來了一些反匯編的困難。
關于鏈接的順序,obj的不清楚(好像是順序無關的,那就是按照排列順序);外部庫的連接順序取決于VS項目鏈接配置里的項目屬性-->鏈接器--> 輸入-->附加依賴項里的順序。