动静态库的制作
创始人
2024-02-05 22:39:07
0

目录

一.动静态库的原理

二.静态库

2.1制作静态库

 2.2使用静态库

三.动态库

3.1制作动态库

3.2动态库的使用 


一.动静态库的原理

首先要知道可执行程序的生成过程:1,预处理  2,编译 3,汇编  4 ,链接

1.预处理

头文件include的包含,删注释,#define定义符号的替换,条件编译等..形成XXX.i文件

2.编译 

编译: 完成词法分析、语法分析、语义分析、符号汇总等,形成XXX.x文件

3.汇编

 将汇编指令转换成二进制指令,形成符号表,最终形成XXX.o文件
 

4.链接 

合并段表,符号表的合并和重定位, 将生成的各个xxx.o文件进行链接,最终形成可执行程序。  

看下面很简单的代码:

add.cpp

#include"add.h"int add(int a,int b)
{int sum=a+b;return sum;
}

add.h

#pragma once
#include
using namespace std;extern int add(int a,int b);

 test.cpp

#include"add.h"int main()
{int a=10;int b=10;int sum=add(a,b);cout<

 结果:

包头文件用"",是在当前路径上找,<>是在系统目录下找。

test.cpp形成test.o时,之前只是将该头文件展开,只找到函数的声明,add 的符号表中的地址是无效的,链接时与add.o重定位后才有效,合并段表,形成可执行程序。

我们可以将函数的实现变为XXX.o文件,放在一起,并将该函数的声明(头文件)放入系统头文件中,就可以认为形成了一个库。后面要使用这个函数就可以配合那个库去使用。

1.静态库:Linux下静态库是以.a为后缀的文件。程序在编译链接时会将库里面的代码拷贝一份放入我们的可执行程序里面,程序运行的时候将不再需要静态库

2.动态库:在Linux下动态库是以.so为后缀的文件。动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。

3.静态链接:将库里的代码拷贝到可执行程序的过程。

4.动态链接:在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamic linking)。

5.库名称的识别:例如:libc.so,只需要去掉前缀lib和后缀.so

6.链接的本质:链接.lib文件和.o文件

二.静态库

2.1制作静态库

例如:我们来实现一个加法函数与打印时间的函数,将它的方法打包成库。

add.h头文件:

#pragma once
#include
using namespace std;extern int add(int a,int b);

add.cpp文件:

#include"add.h"
int add(int a,int b)
{int sum=0;for(int i=a;i<=b;i++)sum+=i;return sum;
}

Print.h头文件:

#pragma once
#include
#include
using namespace std;extern void Print();

print.cpp文件:

