库文件
不将所有功能写到同一个.c中
.c编译得到一个二进制.o目标文件,将所有.o与main.c编译得到一个a.out二进制可执行程序/文件
静态库
库也是文件,linux万物皆文件
a.o,b.o,c.o放到libxxx.a库
编译时,静态库+调用模块main.c一起编译生成a.out,会将用到的功能.o复制到a.out 中
编译得到calc.o,show.o,打包成库libmath.a,main.c调用时找libmath.a即可
-c表示只编译(compile)源文件但不链接,会把.c或.cc的c源程序编译成目标文件,一般是.o文件。-o用于指定输出(out)文件名。不用-o的话,一般会在当前文件夹下生成默认的a.out文件作为可执行程序。
例如:
gcc -c test.c将生成test.o的目标文件
gcc -o app test.c/gcc test.c -o app将生成可执行程序app
写调用模块main.c
此时main.c只有调用,add与sub的功能并不知道
将调用与库一起编译则成功
gcc -o main main.c calc.c show.c等价于
gcc -o main main.c libmath.a
只有两个.o所以还可以,但是.o多了起来后使用库方便管理,可以单人用也可以多人用
通过接口文件,方便维护函数
调用模块和库在同一目录下时,可以直接编译
调用模块和库不在同一目录下时
-l后面跟库名,不需要带拓展名和前缀lib, -L..代表当前目录的上层目录
-L后面跟相对路径和绝对路径都可以
动态库
二二进制文件就是指令,cpu读取二进制就是读取指令
so:share object
cp ../static/*.h . (..代表当前路径的上一路径,复制当前路径的上一路径下的static目录下所有的.h)
动态库不用ar打包,用gcc打包
调用模块main.c与库libmath.so在同一目录下,直接编译
报错是执行时的问题,不是编译的问题
链接器也叫加载器
PATH给bash使用,用来找命令/可执行程序
LIBRARY_PATH给gcc使用,用来在编译阶段,找库
LD_LIBRARY_PATH给链接器使用,用来在文件/程序执行时找库,跳转
此处《程序员的自我修养》或可解答
a.out中的指令和数据加载到内存条中,cpu从内存条中把指令和数据读取,cpu执行
库也要加载到内存条中,cpu要知道函数的地址才能执行,
库(中的函数)的地址是虚拟地址,会映射到不同的可执行程序/文件中
通过地址+偏移量的方式来确定库中函数的地址
多数情况下会使用动态库,因为便于更新维护,例如王者荣耀更新就是下载新的动态库,不用更新客户端