GCC编译器和静态库动态库制作使用

本文详细介绍了GCC编译器的使用,包括其安装、版本查看及C程序的编译流程。接着,重点讲解了静态库和动态库的制作方法,包括创建.o文件、使用ar工具打包.o文件成静态库,以及使用gcc生成动态库。同时,阐述了静态库和动态库的使用场景及其优缺点,如静态库的代码打包、动态库的动态加载和路径查找。
摘要由CSDN通过智能技术生成

一、GCC编译器

1.GCC编译器的介绍

◼ GCC 原名为 GNU C语言编译器(GNU C Compiler) ◼ GCC(GNU Compiler Collection,GNU编译器套件)是由 GNU 开发的编程语言
译器。GNU 编译器套件包括 C、C++、Objective-C、Java、Ada 和 Go 语言前
端,也包括了这些语言的库(如 libstdc++,libgcj等)
◼ GCC 不仅支持 C 的许多“方言”,也可以区别不同的 C 语言标准;可以使用命令行
选项来控制编译器在翻译源代码时应该遵循哪个 C 标准。例如,当使用命令行参数
-std=c99 启动 GCC 时,编译器支持 C99 标准。
◼ 安装命令 sudo apt install gcc g++ (版本 > 4.8.5)
◼ 查看版本 gcc/g++ -v/–version

2.GCC的工作流程

在这里插入图片描述预处理去掉注释,将头文件复制到源代码,宏替换。.i为文本代码, 目标代码为2进制指令

3、用GCC编译来编译C程序

kekecoder@kekecoder-virtual-machine:~/Linux/lesson03$ gcc test.c -o app //生成目标文件
kekecoder@kekecoder-virtual-machine:~/Linux/lesson03$ ls
app test test.c
kekecoder@kekecoder-virtual-machine:~/Linux/lesson03$ ./app //运行程序
hello, GCC!!!
hello, GCC!!!
hello, GCC!!!
kekecoder@kekecoder-virtual-machine:~/Linux/lesson03$

4、GCC常见指令

在这里插入图片描述

二、静态库的制作和使用

1.静态库的制作

◼ 命名规则:
◆ Linux : libxxx.a
lib : 前缀(固定)
xxx : 库的名字,自己起
.a : 后缀(固定)

◼ 静态库的制作:
◆ (1)gcc 获得 .o 文件
◆ (2)将 .o 文件打包,使用 ar 工具(archive)
ar rcs libxxx.a xxx.o xxx.o
r – 将文件插入备存文件中
c – 建立备存文件
s – 索引

◆(1) gcc 获得 .o 文件
kekecoder@kekecoder-virtual-machine:~/Linux/lesson04/calc$ ls
add.c div.c head.h main.c mult.c sub.c
kekecoder@kekecoder-virtual-machine:~/Linux/lesson04/calc$
kekecoder@kekecoder-virtual-machine:~/Linux/lesson04/calc$ tree
.
├── add.c
├── div.c
├── head.h
├── main.c
├── mult.c
└── sub.c

0 directories, 6 files
kekecoder@kekecoder-virtual-machine:~/Linux/lesson04/calc$ gcc -c add.c mult.c div.c sub.c
kekecoder@kekecoder-virtual-machine:~/Linux/lesson04/calc$ tree
.
├── add.c
├── add.o
├── div.c
├── div.o
├── head.h
├── main.c
├── mult.c
├── mult.o
├── sub.c
└── sub.o

0 directories, 10 files
kekecoder@kekecoder-virtual-machine:~/Linux/lesson04/calc$

◆(2) 将 .o 文件打包,使用 ar 工具(archive)
kekecoder@kekecoder-virtual-machine:~/Linux/lesson04/calc$ ar rcs libcalc.a add.o sub.o mult.o div.o
kekecoder@kekecoder-virtual-machine:~/Linux/lesson04/calc$ tree
.
├── add.c
├── add.o
├── div.c
├── div.o
├── head.h
├── libcalc.a
├── main.c
├── mult.c
├── mult.o
├── sub.c
└── sub.o

0 directories, 11 files
kekecoder@kekecoder-virtual-machine:~/Linux/lesson04/calc$
最终生成libcalc.a

2.静态库的使用

kekecoder@kekecoder-virtual-machine:~/Linux/lesson05/library$ gcc main.c -o app -I ./include/ -L ./lib/ -l suanshu//返回上次目录找头文件,导入头文件 -L指定库路径 -l指定库名称
kekecoder@kekecoder-virtual-machine:~/Linux/lesson05/library$ tree
.
├── app
├── include
│ └── head.h
├── lib
│ └── libsuanshu.a
├── main.c
└── src
├── add.c
├── add.o
├── div.c
├── div.o
├── mult.c
├── mult.o
├── sub.c
└── sub.o

3 directories, 12 files
kekecoder@kekecoder-virtual-machine:~/Linux/lesson05/library$ ./app 运行app
a = 20, b = 12
a + b = 32
a - b = 8
a * b = 240
a / b = 1.666667
kekecoder@kekecoder-virtual-machine:~/Linux/lesson05/library$

三、动态库的制作和使用

1、动态库的制作

◼ 命名规则:
◆ Linux : libxxx.so
lib : 前缀(固定)
xxx : 库的名字,自己起
.so : 后缀(固定)
在Linux下是一个可执行文件
◼ 动态库的制作:
◆ gcc 得到 .o 文件,得到和位置无关的代码
gcc -c –fpic/-fPIC a.c b.c
◆ gcc 得到动态库
gcc -shared a.o b.o -o libcalc.so

