gcc 是 GUN Compiler Collection的缩写,可以支持多种语言编译,比如 C,C++,Java, pascal 等。
一、gcc的编译过程
1.四个过程
- 预处理(pre-processing)E
编译器将C源代码中的包含的头文件如stdio.h编译进来,替换宏。 - 编译(Compiling)S
gcc首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc把代码翻译成汇编语言。 - 汇编(Assembling) c
把编译阶段生成的”.s”文件转成二进制目标代码。 - 链接 (Linking)
链接到库中,生成可执行文件。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
2.一次性完成
gcc hello.c –o hello
但一般情况下生成.o文件比较好,可以重定位文件,让别人使用。
二、gcc常用选项
选项名 | 作用 |
---|---|
E | 激活预处理;头文件、宏等展开(.i文件) |
S | 激活预处理、编译;生成汇编代码(.s文件) |
c | 激活预处理、编译、汇编;生成目标文件(.o文件) |
o | 生成目标 |
Wall | 打开编译告警(所有) |
g | 嵌入调试信息,方便gdb调试 |
llib | 链接 lib 库 (这里是小写 L ) 相当于 C++ #pragma comment(lib, “xxx.lib”) |
Idir | 增加 include 目录 (这里是大写 i ) 头文件路径 |
LDir | 增加 lib 目录 (编译静态库和动态库) |
三、多模块编译
- 一次性编译:
gcc -Wall fun.c main_fun.c –o main_fun
- 独立编译:
gcc –Wall –c main_fun.c –o main_fun.o gcc –Wall –c fun.c –o fun.o gcc –Wall main_fun.o fun.o –o main_fun
多模块编译中如果某一个模块发生了变化,只需要编译更改的模块即可
四、静态库与动态库
1.静态库(.a)
程序在编译链接时候把库的代码链接到可执行文件中。程序运行时候,不再需要静态库,生成的可执行文件大,每个可执行文件都会加载一份拷贝到内存。
- 静态库生成(libxxx.a)
首先生成.o文件,然后通过.o文件生成.a文件,例如:gcc –c fun.c ar rcs libfun.a fun.o
- 静态库使用
-L. 表示在当前目录搜索 libfun.agcc –Wall main.c libfun.a –o main gcc –Wall –L. main.c –o main –lfun
- 静态库搜索路径
1:编译使用选项 –L 指定的目录(建议)
2:修改环境变量,搜索指定的目录,设置环境变量LIBRARY_PATH
并导出:
3:lib文件放入系统指定目录,例如export LIBRARY_PATH=“库目录”
/usr/lib/
等
2.动态库(.so或.sa)
动态库编译链接时并没有把库文件的代码加入到可执行文件中,而是程序运行时候才去链接动态库代码,多个程序动态使用,使用时候只需要加载一份到内存,从而节省系统的开销。
- 动态库生成(libxxx.so)
直接可以通过.c文件生成.so文件,例如:
shared:生成动态库格式。gcc –shared –fPIC fun.o –o libFun.so
fPIC: 产生位置无关码,允许在任何地址加载相对地址,否则只能从指定地址加载,无法控制。 - 动态库使用
只需要 -l + 文件名即可。gcc –Wall main.o –o main –L. -lFun
- 配置方式
1:拷贝到so文件到动态库目录 /usr/lib/。
2:更改LD_LIBRARY_PATH
,如果已经有了一个这样的目录,要写成:
如果没有的话就写成:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:“库目录”
3:配置 /etc/ld.so.conf;并使用 ldconfig 命令进行更新。export LD_LIBRARY_PATH=“库目录”
- ldd查看动态库加载情况
五、默认头文件路径
每个编译器都有自己的头文件和库文件,可以通过以下命令查看gcc默认搜索的头文件路径和库路径:
echo 'main'|gcc -E -v -
部分结果如下:
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/5/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "<stdin>"
main
使用该命令查询arm-linux-gcc
时得到以下结果:
#include "..." search starts here:
#include <...> search starts here:
/usr/local/arm/arm-2009q3/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.1/include
/usr/local/arm/arm-2009q3/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.1/include-fixed
/usr/local/arm/arm-2009q3/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.1/../../../../arm-none-linux-gnueabi/include
/usr/local/arm/arm-2009q3/bin/../arm-none-linux-gnueabi/libc/usr/include
End of search list.
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "<stdin>"
main
转载地址: