动态库&&静态库&&MakeFile
库文件
-
概念
- 库文件就是将一堆函数的源代码封装在一起,经过编译之后形成一种可执行的二进制代码(但是不可以独立执行),供自己或者他人调用
-
在linux下,有非常多的目录存在库文件
比如:
/lib------>linux协同库文件,一般是linux自带的
/usr/lib------>有的是系统自带的,有的是用户自定义移植的 -
库文件存放的是一些什么数据
- 因为库文件是二进制文件,只是看到一片代码
- 库文件里面存放的是数据,一般是一些函数
为什么要制作库文件
- 编译之后的库文件看不到源码,可保密;同时不会因为不小心修改了函数而出问题,便于维护
分类
- Windows下的库有两种:静态库(.lib)和动态库(.dll)
- Linux下的库有两种:静态库(.a)和动态库(.so)
我们主要研究linux下的库,动态库也称之为共享库
静态库与动态库的区别
- 静态库在gcc编译阶段把静态库放在一起编译,最后生成的二进制文件(文件比较大)
- 动态库在gcc编译阶段仅仅是记录了动态库的存放位置,在执行的时候才去指定的路径下调用该库
如何制作库文件
静态库----->libxxx.a
动态库----->libxxx.so
比如:liblockmgr.so.1.0.1
lib:库的前缀
lockmgr:库的名字
.so:库的后缀
.1:版本号
.0.1:库的修正号
静态库的制作
- 把.c文件编译成.o文件
gcc -c add.c -o add.o
- 把.o文件编译成静态库文件
ar -rc libadd.a add.o
制作完毕之后,libadd.a就是静态库文件
工程项目在编译的时候,把静态库加进来即可
编译:gcc main.c libadd.a -o main
执行:./main
动态库的制作
- 把.c文件制作成.so动态库
gcc -fpic -shared add.c -o libadd.so
-fpoc:制作动态库的参数
shared:共享库
- 在工程项目编译的时候,把动态库加进来
gcc main.c -o mian -L . -laa -L: 告诉编译器去哪里找动态库 -l告诉编译器要连接的动态库的库名(不需要写前缀、后缀、版本号) -I 告诉编译器去哪里找头文件
工程管理文件makefile
-
什么是makefile
- MakeFile称之为工程管理文件,用于管理一个工程中所有关联的文件。比如头文件,源文件,库文件...
-
MakeFile在工程中是不是一定要写
- 不一定。一般来说如果编译命令比较复杂,就会写makefile文件
- 项目工程文件比较多的时候,一般会写makefile去管理所有文件
- 项目工程文件比较少的时候,一般不写,因为编译命令比较简单
-
目的
- makefile就是为了简化编译时的复杂度
项目工程文件应该有哪些文件组成?
- 简单版:所有的文件都在相同的路径下
- 复杂版:对应的文件放在对应的路径下
makefile书写规则
-
了解makefile书写规则的两个核心
- 依赖:一般指.c文件
- 目标:一般指可执行目标文件
-
makefile书写规则
- 确定目标叫什么名字
- 按照以下规则去写makefile
目标:依赖(如果有多个依赖,则每个依赖之间用空格分开) <tab键>执行规则 比如:使用makefile来编译一个简单的程序 hello:<tab键>hello.c <tab键>gcc $^ -o $@
-
重复执行 make命令,那么会出现什么情况?
第一次make正常编译
第二次make:
make: “test”已是最新。
makefile变量的种类
在makefile中定义变量,不需要声明数据类型,只需要定义名字就可以了,所有的变量默认时字符串类型的
A------->默认就是字符串类型的变量
规定:
- 变量名的命名规则与c语言一致
- 给变量赋值的时候,等号两边可以有空格,也可以没有空格
- 比如说A = hello A = hello
- 在引用变量的值时,需要在变量前加一个\(,变量名也需要用()包含
A=hello
B=\)(A)world
因变量都是字符串类型,所以双引号可以省略
A = hello
A = "hello"
修改简单版本的makefile,将目标和依赖保存在变量中
系统预设定变量
- 有的变量已经在系统中定义好了,并且可以赋值,我们可以直接引用即可
CC----->编译器名字,默认=cc cc等价于gcc 也就是说CC = gcc
RM----->删除命令,默认等于rm -f 也就是RM = rm -f
自动化变量----->变量的值时不固定的,是变化的
- $^------>代表所有依赖
- $@------>代表所有的目标
makefile伪指令
-
场景一:假设makefile中有一套规则:
clean:
$(RM)bin/main
当我们执行make clean时,makefile就会执行这个规则 -
场景二:假设makefile中有一套规则,并且当前目录下有一个文件夹clean
clean:
$(RM)bin/main
当我们执行makefile时,出现如下情况
如何告诉编译器,这个make clean是一套规则,而不是生成文件?
解决方案:使用伪指令
怎么添加?------->只需要在makefile中添加一句话
.PHONY
:clean
makefile函数
- wildcard------->在指定的路径下寻找匹配的文件
C语言函数调用 函数名(参数1,参数2,参数3)
makefile函数调用$(函数名 参数1,参数2,参数3)
比如:我想把当前目录下的所有.c文件名都找出来,并将这些文件名保存在C_SOURCE中
C_SOURCE = $(wildcard ./c_source/*.c)