GCC 命令
目录
gcc 编译流程
GCC 编译器编译一个 C 语言程序分为四个阶段:
- 预处理阶段(Pre-Processing):将头文件内容添加到程序里面,生成 .i 文件
- 编译阶段(Compiling):将 .i 文件编译成汇编语言,生成 .s 文件
- 汇编阶段(Assembling):将 .s 文件编译成机器指令,生成目标文件 .o 文件
- 链接阶段(Linking):将各个模块的 .o 文件链接起来生成一个可执行目标文件
gcc 命令
gcc -E hello.c -o hello.i
gcc -S hello.i -o hello.s
gcc -c hello.s -o hello.o
gcc hello.o -o hello
gcc 常用选项
选项 | 意义 |
---|---|
-c | 预处理、编译、汇编指定源文件,不进行链接,生成 .o 的 obj 文件 |
-S | 预处理、编译指定源文件,生成 .s 的汇编文件 |
-E | 只进行预处理,不生成文件,需要 -o 指定或者重定向生成 .i 文件 |
-o [file1] [file2] | 将文件 file2 编译成可执行文件 file1 |
-C | 在预处理的时候, 不删除注释信息, 一般和-E使用, 有助于分析程序 |
-g | -g选项可生成能被 gdb 调试器所使用的调试信息。只有使用了该选项后生成的可执行文件,才带有程序中引用的符号表。这时 gdb 调试程序才能对该可执行程序进行调试 |
-O0 、-O1 、-O2 、-O3 | 编译器的优化选项的 4 个级别,-O0 表示没有优化, -O1为 缺省值,-O3 优化级别最高。 |
-shared | 生成共享目标文件。通常用在建立共享库时 |
-static | 禁止使用共享连接 |
-w | 不生成任何警告信息 |
-W | 生成所有警告信息 |
-fPIC | 作用于编译阶段,告诉编译器产生与位置无关的代码(Position-Independent Code) |
-l[lib] | 指定程序要链接的库,lib 是库名,数学库的文件名是 libm.so,那么 -lm 就代表链接数学库,同理 -ldl 代表链接加载动态库的 libdl.so 库 |
gcc 生成动态链接库
从源文件生成动态链接库:
gcc -fPIC -shared func.c -o libfunc.so
从目标文件生成动态链接库:
gcc -fPIC -c func.c -o func.o gcc -shared func.o -o libfunc.so
-fPIC 选项作用于编译阶段,在生成目标文件时就得使用该选项,以生成位置无关的代码。产生的代码全部使用相对地址,这样代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。
gcc 将动态链接库链接到可执行文件
如果希望将一个动态链接库链接到可执行文件,那么需要在命令行中列出动态链接库的名称,具体方式和普通的源文件、目标文件一样。
gcc main.c libfunc.so -o app.out
将 main.c 和 libfunc.so 一起编译成 app.out,当 app.out 运行时,会动态地加载链接库 libfunc.so。
当然,必须要确保程序在运行时可以找到这个动态链接库。你可以将链接库放到标准目录下,例如 /usr/lib,或者设置一个合适的环境变量,例如 LIBRARY_PATH。不同系统,具有不同的加载链接库的方法。