1linux gcc命令以及c语言动态库静态库编译

来源:互联网 发布:淘宝网店运营策划书 编辑:程序博客网 时间:2024/05/18 23:28

gcc介绍

GNU编译器套件(GNU Compiler Collection)包括C、C++、Objective-C、Fortran、Java、Ada和Go语言的前端,也包括了这些语言的库(如libstdc++、libgcj等等)。GCC的初衷是为GNU操作系统专门编写的一款编译器。GNU系统是彻底的自由软件。

1)gcc是一个可移植的编译器,支持多种硬件平台
2)gcc不仅仅是个本地编译器,它还能跨平台交叉编译。
3)gcc有多种语言前端,用于解析不同的语言。
4)gcc是按模块化设计的,可以加入新语言和新CPU架构的支持
5)gcc是自由软件

gcc常用编译选项

选项 作用
-o 产生目标(.i、.s、.o、可执行文件等)
-c 通知gcc取消链接步骤,即编译源码并在最后生成目标文件
-E 只运行C预编译器
-S 告诉编译器产生汇编语言文件后停止编译,产生的汇编语言文件扩展名为.s
-Wall 使gcc对源文件的代码有问题的地方发出警告
-Idir 将dir目录加入搜索头文件的目录路径
-Ldir 将dir目录加入搜索库的目录路径
-llib 链接lib库
-g 在目标文件中嵌入调试信息,以便gdb之类的调试程序调试

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(链接)//此时这个hello是linux下的可执行文件

以上四个步骤,可合成一个步骤
gcc hello.c -o hello(直接编译链接成可执行目标文件)

!gcc 运行上一个gcc命令

gcc编译警告提示

#include <stdio.h>int main(void){        printf("2+1 is %f", 3);        return 0;}

上面一段代码,编译可以通过,但是运行结果:
gcc编译不加上-Wall

而且我们编译的时候,没有给我们任何提示。
所以我们一般编译的时候,需要加上-Wall命令
gcc编译加上-Wall

gcc编译多个文件

一次行编译

 gcc 1.c 2.c -o hello 

分多次编译

gcc -Wall -c 1.c -o mainf.ogcc -Wall -c 2.c -o fun.ogcc fun.o  mainf.o  -o hello//汇编,进行链接

然后就可以./hello 运行得出结果

用脚本文件静态库生成并且链接

我的目录结构:

目录结构
inc:存放的是.h文件
lib:存放的是生成的静态库.a文件
src:存放静态库函数
test:测试程序
script:里面是gcc编译命令以及一些其他命令(后面文章会用makefile代替)
需要chmod 775 script 将script变为可执行文件
script内容:

#将myadd.c生成一个二进制文件,-I ./inc 代表从这个里面找头文件gcc -c -Wall -I ./inc ./src/myadd.c -o myadd.o#将myadd.o的二进制文件生成静态库,静态库文件名为libmyadd.a(为什么lib开头后面讲)ar rcs libmyadd.a myadd.o#删除.o结尾的文件,将静态库移动到lib目录下rm *.omv libmyadd.a ./lib

*静态库名称一般为libXXX.a
那么我们调用这个静态库就要在结尾加上-lXXX

编译测试程序将静态库链接进来

gcc -Wall -L./lib -I ./inc ./test/main.c -o ./main.out -lmyadd

这个时候,静态库会包含到main.out这个程序里面去,就可以不需要libmyadd.a这个静态库了
此时可以运行这个程序

nm命令

nm 静态库名称
这个就可以查看到静态库里面的哪些函数

生成动态库并链接

1生成动态库

目录结构和上面的结构一样,这里我们会将生成的动态库也放到lib目录下,此时不生成静态库
动态库目录
在script下的脚本

gcc -shared -fPIC -I ./inc ./src/myadd.c -o libmyadd.somv *so ./lib

shared: 表示生成共享库格式
fPIC:产生位置无关码(position independent code)
这个动态库,可在任何位置加载,叫做位置无关码。
这个动态库,在指定位置加载,成为与位置有关

这个时候生成一个so文件动态库文件在lib目录下

2调用动态库

编译test下的测试程序

gcc -Wall -I ./inc -L ./lib ./test/main.c  -o main -lmyadd

-L:指定动态库的位置

这个时候我们调用main这个程序发现报错:找不到动态库,默认/usr/lib
是因为系统不知道我们这个库所在的目录
1我们通过cd命令进入桌面目录目录
2vi .bash_profile #这个文件是隐藏的,是环境变量,不同的用户不一样
添加如下:寻找当前目录和当前目录下的lib目录
环境变量配置
3source .bash_profile 刷新这个配置文件使配置文件生效
4运行成功

ldd命令

ldd命令:查看程序链接了库的位置

file命令

file 文件名查看文件的属性