Linux学习——静态库与动态库的打包

Linux学习——静态库与动态库的打包_第1张图片

目录

​编辑

一,动静态库介绍

1,动静态库的特点

二,静态库的打包

计算器示例

编译:

1,直接编译

2,打包

三,动态库打包

计算器示例:同上

编译:

1,直接编译:同上

2,动态库打包的方式

在写库的人在库文件所在位置使用时: 

当别人想要使用时:


一,动静态库介绍

1,动静态库的特点

1,在linux中带有.a后缀的便是静态库。带有.so的便是动态库。比如libmymath.a便是一个静态库,libmymath.so便是一个动态库,但是库的名字则是mymath,lib是库前缀。

2,静态库会被加载到可执行程序的内部所以可执行程序会变得很大。动态库则只有一份,可执行程序要使用时需要加载动态库。

3,可执行程序默认使用动态链接,只有在编译时在可执行程序后面加上-static或者只有静态库文件时才会使用静态链接的方式。

示例:

 #include
  2 int main()
  3 {
  4   printf("hello linux\n");                                                                                                                                                              
  5 }

直接使用gcc编译:

Linux学习——静态库与动态库的打包_第2张图片

使用加上-static的编译:

Linux学习——静态库与动态库的打包_第3张图片 

二,静态库的打包

计算器示例

代码:

add.h:

extern int add(int,int)//函数声明

add.c

  1 #include"add.h"                                                                                                                                                                         
  2                                                                                                
  3 int add(int x,int y)                                                                                               
  4 {                                                                                               
  5   return x+y;                                                                                               
  6 }  

sub.h

extern int sub(int,int);

sub.c

  1 #include"sub.h"                                                                                                                                                                         
  2 int sub(int x,int y)
  3 {
  4   return x-y;
  5 }

test_main.c:

  2 #include"add.h"
  3 #include"sub.h"
  4 
  5 
  6 int main()
  7 {
  8   int x = 10,y = 9;
  9   printf("%d-%d=%d\n",x,y,sub(x,y));
 10   printf("%d+%d=%d\n",x,y,add(x,y));
 11   return 0;
 12 }

编译:

1,直接编译

如果我们想要形成一个可执行文件的话,直接编译便可以了:

 gcc add.c sub.c test_main.c
Linux学习——静态库与动态库的打包_第4张图片

2,打包

但是这样编译要将.c文件提供给使用者,这样一般是不符合开发时的要求的。开发时一般是不会将源文件提供给别人的,而只会给.h文件和库文件。所以我们就得来打包一番了。

1,打包.o文件:将所有要用到的.o文件打包到libmymath.a文件中。

2,打包.h文件:将所有的.h文件打包到一个include目录下。

Makefile文件代码:

  1  lib=libmymath.a
  2 $(lib):sub.o add.o
  3   ar -rc $@ $^ 
  4 
  5 %.o:%.c
  6   gcc -c $<  
  7 
  8 .PHONY:output
  9 output:
 10   mkdir -p  _lib/include
 11   mkdir -p _lib/mymath
 12   cp -rf *.h _lib/include                                                               
 13   cp -rf *.a _lib/mymath
 14 
 15 .PHONY:clean
 16 clean:
 17   rm -rf *.o *.a

在当前路径下生成静态库 

Linux学习——静态库与动态库的打包_第5张图片

编译指令:gcc test_main.c -lmymath -L.

Linux学习——静态库与动态库的打包_第6张图片

打包给别人使用:

Linux学习——静态库与动态库的打包_第7张图片 然后便可以像之前在当前路径下使用了。

三,动态库打包

计算器示例:同上

编译:

1,直接编译:同上
2,动态库打包的方式

代码:

  1 lib=libmymath3.so //生成.so为后缀的动态库
  2 $(lib):sub.o add.o
  3   gcc -shared -o $@ $^  //使用gcc -shared命令生成共享库(动态库)                                                                
  4 
  5 %.o:%.c
  6   gcc -fPIC  -c $<  //加上fPIC(与位置无关码)
  7 
  8 .PHONY:output
  9 output:
 10   mkdir -p  _lib/include
 11   mkdir -p _lib/mymath
 12   cp -rf *.h _lib/include
 13   cp -rf *.so _lib/mymath
 14 
 15 .PHONY:clean
 16 clean:
 17   rm -rf *.o *.so _lib 
 18   
在写库的人在库文件所在位置使用时: 

Linux学习——静态库与动态库的打包_第8张图片

关于第四步:-I(大写的i)是为了链接头文件  -l(小写的L)是为了链接库   -L是为了告诉编译器去哪里找。 

当别人想要使用时:

假如现在是别人想要使用:

Linux学习——静态库与动态库的打包_第9张图片

当前在test2文件下,_lib是下载后解压得到的。

使用:

能生成可执行文件,但是不能编译,原因是找不到.so文件。

可以使用ldd+可执行程序查看:

Linux学习——静态库与动态库的打包_第10张图片

解决方式:让可执行程序能够找到动态库

1,将动态库拷贝到系统库中(推荐做法,但不要把自己写的文件塞进去):.so文件拷贝到usr/include路径下   .h文件拷贝到usr/include路径下

Linux学习——静态库与动态库的打包_第11张图片

2,建立软连接

在当前文件下建立软连接:相对路径。

在系统文件里:要有完整的路径。

3,定义环境变量

定义环境变量然后export。示例:export LD_LIBRARY_PATH = $LD_LIBRARY_PATH:绝对路径

4,找到/etc/ld.so.cnf.d/然后在里面touch一个.cnf文件,然后用sudo vim打开,然后在里面添加动态库的完整路径。

你可能感兴趣的:(Linux系统编程,学习,学习笔记,linux)