静态编译与动态编译
背景:
使用静态库完成如下程序:
输入一个菱形半径,打印菱形。=====》main.c
输入整数封装成IOTool==========》iotool.c
菱形的打印封装成Graphics=======》graphics.c
计划:
1.实现输入
2.实现菱形
3.编译静态库
4.调用静态库
iotool.c代码
#include <stdio.h>
int inputInt(const char *info)
{
int r;
printf("%s:",info);
scanf("%d",&r);
return r;
}
graphics.c代码
#include <stdio.h>
void diamond(int r)
{
int x,y;
for(y=0;y<=2*r;y++)
{
for(x=0;x<=2*r;x++)
{
if(y==x+r || y==x-r
|| y==-x+r || y==-x+3*r)
{
printf("*");
}
else
{
printf(" ");
}
}
printf("\n");
}
}
此处应有掌声。这是一个算法,利用坐标轴来分别画出菱形的四条边。
main.c函数
#include <stdio.h>
#include <unistd.h>
main()
{
int r=inputInt("输入菱形半径");
diamond(r);
printf("%d\n",getpid());
while(1);
}
静态库的编译
编译过程:
gcc -c -static -iotool.c
gcc -c -static -graphics.c
归档成静态库:
ar -r libdemo.a iotool.o grahics.o
查看函数符号表:nm libdemo.a
使用静态库: gcc main.c -o main -l demo -L .
运行程序: main
1.编译过程(*.a achieve)
1.1.编译成目标文件
-static 可选
gcc -c -static 代码文件.c
1.2.归档成静态库
ar工具
ar -r
-t
ar -r 静态库文件 被归档的文件
nm工具(察看函数符号表)
nm 静态库或者动态库或者目标文件或者执行文件
1.3.使用静态库
gcc 代码 静态库
总结:
1.什么是库?
函数等代码封装的二进制已经编译的归档文件
2.ar归档工具
3.采用库的方式管理代码优点:
容易组织代码
复用
保护代码版权
4.静态库的静态的含义:
编译好的程序运行的时候不依赖库。
库作为程序的一部分编译连接。
5.静态库本质:
就是目标文件集合(归档)
6.-static可选
2.库的规范与约定
库命名规则:
lib库名.a.主版本号.副版本号.批号
一般情况下 lib库名.a
库使用规则
-l 库名
-L 库所在目录
例如 :有一个libdemo.a的归档文件
gcc main.c -o main -l demo -L.
系统会自动查找lib开头和.a文件
动态库的编译
编译:
gcc -c iotool.c
gcc -c graphics.c
3.2.连接
gcc -fpic(可选) -shared -o libdemo1.so iotool.o graphics.o
4.使用动态库
gcc mian.c -o main -l demo1.so -L .
5.运行程序
main
编译没出现出错,但运行出错了,看提示信息,说不能加载libdemo1.so,因为没有那个目录.
原来,我们自己那个共享库不在系统默认的共享库路径中。有几种方法,一是将当前目录添加到共享库搜索目录;
二是将我们自己的共享库放到系统默认的库目录中;三是暂时指定共享库的路径。显然,第一种方法和第二种不
太可取,——就像将我们自己编写的头文件放到系统默认头文件目录那样。当然,在我们设计嵌入式根文件系
统时,我们是可以将自定义的库放到系统目录中的。这里,我们使用第三种方法。执行以下命令
$ export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
总结:
1.什么是动态库?(共享库)
动态库是可以执行,静态库不能执行
但动态库没有main,不能独立执行。
动态库不会连接成程序的一部分。
程序执行的时候,必须需要动态库文件。
2.工具
ldd 察看程序需要调用的动态库
ldd 只能察看可执行文件.
readelf -h 察看执行程序头.
nm 察看库中的函数符号
3.动态库的编译
3.1.编译
-c -fpic(可选)
3.2.连接
-shared
4.使用动态库
gcc 代码 动态库文件名
gcc 代码 -l库名 -L动态库所在路径
标准命名规则:
lib库名.so
lib库名.a
-l 库名 -L 库所在路径
问题:
4.1.执行程序怎么加载动态库?
4.2.动态库没有作为执行程序的一部分,为什么连接需要指定动态库以及目录?
连接器需要确定函数在动态库的中的位置
动态库的加载:
1.找到动态库
2.加载动态库到内存
3.映射到用户的内存空间
系统对动态库查找规则:
/lib
/usr/lib
到环境变量LD_LIBRARY_PATH指定的路径中查找

浙公网安备 33010602011771号