当前位置: 首页 > news >正文

GCC/G++ + Makefile/make 使用

一、gcc\g++编译器

什么是gcc和g++,它们的区别又是什么?
gcc编译器是专门用来编译C语言的,而g++编译器既可以编译C语言又可以用来编译C++,但是主要还是用来编译C++。
我们都知道代码形成可执行程序都是需要经过预处理、编译、汇编和链接这四个过程的,既然如此上述我们看到的两个编译器也必然是要围绕着这四个过程来进行说明。

1、预处理

预处理是做是什么工作的?

头文件展开、宏替换、去掉注释和条件编译

我们在linux中输入什么指令可以看见预处理这个阶段呢?

filename.c为要编辑的文件名
gcc -E filename.c 将预处理后的内容打印到显示屏上
gcc -E filename.c -o test.c 将预处理后的内容写到test.c文件里

什么是头文件展开呢?

头文件展开其实就是把头文件中相关的内容拷贝到源文件中,也就是说当预处理完成后我们其实就可以不用头文件了

什么是裁剪?我们又怎么理解裁剪呢?

裁剪其实就是对代码进行增、删和改操作。在预处理阶段,我们会发现代码从原来的几行一下子变成了几百行,这其实就是将头文件里面的内容拷贝到了源文件中了这里就是增,之后去掉注释这里就是删,最后根据条件可以修改代码这就是改。

2、编译

实现编译的操作

gcc -S filename.c -o test.c 对预处理阶段的文件进行编译

在这里插入图片描述
我们可以看到当我们输入上述指令后,会形成一堆我们看不懂的东西,而这个东西是什么呢?其实就是汇编语言

3、汇编

实现汇编操作

gcc -c filename.c -o test.c 对test.c进行汇编

经过上面的编译生成的汇编,而这里的汇编是生成可执行程序当中的一个阶段。它其实就是将汇编语言翻译成可重定位目标二进制文件。这里我们就有疑问了,既然它是翻译成二进制文件,是不是到这里我们计算机就可以识别了呢?并不是我们可以尝试使用./test.c来运行这个程序
在这里插入图片描述
我们发现直接就是报错了,这是为什么呢?我们接着往下看。

4、链接

实现链接的操作

gcc filename.c -o test.c

上面的汇编形成的可重定位二进制文件并不是一个可执行程序,它必须要经过链接才能生成可执行程序。这又是为什么呢?

比如在编程时,我们经常使用现成的库函数,而不必每次都重新编写所有功能代码,只需声明即可调用。同样,汇编生成的可重定位二进制文件也需要与库函数链接,才能最终生成可执行程序文件。

那么什么是链接呢?

在代码编译阶段,库函数的实际地址尚未确定,因为这些函数的具体实现位于库文件中。当进行链接时,链接器会将目标文件(.o)与库文件合并,在此过程中会解析并填充库函数在目标文件中的调用地址,最终生成完整的可执行文件。

为什么要有库?

使用库的主要目的是提升开发效率。在日常开发中,我们经常需要重复使用某些功能函数。如果每个开发者都自行编写这些基础功能,会造成大量重复劳动和时间浪费。

如何理解库呢?

库的常见分类有两种:静态库和动态库
在windows中后缀分别是:.lib 和 .dll
在linux中后缀分别是:.a 和 .so

动态链接:与动态库链接

在这里插入图片描述
静态链接:与静态库链接
在这里插入图片描述

注意:
静态链接有可能会失败,原因是因为系统中可能没有默认安装C\C++的静态库。编译器默认采用动态链接的方式,形成可执行程序。

什么是动态链接?

动态链接就是程序还未加载到内存的时候,就已经和动态库建立了信息上的链接,执行到库函数的时候,跳转到动态库执行,然后继续执行自己的代码

优点:节省资源
缺点:一旦丢失所有的程序都将无法运行

什么是静态库?

一组编译好的代码和数据的集合,它们在编译期间被链接到应用程序中

优点:不依赖任何库,自己独立就能运行
缺点:体积大,占据资源多,加载速度受影响

二、自动化构建make\Makedife

1、基本概念

make是一个linux系统内置的命令
Makefile是一个需要自己创建的文件
make命令会在当前目录下寻找makefile文件,解析里面的内容

2、操作步骤

(1)创建makefile文件

在这里插入图片描述

(2)编写makefile文件

在这里插入图片描述

在这里插入图片描述

(3)make指令运行代码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、makefile

在这里插入图片描述
这里我们会有很多的疑问。
为什么make的时候只执行了第一个目标呢?

这是因为make,makefile默认只形成一个目标,就是从上往下遇到的第一个目标

什么是伪目标?

.PHONY:表示被修饰的目标是一个伪目标
特点:伪目标总是被执行的。

http://www.dtcms.com/a/307559.html

相关文章:

  • Visual Studio调试技巧与函数递归详解
  • “0 成本开跨境店” 噱头下的优哩哩:商业模式深度剖析
  • 5G 单兵终端 + 无人机:消防应急场景的 “空 - 地” 救援协同体系
  • 【可用有效】Axure RP 9 授权码
  • imx6ull-驱动开发篇5——新字符设备驱动实验
  • springcloud04——网关gateway、熔断器 sentinel
  • cas自定义返回信息和自定义认证
  • 考研408_数据结构笔记(第三章栈、队列和数组)
  • 解构衡石嵌入式BI:统一语义层与API网关的原子化封装架构
  • Vue 中使用 Dexie.js
  • 城市客运安全员证考试难不难?如何高效备考
  • CUDA系列之常用Runtime API简介
  • BatchNorm 一般放在哪里?
  • Ⅹ—6.计算机二级综合题19---22套
  • 接口自动化测试以及requests
  • TS语法最佳实践
  • 【笔记】热力学定律推导(6)热力学第二定律推导
  • 【MATLAB】(二)基础知识
  • Golang 指针
  • Valgrind终极指南:深入内存安全与性能瓶颈检测
  • 云原生运维与混合云运维:如何选择及 Wisdom SSH 的应用
  • Android依赖注入框架Hilt入门指南
  • 大白话畅谈:stm32中断和FreeRTOS的中断
  • 【源力觉醒 创作者计划】_巅峰对话文心 4.5 与通义千问、DeepSeek 能力对比解析
  • 【工具】NVM完全指南:Node.js版本管理工具的安装与使用详解
  • 如何将照片从 realme 手机传输到电脑?
  • MongoDB系列教程-第四章:MongoDB Compass可视化和管理MongoDB数据库
  • node.js之Koa框架
  • 蓝牙 BR/EDR 与 BLE PHY
  • Kafka在Springboot项目中的实践