1,基本语法
-o filename 输出文件
-c 只编译或者汇编,但不链接,产生目标文件(一般用file.o)
-E 预处理后即停止
-S 编译后即停止,不进行汇编,输出汇编文件
-Ldir 在`-l'选项的搜索路径列表中添加dir目录.
-llibrary 连接名为library的库文件
-static 阻止连接共享库
-shared 生成一个共享目标文件(即.so)
-Idir 在头文件的搜索路径列表中添加dir 目录
-fpic 生成位置无关目标码.适用于共享库
-fPIC 生成位置无关目标码.适用于共享库
2,编译流程
· 预处理(Preprocessing)
· 编译(Compilation)
· 汇编(Assembly)
· 链接(Linking)
2.1预处理(Preprocessing)
预处理的过程主要处理包括以下过程:
-
将所有的#define删除,并且展开所有的宏定义
-
处理所有的条件预编译指令,比如#if #ifdef #elif #else #endif等
-
处理#include 预编译指令,将被包含的文件插入到该预编译指令的位置。
-
删除所有注释“//”和”/* */”.
-
添加行号和文件标识,以便编译时产生调试用的行号及编译错误警告行号。
-
保留所有的#pragma编译器指令,因为编译器需要使用它们
通常使用以下命令来进行预处理:
gcc -E hello.c -o hello.i
直接cat hello.i 你就可以看到预处理后的代码
2.2编译(Compilation)
编译过程就是把预处理完的文件进行一系列的词法分析,语法分析,语义分析及优化后生成相应的汇编代码。
$gcc –S hello.i –o hello.s
2.3汇编(Assembly)
汇编器是将汇编代码转变成机器可以执行的命令,每一个汇编语句几乎都对应一条机器指令。汇编相对于编译过程比较简单,根据汇编指令和机器指令的对照表一一翻译即可。
$ gcc –c hello.c –o hello.o #一般用hello.s
由于hello.o的内容为机器码,不能以普通文本形式的查看(vi 打开看到的是乱码)
2.4链接(Linking)
通过调用链接器ld来链接程序运行需要的一大堆目标文件,以及所依赖的其它库文件,最后生成可执行文件。
ld -static crt1.o crti.o crtbeginT.o hello.o -start-group -lgcc -lgcc_eh -lc-end-group crtend.o crtn.o
链接分为静态链接和动态链接。
静态链接是指在编译阶段直接把静态库加入到可执行文件中去,这样可执行文件会比较大。
而动态链接则是指链接阶段仅仅只加入一些描述信息,而程序执行时再从系统中把相应动态库加载到内存中去。
静态链接的大致过程如下图所示:
3,查看
$ ldd hello
libc.so.6 => /lib64/libc.so.6 (0x0000003848200000)
/lib64/ld-linux-x86-64.so.2 (0x0000003847e00000)
.a静态库 (archive)
.C
.c
.cc
.cp
.cpp
.cxx
.c++ 以上为C/C++源代码(需要编译预处理)
.hC或者C++源代码头文件
.iiC++源代码(不需编译预处理)
.o对象文件
.s汇编语言代码
.so动态库