1.编译过程与动态库静态库的实现

1.Linux 如何安装 C++ 编译环境

(1)安装 gcc

下载:sudo apt install gcc g++ 
安装:gcc/g++ -v/--version

其中 gcc 用于编译 C ,g++ 用于编译 C++

版本要 >4.8.5 这样才能使用 C++11 的特性

(2) 使用 g++ 编译代码

首先现在对应目录下编写一个 c++ 程序,如:test.cpp,然后执行下面的命令进行编译

g++ test.cpp -o test.out

其中 -o 代表:生成可执行目标文件

test.out 是用户自定义的可执行文件名称,在 linux 下是 .out 在 windows 中是 .exe

(3)运行可执行文件

不能直接敲指令 test.out ,要在前面加 ./test.out

2.编程语言的发展

2.1 编程语言的发展

image-20211029105526970

机器语言:计算机识别的语言

汇编语言:使用简单的符号代替机器语言

2.2 GCC 工作流程

image-20211029110101814

预处理:将头文件导入,宏替换,去掉一些注释

编译:对预处理完的文件进行一系列的词法分析,语法分析,语义分析及优化后生成相应的汇编代码

汇编:对汇编代码进行处理,生成处理器能识别的指令

目标代码:计算机可以识别的代码

链接:将这个文件中使用的相关库进行链接,形成可执行程序

2.3 gcc 编译选项代码演示

image-20211029111249299 image-20211029110233749 image-20211030103225473

分别执行上面的代码:

1.-E

预处理源文件

g++ test.cpp -E -o test.i
image-20211029111708675

这是一个长长的文件,直接定位到 Hello World 部分,可以看到所有的注释,宏定义,头文件全部被替换

2.-S

生成汇编代码

g++ test.i -S -o test.s
image-20211029111913031

**3.-s **

生成可执行文件

g++ test.s -s -o test.o
image-20211029112057911

上图是一对乱七八糟的东西,其实这个文件不能被打开。但是可以直接执行

image-20211029112207044

4.一步式操作

g++ test.cpp
image-20211029112518629

可以看到上图直接生成了一个 ,out 文件,同理如果直接跳过 -E 还有 -S 直接执行 -s 也是可以的

2.库的制作

库文件是计算机上的一类文件,可以将库文件看做是一种代码仓库。它提供给使用者一些可以直接拿来用的变量,函数或类。库是一种特殊的程序,但是库是不能单独运行的。

库文件有两种:静态库和动态库

静态库: GCC进行链接时,会把静态库中代码打包到可执行程序中

动态库: GCC进行链接时,动态库的代码不会被打包到可执行程序中,程序启动之后,动态库会被动态加载到内存中,通过动态库地址访问动态库,但是对于自己刚刚写的库系统是不知道库的内存地址的,所以就要自己手动为动态库添加环境变量地址,通过ldd (list dynamic dependencies)命令检查动态库依赖关系

库的好处:1.代码保密(C++ 的反编译还原度非常低) 2.方便部署和分发

应用场景:比如Office软件的各个组成部分有相似的外观和功能,那么就可以调用同一个库文件中的函数生成那些组件

2.1 如何生成静态库

2.1.1 书写相关函数

1.文件如何保存

这里实现了一个算术运算的库,主要进行相关加减乘除操作,并根据命名规则将他们放在对应的目录下

image-20211030111747506

2.文件内容

(1)head.h

对函数进行声明

image-20211030112241751

(2)方法体的实现

add.c

image-20211030112339704

(3) main 执行方法实现

image-20211030112442437

2.1.1 静态库的命名规则

image-20211030105426907 image-20211030105510007

2.1.2 静态库的制作

(1)gcc -c 对库文件编译

gcc -c add.c mult.c sub.c div.c

报错,头文件找不到,使用 -I 将头文件导入

image-20211030112709156
gcc -c add.c mult.c sub.c div.c -I ../include

上面代码注意,不需要添加 head.h ,直接将文件 dictionary 添加进来即可。于是就生成了一堆 .o 文件

image-20211030113140520

(2)对 .o文件进行打包 ,成 .a 库文件

ar rcs libmath.a add.o div.o mult.o sub.o

(3)执行 main.c 方法

