说明
-
C/CPP 程序从源文件到可执行文件需要经历 4 个阶段完成。
- 预处理: 由
.cpp
到.i
的过程,过程一般不可见。主要是处理像#include、#define、#if、#else、#line 等指令。 - 编译: 由
.i
到.a
的过程,注意此处的 .a 后缀不代表静态库。 - 汇编: 由
.a
到.o
的过程。 - 链接: 由
.o
到.exe
的过程,生成了可执行文件。如果依赖于其他的运行库,也是在这一步建立连接的。
- 预处理: 由
-
有时候也会在把这 4 步统称作 编译。
-
有时候也会把 预处理+编译+汇编 的过程统称作编译 ,进而把整个过程分为编译+链接。
1. 预处理
-
首先创建一个
CppTest.cpp
文件,代码如下#include <iostream> using namespace std; int main() { cout<<"Testing Compiling"<<endl; int i; cin>>i; return 0; }
-
CMD 进入该目录,执行
F:\CGAL教程\Cpp基础> g++ -o CppTest.i -E CppTest.cpp
-E 选项可以保留预处理器的输出文件。因为在正常的情况下,G++ 不会保留预处理阶段的输出文件,也即.i文件。-E 选项指示 GCC 在预处理完毕之后即可停止。
-o 选项指定输出文件。 -
可以看到同目录下生成了新的
CppTest.i
,这个文件里的内容就是预处理后的CPP,大致如下。# 1 "CppTest.cpp" # 1 "<built-in>" # 1 "<command-line>" # 1 "CppTest.cpp" # 1 "C:/Qt/Qt5.14.0/Tools/mingw730_64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/iostream" 1 3 # 36 "C:/Qt/Qt5.14.0/Tools/mingw730_64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/iostream" 3 ··· # 2 "CppTest.cpp" 2 # 2 "CppTest.cpp" using namespace std; int main() { cout<<"Testing Compiling"<<endl; int i; cin>>i; return 0; }
2. 编译
- CMD 进入该目录,执行
-S 选项可以生成汇编文件。因为在通常情况下,G++ 把汇编语言输出存储到临时文件中,并且在汇编器执行完后立刻删除它们。但是可以使用-S选项,让编译程序在生成汇编语言输出之后立刻停止。F:\CGAL教程\Cpp基础> g++ -o CppTest.s -S CppTest.i
汇编语言是非常有用的,因为它将不同高级语言的不同编译器提供了通用的输出语言。 - 可以看到同目录下生成了新汇编文件
CppTest.s
,这个文件里的内容大致如下。.file "CppTest.cpp" .text .section .rdata,"dr" _ZStL19piecewise_construct: .space 1 .lcomm _ZStL8__ioinit,1,1 .def __main; .scl 2; .type 32; .endef .LC0: .ascii "Testing Compiling\0" .text .globl main .def main; .scl 2; .type 32; .endef .seh_proc main main: .LFB1549: pushq %rbp .seh_pushreg %rbp ···
3. 汇编
- CMD 进入该目录,执行
-c 生成名为source_file.o的目标文件。F:\CGAL教程\Cpp基础> g++ -o CppTest.o -c CppTest.cpp
- 可以看到同目录下生成了新目标文件
CppTest.o
,是二进制文件。
4. 链接
- 如果需要引用了其他库函数,是在这一步完成的。
- CMD 进入该目录,执行
-c 生成名为source_file.o的目标文件。F:\CGAL教程\Cpp基础> g++ -o CppTest CppTest.o
- 可以看到同目录下生成了新可执行文件
CppTest.exe
。
.
.
.
.
.
.
桃花仙人种桃树,又摘桃花换酒钱_