静态编译与动态编译

背景:

使用静态库完成如下程序:
输入一个菱形半径,打印菱形。=====》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指定的路径中查找

 

posted @ 2017-02-18 15:34  ren_zhg1992  阅读(830)  评论(0)    收藏  举报