【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

相关推荐
..空空的人2 小时前
C++基于websocket的多用户网页五子棋 ---- 整合封装服务器模块设计实现
运维·服务器
愚戏师2 小时前
Python3 多线程
linux·运维·服务器·python
n***33352 小时前
linux redis简单操作
linux·运维·redis
h***59332 小时前
使用Canal将MySQL数据同步到ES(Linux)
linux·mysql·elasticsearch
xu_yule3 小时前
网络和Linux网络-5(应用层)HTTP协议(方法+报头+状态码)
linux·网络·网络协议·http
n***4433 小时前
Node.js HTTP模块详解:创建服务器、响应请求与客户端请求
服务器·http·node.js
lhyzws3 小时前
CENTOS上的网络安全工具(三十二) Portainer Kafka-Clickhouse部署(1)
linux·kafka·centos
2***s6724 小时前
【Go】Go语言基础学习(Go安装配置、基础语法)
服务器·学习·golang
xuchaoxin13754 小时前
cdn节点代理的副作用@fail2ban对接cdn封锁恶意请求ip@fail2ban封锁ip有效性问题
运维·网络·cdn·cloudflare