linux下动态库必须以lib开头、.so结尾,如libmathutil.so;源码建议命名为mathutil.c;编译需-fpic和-shared参数;makefile须显式指定目标与依赖,生成后建立符号链接。

动态库命名和源码组织必须匹配
Linux下动态库文件名必须以 lib 开头、.so 结尾,比如想生成 libmathutil.so,对应源码文件名建议叫 mathutil.c(或 mathutil.cpp),否则 Makefile 里容易混淆目标名和依赖名。Makefile 不会自动推导“哪个 .c 文件该编译进哪个 .so”,必须显式写清楚。
-
libxxx.so是链接时用的名字(-lxxx),也是LD_LIBRARY_PATH查找时的基准名 - 实际生成的文件是
libxxx.so.1.0,再用ln -sf创建libxxx.so.1和libxxx.so符号链接 - 如果你写
gcc -shared -fPIC math.c -o libmath.so,那 Makefile 里目标就该是libmath.so,不能写成math.so
关键编译参数不能漏:-fPIC 和 -shared
缺 -fPIC 会导致 relocation R_X86_64_32 against `.rodata' can not be used when making a shared object 错误;缺 -shared 则生成的是普通可执行文件或目标文件,不是动态库。
-
-fPIC:让编译器生成位置无关代码,这是动态库的硬性要求 -
-shared:告诉链接器输出共享对象(即 .so),不是可执行文件 - 如果源码含 C++ 类或 STL,用
g++编译,并加-lstdc++(或确保链接阶段隐式包含) - 不要加
-static,它会强制静态链接,跟生成动态库目标冲突
Makefile 中的典型规则写法
一个最小可行的 Makefile 要覆盖:编译目标文件 → 打包成 so → 安装符号链接 → 清理。下面是一个针对 mathutil.c 生成 libmathutil.so 的例子:
CC = gcc CFLAGS = -Wall -fPIC -O2 TARGET = libmathutil.so SOURCES = mathutil.c OBJECTS = $(SOURCES:.c=.o) $(TARGET): $(OBJECTS) $(CC) -shared -o $@ $^ %.o: %.c $(CC) $(CFLAGS) -c $
-
$(OBJECTS)必须先于$(TARGET)构建,否则make无法自动推导 .o 依赖 -
$^表示所有依赖项,$@表示当前目标,避免硬编码文件名 - 安装部分没调用
sudo install,因为普通用户通常只在本地测试,直接 ln 更轻量 - 没写
.PHONY: clean install也能跑,但加上更健壮(尤其当目录下真有叫clean的文件时)
测试动态库是否可用:dlopen/dlsym 与 LD_LIBRARY_PATH
生成后不能只看文件是否存在,得验证能否被程序加载。常见失败点不是编译,而是运行时找不到库。
- 写个简单测试程序调用
dlopen("libmathutil.so", RTLD_LAZY),编译时加-ldl - 运行前必须设置
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH,否则./test会报error while loading shared libraries: libmathutil.so: cannot open shared object file -
ldd ./test可查看是否成功链接到你的libmathutil.so,注意路径是否为not found - 如果要用
-lmathutil链接,得把libmathutil.so放进系统库路径(如/usr/local/lib)并执行sudo ldconfig,否则链接会失败











