前言:当我们写了一段代码实现了一个方法,如果我们不想把方法的实现过程暴露给别人看,可以把代码打包成一个库,其中形成后缀为.a的是静态库,后缀为.so的为动态库;当别人想使用你的方法时,把打包好的库跟头文件一起扔给他就行。
一、静态库
1.1生成一个简单的静态库
①首先创建两个文件,一个.c方法的实现,一个.h方法的声明;
②简单实现一下
//mymath.h文件
#pragma once int add(int x,int y);int sub(int x,int y);
//mymath.c文件1 #include "mymath.h" 2 int add(int x,int y) 3 { 4 return x+y; 5 } 6 int sub(int x,int y) 7 { 8 return x-y; 9 }
③makefile怎么写?
首先要把所有.c文件生成.o文件,然后把.o文件打包生成库(如果是静态库就是.a;如果是动态库就是.o)
//makefile文件1 lib=libmymath.a 2 $(lib):mymath.o 3 ar -rc $@ $^ ## ar :生成静态库命令; rc:把所有.o文件打包生成.a文件,如果.a里面已存在则覆盖; $@ :依赖目标 $^:依赖文件;4 mymath.o:mymath.c5 gcc -c mymath.c ##-c 默认生成.o文件6 .PHONY:clean ##清理7 clean:8 rm -rf *.o *.a mylib 10 .PHONY:output ##库发布 11 output: 12 mkdir -p mylib/lib #创建一串路径 13 mkdir -p mylib/include 14 cp *.h mylib/include #把头文件拷贝到include15 cp *.a mylib/lib #把.a 库文件拷贝到lib
~
④make一下
当前目录下已写好.c .h和makefile文件:
make后可以看到生成了mymath的.o文件,然后由.o文件生成静态库 libmymath.a:
⑤发布一下
查看一下当前目录:
可以看到生成的mylib文件就是我们制作的库文件,查看里面的内容:
可以看到其中include文件中包含了方法的头文件,lib文件中包含的就是静态库文件!
既然生成好了就来使用以下吧!
1.2 静态库的使用
①创建一个test文件然后把mylib文件拿过来用
②创建一个.c文件里面包含main函数来使用这个库
//main.c文件
1 #include "mymath.h"
2 int main()
3 {
4 printf("1+1= %d\n",add(1,1));
5 return 0;
6 }~
③静态库的编译链接
注意:库的编译链接:gcc + 带main函数的.c文件 + -I + 头文件所在的目录 + -L + 库所在的目录 + -l跟库真实的名字(去掉前缀去掉后缀)
编译后查看当前目录:
运行:
这样就成功的完成了静态库的制作到使用!接下来我们来实现下动态库吧!
二、动态库
2.1 生成一个简单的动态库
我们回到lesson16,然后makeclean,然后再创建两个.c文件分别存放两个方法,和其对应的.h方法使用声明(这两个方法用来生成动态库)
随便实现一下这两个方法(主要为了展示动态库的生成和使用):
//mylog.h文件1 #pragma once 2 void log(char* message);
//mylog.c文件1 #include "mylog.h"2 void log(char* message)3 {4 printf("%s\n",message); 5 }
//myprint.h文件1 #pragma once 2 void print();
//myprint.c文件1 #include "myprint.h"2 void print()3 {4 printf("hello linux!!!\n"); 5 }
2.2 makefile怎么写
首先makefile 一次生成两个库,一个静态库、一个动态库,生成之后发布为mylib(动、静态库、头文件都在里面):
//makefile文件1 static_lib=libmymath.a ##静态库2 dynamic_lib=libmymethod.so ##静态库3 .PHONY:all4 all:$(static_lib) $(dynamic_lib)5 $(static_lib):mymath.o6 ar -rc $@ $^ ## ar :生成静态库命令; rc:把所有.o文件打包生成.a文件,如果.a里面已存在则覆盖; $@ :依赖目标 $^:依赖文件;7 mymath.o:mymath.c8 gcc -c mymath.c ##-c 默认生成.o文件9 10 $(dynamic_lib):myprint.o mylog.o11 gcc -shared -o $@ $^ ##shared: 生成动态库12 myprint.o:myprint.c13 gcc -fPIC -c $^ ##fpic :产生位置无关码14 mylog.o:mylog.c15 gcc -fPIC -c $^16 .PHONY:clean ##清理17 clean:18 rm -rf *.o *.a mylib *.so 19 .PHONY:output ##库发布20 output: 21 mkdir -p mylib/lib #创建一串路径22 mkdir -p mylib/include 23 cp *.h mylib/include #把头文件拷贝到include24 cp *.a mylib/lib #把.a 库文件拷贝到lib25 cp *.so mylib/lib
make一下:
mymath生成的静态库libmumatg.a ; mylog和myprint生成的libmymethod.so动态库;
发布一下:
拿到test文件夹里用一下:
2.3 动态库的使用
创建一个main函数调用它:
//main.c文件
1 #include "mylog.h"
2 #include "myprint.h"
3 #include "mymath.h"
4 #include <stdio.h>
5 int main()
6 {
7 printf("1-1=%d\n",sub(1,1));
8 log("hello linux!!!\n");
9 print();
10 print();
11 return 0;
12 }
编译链接:
运行:
报错因为加载的时候找不到动态库,解决方法:
①、把库拷贝到系统默认的路径下 /lib64/usr/lib64/
②、在系统文件下创建软连接 /lib64/usr/lib64/
③、LD-LIBRARY_PATH 导入环境变量
④、进入/etc/ld.so.conf.d创建.conf文件并把库路径加进去,然后重新加载 ldconfig
这里我随便用一个,导入环境变量的方法:
导入前:
导入后:
再运行:
动态库使用成功!!