执行 main.c 方法,调用的库都是从 head 文件中查找的,所以还会报一个找不到 head.h 文件的情况。这时候将 head.h 再次导入

gcc  main.c -I include/ // 编译
image-20211030114005640

如上图所示,提示未引用库的 error ,这里需要使用 -L 参数将打包的库进行引用

gcc main.c -o app -I ./include/ -L ./lib/ -l math

注意:

-l 参数后的内容是和 -L 后面的文件对应的 .a 文件相关,调用的时候直接添加 lib 的名称即可

2.2 动态库的制作

这里是将上面的文件定义成动态库的方式

2.2.1 文件命名规则

image-20211030121941820

2.2.2 动态库的制作

1.gcc 得到 .o 文件,得到和位置无关的代码

gcc -c -fpic add.c div.c mult.c sub.c -I ../include/

参数:fpic 生成与位置无关的代码,原因是动态库与静态库不同,静态库是将静态库代码嵌套在可执行文件中。但是动态库的代码是放在内存的,是不确定位置的,所以就需要有这个参数

2.gcc 得到动态库

gcc -shared *.o -o libmath.so

*.o 就是将所有的 .o 文件聚合,注意这里别忘了加 .o 参数

shared 作用是生成一个共享库

image-20211030122540111

如上图所示就生成了一个 .so 的可执行文件

3.根据动态库生成可执行文件

gcc main.c -o main -I include/ -L lib/ -l math

但是如果执行这个可执行文件就发现报错,主要是找不到共享库的地址

image-20211030123155301

2.2.3 如何让程序找到共享库

image-20211030123245912
ldd main // 查看所用动态库
image-20211030123531107

查看电脑环境变量:

那么这样的话只需要将动态库的地址配置到环境变量中既可

env

其中 path 就是配置的环境信息

image-20211031223057671

2.2.4 在环境变量中声明动态库

为环境变量添加动态库(用户级别的配置)

用户级别配置是在 .bashrc 文件下配置的

编辑 .branch 文件,在最后添加动态库地址,最后再将这个文件编译一下

image-20211031224750386
source .bashrc   or  . .bashrc // 编译文件

source 的含义是读取并执行 source 后面文件;. 是 source 这个 operation 的简写。最后在执行 ldd main 就找到了这个库的地址,并且 main 这个文件也可以执行

image-20211031225123798

知识延伸:如何查看某个变量的值

上面使用 $+变量名获取变量值,用同样的方法再结合shell 指令就可以使用 ¥ 将这个值输出,看到这个变量中拼接的值

echo $LD_LIBRARY_PATH
image-20211031230234741

为环境变量添加动态库(系统级别的配置)

系统界别的配置主要是在 /etc/profile 文件中,所以就在这个文件下对这个变量添加动态库目录

sudo vim /etc/pro

使用和上面相同的添加动态库的指令,并在最后一行添加动态库地址,并且使用 source 进行编译

image-20211031230654338

最后在执行 main 方法就发现可以运行了

2.2.5 在文件列表中添加 PATH

通过 2.2.3 动态库的保存路径中获知可以直接修改 /etc/ld.so.cache 文件对动态库 path 进行调用。但是这个文件如果使用 vim 打开都是乱码,其实这个文件可以通过使用 conf 文件进行映射

sudo vim /etc/ld.so.conf

直接将地址粘贴到这个文件中即可

image-20211031232137699

然后使用 ldconfig 指令将动态库进行共享

sudo ldconfig

最后就可以直接对 main 文件执行

视频作者不太建议使用直接更改 lib 的方式更改库文件,因为 lib 中的文件太多,容易混乱

2.3 动态库和静态库的区别

2.3.1 制作流程上的差别

1.静态库的制作

image-20211101103923631

2.动态库的制作

image-20211101104000087

2.3.2 静态库的优缺点

1.静态库

优点缺点
静态库被打包到应用程序中加载速度快消耗系统资源,浪费内存
发布程序无序提供静态库,直接调用静态库当静态库中代码更新后,所以引用它的文件全部要进行相关喜欢,更新,部署,发布麻烦

2.动态库

优点缺点
可以实现进程间资源共享加载速度比静态库慢
相比于静态库,动态库更新部署发布简单发布程序是时需要提供依赖的库文件
可以控制何时加载动态库
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值