Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件

目录

一、gcc生成静态库.a和动态库.so

 1.1、以hello为例进行这两个库的使用

 1.1.1、静态库与动态库创建之前的准备:

(1)先创建一个作业目录,保存本次练习的文件。

(2)用vim文本编辑器编辑生成所需要的 3 个文件: 程序 hello.h 、hello.c 和 和 main.c。 

 (3)将 hello.c 编译成.o 文件 :

 1.1.2、静态库的创建与使用:

(1)创建静态库: 

 (2)在程序中使用静态库,并且运行可执行文件hello :

(3)验证静态库的特点:

 1.1.3、动态库的创建与使用:

(1). 创建动态库:

 (2). 在程序中使用动态库,并且运行可执行文件hello:

 1.1.4、静态库与动态库同名时,gcc会优先运行谁?

1.2、实例1使用静态库与动态库 

 1.2.1、静态库与动态库创建之前的准备:

 1.2.2、静态库.a 文件的生成与使用:

1.2.3、动态库.so 文件的生成与使用:

 1.3、实例2使用静态库与动态库

 1.3.1、静态库与动态库创建之前的准备:

 1.3.2、静态库的创建与运行:

 1.3.3、动态库的创建与运行:

 1.3.4、静态库与动态库的生成文件的比较:

二、总结 

三、参考资料


一、gcc生成静态库.a和动态库.so

       我们通常把一些公用函数制作成函数库,供其它程序使用。函数库分为 静态库和 动态库两种。

       静态库:在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。

       动态库:在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。
       本文主要通过举例来说明在 Linux 中如何创建静态库和动态库,以及使用它们。

 1.1、以hello为例进行这两个库的使用

 1.1.1、静态库与动态库创建之前的准备:

(1)先创建一个作业目录,保存本次练习的文件。

  #mkdir test2
      #cd test2

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第1张图片

(2)用vim文本编辑器编辑生成所需要的 3 个文件: 程序 hello.h 、hello.c 和 和 main.c。 

hello.h:

#ifndef HELLO_H
#define HELLO_H
void hello(const char *name);
#endif//HELLO_H

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第2张图片

hello.c:

#include
void hello(const char *name)
{
	printf("Hello %s\n",name);
}

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第3张图片

main.c:

#include"hello.h"
int main()
{
	hello("everyone");
	return 0;
}

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第4张图片

 (3)将 hello.c 编译成.o 文件 :

       无论静态库,还是动态库,都是由.o 文件创建的。因此,我们必须将源程序 hello.c 通过 g
cc 先编译成.o 文件,为后面创建与使用静态库和动态库做铺垫。在系统提示符下键入以下命令得到 hello.o 文件。

gcc -c hello.c

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第5张图片

 我们运行 ls 命令看看是否生存了 hello.o 文件,可以看到已经有编译成功的hello.o文件了!

 1.1.2、静态库的创建与使用:

(1)创建静态库: 

       静态库文件名的命名规范是以 lib 为前缀,紧接着跟静态库名,扩展名为.a。例如:我们将
创建的静态库名为 myhello,则静态库文件名就是 libmyhello.a。在创建和使用静态库时,需要注意这点。创建静态库用 ar 命令。在系统提示符下键入以下命令将创建静态库文件libmyhello.a。 

ar -crv libmyhello.a hello.o
 (2)在程序中使用静态库,并且运行可执行文件hello :

方法一:

gcc -o hello main.c -L. -lmyhello
注意:对于自定义的静态库,main.c还可以放在-L.和-lmyhello之间,否则myhello没有定义。
-L.:表示连接的库在当前目录

 方法二:

gcc -c main.c
gcc -o hello main.c libmyhello.a
注:先生成main.o,再生成可执行文件 

方法三:

gcc main.c libmyhello.a -o hello

(3)验证静态库的特点:

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第6张图片

在删掉静态库的情况下,运行可执行文件hello,发现程序仍旧正常运行,表明静态库跟程序执行没有联系。同时,也表明静态库是在程序编译的时候被连接到代码中的。 

 1.1.3、动态库的创建与使用:

(1). 创建动态库:

       动态库文件名命名规范和静态库文件名命名规范类似,也是在动态库名增加前缀 lib,但其
文件扩展名为.so。例如:我们将创建的动态库名为 myhello,则动态库文件名就是 libmyhello.so。用 gcc 来创建动态库。在系统提示符下键入以下命令得到动态库文件 libmyhello.so。

gcc -shared -fPIC -o libmyhello.so hello.o
shared:表示指定生成动态链接库,不可省略
-fPIC:表示编译为位置独立的代码,不可省略
命令中的-o一定不能够被省略

 (2). 在程序中使用动态库,并且运行可执行文件hello:

       在程序中使用动态库和使用静态库完全一样,也是在使用到这些公用函数的源程序中包含
这些公用函数的原型声明,然后在用 gcc 命令生成目标文件时指明动态库名进行编译。

gcc -o hello main.c -L. -lmyhello或gcc main.c libmyhello.so -o hello

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第7张图片

发现运行可执行文件hello出现错误,因为虽然连接时用的是当前目录的动态库,但是运行时,是到/usr/lib 中找库文件的,将文件 libmyhello.so 复制到目录/usr/lib 中就 OK 了。

sudo mv libmyhello.so /usr/lib

 Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第8张图片

 1.1.4、静态库与动态库同名时,gcc会优先运行谁?

       我们回过头看看,发现使用静态库和使用动态库编译成目标程序使用的 gcc 命令完全一样,