kekecoder@kekecoder-virtual-machine:~/Linux/lesson06/calc$ gcc -shared *.o -o libcalc.so
kekecoder@kekecoder-virtual-machine:~/Linux/lesson06/calc$ tree
.
├── add.c
├── add.o
├── div.c
├── div.o
├── head.h
├── libcalc.so
├── main.c
├── mult.c
├── mult.o
├── sub.c
└── sub.o

0 directories, 11 files
kekecoder@kekecoder-virtual-machine:~/Linux/lesson06/calc$ ll
总用量 56
drwxrwxr-x 2 kekecoder kekecoder 4096 8月 13 16:25 ./
drwxrwxr-x 4 kekecoder kekecoder 4096 8月 12 16:20 …/
-rw-rw-r-- 1 kekecoder kekecoder 80 8月 12 16:20 add.c
-rw-rw-r-- 1 kekecoder kekecoder 1232 8月 13 16:13 add.o
-rw-rw-r-- 1 kekecoder kekecoder 94 8月 12 16:20 div.c
-rw-rw-r-- 1 kekecoder kekecoder 1240 8月 13 16:13 div.o
-rw-rw-r-- 1 kekecoder kekecoder 189 8月 12 16:20 head.h
-rwxrwxr-x 1 kekecoder kekecoder 7624 8月 13 16:25 libcalc.so*
-rw-rw-r-- 1 kekecoder kekecoder 306 8月 12 16:20 main.c
-rw-rw-r-- 1 kekecoder kekecoder 85 8月 12 16:20 mult.c
-rw-rw-r-- 1 kekecoder kekecoder 1240 8月 13 16:13 mult.o
-rw-rw-r-- 1 kekecoder kekecoder 85 8月 12 16:20 sub.c
-rw-rw-r-- 1 kekecoder kekecoder 1232 8月 13 16:13 sub.o

kekecoder@kekecoder-virtual-machine:~/Linux/lesson06/library$ tree
.
├── include
│ └── head.h
├── lib
│ └── libcalc.so
├── main.c
└── src
├── add.c
├── div.c
├── mult.c
└── sub.c

3 directories, 7 files
kekecoder@kekecoder-virtual-machine:~/Linux/lesson06/library$

2、动态库的使用(需要加入绝对路径)

02 / 工作原理
◼ 静态库:GCC 进行链接时,会把静态库中代码打包到可执行程序中
◼ 动态库:GCC 进行链接时,动态库的代码不会被打包到可执行程序中
◼ 程序启动之后,动态库会被动态加载到内存中,通过 ldd (list dynamic
dependencies)命令检查动态库依赖关系
◼ 如何定位共享库文件呢?
当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路
径。此时就需要系统的动态载入器来获取该绝对路径。对于elf格式的可执行程序,是
由ld-linux.so来完成的,它先后搜索elf文件的 DT_RPATH段 ——> 环境变量
LD_LIBRARY_PATH ——> /etc/ld.so.cache文件列表 ——> /lib/,/usr/lib
目录找到库文件后将其载入内存。
kekecoder@kekecoder-virtual-machine:~/Linux/lesson06/library$ export LD_LIBRARY_PATH= L D L I B R A R Y P A T H : / h o m e / k e k e c o d e r / L i n u x / l e s s o n 06 / l i b r a r y / l i b k e k e c o d e r @ k e k e c o d e r − v i r t u a l − m a c h i n e :   / L i n u x / l e s s o n 06 / l i b r a r y LD_LIBRARY_PATH:/home/kekecoder/Linux/lesson06/library/lib kekecoder@kekecoder-virtual-machine:~/Linux/lesson06/library LDLIBRARYPATH:/home/kekecoder/Linux/lesson06/library/libkekecoder@kekecodervirtualmachine: /Linux/lesson06/library echo L D L I B R A R Y P A T H : / h o m e / k e k e c o d e r / L i n u x / l e s s o n 06 / l i b r a r y / l i b k e k e c o d e r @ k e k e c o d e r − v i r t u a l − m a c h i n e :   / L i n u x / l e s s o n 06 / l i b r a r y LD_LIBRARY_PATH :/home/kekecoder/Linux/lesson06/library/lib kekecoder@kekecoder-virtual-machine:~/Linux/lesson06/library LDLIBRARYPATH:/home/kekecoder/Linux/lesson06/library/libkekecoder@kekecodervirtualmachine: /Linux/lesson06/library tree
.
├── include
│ └── head.h
├── lib
│ └── libcalc.so
├── main
├── main.c
└── src
├── add.c
├── div.c
├── mult.c
└── sub.c

3 directories, 8 files
kekecoder@kekecoder-virtual-machine:~/Linux/lesson06/library$ ldd main
linux-vdso.so.1 (0x00007ffc4e7e1000)
libcalc.so => /home/kekecoder/Linux/lesson06/library/lib/libcalc.so (0x00007fc16c3bc000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc16bfcb000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc16c7c0000)
kekecoder@kekecoder-virtual-machine:~/Linux/lesson06/library$ ./main
a = 20, b = 12
a + b = 32
a - b = 8
a * b = 240
a / b = 1.666667
kekecoder@kekecoder-virtual-machine:~/Linux/lesson06/library$

四、静态库和动态库的区别

1、 静态库的优缺点

◼ 优点:
◆ 静态库被打包到应用程序中加载速度快
◆ 发布程序无需提供静态库,移植方便
缺点:
◆ 消耗系统资源,浪费内存
◆ 更新、部署、发布麻烦

2、动态库的优缺点

◼ 优点:
◆ 可以实现进程间资源共享(共享库)
◆ 更新、部署、发布简单
◆ 可以控制何时加载动态库
◼ 缺点:
◆ 加载速度比静态库慢
◆ 发布程序时需要提供依赖的动态库

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值