gcc
-O0 -O1 -O2 -O3 优化方式
-g0 -g1 -g2 -g3 加入调试信息
-Wall 显示所有警告
-Werror 把所有警告当做错误
-w 关闭警告
-o 指定输出文件名
-E 预编译
-c 只编译不连接
-S 汇编
-D 在命令行定义宏
-x 指定编译的语言类型
-std=c89
-std=c99
编译过程:-E -c -S 自动调用连接器
连接器:ld
gcc只是编译器,ld是链接器
.a 静态库,也称
.so 动态库
.i 预编译文件
.s 汇编文件
库:
二进制已经编译的归档文件
容易组织代码,容易复用,保护版权。
库命名规则
lib库名.a.主版本号.副版本号.批号
库使用规则
-l库名
-L库所在目录
静态库的编译
编译好的程序运行的时候不依赖库。
库作为程序的一部分编译链接。
本质:目标文件的归档。
1:编译成目标文件(.archieve)
ar归档工具
-r -t(查看归档文件)可选
查看函数符号表
3:使用静态库
-O0 -O1 -O2 -O3 优化方式
-g0 -g1 -g2 -g3 加入调试信息
-Wall 显示所有警告
-Werror 把所有警告当做错误
-w 关闭警告
-o 指定输出文件名
-E 预编译
-c 只编译不连接
-S 汇编
-D 在命令行定义宏
gcc test.c -omain -DNUM=56
-x 指定编译的语言类型
-std=c89
-std=c99
编译过程:-E -c -S 自动调用连接器
连接器:ld
gcc只是编译器,ld是链接器
.a 静态库,也称
.so 动态库
.i 预编译文件
.s 汇编文件
库:
二进制已经编译的归档文件
容易组织代码,容易复用,保护版权。
库命名规则
lib库名.a.主版本号.副版本号.批号
库使用规则
-l库名
-L库所在目录
静态库的编译
编译好的程序运行的时候不依赖库。
库作为程序的一部分编译链接。
本质:目标文件的归档。
1:编译成目标文件(.archieve)
-static 可选
gcc -static -c add.c
2:归档成静态库
ar归档工具
-r -t(查看归档文件)可选
ar -r libadd.a add.o
nm + 静态库、动态库、目标文件、执行文件
查看函数符号表
3:使用静态库
gcc appc.c -ladd -L. -o main
动态库的编译
动态库不会连接成程序的一部分。
编译
-c -fpic
连接
-shared
使用动态库
gcc 文件名 -l库名 -L动态库路径
运行文件
发现运行找不到动态库:
通过修改环境变量LD_LIBRARY_PATH,设定当前路径。运行即可。
动态库加载:
找到动态库
加载动态库到内存
映射到用户的内存空间
动态库查找规则:
/lib;/usr/lib;LD_LIBRARY_PATH指定的路径中找
使用dlfcn.h和libdl.so在程序中加载动态库
#include <stdio.h>
#include <dlfcn.h>
int main(){
void * handler = dlopen("./libadd.so",RTLD_LAZY);
int (*fun)(int,int) =(int(*)(int,int)) dlsym(handler,"add");
int sum = (*fun)(1,2);
printf("%d\n",sum);
dlclose(handler);
return 0;
}
查找文件
find / -name "*.a" -type f 2 > /dev/null
ldd
查看动态库或者可执行文件中用到的库
readelf