静态库制作需先用gcc -c编译源文件生成.o,再用ar rcs libname.a *.o打包;命名必须以lib开头、.a结尾,链接时须配合-l指定路径和-l指定库名。

gcc -c 编译多个 .c 文件生成对应 .o 文件
静态库本质是多个 .o 目标文件的归档集合,不能直接用源文件(.c)打包。必须先分别编译出目标文件,再交给 ar 打包。
常见错误是执行 ar rcs libfoo.a foo.c bar.c —— 这会失败,因为 ar 只接受已编译的 .o,不认 .c。
- 逐个编译:
gcc -c foo.c -o foo.o、gcc -c bar.c -o bar.o - 批量编译(推荐):
gcc -c foo.c bar.c→ 自动生成foo.o和bar.o - 加
-I指定头文件路径(如有自定义头文件):gcc -c -I./include foo.c bar.c - 建议加
-Wall检查潜在问题:gcc -Wall -c foo.c bar.c
ar rcs 生成 .a 文件时注意命名和顺序
ar 命令本身不检查符号定义或依赖关系,只是把 .o 文件“塞进”归档里。名字必须以 lib 开头、.a 结尾,否则链接时 -lfoo 找不到。
错误示例:ar rcs mylib.a foo.o bar.o → 链接时写 -lmylib 会失败,因为实际库名是 mylib.a,而 -l 默认找 libmylib.a。
- 正确命名:
ar rcs libfoo.a foo.o bar.o - 参数含义:
r(插入)、c(创建)、s(生成索引,必需) - 顺序无关紧要:
ar不依赖.o的排列顺序,链接器会在整个归档中搜索符号
链接静态库时 -L 和 -l 必须配对使用
用 gcc 链接静态库时,不能直接写 gcc main.o libfoo.a -o app(虽然能工作,但不规范、不可移植);应使用标准的 -L + -l 组合,否则跨目录或换环境容易出错。
典型错误:只写 -lfoo 却没告诉编译器去哪找 libfoo.a,报错 cannot find -lfoo。
- 库在当前目录:
gcc main.o -L. -lfoo -o app - 库在
./lib下:gcc main.o -L./lib -lfoo -o app -
-L和-l的顺序有影响:库选项要放在目标文件之后、输出选项之前 - 静态库优先于同名动态库:若同时存在
libfoo.a和libfoo.so,-lfoo默认选.a;强制用动态库需加-shared-libgcc或改用-Wl,-Bdynamic
静态库不导出符号表,调试时看不到内部函数名
和动态库不同,静态库在链接时把代码直接复制进可执行文件,nm libfoo.a 能看到符号,但运行时 GDB 无法按函数名断点(除非编译时加 -g 且保留调试信息)。
- 编译
.o时务必加-g:gcc -g -c foo.c bar.c - 打包不影响调试信息:
ar rcs libfoo.a foo.o bar.o会保留.o中的 debug section - 链接时不 strip:
gcc -g main.o -L. -lfoo -o app,否则 GDB 无法解析源码行 - 验证是否含调试信息:
file app应显示 “with debug_info”,readelf -S app | grep debug应有非空输出











