【Linux工具】編譯器、調(diào)式器、項目自動化構(gòu)建工具以及git的使用(1)
作者:愛寫代碼的剛子
時間:2023.6.3
本篇博客主要詳細介紹Linux中十分重要的工具:編譯器,靈活使用這些工具是Linux中一項必備技能。項目自動化構(gòu)建工具、調(diào)式器、git工具會在下一篇博客中進行介紹。
Linux編譯器-gcc/g++使用
gcc編譯C語言:
g++編譯C++:
- gcc只能編譯C語言,而g++可以編譯C語言也可以編譯C++,編譯生成的可執(zhí)行文件默認文件名都是a.out,后一個a.out會覆蓋前一個a.out(我們用gcc/g++ -o的選項重命名就不會重名且覆蓋了)
gcc的編譯過程
預處理(進行宏替換)
預處理的主要步驟:
a.去注釋
b.頭文件展開
c.條件編譯(C語言的學習中認識過,以是否定義該宏為條件進行代碼的裁剪,可以用于不同版本的軟件裁剪對應的功能)
d.宏替換
- 預處理功能主要包括宏定義,文件包含,條件編譯,去注釋等。
- 預處理指令是以#號開頭的代碼行。
- 實例: gcc –E hello.c –o hello.i
- 選項“-E”,該選項的作用是讓 gcc 在預處理結(jié)束后停止編譯過程。
- 選項“-o”是指目標文件,“.i”文件為已經(jīng)過預處理的C原始程序。
- gcc -E caogao.c -o caogao.i生成預處理文件(其中==-E的意思是:從現(xiàn)在開始進行程序的翻譯,將預處理工作做完就停止==)
【問題】:為什么能夠在windows或者Linux上進行C/C++或者其他形式的開發(fā)呢?
我們的系統(tǒng)中一定要提前或者后續(xù)安裝上C/C++開發(fā)相關的頭文件,庫文件,C/C++開發(fā)環(huán)境不僅僅指的是vs、gcc、g++,更重要的是語言本身的頭文件和庫文件(安裝vs2019、vs2022等,選擇了對應的開發(fā)包,同步也在下載C的頭文件和庫文件,所以編譯器不用#include </usr/include/stdio.h>,因為編譯器已經(jīng)知道了頭文件的默認路徑,所以直接使用#include <stdio.h>即可)
- **ls /usr/include/**查看Linux中的頭文件,/usr/include/是gcc或者g++搜索頭文件時默認的路徑
用vim打開頭文件: -
gcc -E caogao.c -o caogao.i -DDEBUG可以直接使用gcc指令來定義宏DEBUG(編譯器具有直接修改代碼的能力)
- 預處理過后還是C語言
編譯(生成匯編)
- 在這個階段中,gcc 首先要檢查代碼的規(guī)范性、是否有語法錯誤等,以確定代碼的實際要做的工作,在檢查
- 無誤后,gcc 把代碼翻譯成匯編語言。
- 用戶可以使用“-S”選項來進行查看,該選項只進行編譯而不進行匯編,生成匯編代碼。
- 實例: gcc –S hello.i –o hello.s
-
gcc -S caogao.c -o caogao.s生成對應的匯編文件(其中-S的意思是:從現(xiàn)在開始進行程序的翻譯,將編譯工作做完就停下來)
匯編(將匯編語言變成機器可識別代碼(二進制文件))
- 匯編階段是把編譯階段生成的“.s”文件轉(zhuǎn)成目標文件
- 讀者在此可使用選項“-c”就可看到匯編代碼已轉(zhuǎn)化為“.o”的二進制目標代碼了
- 實例: gcc –c hello.s –o hello.o
-
gcc -c caogao.s -o caogao.o 將匯編語言變成二進制文件(-c的意思是:從現(xiàn)在開始進行程序的翻譯,將匯編工作做完就停下來)
- 其中生成的.o文件我們稱為可重定位目標二進制文件。簡稱目標文件(.obj文件)雖然已經(jīng)是二進制,但是并不能獨立執(zhí)行,還需要經(jīng)過鏈接,有可執(zhí)行權限但是沒有可執(zhí)行能力。
由于是二進制文件,所以用vim(文本編輯器,只能識別文本)打開時會出現(xiàn)亂碼
-
od caogao.o用od(二進制查看工具)來查看二進制文件
鏈接(生成可執(zhí)行文件或庫文件)
- 在成功編譯之后,就進入了鏈接階段。
- 實例: gcc hello.o –o hello
-
gcc caogao.o -o caogao.exe進行鏈接,生成可執(zhí)行文件(將可重定位目標二進制文件,和庫進行鏈接形成可執(zhí)行程序)
函數(shù)庫
我們的C程序中,并沒有定義“printf”的函數(shù)實現(xiàn),且在預編譯中包含的“stdio.h”中也只有該函數(shù)的聲明,而
沒有定義函數(shù)的實現(xiàn),那么,是在哪里實“printf”函數(shù)的呢?
最后的答案是:系統(tǒng)把這些函數(shù)實現(xiàn)都被做到名為 libc.so.6 的庫文件中去了,在沒有特別指定時,gcc 會到系統(tǒng)默認的搜索路徑“/usr/lib”下進行查找,也就是鏈接到 libc.so.6 庫函數(shù)中去,這樣就能實現(xiàn)函數(shù)“printf”了,而這也就是鏈接的作用
C語言標準庫給我們提供方法的實現(xiàn),庫的本質(zhì)是一個文件,存在路徑
- Linux下: .so(動態(tài)庫) .a(靜態(tài)庫)
- Windows:.dll(動態(tài)庫) .lib(靜態(tài)庫)
庫也有自己的命名規(guī)則:libname .so.XXX (name是庫真正的名字)
默認機器上安裝了動態(tài)庫,默認沒有安裝靜態(tài)庫
方法的實現(xiàn)在庫中,庫其實是把.c文件(源文件),經(jīng)過一定的翻譯,然后打包——只給你提供一個文件即可,不用提供太多的源文件,也可以達到隱藏源文件的目的。
- 在編譯器使用靜態(tài)庫進行靜態(tài)鏈接的時候,會將自己的方法拷貝到目標程序中,該程序以后不用再依賴靜態(tài)庫!
- 動態(tài)庫不能缺失,一旦對應的動態(tài)庫缺失,影響的不止一個程序,可能導致很多程序都無法進行正常運行!
在Linux中,編譯形成的可執(zhí)行程序默認采用的就是動態(tài)鏈接——要求系統(tǒng)提供動態(tài)庫
【-static選項】:
-
gcc caogao.c -o caogao_static -static采用靜態(tài)鏈接進行編譯可執(zhí)行程序
采用靜態(tài)鏈接進行編譯的可執(zhí)行程序明顯比采用動態(tài)鏈接進行編譯的可執(zhí)行程序要大
靜態(tài)鏈接:
動態(tài)鏈接:
- 在Linux中,編譯形成可執(zhí)行程序,默認采用的就是動態(tài)鏈接——需要動態(tài)庫
- 在Linux系統(tǒng)中,如果要按照靜態(tài)鏈接的方式,進行形成可執(zhí)行程序,需要添加-static選項——需要靜態(tài)庫
一般Linux服務器上默認裝了動態(tài)庫而沒有裝靜態(tài)庫,無論是C還是C++。
附:如何在Linux服務器上安裝靜態(tài)庫?
安裝C語言靜態(tài)庫:
輸入指令:(sudo) yum install -y glibc-static
安裝C++靜態(tài)庫:
輸入指令:(sudo) yum install -y libstdc+±static
【問題】
- 如果我們沒有靜態(tài)庫,但是我們就是要用-static進行靜態(tài)鏈接可以嗎?【不行】
- 如果我們沒有動態(tài)庫,只有靜態(tài)庫,而且gcc能找到,可以進行編譯嗎?【可以】gcc默認優(yōu)先動態(tài)鏈接,-static的本質(zhì)是改變優(yōu)先級
- 所以可執(zhí)行程序不一定全部都是動態(tài)鏈接或者靜態(tài)鏈接,可能是混合的。但是如果我們加了-static就會默認將所有的鏈接要求全部變成靜態(tài)鏈接,-static只適配一次
file指令(直接查看程序)
動態(tài)庫vs靜態(tài)庫
- 動態(tài)庫因為是共享庫,有效地節(jié)省資源(磁盤空間,內(nèi)存空間,網(wǎng)絡空間等)【優(yōu)】動態(tài)庫一旦缺失,導致各個程序都無法運行【缺點】
- 靜態(tài)庫,不依賴庫,程序可以獨立運行【優(yōu)點】,體積大,比較消耗資源【缺點】
debug(開發(fā)版)&&release(發(fā)布版)
- 發(fā)布debug:
- 可以被追蹤調(diào)試
- 形成可執(zhí)行程序的時候,添加了debug信息(比release版本要大)
-
readelf -S caogao1_d將我們的可執(zhí)行程序按照空間布局情況和數(shù)據(jù)區(qū)以段的形式呈現(xiàn)
查看可執(zhí)行程序是不是debug版本:
-
readelf -S caogao.exe | grep -i debug過濾一下debug信息發(fā)現(xiàn)沒有
-
readelf -S caogao1_d | grep -I debug caogao1_d存在debug信息
補充:形成可執(zhí)行的程序時并不是無序的二進制,而是有自己的格式(ELF格式)文章來源:http://www.zghlxwxcb.cn/news/detail-489821.html
之后可以通過《程序員的自我修養(yǎng)》、《深入理解計算機系統(tǒng)》加深了解。文章來源地址http://www.zghlxwxcb.cn/news/detail-489821.html
到了這里,關于【Linux工具】編譯器、調(diào)式器、項目自動化構(gòu)建工具以及git的使用(1編譯器)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!