什么是库
库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。库有两种:
- 静态库 .a[Linux]、.lib[windows]
- 动态库 .so[Linux]、.dll[windows]
// ubuntu 动静态库
// C
$ ls -l /lib/x86_64-linux-gnu/libc-2.31.so
-rwxr-xr-x 1 root root 2029592 May 1 02:20 /lib/x86_64-linux-gnu/libc-2.31.so
$ ls -l /lib/x86_64-linux-gnu/libc.a
-rw-r--r-- 1 root root 5747594 May 1 02:20 /lib/x86_64-linux-gnu/libc.a
//C++
$ ls /usr/lib/gcc/x86_64-linux-gnu/9/libstdc++.so -l
lrwxrwxrwx 1 root root 40 Oct 24 2022 /usr/lib/gcc/x86_64-linux-
gnu/9/libstdc++.so -> ../../../x86_64-linux-gnu/libstdc++.so.6
$ ls /usr/lib/gcc/x86_64-linux-gnu/9/libstdc++.a
/usr/lib/gcc/x86_64-linux-gnu/9/libstdc++.a
// Centos 动静态库
// C
$ ls /lib64/libc-2.17.so -l
-rwxr-xr-x 1 root root 2156592 Jun 4 23:05 /lib64/libc-2.17.so
[whb@bite-alicloud ~]$ ls /lib64/libc.a -l
-rw-r--r-- 1 root root 5105516 Jun 4 23:05 /lib64/libc.a
// C++
$ ls /lib64/libstdc++.so.6 -l
lrwxrwxrwx 1 root root 19 Sep 18 20:59 /lib64/libstdc++.so.6 ->
libstdc++.so.6.0.19
$ ls /usr/lib/gcc/x86_64-redhat-linux/4.8.2/libstdc++.a -l
-rw-r--r-- 1 root root 2932366 Sep 30 2020 /usr/lib/gcc/x86_64-redhat-
linux/4.8.2/libstdc++.a
预备工作,准备好代码,在任意新增"库文件"
//file.c
#include<stdio.h>
int main()
{
Myprint();
return 0;
}
//hello.c
#include<stdio.h>
void Myprint()
{
printf("hello\n ");
}
//hello.h
void Myprint();
//Makefile
libmyc.a:hello.o file.o
ar -rc $@ $^
hello.o:hello.c
gcc -c $<
file.o:file.c
gcc -c $<
.PHONY:output
output:
mkdir -p lib/include
mkdir -p lib/mylib
cp -f *.h lib/include
cp -f *.a lib/mylib
.PHONY:clean
clean:
rm -f *.o libmyc.a
上述代码实现是静态库的原理,原来只要我把.o文件,打包链接起来就可以达到库的效果!头文件包含了方法的声明,库包含了方法的实现,所有的库(无论是动还是静),本质是源文件对应的.o!
静态库
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中,程序运行的时候将不再
需要静态库,本质就是.o打了一个包。
- 一个可执行程序可能用到许多的库,这些库运行有的是静态库,有的是动态库,而我们的编译默认为动态链接库,只有在该库下找不到动态.so的时候才会采用同名静态库。我们也可以使用 gcc的 -static 强转设置链接静态库。
ar 是 gnu 归档工具, rc 表示 (replace and create),.a静态库,本质是一种归档文件,不需要使用者解包,而用gcc/g++直接进行链接即可!
- t: 列出静态库中的文件
- v:verbose 详细信息
库的命名一般一lib开头,.a结尾,去首区尾就是库的名字
库的使用
1.指定参数
//user.c
#include<stdio.h>
int main()
{
Myprint();
return 0;
}
如果我们要连接任何非C/C++标准库(包括其他外部或者我们自己写的) 都要指明 -l 或 -L
去哪里找(-L)找什么库(-l)
- -L: 指定库路径
- -I: 指定头文件搜索路径
- -l: 指定库名
- 测试目标文件生成后,静态库删掉,程序照样可以运行
或着在需要链接库的.c文件里面导包链接绝对路径
2.将库拷贝至Linux的默认路径下
因为是第三方库,还得带-l
所以,对库的安装,其实就是将对应的头文件,库文件拷贝到系统的指定文件下