那当静态库和动态库同名时,gcc 命令会使用哪个库文件呢 命令会使用哪个库文件呢?先删除除.c 和.h 外的所有文件,恢复成我们刚刚编辑完举例程序状态。再来创建静态库文件 libmyhello.a 和动态库文件 libmyhello.so。

 Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第9张图片

      通过上述最后一条 ls 命令,可以发现静态库文件 libmyhello.a 和动态库文件 libmyhello.s
o 都已经生成,并都在当前目录中。然后,我们运行 gcc 命令来使用函数库 myhello 生成目
标文件 hello,并运行程序 hello。从程序 hello 运行的结果中很容易知道,当静态库和动态库同名时,gcc 命令将优先使用动态库,默认去连/usr/lib 和/lib 等目录中的动态库,将文件 libmyhello.so 复制到目录/usr/lib中即可。

1.2、实例1使用静态库与动态库 

 1.2.1、静态库与动态库创建之前的准备:

依据之前对于hello的静态库与动态库的创建与使用,此处知识用于hello之外的实例1罢了!

 先创建一个作业目录,保存本次练习的文件:

#mkdir test22
#cd test22

然后用 vim文本编辑器编辑生成所需要的四个文件 A1.c 、 A2.c、 A.h、test.c 。 

A1.c:

#include
void print1(int arg)
{
	printf("A1 print arg:%d\n",arg);
}

 Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第10张图片

A2.c:

#include
void print2(char *arg)
{
	printf("A2 printf arg:%s\n",arg);
}

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第11张图片

A.h:

#ifndef A_H
#define A_H
void print1(int);
void print2(char *);
#endif

 Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第12张图片

 test.c:

#include
#include"A.h"
int main()
{
	print1(1);
	print2("test");
	exit(0);
}

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第13张图片

 终端总操作演示:

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第14张图片

 1.2.2、静态库.a 文件的生成与使用:

 (1)生成目标文件(xxx.o):

 gcc -c A1.c A2.c

(2)生成静态库.a 文件:

ar crv libfile.a A1.o A2.o

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第15张图片

 (3)使用.a 库文件,创建可执行程序并运行:

gcc -o test test.c libfile.a
./test

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第16张图片

发现报错,错误解决方式:将test.c中的exit(0)修改为return 0 即可。修改了test.c之后,重新进行一遍使用.a 库文件,创建可执行程序并运行的代码过程,成功进行!

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第17张图片

1.2.3、动态库.so 文件的生成与使用:

(1)生成目标文件(xxx.o) :

gcc -c -fpic A1.c A2.c

(2)生成动态库.so 文件:

gcc -shared -fPIC -o libfile.so A1.o A2.o

(3)使用.so 库文件,创建可执行程序:

gcc -o test test.c libsofile.so
./test

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第18张图片

发现错误, 将文件 libmyhello.so 复制到目录/usr/lib 中就 OK 了。

sudo mv libfile.so /usr/lib

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第19张图片

 1.3、实例2使用静态库与动态库

 1.3.1、静态库与动态库创建之前的准备:

  依据之前对于hello的静态库与动态库的创建与使用,此处知识用于hello之外的实例2罢了!

 用 vim文本编辑器编辑生成所需要的四个文件sub1.c 、sub2.c、sub1.h、main.c:

sub1.c:

#include"sub1.h"
float x2x(int a,int b)
{
	float sum;
	sum=a+b;
	return sum;
}

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第20张图片

 sub2.c:

#include"sub1.h"
float x2y(int a,int b)
{
	float c=0;
	c=a/b;
	return c;
}

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第21张图片

sub1.h :

#ifndef _SUB1_H
#define _SUB1_H
float x2x(int a,int b);
float x2y(int a,int b);
#endif

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第22张图片

 main.c:

#include
#include"sub.h"
void main()
{
	int a=9,b=3;
    float sum1=x2x(a,b);
	printf("%.2f\n",sum1);
    float sum2=x2y(a,b);
	printf("%.2f\n",sum2);
    return 0;
}

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第23张图片

 生成目标文件(xxx.o):

gcc -c sub1.c sub2.c

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第24张图片

 1.3.2、静态库的创建与运行:
ar crv libsub.a sub1.o sub2.o    创建静态库
gcc -o main main.c libsub.a      创建可执行文件
./main                           运行可执行文件结果

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第25张图片

 1.3.3、动态库的创建与运行:
gcc -shared -fPIC -o libsub.so sub1.o sub2.o  创建动态库
gcc -o main main.c libsub.so                  创建可执行文件
sudo mv libsub.so /usr/lib                    移动libsub.so文件的位置解决错误
./main                                        运行可执行文件结果

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第26张图片

 1.3.4、静态库与动态库的生成文件的比较:

 静态库:

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第27张图片

动态库:

Linux系统(Ubuntu)下利用gcc生成静态库.a与动态库.so文件_第28张图片

 通过比较发现静态库要比动态库要小很多,生成的可执行文件大小也存在较小的差别。

二、总结 

        通过上面三个例子用gcc生成静态库.a和动态库.so的练习过程,本人能够基本上熟练的生成静态库和动态库。在两种库的比较中,能够明显看出两者的差别。在过程中也遇到一些问题,但是通过CSDN查资料很快就找到了解决方法了。总的来说,本人通过跟着例程一步一步做,接触了gcc生成静态库与动态库的知识,学习并且理解与掌握了,自我会感觉不错!

三、参考资料

 gcc生成静态库.a和动态库.so_c源文件转换为a静态库-CSDN博客

你可能感兴趣的:(嵌入式Linux开发基础,linux,ubuntu,运维)