gcc即GNU CC 是GNU项目中符合ANSI标准的编译系统,能过编译的C、C++、Object-C等语言,同时它又是一个交叉编译工具,可以在当前CPU下为不同体系架构的硬件平台开发软件。
gcc 支持的后缀名解析
后缀名 | 解析 | 后缀名 | 解析 |
.c | c程序文件 | .s/.S | 汇编文件 |
.C/.cc/.cxx | C++源文件 | .h | 预处理文件(头文件) |
.m | Object-C源文件 | .o | 目标文件 |
.i | C预处理后的文件 | .a/.so | 静态/动态库文件 |
.ii | C++预处理后的文件 |
一、gcc 编译hello.c程序的流程
有如下文件
#include<stdio.h>
int main(int argc, char * argv[])
{
printf("hello world");
return 1;
}
(1)、预处理(Pro-Processing) 选项 -E
这个阶段将hello.c 中包含的.h头文件包含经来
$:gcc -E -o hello.i hello.c
预处理后生成hello.i
(2)、编译(Compiling) 选项 -S
这个阶段,gcc会检查代码的规范性,是否有语法错误,如果检查通过将会翻译成i386的汇编语言
$: gcc -S -o hello.s hello.i
将生产汇编代码 hello.s
也可以直接由 hello.c生产 gcc -S -o hell.s hello.c
(3)、汇编(Assembling) 选项 -c
汇编阶段,将编译阶段生产的“.s”生产的文件转成目标文件
$: gcc -c -o hello.o hello.s
也可以直接由hello.c生产 gcc -c -o hello.c hello.s
(4)、链接(Linking)
$: gcc -o hello hello.o 或 gcc -o hello hello.c
这个阶段命令很简单但其实编译器做了很多的事情,它将各个目标文件链接在一起生成执行文件。在函数中我们使用了printf函数,我们只包含了头文件<stdio.h>,却并没有实现这个函数。实际这就是系统早就将这些库函数实现编译成动态库中放到了系统默认的/lib/中去了。
二、静态库和动态的库的概念。
1、静态库在编译的时候就已经载入了可执行程序中去了,它是可执行程序的一部分,程序执行时不需要再加载什么库了,因此生成的可执行程序比较大,后缀名为“.a”。
2、动态库在编译的过程中不会别连接在可执行文件中,只有程序运行的时候才被加载到内存中来,因此程序较小运行的时候还需要动态库的存在,这就是我们有时候运行别人的程序会出现找不到库的原因,因为我们通常只copy他的执行程序,而所依赖的库却没有安装,后缀名“.so”。动态库的还有一个显著的特点就是:当多个程序同时调用同一个动态库的时候,内存中只有一个动态库存在,例如多个程序同时使用printf()函数,在内存中只加载了一个libc.so.6库。
有如下四个文件
/****** getmin.c ******/
int get_min(int x,int y)
{
return x<y?x:y;
}
/****** getmax.c ******/
int get_max(int x,int y)
{
return x<y?y:x;
}
/****** func.h *******/
int get_min(int x,int y)
int get_max(int x,int y)
/****** test.c *******/
#include<stdio.h>
#include"func.h"
void main(void)
{
printf("max=%d\n min=%d\n",get_min(3,4),get_max(3,4));
}
3、静态库测试静态库需要.o文件生成
执行下列命令:
$: gcc -o getmax.o getmax.c
$: gcc -o getmin.o getmin.c
$: ar crv libstatic.a getmax.o getmin.o
将得到一个名字为libstatic.a的静态库。程序中使用静态库:
$: gcc -o static_test test.c -L. -lstatic
$: rm libstatic.a
$: ./static_test
$: 3 4
第一条命令中-L为查找库的路径后面跟个小点. 就是在当前目录下查找,-l为文件格式为lib开个.a结束中间内容为static的库文件。所以我们对静态库命名必须要是lib*.a的格式。
rm libstatic 删除静态库 执行文件任然可以执行说明,静态库已经连接到可执行文件中去了。
4、动态库测试
动态库可以直接由.c文件创建
$: gcc -shared -fPIC -o libdynamic.so getmax.c getmin.c
$: gcc -o dynamic_test main.c -L. -ldynamic
$: ./dynamic_test
类似和静态库一样的方法生成了动态库 -fPIC -shared 生成共享动态库选项运行结果却是如此下:
./dynamic_test: error while loading shared libraries: libdynamic.so:can't open shared object file: No such file or directory
查看下:
$: libdynamic.so => not found
$: libc.so.6 => /lib/x86-64-linux-gnu/libc.so.6
动态库没有链接这更说明了程序运行的时候也要依赖库将libdynamic.so coye 到系统库/lib/或者用户/usr/lib库下就能运行了。
当然你完全可以修改环境变量LD_LIBRARY_PATH来达到目的。
程序查找动态库的路径:
/lib 、/usr/lib 、/etc/ld.so.conf所配置的路径下。