【Linux】基础开发工具(3):编译器

目录

[一 编译器](#一 编译器)

[1 翻译的过程(重点放在编译选项上)](#1 翻译的过程(重点放在编译选项上))

[a 预处理(进行宏替换)](#a 预处理(进行宏替换))

[b 编译](#b 编译)

[c 汇编](#c 汇编)

[d 链接](#d 链接)

[2 一般程序的构建过程(.o文件)](#2 一般程序的构建过程(.o文件))

[3 条件编译](#3 条件编译)

[4 编译器/语言的历史](#4 编译器/语言的历史)

[5 编译器和对应语言的关系:自举](#5 编译器和对应语言的关系:自举)

[6 链接](#6 链接)

(1)初步理解

(2)关于链接和指令查看:ldd关于链接和指令查看:ldd)

(3)动态库和静态库

(4)感性的理解库和链接

(5)gcc是默认动态链接

(6)两个细节


一 编译器

gcc 是 C 语言编译器,g++ 是 C++ 编译器(本质上 G++ 也能编译 C 代码,相当于将C代码转变为C++代码去进行编译,但习惯上 C 用gcc,C++ 用 g++)

编译的本质:将源文件翻译成可执行二进制文件

1 翻译的过程(重点放在编译选项上)

a 预处理(进行宏替换)

我们先在code.c中写入代码,文件包含头文件,宏,注释

如果一次性将整个代码编译完,是看不到翻译过程的

预处理指令:gcc -E code.c -o code.i:将翻译过程放到code.i的临时文件中

预处理的工作:头文件展开、去注释、宏替换、条件编译

vim code.i

code.c文件中的去注释、头文件展开、宏替换的效果都是由预处理产生的

头文件展开:就是把头文件相关内容拷贝到源文件!!头源合并的过程! (编译器只需要再预处理时需要头文件)

当我们把code.c翻译为code.i文件时,code.i还是头文件,它是一个非常干净的c语言,里面没有一个注释和宏替换

b 编译

编译C语言变为汇编语言

编译指令gcc -S code.i -o code.s

c 汇编

汇编:汇编语言变为目标文件(.o/.obj(可重定位二进制目标文件))

结束汇编时,我们不能正常运行code.o文件,还需要链接

d 链接

需要再链接的时候,把我们的.o和C标准库链接形成可执行!

链接指令: gcc code.o -o code.exe

可以这样记忆:ESc -> iso

2 一般程序的构建过程(.o文件)

gcc -c code.c:直接形成同名.o文件

提高效率:gcc -o code.exe code.o

当有很多的源文件时,先把源文件编译成.o文件,然后再把.o链接

所谓的头文件展开,就是把你include包含的头文件拷贝到你所在的源文件中,就是文件合并的过程

3 条件编译

我们在c语言的部分学过条件编译,如果忘记了我们来复习一下:

那我我们在Linux下写一段条件编译的代码:

我们发现在main函数部分,V1并没有被定义,所以编译器不会执行Version1(),会直接被编译器裁剪掉

这种方式可以由编译器在预处理阶段根据特定的条件进行代码裁剪,把这种特性叫做条件编译

预处理器可以对写的c语言代码实现增删查改的,所以预处理器就有一种能力------>可以对我的源文件做二次编辑

所以条件编译本质是文本处理

用条件编译实现不同商业化版本软件的管理

4 编译器/语言的历史

5 编译器和对应语言的关系:自举

编译器的自举是指:用目标语言(如 C++)编写的编译器,最终能编译自身源代码。这是现代编程语言(如 C++、Golang、Rust)的标准实现方式,核心解决 "如何从无到有构建目标语言编译器" 的问题。

6 链接

(1)初步理解
(2)关于链接和指令查看:ldd

ldd:查看文件依赖哪个库

关于链接:
动态库---->通常和程序进行动态链接

静态库---->通常和程序进行静态链接

(3)动态库和静态库

静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大(大不少,前面展示过了),但在运行时也就不再需要库文件了。其后缀名一般为".a"

动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由

运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为"so",如前面所述的libc.so.6就是动态库。gcc在编译时默认使用动态库。完成了链接之后,gcc就可以生成可执行文件

(4)感性的理解库和链接

动态库的小故事:

假如说你是张三,你考上了当地的一中,但是这个一中管理非常的严格,不能带手机,于是你问学长学校附近哪里有上网的地方,学长给你说学校的东门出去向左100米,向右100米,有一家电竞馆,于是你决定在学校里完成任务之后,出去上网,但是随着去电竞馆的人越来越多,电竞馆就被举报了,110就来关闭了电竞馆。

静态库的小故事:

当电竞馆因为举报关闭了之后,张三就没地方上网了,张三就给他爸说,让他爸爸从网吧老板那里买了一台电脑放到了张三的宿舍里,大家发现可以从老板那里买电脑之后,越来越多的人买了电脑回去

(5)gcc是默认动态链接
(6)两个细节

细节1:如果我删掉c动态库呢?

一般而言,系统中大部分指令(c/c++编写的二进制指令)就无法运行了

细节2:gcc默认使用动态库和动态链接

Linux系统中,默认之安装了动态库,怎么办?

我们手动安装一下静态库就可以了

# Centos

yum install glibc-static libstdc++-static -y

静态库是指编译链接时,把库文件的代码全部加⼊到可执行文件中,因此生成的文件比较大,但在运

行时也就不再需要库文件了。其后缀名⼀般为".a"

• 动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由

运行时链接文件加载库,这样可以节省系统的开销。动态库⼀般后缀名为".so",如前⾯所述的

libc.so.6就是动态库。gcc在编译时默认使用动态库 。完成了链接之后,gcc就可以生成可执行文

件,如下所示。 gcc hello.o --o hello

相关推荐
深圳安锐科技有限公司17 分钟前
边坡倾斜自动化监测 倾角仪 如何通过安锐云查看监测曲线?
运维·视觉检测·实时监测·自动化监测·结构健康监测·倾斜角度监测·倾角传感器
相偎1 小时前
Ubuntu搭建svn服务器
服务器·ubuntu·svn
咕噜企业分发小米2 小时前
有哪些开源的直播云服务器安全防护方案?
运维·服务器·云计算
C_心欲无痕3 小时前
nginx - 开启 gzip 压缩
运维·前端·nginx
开开心心_Every3 小时前
安卓后台录像APP:息屏录存片段,行车用
java·服务器·前端·学习·eclipse·edge·powerpoint
qq_316837753 小时前
IP网段冲突 配置指定ip使用指定的网络接口发送,而不经过默认网关
服务器·网络·tcp/ip
王阿巴和王咕噜3 小时前
【WSL】安装并配置适用于Linux的Windows子系统(WSL)
linux·运维·windows
布史3 小时前
Tailscale虚拟私有网络指南
linux·网络
水天需0103 小时前
shift 命令详解
linux
wdfk_prog3 小时前
[Linux]学习笔记系列 -- 内核支持与数据
linux·笔记·学习