gcc生成动态库必须带-fpic和-shared:-fpic使代码可重定位,-shared生成共享对象;漏配会导致undefined symbol或cannot open shared object file等运行时错误。

gcc 生成动态库不是“加个 -shared 就完事”,漏掉关键参数或路径配置,编译能过、运行直接报 undefined symbol 或 cannot open shared object file。
gcc 编译动态库必须带 -fPIC 和 -shared
-
-fPIC不是可选:它让代码能在任意内存地址加载,缺了它,gcc -shared可能成功生成.so,但链接时会失败(尤其在 x86_64 上),错误类似:relocation R_X86_64_32 against `.rodata' can not be used when making a shared object
-
-shared不可省略:没有它,gcc默认生成可执行文件或目标文件,不会导出符号表,调用方根本找不到函数 - 不需要先生成
.o文件:你可以一步到位:gcc -fPIC -shared -o libmylib.so a.c b.c c.h
也可以分两步(适合多源文件或需复用目标文件):gcc -c -fPIC a.c b.c -o a.o b.o
gcc -shared -o libmylib.so a.o b.o
ldd 和 objdump -T 是验证是否真成库的唯一直观手段
-
ldd libmylib.so应该输出干净的依赖列表(不含“not found”),且不报错 -
objdump -T libmylib.so | grep my_func能看到你声明的函数名出现在全局符号表里(DF <em>UND</em>是未定义,DF <em>GLB</em>才是导出) - 常见假成功:文件生成了,但
objdump -T为空 → 函数没加extern声明、头文件没包含、或函数被static修饰了
链接时用 -lxxx 要和 libxxx.so 名字严格对应
-
gcc main.c -L. -lmylib→ 实际查找的是libmylib.so(不是mylib.so,也不是libmylib.so.1) - 如果库叫
libutils.so.2,软链必须存在:ln -sf libutils.so.2 libutils.so,否则-lutils找不到 - 运行时报
libmylib.so: cannot open shared object file,八成是没设LD_LIBRARY_PATH或没放进系统库路径,别急着改代码,先跑:export LD_LIBRARY_PATH="$PWD:$LD_LIBRARY_PATH"
再./a.out
动态库真正麻烦的从来不是编译命令本身,而是符号可见性、运行时路径、版本命名和软链管理——这些地方一错,错误信息几乎不告诉你哪错了。











