【Linux】 编译与动静态库相关


目录

前言

[Part1. GCC四个编译阶段](#Part1. GCC四个编译阶段)

[Part1.1. 预处理](#Part1.1. 预处理)

[Part1.2. 编译](#Part1.2. 编译)

[Part1.3. 汇编](#Part1.3. 汇编)

[Part2. 静态库与动态库](#Part2. 静态库与动态库)

[Part2.1. 动态库](#Part2.1. 动态库)

[Part2.2. 静态库](#Part2.2. 静态库)

[Part2.3. gcc静态链接参数](#Part2.3. gcc静态链接参数)

[Part3. 条件编译](#Part3. 条件编译)

[Part4. /etc/sudoers 权限配置](#Part4. /etc/sudoers 权限配置)

[Part5. 目标文件 .o](#Part5. 目标文件 .o)

[Part6. Make与Makefile](#Part6. Make与Makefile)

[Part7. 结语](#Part7. 结语)


前言

在Linux中对于编译以及动静态库的理解是非常重要的,因此来跟随小编的视角来看看吧。


let's go!!!!!!!!


Part1. GCC四个编译阶段

Part1.1. 预处理

gcc -E x.c -o y.i
对x.c执行预处理,输出预处理结果保存到y.i。
完成:头文件展开、宏替换、条件编译处理、删除注释。


Part1.2. 编译

gcc -S x.c -o y.s
将C代码翻译成汇编代码,汇编结果保存到y.s。


Part1.3. 汇编

gcc -c x.c -o y.o
汇编完成,生成.o目标文件,内容为二进制机器指令,但还不能直接运行,缺少链接步骤。
完整流程:先生成.o目标文件,再通过链接生成可执行程序exe。
完整命令:gcc x.o -o exe。
使用 ldd 可执行程序,可以查看程序依赖哪些共享库。


Part2. 静态库与动态库

后缀区分
库类型 Linux Windows
动态库 .so .dll
静态库 .a .lib


Part2.1. 动态库

**程序运行时才去库文件中寻找对应函数执行。执行printf这类库函数时,**根据地址跳转至库中对应函数执行。

• 动态链接:编译链接阶段,仅做标记,记录库函数符号;程序运行时才跳转到库函数真实地址。

• 优点:内存占用小;多个程序可以共享内存中同一份库,内存中只加载一份。

• 缺点:依赖系统库文件,如果库丢失,程序直接无法运行。


Part2.2. 静态库

编译链接阶段,把库里面的代码拷贝、合并进我们自己的可执行程序内部。

• 优点:不依赖外部库文件,移植方便;程序可以独立运行。

• 缺点:可执行文件体积会显著变大;多个程序会各自拷贝一份库代码,内存冗余。


Part2.3. gcc静态链接参数

gcc x.c -o y -static
加上‑static,使用静态库链接,生成的可执行文件体积会明显增大。

使用file 可执行文件名,可以查看该程序是动态链接还是静态链接。

P.S. ldd命令无法查看静态链接程序的依赖,静态程序已经把库打包进自身。


Part3. 条件编译

条件编译发生在预处理阶段,本质就是修改源代码文本。
根据宏定义,选择性保留/裁剪一部分代码。


cpp 复制代码
#ifdef X
// 如果 X 被 #define 定义过,这部分代码才参与编译
#endif
//gcc命令行定义宏
# 定义宏E
gcc x.c -o y -DE

# 定义宏Z,赋值100
gcc x.c -o y -DZ=100

实际使用场景

<1> 版本控制:外部通过宏控制,实现VIP版本、普通用户版本。预处理阶段直接裁掉对应代码,不会编译进最终程序。

<2> 跨平台开发:一套代码同时在Linux、Windows运行。通过条件编译识别当前操作系统,调用对应平台API。

<3> 调试开关:通过宏打开/关闭调试打印。

p.s. 条件编译是预处理完成,代码裁剪发生在编译之前。


Part4. /etc/sudoers 权限配置

修改/etc/sudoers,可以配置普通用户sudo权限 ,实现普通用户拥有管理员能力。


Part5. 目标文件 .o

<1> 将.c源文件编译生成.o目标文件,可以保护源码不直接暴露
<2> .o存放机器指令,多个.o可以打包成库文件。


Part6. Make与Makefile

• make:工具程序

• Makefile:配置脚本文件,描述编译依赖关系与编译命令。


Makefile基础格式

cpp 复制代码
//目标: 依赖文件
    //编译命令
//示例:
code: code.c
    gcc -o code code.c

逻辑:如果code.c存在,执行gcc指令生成code可执行程序。


Part7. 结语

这篇文章我们认识到了Linux编译与动静态库的相关知识,接下来,小编还会带来更多Linux相关的知识,敬请期待~
最后,祝大家可以:春风得意马蹄疾,一日看尽长安花!

最后的最后,要是觉得本文还可以的话,可以点点赞,关注小编一波,谢谢大家!~

相关推荐
Lonely 净土10 小时前
Linux 运维文件写入操作
linux·运维·服务器·文件管理
吠品12 小时前
Wine 在 Linux 上运行 Windows 软件完整指南
java·linux·服务器
淡海水13 小时前
02-06-历史-托管GC机制-垃圾回收如何影响数据结构选择
c#·编译·gc·机器码
深念Y15 小时前
从 Windows 迁移到 Linux 开发环境的记录
linux·windows·链接·bun·ram·imdisk
知无不研16 小时前
Linux I/O复用之epoll
linux·服务器·epoll·socket编程
fb_1234516 小时前
Linux运维封神|SELinux详解+CentOS7启动原理+Root密码重置+开机故障排查实战
linux·运维·服务器
苏宸啊17 小时前
linux网络编程udp服务器和客户端代码编写(echo版本和字典版本)
linux·网络
~|Bernard|17 小时前
Linux 定时任务(Cron)完整教程
linux·运维·服务器
小雪崩17 小时前
嵌入式学习 day25:哈希表及排序与查找
linux·c语言·数据结构·学习·排序算法