Linux下Gcc 的编译过程
? ? ? ? ?在linux下開(kāi)發(fā)難免會(huì)用到gcc編譯。GCC(GNU Compiler Collection。GNU編譯器套裝),是由 GNU 開(kāi)發(fā)的編程語(yǔ)言編譯器。它是GNU編譯器套裝以GPL許可證所發(fā)行的自由軟件,也是 GNU計(jì)劃的關(guān)鍵部分。
使用GCC編譯程序時(shí),編譯過(guò)程能夠被細(xì)分為四個(gè)階段:
◆ 預(yù)處理(Pre-Processing)
◆ 編譯(Compiling)
◆ 匯編(Assembling)
◆ 鏈接(Linking)
1、預(yù)處理 對(duì)源碼文件里的文件包括(include)、預(yù)編譯語(yǔ)句(如宏定義define等)進(jìn)行分析,編譯選項(xiàng)為gcc -E *.c
#define DEBUG "debug"int main() {char *a = DEBUG;return 1; }經(jīng)過(guò)上面的預(yù)處理后,能夠看到DEBUG被替換成了提前定義的內(nèi)容
# 1 "hello.c" # 1 "<built-in>" # 1 "<command-line>" # 1 "hello.c"int main() {char *a = "debug";return 1; }2、編譯?調(diào)用cc1進(jìn)行編譯,使用gcc -S選項(xiàng)就能夠生成匯編代碼,這個(gè)階段依據(jù)輸入文件生成以.o為后綴的目標(biāo)文件。生成的匯編代碼例如以下:
.file "hello.c".section .rodata .LC0:.string "debug".text .globl main.type main, @function main: .LFB0:.cfi_startprocpushq %rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq %rsp, %rbp.cfi_def_cfa_register 6movq $.LC0, -8(%rbp)movl $1, %eaxleave.cfi_def_cfa 7, 8ret.cfi_endproc .LFE0:.size main, .-main.ident "GCC: (GNU) 4.4.6 20110731 (Red Hat 4.4.6-3)".section .note.GNU-stack,"",@progbits3、匯編 ?匯編過(guò)程是針對(duì)匯編語(yǔ)言的步驟,調(diào)用as進(jìn)行工作。一般來(lái)講,.S為后綴的匯編語(yǔ)言源碼文件和匯編、.s為后綴的匯編語(yǔ)言文件經(jīng)過(guò)預(yù)編譯和匯編之后都生成以.o為后綴的目標(biāo)文件。此過(guò)程生成ELF格式的目標(biāo)代碼,使用gcc -c進(jìn)行匯編
使用readelf -a hello.o能夠看到具體的elf信息
ELF Header:Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64Data: 2's complement, little endianVersion: 1 (current)OS/ABI: UNIX - System VABI Version: 0Type: REL (Relocatable file)Machine: Advanced Micro Devices X86-64Version: 0x1Entry point address: 0x0Start of program headers: 0 (bytes into file)Start of section headers: 296 (bytes into file)Flags: 0x0Size of this header: 64 (bytes)Size of program headers: 0 (bytes)Number of program headers: 0Size of section headers: 64 (bytes)Number of section headers: 13Section header string table index: 10Section Headers:[Nr] Name Type Address OffsetSize EntSize Flags Link Info Align[ 0] NULL 0000000000000000 000000000000000000000000 0000000000000000 0 0 0[ 1] .text PROGBITS 0000000000000000 000000400000000000000013 0000000000000000 AX 0 0 4[ 2] .rela.text RELA 0000000000000000 000005680000000000000018 0000000000000018 11 1 8[ 3] .data PROGBITS 0000000000000000 000000540000000000000000 0000000000000000 WA 0 0 4[ 4] .bss NOBITS 0000000000000000 000000540000000000000000 0000000000000000 WA 0 0 4[ 5] .rodata PROGBITS 0000000000000000 000000540000000000000006 0000000000000000 A 0 0 1[ 6] .comment PROGBITS 0000000000000000 0000005a000000000000002d 0000000000000001 MS 0 0 1[ 7] .note.GNU-stack PROGBITS 0000000000000000 000000870000000000000000 0000000000000000 0 0 1[ 8] .eh_frame PROGBITS 0000000000000000 000000880000000000000038 0000000000000000 A 0 0 8[ 9] .rela.eh_frame RELA 0000000000000000 000005800000000000000018 0000000000000018 11 8 8[10] .shstrtab STRTAB 0000000000000000 000000c00000000000000061 0000000000000000 0 0 1[11] .symtab SYMTAB 0000000000000000 0000046800000000000000f0 0000000000000018 12 9 8[12] .strtab STRTAB 0000000000000000 00000558000000000000000e 0000000000000000 0 0 1 Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings)I (info), L (link order), G (group), x (unknown)O (extra OS processing required) o (OS specific), p (processor specific)There are no section groups in this file.There are no program headers in this file.Relocation section '.rela.text' at offset 0x568 contains 1 entries:Offset Info Type Sym. Value Sym. Name + Addend 000000000008 00050000000b R_X86_64_32S 0000000000000000 .rodata + 0Relocation section '.rela.eh_frame' at offset 0x580 contains 1 entries:Offset Info Type Sym. Value Sym. Name + Addend 000000000020 000200000002 R_X86_64_PC32 0000000000000000 .text + 0There are no unwind sections in this file.Symbol table '.symtab' contains 10 entries:Num: Value Size Type Bind Vis Ndx Name0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS hello.c2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 3: 0000000000000000 0 SECTION LOCAL DEFAULT 3 4: 0000000000000000 0 SECTION LOCAL DEFAULT 4 5: 0000000000000000 0 SECTION LOCAL DEFAULT 5 6: 0000000000000000 0 SECTION LOCAL DEFAULT 7 7: 0000000000000000 0 SECTION LOCAL DEFAULT 8 8: 0000000000000000 0 SECTION LOCAL DEFAULT 6 9: 0000000000000000 19 FUNC GLOBAL DEFAULT 1 main
4、鏈接?鏈接過(guò)程。生成可運(yùn)行代碼。鏈接分為兩種,一種是靜態(tài)鏈接,第二種是動(dòng)態(tài)鏈接。
使用靜態(tài)鏈接的優(yōu)點(diǎn)是,依賴的動(dòng)態(tài)鏈接庫(kù)較少,對(duì)動(dòng)態(tài)鏈接庫(kù)的版本號(hào)不會(huì)非常敏感,具有較好的兼容性。缺點(diǎn)是生成的程序比較大。使用動(dòng)態(tài)鏈接的優(yōu)點(diǎn)是,生成的程序比較小,占用較少的內(nèi)存。
gcc hello.o -o hello 就能夠完畢最后的鏈接操作并生成可運(yùn)行文件,至于怎樣生成動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù),以及怎樣鏈接動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù),以后會(huì)再作介紹。
轉(zhuǎn)載于:https://www.cnblogs.com/lxjshuju/p/6928091.html
總結(jié)
以上是生活随笔為你收集整理的Linux下Gcc 的编译过程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 机器学习--逐步回归算法,线性回归的特征
- 下一篇: 3D打印设计软件 FreeCAD 入门