动态库&&静态库&&MakeFile

发布时间 2023-09-04 08:59:36作者: 若达萨罗

库文件

  1. 概念

    • 库文件就是将一堆函数的源代码封装在一起,经过编译之后形成一种可执行的二进制代码(但是不可以独立执行),供自己或者他人调用
  2. 在linux下,有非常多的目录存在库文件
    比如:
    /lib------>linux协同库文件,一般是linux自带的
    /usr/lib------>有的是系统自带的,有的是用户自定义移植的

  3. 库文件存放的是一些什么数据

    • 因为库文件是二进制文件,只是看到一片代码
    • 库文件里面存放的是数据,一般是一些函数

为什么要制作库文件

  • 编译之后的库文件看不到源码,可保密;同时不会因为不小心修改了函数而出问题,便于维护

分类

  • Windows下的库有两种:静态库(.lib)和动态库(.dll)
  • Linux下的库有两种:静态库(.a)和动态库(.so)
    我们主要研究linux下的库,动态库也称之为共享库

静态库与动态库的区别

  1. 静态库在gcc编译阶段把静态库放在一起编译,最后生成的二进制文件(文件比较大)
  2. 动态库在gcc编译阶段仅仅是记录了动态库的存放位置,在执行的时候才去指定的路径下调用该库

如何制作库文件

静态库----->libxxx.a
动态库----->libxxx.so
比如:liblockmgr.so.1.0.1
lib:库的前缀
lockmgr:库的名字
.so:库的后缀
.1:版本号
.0.1:库的修正号

静态库的制作

  1. 把.c文件编译成.o文件
    gcc -c add.c -o add.o
  2. 把.o文件编译成静态库文件
    ar -rc libadd.a add.o
    制作完毕之后,libadd.a就是静态库文件
    工程项目在编译的时候,把静态库加进来即可
编译:gcc main.c libadd.a -o main
执行:./main

动态库的制作

  1. 把.c文件制作成.so动态库
	gcc -fpic -shared add.c -o libadd.so
	-fpoc:制作动态库的参数
	shared:共享库
  1. 在工程项目编译的时候,把动态库加进来
    gcc main.c -o mian -L . -laa
    
    -L: 告诉编译器去哪里找动态库
    -l告诉编译器要连接的动态库的库名(不需要写前缀、后缀、版本号)
    -I 告诉编译器去哪里找头文件
    

工程管理文件makefile

  1. 什么是makefile

    • MakeFile称之为工程管理文件,用于管理一个工程中所有关联的文件。比如头文件,源文件,库文件...
  2. MakeFile在工程中是不是一定要写

    • 不一定。一般来说如果编译命令比较复杂,就会写makefile文件
    • 项目工程文件比较多的时候,一般会写makefile去管理所有文件
    • 项目工程文件比较少的时候,一般不写,因为编译命令比较简单
  3. 目的

    • makefile就是为了简化编译时的复杂度

项目工程文件应该有哪些文件组成?

  1. 简单版:所有的文件都在相同的路径下
  2. 复杂版:对应的文件放在对应的路径下

makefile书写规则

  1. 了解makefile书写规则的两个核心

    • 依赖:一般指.c文件
    • 目标:一般指可执行目标文件
  2. makefile书写规则

    • 确定目标叫什么名字
    • 按照以下规则去写makefile
    目标:依赖(如果有多个依赖,则每个依赖之间用空格分开)
    <tab键>执行规则
    比如:使用makefile来编译一个简单的程序
    hello:<tab键>hello.c
    <tab键>gcc $^ -o $@
    
  3. 重复执行 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时,出现如下情况
    image

如何告诉编译器,这个make clean是一套规则,而不是生成文件?
解决方案:使用伪指令
怎么添加?------->只需要在makefile中添加一句话
.PHONY:clean

makefile函数

  1. wildcard------->在指定的路径下寻找匹配的文件
    C语言函数调用 函数名(参数1,参数2,参数3)
    makefile函数调用$(函数名 参数1,参数2,参数3)
    比如:我想把当前目录下的所有.c文件名都找出来,并将这些文件名保存在C_SOURCE中
    C_SOURCE = $(wildcard ./c_source/*.c)