静态库与动态库
一、库
1.合久必分——增量编译——易于维护,分久必合——库——易于使用。
2.链接静态库是将库中的被调用代码复制到调用模块中, 而链接共享库则只是在调用模块中,嵌入被调用代码在库中的(相对)地址。
3.静态库占用空间非常大,不易修改但执行效率高。共享库占用空间小,易于修改但执行效率略低。
4.静态库的缺省扩展名是.a,共享库的缺省扩展名是.so。
5.环境变量
C_INCLUDE_PATH - C头文件的附加搜索路径,相当于gcc的-I选项
CPATH - 同C_INCLUDE_PATH
CPLUS_INCLUDE_PATH - C++头文件的附加搜索路径
LIBRARY_PATH - 链接时查找静态库/共享库的路径
LD_LIBRARY_PATH - 运行时查找共享库的路径
•通过gcc的-I选项指定C/C++头文件的附加搜索路径:
# gcc calc.c cpath.c -I.
•将当前目录作为C头文件附加搜索路径,添加到CPATH环境变量中:
# export CPATH=$CPATH:. // export保证当前shell的,子进程继承此环境变量
# echo $CPATH
# env | grep CPATH
•也可以在 ~/.bashrc 或者 ~/.bash_profile,配置文件中写环境变量,持久有效:
export CPATH=$CPATH:.
执行
# source ~/.bashrc 或 # source ~/.bash_profile
//生效,以后每次登录自动生效。
头文件的三种定位方式:
1) #include "目录/xxx.h" - 头文件路径发生变化,需要修改源程序
2) C_INCLUDE_PATH/CPATH=目录 - 同时构建多个工程,可能引发冲突
3) gcc -I目录 - 既不用改程序,也不会有冲突
二、静态库
1. 创建静态库
-
编辑源程序:.c/.h
-
编译成目标文件:gcc -c xxx.c -> xxx.o
-
打包成静态库文件:ar -r libxxx.a xxx.o …
1.# gcc -c calc.c 2.# gcc -c show.c 3.# ar -r libmath.a calc.o show.o
ar指令:ar [选项] 静态库文件名 目标文件列表
-r - 将目标文件插入到静态库中,已存在则更新
-q - 将目标文件追加到静态库尾
-d - 从静态库中删除目标文件
-t - 列表显示静态库中的目标文件
-x - 将静态库展开为目标文件
注意:提供静态库的同时也需要提供头文件
2. 调用静态库
-
直接调用
# gcc main.c libmath.a
-
或通过LIBRARY_PATH环境变量指定库路径
# export LIBRARY_PATH=$LIBRARY_PATH:. # gcc main.c -lmath (环境法)
-
通过gcc的-L选项指定库路径
# unset LIBRARY_PATH # gcc main.c -lmath -L. (参数法)
一般化的方法:gcc .c/.o -l<库名> -L<库路径>
3. 运行
在可执行程序的链接阶段,已将所调用的函数的二进制代码,复制到可执行程序中,因此运行时不需要依赖静态库。
范例:show.h、show.c、calc.h、calc.c、math.h、main.c
show.h
#ifndef _SHOW_H
#define _SHOW_H
void show (int a, char op, int b, int c);
#endif//_SHOW_H
show.c
#include <stdio.h>
#include "show.h"
void show (int a, char op, int b, int c)
{
printf ("%d %c %d = %d\n", a, op, b, c);