Linux基础开发工具 编译器gcc/g++

1、背景知识

gcc是Linux中最常用的c编译器,只能用来编译c语言。g++支持多语言编译,跨平台开发,是基础开发必备工具。

今天我们来谈一下gcc编译程序(程序的编译过程) 翻译语言的本质是:转化成cpu能够识别的指令集

一共包含四步:

(1)预处理

1、头文件展开 2、去注释 3、宏替换 4、条件编译 在预处理完毕后还是c语言

源文件是:

test.i是:

gcc -E是用来进行与处理的指令,是将.c文件变为.i文件,预处理后会将stdio.h头文件中所有内容插入到test.中(这部分内容很多,这里省略大部分,只看和我们代码相关的部分)。可以看到PI被替换为3.14159,SQUARE(num)被替换为((num)*(num)),SQUARE(6)被替换为((6)*(6))

4、条件编译(在预处理阶段对代码进行"选择性裁剪")

|---------|------------------------------------|
| 指令 | 作用 |
| #if | 检查常量表达式是否为真,为真则编译后续代码 |
| #ifdef | 检查某个宏定义是否已经定义(不管宏的值是什么),已定义则编译后续代码 |
| #ifndef | 检查某个宏是否未定义,未定义则编译后续代码 |
| #else | 与 #if #ifdef #ifndef配合,处理"否则"的情况 |
| #elif | 相当于"else if",在#if 之后多条件分支判断 |
| #endif | 结束条件编译块,必须与前面的 #if #ifdef #ifndef |
[条件编译的预处理指令]

(2)编译(将c语言变为汇编语言)

输入上述代码后,程序开始编译,程序变为汇编语言就停下来。(如下图就是汇编语言)

(3)汇编

把汇编语言翻译成二进制文件(.o),这里的二进制文件全称是:可重定位目标二进制文件

cpp 复制代码
gcc -c test.s -o test.o

执行完毕以上操作,就会形成下的文件:

(4)链接

把程序中调用库函数,和库本身函数实现产生关联的过程叫做链接。

在Linux中输入以下代码开始实现:

cpp 复制代码
gcc test.o -o test

成功编译之后,就进入了链接阶段

2、动态链接和静态链接

在我们的实际开发中,不可能将所有代码放在一个源文件中,所以会出现多个源文件,而且多个源文件之间不是独立的,而会存在多种依赖关系,如一个源文件可能要调用另一个源文件中定义的函数,但是每个源文件都是独立编译的,即每一个.c文件会形成一个.o文件,为了满足依赖关系,需要将这些源文件产生的目标文件进行链接,从而形成一个可执行的程序。这个链接的过程就是静态链接。

【学习语法(语言)其实是在学习编译器的规则】

如何理解动静态库?

|---------|------|------|
| | 静态库 | 动态库 |
| Linux | .a | .so |
| Windows | .lib | .ddl |

1、库的命名

lib.name.so(库真正的名字是name,即中间那一部分,去掉前缀lib和后缀so(无论静态库还是动态库))

2、动静态库

(1)静态链接:把库中方法(我们需要用到的),直接拷贝到你的程序中,叫做静态链接。

静态库和静态链接,,一旦链接成功,可执行程序就不再需要静态库。

动态链接:链接的是关联关系,链接的是地址。(一旦库缺失,所有相关程序就无法运行了)

以下是两种不同的库的对比:

|-----------------|-------------------------|
| 动态库 | 静态库 |
| .so | .a |
| 动态链接 | 静态链接 |
| 优点:节省内存空间 | 优点:不需要库跳转,一旦编译成功就不需要依赖库 |
| 缺点:慢,编译完依旧依赖动态库 | 缺点:可执行程序体积较大,消耗内存资源大 |

输入:file test

默认是动态链接的。所以可以得出结论:

gcc默认编译采用动态链接的方式,编译程序我们通常用动态库和动态链接是最佳实践

输入以下命令,强制要求gcc采用静态链接方式

file+文件名 ,查看 ,如下图:

静态库链接成功的大小是:

相关推荐
HIT_Weston9 分钟前
92、【Ubuntu】【Hugo】搭建私人博客:侧边导航栏(六)
linux·运维·ubuntu
CodeAllen嵌入式9 分钟前
Windows 11 本地安装 WSL 支持 Ubuntu 24.04 完整指南
linux·运维·ubuntu
期待のcode22 分钟前
前后端分离项目 Springboot+vue 在云服务器上的部署
服务器·vue.js·spring boot
AI 智能服务30 分钟前
第6课__本地工具调用(文件操作)
服务器·人工智能·windows·php
码农小韩2 小时前
基于Linux的C++学习——指针
linux·开发语言·c++·学习·算法
wdfk_prog2 小时前
[Linux]学习笔记系列 -- [fs]seq_file
linux·笔记·学习
Jay Chou why did2 小时前
wsl安装完无法进入wsl
linux
石头5303 小时前
Rocky Linux 9.6 docker k8s v1.23.17 kubeadm 高可用部署文档
linux
松涛和鸣3 小时前
49、智能电源箱项目技术栈解析
服务器·c语言·开发语言·http·html·php
凉、介3 小时前
SylixOS 中的 Unix Socket
服务器·c语言·笔记·学习·嵌入式·sylixos