習慣使用了具備強大功能的整合工具– IDE(e.g Visual Studio),執行source code(e.g .cpp)僅需點下 建置(Build)
然後▷
,有時是只點下▷
,就完成了許多希望程式去做的事,很方便,但也因此缺乏對於幕後工程的認識。離開了IDE,使用terminal則可以透過下面的指令完成同樣的事情:
1 2 3
| $ g++ main.cpp -o main.out $ ./main.out helloworld
|
編譯透過以上一行簡單的指令,將我們寫的source code編譯成執行檔(在Linux上是.out,在Windows上則是.exe),然後可以直接被電腦執行。簡單的一句指令,過程則可以分為四個步驟,分別是1. 前編譯Preprocessing, 2. 編譯compilation, 3. 組譯assembly 以及 4. 連結linking。

以下用一支比helloworld更簡單的程式來呈現:
main.cpp
1 2 3 4
| #define N 81 int main(){ return 0; }
|
(以下的程式皆是透過vim進行解碼)
Preprocessing: .cpp -> .ii,
處理#,刪除註解(//, /**/),加以編號。
1 2 3 4 5 6 7 8 9 10 11
| $ g++ -E main.cpp -o main.ii main.ii: # 1 "main.cpp" # 1 "<built-in>" # 1 "<command-line>" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 1 "<command-line>" 2 # 1 "main.cpp" int main(){ return 0; }
|
Compilation: .ii -> .s,
將 .ii檔進行分析以及最佳化,將高階語言翻譯成assembly code。屬於程式建構過程最複雜的環節。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| main.s $ g++ -S main.ii -o main.s .file "main.cpp" .text .globl main .type main, @function main: .LFB0: .cfi_startproc endbr64 pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl $0, %eax popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size main, .-main .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0" .section .note.GNU-stack,"",@progbits .section .note.gnu.property,"a" .align 8 .long 1f - 0f .long 4f - 1f .long 5 0: .string "GNU" 1: .align 8 .long 0xc0000002 .long 3f - 2f 2: .long 0x3 3: .align 8 4:
|
Assembly: .s -> .o,
將assembly code一一翻譯成machine code。
1 2 3 4 5 6
| $ g++ -c main.s -o main.o ^?ELF^B^A^A^@^@^@^@^@^@^@^@^@^A^@>^@^A^@^@ ^@^@^@^@^@^@^@^@^@^@X^B^@^@^@^@^@^@^@^@^@^ @@^@^@^@^@^@@^@^L^@^K^@ó^O^^úUHå¸^@^@^ @^@]Ã^@GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0^@^@^@^@^@^@^D^@^......
|
Linking: .o + static library -> .out,
將.o檔連結static library(一大堆.o檔)形成.out檔。
1 2 3 4 5
| $ ld -static (一大堆.o檔) ^?ELF^B^A^A^@^@^@^@^C^@>^@^A^@^@^@À^P^@^@^ ^@^@@^@^@^@^@^@^@^@è;^@^@^@^@^@^@^@^@^@^@@ ^@8^@^M^@@^@^_^@^^^@^F^@^@^@^D^@^@^@@^@^@^ @^@^@^@^@@^@^@^@^@^@^@^@@^......
|