gcc -shared 必须配合 -fPIC 使用,否则因生成固定地址代码导致链接失败;-L必须在-l之前指定非标准库路径;运行时缺库需通过LD_LIBRARY_PATH或ldconfig解决。

gcc -shared 必须配合 -fPIC 使用
直接写 gcc -shared foo.c -o libfoo.so 会失败,链接器报错类似 relocation R_X86_64_32 against `.rodata' can not be used when making a shared object。这是因为动态库必须是位置无关代码(PIC),而默认编译生成的是固定地址代码。-fPIC 告诉编译器生成能加载到任意内存地址的机器码,这是 -shared 的硬性前提。
- 先编译:
gcc -fPIC -c foo.c -o foo.o - 再链接:
gcc -shared foo.o -o libfoo.so - 一步到位也行:
gcc -fPIC -shared foo.c -o libfoo.so(gcc 内部会自动完成编译+链接)
链接外部库时 -L 和 -l 的顺序与路径问题
如果你的源码用了 libcurl 或自定义的 libnetwork.so,仅加 -lcurl 不够——链接器找不到库文件。它默认只查 /usr/lib、/lib 等系统路径。
- 库在非标准路径(比如
/opt/mylib/lib):必须用-L/opt/mylib/lib告诉链接器去哪找 -
-L必须出现在-lxxx之前,否则无效;例如gcc -fPIC -shared main.c -L/opt/mylib/lib -lnetwork -o libmain.so - 头文件路径用
-I,和-L是两回事,别混淆
运行时报 “cannot open shared object file” 怎么办
编译成功 ≠ 运行成功。错误信息如 error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory,说明程序启动时找不到该 .so 文件。
- 临时解决:运行前设
LD_LIBRARY_PATH,例如LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./myapp - 长期方案:把
.so拷到系统库路径(如/usr/local/lib),再执行sudo ldconfig - 检查依赖:用
ldd ./myapp看哪些库显示not found
Windows 下用 MinGW-w64 生成 .so 是个误区
MinGW-w64 默认目标是 Windows PE 格式,它生成的是 .dll,不是 Linux 的 .so。即使你强行用 gcc -shared 输出后缀为 .so,这个文件也无法在 Linux 上加载,反之亦然。跨平台时务必确认目标平台 ABI 和 loader 兼容性。
真正需要 Linux .so,就得在 Linux 环境或 WSL 中用原生 gcc 编译;Windows 用户不要被文件名误导。











