【C】静态链接和动态链接

一、静态库和动态库

Linux的库文件一般分为静态库和动态库:

静态库(.a): 库文件以.a为后缀,程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库 动态库(.so): 库文件以.so为后缀,程序运行的时候才会去链接动态库的代码,多个程序共享使用库的代码

二、理解库

如果不想给对方我们的源代码,我们可以选择给用户提供我们的.o可重定位目标二进制文件(gcc -c 文件)与.h头文件。让用户用我们提供的.o文件进行链接即可。在编译时,只要把源文件编译成.o文件在将其链接便可形成一个可执行的程序

通过 gcc -o 链接目标文件,生成可执行程序:

我们可以把 .o.h 文件提交给用户,可是如果有成百上千个,那一个个提供太过麻烦。因此为了让用户简单的使用库,我们就把所有 .o文件打包成一个包,给对方提供一个库文件即可。把多个文件合并成一个文件,这个文件就是库,打包的方式就分为了静态库和动态库。

三、制作静态库

创建Makefile

c 复制代码
libmymath.a: my_add.o my_sub.o
		ar -rc $@ $^

my_add.o: my_add.c
		gcc -c my_add.c -o my_add.o

my_sub.o: my_sub.c
		gcc -c my_sub.c -o my_sub.o

.PHONY: output
output:
		mkdir -p mylib/include
		mkdir -p mylib/lib
		cp -f *.a mylib/lib
		cp -f *.h mylib/include

.PHONY: clean
clean:
		rm -rf *.o libmymath.a

在Makefile中,$@$^是自动变量,用于表示规则中的目标和依赖项。

  • $@表示当前规则的目标(target),即规则左侧的文件名。
  • $^表示当前规则的所有依赖项(prerequisites),即规则右侧的文件名。

在Makefile中,libmymath.a: my_add.o my_sub.o规则中的 $@ 表示 libmymath.a,即目标文件名。$^ 表示 my_add.o my_sub.o,即所有依赖项的列表。

当执行命令时,$@$^会被替换为实际的目标和依赖项的文件名,以便进行相关操作。例如,ar -rc $@ $^ 中的 $@ 将被替换为 libmymath.a$^ 将被替换为 my_add.o my_sub.o。因此,该命令最终将执行 ar -rc libmymath.a my_add.o my_sub.o,将 my_add.omy_sub.o 打包成 libmymath.a 静态库。

output 是我们要生成的库

链接库:

c 复制代码
 gcc -o mytest my_test.c  -I ./mylib/include -L ./mylib/lib -lmymath

-I:指明头文件的搜索路径

-L:指明库文件的搜索路径

-l:指明要链接哪个库,带上库的名称(去掉前缀和后缀)

四、制作动态库

首先我们需要把库文件全部编译成.o文件,这里与静态库不同,需要带上选项 -fPIC,形成与位置无关码:

c++ 复制代码
gcc -c -fPIC my_add.c

动态库打包:-shared

c++ 复制代码
gcc -shared -o libmymath.so my_add.o my_sub.o

目录结构:

c 复制代码
➜  test tree
.
├── libmymath.so
├── Makefile
├── my_add.c
├── my_add.h
├── my_add.o
├── mylib
│   ├── include
│   │   ├── my_add.h
│   │   └── my_sub.h
│   └── lib
│       └── libmymath.so
├── my_sub.c
├── my_sub.h
├── my_sub.o
├── mytest
└── my_test.c

链接动态库:

c 复制代码
gcc -o mytest my_test.c -I mylib/include -L mylib/lib  -lmymath

报错了:

我们此时已经告诉了库文件,路径和库名称,选项已经给gcc带上了。但是我们当编译完之后,和gcc还有关系吗?答案是无关的,接下来运行是和OS有关的,动态库是运行时才加载的,所以程序运行起来,OS和shell也是需要知道库是在哪里的!而我们自己制作的库并没有在系统路径下,OS无法找到!如何找到动态库。

把库路径添加到环境变量LD_LIBRARY_PATH:

c 复制代码
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/zmm/playground/test/mylib/lib
相关推荐
xiaolang_8616_wjl6 小时前
c++文字游戏_闯关打怪2.0(开源)
开发语言·c++·开源
夜月yeyue6 小时前
设计模式分析
linux·c++·stm32·单片机·嵌入式硬件
无小道6 小时前
c++-引用(包括完美转发,移动构造,万能引用)
c语言·开发语言·汇编·c++
FirstFrost --sy8 小时前
数据结构之二叉树
c语言·数据结构·c++·算法·链表·深度优先·广度优先
Tanecious.9 小时前
C++--map和set的使用
开发语言·c++
Yingye Zhu(HPXXZYY)9 小时前
Codeforces 2021 C Those Who Are With Us
数据结构·c++·算法
liulilittle10 小时前
LinkedList 链表数据结构实现 (OPENPPP2)
开发语言·数据结构·c++·链表
无聊的小坏坏10 小时前
三种方法详解最长回文子串问题
c++·算法·回文串
山河木马10 小时前
前端学习C++之:.h(.hpp)与.cpp文件
前端·javascript·c++
2401_8919573110 小时前
list的一些特性(C++)
开发语言·c++