Gcc编译器能将C、C++语言源程序、汇程式化序和目标程序编译、连接成可执行文件,如果没有给出可执行文件的名字,gcc将生成一个名为a.out的文件。在Linux系统中,可执行文件没有统一的后缀,系统从文件的属性来区分可执行文件和不可执行文件。而gcc则通过后缀来区别输入文件的类别,下面我们来介绍gcc所遵循的部分约定规则。
.c为后缀的文件,C语言源代码文件;
.a为后缀的文件,是由目标文件构成的档案库文件;
.C,.cc或.cxx 为后缀的文件,是C++源代码文件;
.h为后缀的文件,是程序所包含的头文件;
.i 为后缀的文件,是已经预处理过的C源代码文件;
.ii为后缀的文件,是已经预处理过的C++源代码文件;
.m为后缀的文件,是Objective-C源代码文件;
.o为后缀的文件,是编译后的目标文件;
.s为后缀的文件,是汇编语言源代码文件;
.S为后缀的文件,是经过预编译的汇编语言源代码文件。
命令解说:
-c只进行编译,不进行链接。输出.o文件。
-s输出汇编语言文件
-o链接输出可执行文件,也可能输出链接库。
-O进行优化
-I(大写i)头文件存放目录。编译过程中搜索头文件,默认存放在/usr/includes下,针对用“”引用的头文件
-L 链接过程中搜索库文件的目录。首先到-L后的路径找,然后到/usr/lib下找。
-l(小写L)链接过程中搜索库文件的文件。比如-la链接过程中加载名字为liba.a的库文件。
例子:
生成静态链接库文件:
#mkdir test
#cd test
#mkdir inc
#mkdir lib
#mkdir src
#cd src
#vim tool.c
在vim下编写:
#include<stdio.h>
int add(int x,int y)
{
return x+y;
}
编译操作:
#gcc -c -O tool.c
查看文件内容,其中生成了tool.o文件。
用objdump查看.o文件的内容(汇编),其中包含了add函数。
#objdump -d tool.o
用ar命令创建函数库:
#ar rv libtools.a tool.o
ar命令缺省情况下第一个文件必须使用lib开头 ,.a结束。第二个文件使用目标文件全名就行。
上面的函数库包含了add函数 ,下面往tools.a中添加另一个函数。
#vim tool1.c
在vim下编写:
#include<stdio.h>
int sub(int x,int y)
{
return x-y;
}
编译操作:
#gcc -c -O tool1.c
把tool1.o附加到libtools.a中:
#ar rv libtools.a tool1.o
查看libtools.a中包含哪些目标文件:
#ar tv libtools.a
把libtools.a移动到~/test/lib目录中:
#mv libtools.a ../lib
在inc目录下创建自己的头文件:
#cd inc
#vim my.h
在vim下输入:
#define VALUE 100
在src中写个c文件:
#cd ../src
#vim a.c
在vim中输入:
#include"my.h"
#include<stdio.h>
void main()
{
fprintf(stderr,"VALUE+10=%d\n",add(VALUE,10));
}
编译操作生成a.o:
#gcc -c -I../inc a.c
假如使用
#cc -c a.c
由于没使用-I,所以编译出错。
链接操作生成可执行的a文件:
#gcc a.o -L../lib -ltools -o a
gcc生成动态链接库:
在vim下输入:
#mkdir test1
#cd test1
#vim a.c
#include<stdio.h>
int add(int x,int y)
{
return x+y;
}
对源文件编译操作:
#gcc -fPIC -c a.c
-fPIC让编译器生成可重定位的目标代码a.o文件。
链接操作生成动态链接库:扩展名为.so
#gcc -shared -o libabc.so a.o
用file命令查看.so文件的形式,可知.so文件为ELF文件。
使用动态链接库:
#vim b.c
#include<stdio.h>
void main()
{
fprintf(stderr,"%d\n",add(1,2));
}
#gcc -c -O b.c
#gcc b.o -L./ -labc -s -o b
但是此时执行b文件的话,会出错。因为环境变量LD_LIBRARY_PATH没有设置,必须把LD_LIBRARY_PATH设置到动态链接库文件.so文件的路径。此时可以执行了
需要使用环境变量LD_LIBRARY_PATH
#export LD_LIBRARY_PATH=./
环境变量LD_LIBRARY_PATH指向使用的目标函数库所在的路径。
执行b文件,系统不会报错了。