#include"Print.h"void Print()
{cout<

步骤:

1.让所有源文件生成对应的目标文件

2.使用ar命令将所有目标文件打包为静态库

  • -r(replace):若静态库文件当中的目标文件有更新,则用新的目标文件替换旧的目标文件。
  • -c(create):建立静态库文件。

3.将头文件和生成的动态库组织起来

 编写makefile:

libshow.a:add.o print.oar -rc libshow.a add.o print.o
add.o:add.cppg++ -c add.cpp -std=c++11
print.o:print.cppg++ -c print.cpp -std=c++11.PHONY:lib
lib:mkdir -p lib-static/lib   mkdir -p lib-static/include  cp *.a lib-static/lib        //将形成的静态库放入lib-static/lib目录下 cp *.h lib-static/include    //将对应的头文件放入lib-static/include目录下.PHONY:clean
clean:rm -rf *.o *.a  lib-static

结果:

此外,我们可以用ar命令的-t选项和-v选项查看静态库当中的文件。

  • -t:列出静态库中的文件。
  • -v(verbose):显示详细的信息。

例如:

 2.2使用静态库

方法1:推荐使用

使用gcc编译main.c生成可执行程序时需要携带三个选项:

  • -I:指定头文件搜索路径。
  • -L:指定库文件搜索路径。
  • -l:指明需要链接库文件路径下的哪一个库。

例如:

test.cpp文件调用那两个方法:

#include"add.h"
#include"Print.h"int main()
{int a=1;int b=10;int sum=add(a,b);cout<

结果:

 注意:上面的路径用绝对与相对路径都可以,-I-L-l这三个选项后面可以加空格,也可以不加空格。库的名称是去掉前缀与后缀。

补充:

  1. 因为编译器不知道你所包含的头文件add.h在哪里,所以需要指定头文件的搜索路径。
  2. 因为头文件add.h当中只有my_add函数的声明,并没有该函数的定义,所以还需要指定所要链接库文件的搜索路径。

方法2:把头文件和库文件拷贝到系统路径下

头文件路径:/usr/include/

库的路径:/lib64/

例如:

 补充:使用g++编译的是.cpp,而g++就是用来编译C++程序的,所以g++编译的时候默认就找的是C++库,但此时我们要链接的是哪一个库编译器是不知道的,因此我们还是需要使用-l选项,指明需要链接库文件路径下的哪一个库.

三.动态库

3.1制作动态库

1.让所有源文件生成对应的目标文件

用源文件生成目标文件时需要携带-fPIC选项:产生与位置无关码。-fPIC作用于编译阶段,告诉编译器产生与位置无关的代码,此时产生的代码中没有绝对地址,全部都使用相对地址,从而代码可以被加载器加载到内存的任意位置都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。

2.使用-shared选项将所有目标文件打包为动态库

3.将头文件和生成的动态库组织起来

编写makefile:

libshow.so:add.o print.og++ -o libshow.so -shared add.o print.o -std=c++11
add.o:add.cppg++ -c add.cpp -fPIC -std=c++11
print.o:print.cppg++ -c print.cpp -fPIC -std=c++11.PHONY:lib
lib:mkdir -p lib-dyl/libmkdir -p lib-dyl/includecp *.so lib-dyl/libcp *.h lib-dyl/include.PHONY:clean
clean:rm -rf *.o *.a libshow.a libshow.so lib-static lib-dyl

结果:

3.2动态库的使用 

使用该动态库的方法与使用静态库的方法一样,可以使用 -I-L-l这三个选项来生成可执行程序,也可以先将头文件和库文件拷贝到系统目录下,然后再使用-l选项指明需要链接的库名字来生成可执行程序。

例如:生成的可执行程序的路径下不含要使用的库,发现该程序运行不起来。

 

方法1:拷贝.so文件到系统共享库路径下

 

方法二:更改LD_LIBRARY_PATH

LD_LIBRARY_PATH是程序运行动态查找库时所要搜索的路径,我们只需将动态库所在的目录路径添加到LD_LIBRARY_PATH环境变量当中即可。

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/LF/linux-l/lesson3/lib-dyl/lib

 

方法三:配置/etc/ld.so.conf.d/

/etc/ld.so.conf.d/路径下存放的是以.conf为后缀的配置文件,这些配置文件当中存放的都是路径,系统会自动在/etc/ld.so.conf.d/路径下找所有配置文件里面的路径,之后就会在每个路径下找你所需要的库。若将自己库文件的路径也放到该路径下,那么当可执行程序运行时,系统就能够找到我们的库文件了。再使用ldconfig命令将配置文件更新一下,更新之后系统就可以找到该可执行程序所依赖的动态库了。

例如:

[LF@ecs-100710 lesson3]$ echo /home/LF?linux-l/lesson3/lib-dyl/lib > xx.conf
[LF@ecs-100710 lesson3]$ sudo cp xx.conf /etc/ld.so.conf.d/
[LF@ecs-100710 lesson3]$ sudo ldconfig
[LF@ecs-100710 lesson3]$ ./test
55
1669019703

相关内容

热门资讯

描写开心的句子 描写开心的句子(精选120句)  无论是身处学校还是步入社会,大家都看到过许多经典的句子吧,不同的句...
感谢姐姐的短句暖心感恩姐姐的... 感谢姐姐的短句暖心2022感恩姐姐的句子  在平凡的学习、工作、生活中,大家总少不了接触一些耳熟能详...
刻骨铭心的爱情句子 有关刻骨铭心的爱情句子  1、爱情不在于一朝一夕,需要的是刻骨铭心。  2、回首往事,是谁欠谁的债,...
自我提神醒脑的句子 自我提神醒脑的句子(精选185句)  在平平淡淡的日常中,大家都收藏过令自己印象深刻的句子吧,句子可...
草房子好句 草房子好句  1、立在炉上的那只黑色的瓦罐,造型土气,但似乎又十分讲究,粗朴的身子,配了一只弯曲得很...
火树银花造句 火树银花造句  一、火树银花简介  意思是形容张灯结彩或大放焰火的灿烂夜景。出自唐·苏味道《正月十五...
友谊留言句子   友情的真挚永远比不上真金。真金能卖友情不能。友情,就好比一条简单的线。无论你在什么地方,发生什么...
短而精的句子   短而精的句子  1、爱是一种需要不断被人证明的虚妄,就像烟花需要被点燃才能看到辉煌一样。  2、...
简单的排比句 简单的排比句  在学习、工作或生活中,大家总少不了接触一些耳熟能详的句子吧,从语气上分,句子可以分为...
优美文艺句子 通用优美文艺句子48句  黑白头像下隐藏着一颗破碎的心和一个等待的人。下面是小编搜索整理的优美文艺句...
对人生路迷茫的句子 对人生路迷茫的句子  迷茫,让我们的生活像水一样平乏无味却又无处不在,久而久之,渗透出汩汩水流,汇而...
描写周边环境的句子 描写周边环境的句子(精选50句)  在生活、工作和学习中,大家都接触过很多优秀的句子吧,不同的句子在...
高中好词佳句摘抄 高中好词佳句摘抄大全  摘抄是指从文刊、文件等资料里阅读的时候 ,把语言优美,值得品析,值得学习的词...
真心思念一个人的句子 真心思念一个人的句子1、无论如何谢谢你,七年里,你见证了我的一切。2、我在怀念,没有想念的意思。3、...
描写母爱伟大的经典句子 描写母爱伟大的经典句子(精选75句)  无论在学习、工作或是生活中,大家最不陌生的就是句子了吧,句子...
新年祝福语句子 新年祝福语句子(精选160句)  在学习、工作乃至生活中,大家或多或少都会用到过祝福语吧,祝福语是人...
相濡以沫爱情唯美句子 相濡以沫爱情唯美句子  时间会告诉我们,简单的喜欢,最长远;平凡中的陪伴,最心安;懂你的人,最温暖。...
描写瀑布的好词佳句介绍 描写瀑布的好词佳句介绍  拔地万里青嶂立,悬空千丈素流分。共看玉女机丝挂,映日还成五色文。  好像叠...
朋友之间的友谊句子 朋友之间的友谊句子  如果我找不到你,我就会对着天空大喊你的名字,直到你出现。下面是小编为大家精心推...
表达感恩父母的话 表达感恩父母的一句话  父母恩情,一生不忘,我们要学会感恩父母,以下是小编搜索整理表达感恩父母的一句...