1. 什么是库
库是写好的现有的,成熟的,可以复⽤的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个⼈的代码都从零开始,因此库的存在意义非同寻常。
本质上来说库是⼀种可执⾏代码的⼆进制形式,可以被操作系统载⼊内存执行。库有两种:
bash
• 静态库 .a[Linux]、.lib[windows]
• 动态库 .so[Linux]、.dll[windows]
2. 静态库
静态库(.a):程序在编译链接的时候把库的代码链接到可执行⽂件中,程序运行的时候将不再
需要静态库。
⼀个可执行程序可能⽤到许多的库,这些库运⾏有的是静态库,有的是动态库,而我们的编译默
认为动态链接库,只有在该库下找不到动态.so的时候才会采⽤同名静态库。我们也可以使⽤ gcc
的 -static 强转设置链接静态库。
编译当前目录所有的.c文件,将它们链接成一个单一的可执行文件
编译当前目录所有的.o文件,将它们链接成一个单一的可执行文件

将所有的.o文件打包形成一个静态库

ar
是 Unix/Linux 系统中的一个重要命令,全称是 "archive"(归档),主要作用是创建、修改和提取静态库(归档文件)。它最常见的用途是将多个目标文件(
.o
文件)打包成一个后缀为.a
的静态库文件,方便程序编译时链接使用。
r
(replace):替换或添加文件到归档文件中
- 如果指定的文件已存在于归档中,则替换它
- 如果不存在,则添加到归档中
c
(create):创建归档文件
- 当指定的归档文件不存在时,自动创建一个新的归档文件
- 如果不使用
c
选项,而归档文件又不存在,命令会报错
libmy.a : 静态库命名
- lib :固定前缀,所有静态库都以
lib
开头,是系统识别静态库的标志;- my :自定义的库名称(如
math
、utils
、myapp
);- .a:固定后缀(archive 的缩写,意为 "归档文件"),表示该文件是静态库。

可以看到直接将usercode.c编译成usercode是找不到库的。因为系统会默认去 /lib
、/usr/lib
等标准目录找库。自定义库(如 mylibc.a
)不在这些目录,所以编译器找不到。

-L.
:指定库文件的搜索路径这里的
.
表示当前目录,-L
选项告诉 GCC 编译器:在链接阶段,除了系统默认的库目录外,还要到-L
后面指定的路径(此处为当前目录)中查找需要的库文件。
-lmy
:指定要链接的库名称
lib
是 Linux 系统中库文件的默认前缀 ,-lmy
实际上告诉 GCC 去链接名为libmy.a
(静态库)或libmy.so
(动态库)的库文件。编译器会根据搜索路径(包括-L
指定的路径和系统默认路径)查找并链接这个库。

-I.
:指定头文件的搜索路径这里的
.
表示当前目录,-I
选项告诉 GCC 编译器:在编译阶段(预处理阶段),除了系统默认的头文件目录外,还要到-I
后面指定的路径(此处为当前目录)中查找需要的头文件。
把头文件和库文件拷贝到系统指定的头文件和库文件目录下


将.h 和 .a进行打包:


-I
选项用于指定 头文件(header files)的搜索目录。
3. 动态库
3.1 制作动态库:

-fPIC
:生成位置无关代码(Position-Independent Code),用于创建可被多个程序共享的动态链接库(.so 文件),确保库代码在不同内存地址加载时能正确执行。

-shared
: 告诉gcc
编译器,要将输入的目标文件(.o
文件) 链接成一个共享库文件。共享库是一种可在运行时被多个程序同时使用的动态链接库,在 Linux 系统中,共享库文件的后缀通常是.so
。
3.2 打包动态库:
cpp
l: Makefile
1 libmy.so:mystdio.o mystring.o
2 gcc -shared -o $@ $^
3 mystdio.o:mystdio.c
4 gcc -fPIC -c $<
5 mystring.o:mystring.c
6 gcc -fPIC -c $<
7
8 .PHONY:output
9 output:
10 mkdir -p lib/include
11 mkdir -p lib/mylib
12 cp -f *.h lib/include
13 cp -f *.so lib/mylib
14 tar czf lib.tgz lib
15
16 .PHONY:clean
17 clean:
18 rm -rf *.o libmy.so lib lib.tgz

3.3 编译运行程序:

静态库能直接运行,是因为链接时会将库中代码完整拷贝到可执行文件里,运行时不依赖外部文件。
动态库找不到,是因为链接时仅记录库的引用,运行时系统默认只在标准路径找库。若动态库在非标准路径(如这里的lib/mylib
),未通过LD_LIBRARY_PATH
等方式告知系统位置,就会找不到。
当系统运行可执行文件时找不到对应的动态链接库,主要有以下几种解决方法:
1. 拷贝至系统标准库目录 :将动态库文件(如
libmy.so
)直接复制到系统默认搜索动态库的目录,比如/lib
或/usr/lib
等。这样系统在运行程序时,能在这些标准目录中找到动态库。2. 建立软链接 :
在系统的标准库目录(如
/lib
或/usr/lib
)下,为动态库文件创建软链接。通过软链接,系统可以间接定位到实际的动态库文件,从而让程序能够加载到动态库。3. 设置
LD_LIBRARY_PATH
环境变量:设置环境变量 :执行
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/home/user1/linux-learning/course/lesson14/ku/zhangsan/lib/mylib
,把动态库libmy.so
所在的目录/home/user1/linux-learning/course/lesson14/ku/zhangsan/lib/mylib
添加到LD_LIBRARY_PATH
中。LD_LIBRARY_PATH
是 Linux 系统中用于指定动态链接库搜索路径的环境变量,程序运行时会在该变量指定的路径里查找所需的动态库。验证环境变量 :用
echo ${LD_LIBRARY_PATH}
查看,能看到刚添加的路径已在其中。4. 配置
/etc/ld.so.conf.d/
:在/etc/ld.so.conf.d/
目录下创建一个以.conf
为后缀的配置文件(例如mylib.conf
),在该文件中添加动态库所在的目录。然后运行sudo ldconfig
命令,更新系统的动态链接库缓存。这样系统会将该目录纳入动态库的搜索范围,所有程序都能在该目录下查找动态库,这是一种较为持久且系统级的配置方法。