动态库、静态库以及Makefile的使用

本文详细介绍了Linux系统中的动态库和静态库的概念、制作方法及优缺点,包括动态库(libxxx.so)和静态库(libxxx.a)的创建过程。此外,还阐述了Makefile的使用,包括其含义、结构、常用选项和示例,讲解如何通过Makefile简化编译链接过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.动态库和静态库

库用于将相似函数打包在一个单元中。然后这些单元就可为其他开发人员所共享,并因此有了模块化编程这种说法 — 即,从模块中构建程序。Linux 支持两种类型的库,每一种库都有各自的优缺点。静态库包含在编译时静态绑定到一个程序的函数。动态库(也叫共享库)则不同,它是在加载应用程序时被加载的, 而且它与应用程序是在运行时绑定的。Linux系统有几个重要的目录存放相应的函数库,如/lib, /usr/lib; 头文件 放在/usr/include。

1.1动态库的概念

动态库:这类库的名字一般是libxxx.so,动态库又称共享库;相对于静态函数 库,动态函数库在编译的时候并没有被编译进目标代码中,你的程序执行到相关函数时才调用函数库里的相应函数, 因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态申请并调用, 所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。 而且如果多个应用程序都要使用同一函数库,动态库就非常适合,可以减少应用程序的体积。

1.2静态库的概念

静态库: 这类库的名字一般是libxxx.a;利用静态函数库编译成的文件比较大 ,因为整个函数库的所有数据都被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函 数库支持,因为所有使用的函数都已经被编译进可执行文件了。当然这也会称为它的缺点,因为如果静态函数库改变 了,那么你的程序必须重新编译,而且体积也较大。

1.3动态库的制作

gcc命令:gcc -shared -fpic -o libname.so file1.c file2.c ... fileN.c
输入该命令制作后,后面的.c文件均合并到该动态库里,这里动态库的名字为“name”。

下面通过一个示例来看:
在这里插入图片描述
这里输入制作动态库的命令之后,便生成了这个libbook.so的动态库,而这动态库的名字是book,其后缀为.so。

1.4静态库的制作

gcc命令:gcc -c file.car -rcs libname.a file.o
静态库的制作要先把c文件处理成为.o文件,然后在进行静态库的制作。
下面来看示例:
在这里插入图片描述
这里的main.c文件首先被处理成main.o文件,然后在处理成为了静态库。这里静态库的名字是library,其后缀为.a。

1.5编译链接

在我们编译过程中要用到库的时候,如果静态库和动态库同时存在,则系统优先使用动态库,若想用静态库的话要加上-static选项。
通常会用到以下选项:

  • -L:指定库的路径
  • -l:指定头文件路径
  • -lname:指定库的名字

下面的例子为动态库的链接:
在这里插入图片描述
编译成功后就生成了一个可执行文件了。
在使用动态库的时候,通常会在/lib,/user/lib路径下去找,没有的时候还需要通过改备环境变量去告诉系统去哪里找,linux命令为:export LD_LIBRARY_PATH=xxx,后面的xxx为指定的路径。

2.Makefile的使用
2.1Makefile的含义

一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于 进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。
在 Linux(unix )环境下使用GNU 的make工具能够比较容易的构建一个属于你自己的工程,整个工程的编译只需要一个命令就可以完成编译、连接以至于最后的执行。不过这需要我们投入一些时间 去完成一个或者多个称之为Makefile 文件的编写。
所要完成的Makefile 文件描述了整个工程的编译、连接等规则。其中包括:工程中的哪些源文件需要编译以及如何编译、需要创建那些库文件以及如何创建这些库文件、如何最后产生我们想要 的可执行文件。尽管看起来可能是很复杂的事情,但是为工程编写Makefile 的好处是能够使用一行命令来完成“自动 化编译”,一旦提供一个正确的 Makefile。编译整个工程你所要做的唯一的一件事就是在shell 提示符下输入make命 令。整个工程完全自动编译,极大提高了效率。

2.2Makefile的结构
#注释
target:   depend1  depend2 depend3 ...
TAB]  action1  
[TAB ] action2
target1:
[TAB] action1 
[TAB] action2
  • #表示注释
  • 变量定义 VAL=pen,定义变量VAL,强制赋值pen。VAL+=opp,在VAL之前定义的值后面在追加opp这个值。VAL?=penopp,如果之前VAL没有被定义就使用penopp这个值,否则使用原来的值。
  • 第一个target为总目标。
  • 目标后面的depend为依赖,依赖可以是一个文件。也可以是一个目标。
  • action动作一定可以是linux命令,但前面的字符一定要是[TAB]。
2.3Makefile的使用
  • make:直接输入make为找makefile或Makefile文件中执行总目标。
  • make xxx:到makefile中找指定的xxx目标。
  • make -C directory:进入到指定的directory文件夹中执行总目标。
  • make xxx -C directory:进入指定的directory文件夹中执行指定的xxx目标。
  • make -f comm_makefile:通过-f选项指定一个makefile文件。
  • make VAR=value:给makefile文件传一个VAR参数,其值为value。
  • linux下通过命令vim makefile创建makefile。
  • 要是不想makefile的命令打印到标准输出上,可以在命令前面加@符号
2.4Makefile示例
2.4.1当前文件夹下的操作
  1 all:
  2         gcc daemon.c -o elf
  3         mv elf a.out
  4 
  5 clean:add
  6         rm -rf a.out
  7 
  8 add:
  9         ls

直接使用make:
在这里插入图片描述
指定使用clean:
在这里插入图片描述这里的clean目标要先执行add依赖,然后执行clean.

2.4.2有子目录文件夹的操作

在有子目录的情况下,只有make -C directory命令即可进入指定的子目录下执行makefile。以上一个程序为例执行总目标:
在这里插入图片描述
执行指定的add:
在这里插入图片描述
makefile对一个优秀的程序员来说非常重要,学会它很有必要!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值