一、头文件和库文件
1、在使用C语言和其他语言进行程序设计的时候,我们需要头文件来提供对常数的定义和对系统及库函数调用的声明。
2、库文件是一些预先编译好的函数集合,那些函数都是按照可重用原则编写的。它们通常由一组互相关联的用来完成某项常见工作的函数构成。比如用来处理屏幕显示情况的函数(ncurses库)和数据库访问例程(dbm库)等。
二、头文件与库文件位置
1、usr/include及其子目录底下的include文件夹
2、/usr/local/include及其子目录底下的include文件夹
3、/usr/lib
4、/usr/local/lib
三、使用外部库(-l选项)
//calc.c
#include <math.h>
#include <stdio.h>
int main(void)
{
double x = pow(2.0, 3.0);
printf("The cubed is %f\n", x);
return 0;
}
gcc -Wall calc.c -o calc -lm
-lm表示要链接libm.so或者libm.a库文件
四、静态库与共享库
1、静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库
静态库占用磁盘空间,多个程序不能共享,因为每个程序想要使用这个库都会被链接到可执行文件中去,所以导致可执行文件体积增大。加载时候,在内存中运行时候,导致占用内存,因为需要将库的代码加载到内存才能运行,不同程序使用同样一个库,需要加载多分拷贝
2、共享库( .so或.sa ):程序在运行的时候才去链接共享库的代码,多个程序共享使用库的代码。
3、一个与共享库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码
4、在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该共享库中复制到内存中,这个过程称为动态链接(dynamic linking)
5、共享库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份共享库被要用到该库的所有进程共用,节省了内存和磁盘
五、生成静态库
hello_fn.h
#ifndef _HELLO_FN_H
#define _HELLO_FN_H
void hello(const char* name);
#endif
hello_fn.c
#include <stdio.h>
#include "hello_fn.h"
void hello(const char* name)
{
printf("hello %s!!!\n", name);
}
main.c
#include "hello_fn.h"
int main(void)
{
hello("world");
return 0;
}
执行shell
gcc -Wall hello_fn.c -o hello_fn.o
ar rcs libhello.a hello_fn.o #ar是gnu归档工具,rcs表示(replace and create)
两种链接方式
gcc -Wall main.c libhello.a -o main
gcc -Wall -L. main.c -o main -lhello # -L 指定库搜索路径
六、库搜索路径
1、从左到右搜索-I -L指定的目录(-I表示指定头文件 -L表示静态库.a文件路径)
2、由环境变量指定的目录,C_INCLUDE_PATH、LIBRARY_PATH
vim ~/.bash_profile
export LIBRARY_PATH=你的.a文件的绝对路径
source ~/.bash_profile #生效环境变量
gcc -Wall main.c -o main -lhello #不需要-L指定库路径
3、由系统指定的目录
七、生成共享库
adasda
shared: 表示生成共享库格式
fPIC:产生位置无关码(position independent code)
库名规则:libxxx.so
示例:gcc -shared -fPIC hello.o –o libhello.so
使用共享库
编译选项
I:链接共享库,只要库名即可(去掉lib以及版本号)
L:链接库所在的路径.
示例:
gcc main.o -o main –L. -lhello
gcc -c hello_fn.c -o hello.o
gcc -shared -fPIC hello.o -o libhello.so
gcc main.c -L. -lhello -o main
共享库使用需要共享库在场,如果删除libhello.so,在执行main会报错。因为共享库没有被链接到可执行文件中,需要在运行中将共享库加载到内存中
八、运行共享库
如果将main这个可执行文件mv到别的目录,执行也会报错,如何解决呢?
1、拷贝.so文件到系统共享库路径下,一般指/usr/lib
2、更改LD_LIBRARY_PATH
vim ~/.bash_profile
修改~/.bash_profile内容,export LD_LIBRARY_PATH=你的so文件绝对路径:$LD_LIBRARY_PATH
source ~/.bash_profile #生效LD_LIBRARY_PATH环境变量
3、ldconfig, 配置/etc/ld.so.conf,ldconfig更新ld.so.cache
/etc/ld.so.conf如下图配置
ldd查看程序运行需要加载哪些共享库
error while loading shared libraries: libmysqlclient.so.20解决办法:https://blog.csdn.net/jolly10/article/details/80388217/