Linux编译器--gcc和g++使用

gcc和g++使用

  • 一、gcc/g++的作用
    • 1.1 预处理
    • 1.2 编译
    • 1.3 汇编
    • 1.4 链接
  • 二、静态库和动态库
  • 三、make/Makefile
    • 3.1 make/Makefile
    • 3.2 依赖关系和依赖方法
    • 3.3 多文件编译
    • 3.4 make原理
    • 3.5 项目清理
  • 四、linux下的第一个小程序-进度条
    • 4.1 行缓冲区的概念
    • 4.2 \r和\n
    • 4.3 进度条代码

一、gcc/g++的作用

gcc和g++分别是GUN的C和C++的编译器,gcc和g++在执行编译的时候一般有以下四个步骤:

1.预处理(a.去注释 b.宏替换 c.头文件展开 d.条件编译)–(还是C语言)
2.编译(C代码翻译成->汇编语言)
3.汇编(汇编代码转换成->可重定向二进制目标文件)
4.链接(将汇编过程产生的二进制代码进行链接,将多个.o,.obj 合并形成一个可执行)

gcc只能用来编译C语言,g++可以编译C语言也可以编译C++
没有安装则可使用下面命令进行安装:

sudo yum install -y gcc-c++

1.1 预处理

gcc -E mytest.c -o mytest.i

在这里插入图片描述

  • 预处理功能主要包括头文件展开、去注释、宏替换、条件编译等。
  • 预处理指令是以#开头的代码行。
  • -E选项的作用是让gcc/g++在预处理结束后停止编译过程。
  • -o选项是指目标文件,“xxx.i”文件为已经过预处理的原始程序。

在这里插入图片描述

1.2 编译

gcc -S mytest.i -o mytest.s 

在这里插入图片描述

  • 在这个阶段中,gcc/g++首先检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,将代码翻译成汇编语言。
  • 用户可以使用-S选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码
  • -o选项是指目标文件,“xxx.s”文件为已经过翻译的原始程序。
    在这里插入图片描述

1.3 汇编

gcc -c mytest.s -o mytest.o

在这里插入图片描述

  • 汇编阶段是把编译阶段生成的“xxx.s”文件转成目标文件
  • 使用-c选项就可以得到汇编代码转化为“xxx.o”的二进制目标代码了

在这里插入图片描述

1.4 链接

gcc mytest.c -o mytest

在这里插入图片描述

  • 在成功完成以上步骤之后,就进入了链接阶段。
  • 链接的主要任务就是将生成的各个“xxx.o”文件进行链接,生成可执行文件。
  • gcc/g++不带-E、-S、-c选项时,就默认生成预处理、编译、汇编、链接全过程后的文件。
  • 若不用-o选项指定生成文件的文件名,则默认生成的可执行文件名为a.out

注意:链接后生成的也是二进制文件

二、静态库和动态库

函数库一般分为静态库和动态库两种

  • 静态库是指编译链接时,把库文件的代码全部加入到可执行文件当中,因此生成的文件比较大,但在运行时就不再需要库文件了,静态库一般以.a为后缀。
  • 动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件当中,而是在程序运行时由链接文件加载库,这样可以节省系统的开销,动态库一般以.so为后缀。

动态链接
优点:省空间(磁盘的空间,内存的空间),bin体积小,加载速度快。
缺点:依赖动态库,程序可移植性较差。
静态链接
优点:不依赖第三方库,程序的可移植性较高
缺点:浪费空间

gcc和g++默认生成的二进制程序是动态链接的,我们可以使用file指令进行查看。其次,我们还可以使用ldd指令查看动态链接的可执行文件所依赖的库。
在这里插入图片描述
虽然gcc和g++默认采用的是动态链接,但如果我们需要使用静态链接,带上-static选项即可。

gcc test.c -o mytest-s -static

在这里插入图片描述
在这里插入图片描述
此时生成的可执行文件就是静态链接的了。我们可以查看源代码相同,但链接方式不同而生成的两个可执行程序mytest和mytest-s的大小。这也证明了动态链接比较节省空间,而静态链接比较浪费空间。

你的机器可能因为没有静态库,而导致链接失败!
动态链接必须使用.so动态库文件

sudo yum install -y glibc-static  #C静态库

静态链接必须使用.a静态库文件

sudo yum install -y libstdc++-static  #C++静态库

三、make/Makefile

3.1 make/Makefile

  • 会不会写Makefile,从侧面说明了一个人是否具备完成大型工程的能力。
  • 一个工程的源文件不计其数,按照其类型、功能、模块分别放在若干目录当中,Makefile定义了一系列的规则来指定:哪些文件需要先编译,哪些文件需要后编译,甚至于进行更复杂的功能操作。
  • Makefile带来的好处就是“自动化编译”,一旦写好,只需一个make命令,整个工程完全自动编译,极大地提高了软件开发的效率。
  • make是一个命令工具,是一个解释Makefile当中指令的命令工具,一般来说,大多数的IDE都有这个命令,例如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,Makefile都成为了一种在工程方面的编译方法。
  • make是一条命令,Makefile是一个文件,两个搭配使用,完成项目自动化构建。

3.2 依赖关系和依赖方法

在使用make/Makefile前我们首先应该理解各个文件之间的依赖关系以及它们之间的依赖方法。
依赖关系:文件A的变更会影响文件B,那么就称文件B依赖于文件A。

  • 例如,test.o文件是由test.c文件通过预处理、编译以及汇编之后生成的文件,所以test.c文件的改变会影响test.o,所以说test.o文件依赖于test.c文件

依赖方法:如果文件B依赖于文件A,那么通过文件A得到文件B的方法,就是文件B依赖于文件A的依赖方法。

  • 例如,test.o依赖于test.c,而test.c通过gcc -c test.c -o
    test.o 指令就可以得到test.o,那么test.o依赖于test.c的依赖方法就是gcc -c test.c -o test.o

3.3 多文件编译

当你的工程当中有多个源文件的时候,应该如何进行编译生成可执行程序呢?
首先,我们可以直接使用gcc指令对多个源文件进行编译,进而生成可执行程序。
但进行多文件编译的时候一般不使用源文件直接生成可执行程序,而是先用每个源文件各自生成自己的二进制文件,然后再将这些二进制文件通过链接生成可执行程序。
原因

  • 若是直接使用源文件生成可执行程序,那么其中一个源文件进行了修改,再生成可执行程序的时候就需要将所有的源文件重新进行编译链接。
  • 而若是先用每个源文件各自生成自己的二进制文件,那么其中一个源文件进行了修改,就只需重新编译生成该源文件的二进制文件,然后再将这些二进制文件通过链接生成可执行程序即可。

注意:编译链接的时候不需要加上头文件,因为编译器通过源文件的内容可以知道所需的头文件名字,而通过头文件的包含方式(“尖括号”包含和“双引号”包含),编译器可以知道应该从何处去寻找所需头文件。

但是随着源文件个数的增加,我们每次重新生成可执行程序时,所需输入的gcc指令的长度与个数也会随之增加。这时我们就需要使用make和Makefile了,这将大大减少我们的工作量。

步骤一:在源文件所在目录下创建一个名为Makefile的文件。
在这里插入图片描述
步骤二:编写Makefile文件
Makefile文件最简单的编写格式是,先写出文件的依赖关系,然后写出这些文件之间的依赖方法,一次写下去。
在这里插入图片描述
编写完毕Makefile文件后保存退出,然后在命令行当中执行make指令便可以生成可执行程序,以及该过程产生的中间产物

在这里插入图片描述

说明:gcc/g++携带-c选项时,若不指定输出文件的文件名,则默认输出文件名为xxx.o,所以这里也可以不用指定输出文件名。

3.4 make原理

1.make会在当前目录下找名字为“Makefile”或“”makefile
的文件。
2. 如果找到,它会找文件当中的第一个目标文件,在上面的例子中,它会找到mytest这个文件,并把这个文件作为最终的目标文件。
3. 如果mytest文件不存在,或是mytest所依赖的后面的test.o文件和main.o文件的文件修改时间比mytest文件新,那么它就会执行后面的依赖方法来生成mytest文件。
4. 如果mytest所依赖的test.o文件不存在,那么make会在Makefile文件中寻找目标为test.o文件的依赖关系,如果找到则再根据其依赖方法生成test.o文件(类似于堆栈的过程)。
5. 当然,你的test.c文件和main.c文件是存在的,于是make会生成test.o文件和main.o文件,然后再用test.o文件和main.o文件生成最终的mytest文件。
6. make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
7. 在寻找的过程中,如果出现错误,例如最后被依赖的文件找不到,那么make就会直接退出,并报错。

makefile是如何得知,我的可执行程序是最新的?
根据文件的最近修改时间来的!

stat mytest

在这里插入图片描述

Access:表示文件最近被访问的时间(修改也算访问)
Modify:修改时间(是指文件内容的改变,改变内容其实也会改变文件的属性(大小))
Change:修改时间(是指文件属性的改变,比如权限设置)

源文件的可执行文件一定比新文件的时间要早,make根据这个时间来判断文件是不是最新的,是否需要执行该文件。

3.5 项目清理

在我们每次重新生成可执行程序前,都应该将上一次生成可执行程序时生成的一系列文件进行清理,但是如果我们每次都手动执行一系列指令进行清理工作的话,未免有些麻烦,因为每次清理时执行的都是相同的清理指令,这时我们可以将项目清理的指令也加入到Makefile文件当中。
想clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,但我们可以显示要make执行。
在这里插入图片描述
:一般将这种clean的目标文件设置为伪目标,用.PHONY修饰,伪目标的特性是:总是被执行。

四、linux下的第一个小程序-进度条

4.1 行缓冲区的概念

首先,我们来感受一下行缓冲区的存在,在Linux当中以下代码的运行结果是什么样的?
在这里插入图片描述
对于此代码,大家应该都没问题,当然是先输出字符串hello 然后休眠1秒之后结束运行。那么对于以下代码呢?

在这里插入图片描述
可以看到代码中仅仅删除了字符串后面的‘\n’,那么代码的运行结果还与之前相同吗?答案是否定的,该代码的运行结果是:先休眠3秒,然后打印字符串hello 之后结束运行。该现象就证明了行缓冲区的存在。

显示器对应的是行刷新,即当缓冲区中遇到‘\n’或是缓冲区被写满才会被打印出来,而在第二份代码中并没有‘\n’,所以字符串hello world先被写到缓冲区当中去了,然后休眠3秒后,直到程序运行结束时才将hello打印到显示器当中。
我们在代码中添加fflush(stdout)后就能够实现立马刷新,直接显示hello
在这里插入图片描述
这次的结果就是马上输出hello

4.2 \r和\n

\r:回车,使光标回到本行行首
\n:换行,使光标下移一格
而我们键盘上的Enter键实际上就等价于\n+\r
既然是\r是使光标回到本行行首,那么如果我们像显示器上写了一个数之后再让光标回到本行行首,然后再写一个数,不就相当于将前面一个数字覆盖了吗?
但这里有一个问题:不使用‘\n’进行换行怎么将缓冲区当中数据打印出来?
这里我们可以使用ffush函数,该函数可以刷新缓冲区,即将缓冲区当中的数据刷新到显示器当中。
对此我们可以编写一个倒计时的程序。
在这里插入图片描述

4.3 进度条代码

知道了\r这个概念我们就可以实现一个简单的进度条了。
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/332357.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

细讲Labview条件结构用法及易错点

本文讲解Labview条件结构的常用情景及易错点注意事项。帮助大家深刻理解并使用该结构,欢迎点赞关注加评论,有问题可以私聊或在下方评论区留言。 本文程序均附在文章结尾,可自行下载学习。 博主之前讲过Labview事件结构、For循环等的基础知识介…

SpringBoot连接远程服务器redis

SpringBoot连接远程服务器redis 1、指定redis配置启动 进入redis安装地址,我这里安装的是 /usr/local/src/redis-6.2.6 先copy一份配置文件 cp redis.conf redis.conf.bck然后修改配置文件信息 vim redis.conf bind 0.0.0.0 # 守护进程,修改为yes后即可…

Flutter中使用minio_new库

前言 在移动开发中,我们常常会遇到需要在App中处理文件上传和下载的需求。Minio是一个开源的对象存储服务,它兼容Amazon S3云存储服务接口,可以用于存储大规模非结构化的数据。 开始之前 在pubspec.yaml文件中添加minio_new库的依赖&#xf…

2023企业怎样抵御经济的不确定性?

在日益不确定的经济环境,继续业务照旧可能会超过陷入逆风的风险。要加入真正有复原力的企业行列,实现整个经济周期的增长,2023是时候发力业务创新:优化选择新的创新组合,洞察并发现新的创新机会,并发展新的…

Android Launcher3各启动场景源码分析

文章目录 一、概述二、开机启动Launcher2.1、开机启动Launcher流程图2.2、开机启动流程源码分析 三、短压Home键启动Launcher3.1、短压Home键启动Launcher流程图3.2、短压Home键启动Launcher源码分析 四、Launcher异常崩溃后的自启动4.1、Launcher异常崩溃后的自启动流程图4.2、…

C语言总结十三:程序环境和预处理详细总结

了解程序的运行环境可以让我们更加清楚的程序的底层运行的每一个步骤和过程,做到心中有数,预处理阶段是在预编译阶段完成,掌握常用的预处理命令语法,可以让我们正确的使用预处理命令,从而提高代码的开发能力和阅读别人…

在线扒站网PHP源码-在线扒站工具网站源码

源码介绍 这是一款在线的网站模板下载程序,也就是我们常说的扒站工具,利用它我们可以很轻松的将别人的网站模板样式下载下来,这样就可以大大提高我们编写前端的速度了!注:扒取的任何站点不得用于商业、违法用途&#…

如何在CentOS 7 中基于OpenSSL 3.0 搭建Python 3.0 环境

1、OpenSSL 1.1 原因 [rootlocalhost ~]# openssl version OpenSSL 1.0.2k-fips 26 Jan 2017 [rootlocalhost ~]#通过执行openssl version可知Linux系统已经安装了OpenSSL,但该版本较低;Python 3 要求 OpenSSL版本不能低于1.1.1,否则安装P…

【02】mapbox js api加载arcgis切片服务

需求: 第三方的mapbox js api加载arcgis切片服务,同时叠加在mapbox自带底图上 效果图: 形如这种地址去加载: http://zjq2022.gis.com:8080/demo/loadmapbox.html arcgis切片服务参考链接思路:【01】mapbox js api加…

【Copula】最可能场景详解

基于Copula联合分布的最可能场景详解 最可能场景(The most-likely scenario)实例探讨参考 最可能场景(The most-likely scenario) 相应英文介绍原理介绍如下:(出自论文J2020-Drought hazard transferabilit…

RTC讲解

RTC(Real Time Clock)实时时钟 RTC实时时钟本质上是一个独立的定时器。RTC模块拥有一组连续计数的32位无符号计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。 RTC模块和时钟配…

基于XG24-EK2703A的BLE HID蓝牙键盘+鼠标复合设备功能开发(BLE+HID+FreeRTOS+Gecko SDK)

目录 项目介绍硬件介绍项目设计开发环境及工程参考总体流程图硬件基本配置应用初始化按键中断回调定时器回调按键响应任务蓝牙事件回调BLE HIDReport Map及报文键盘设备鼠标设备复合设备 发送字符串上/下滚动 功能展示项目总结 👉 【Funpack3-1】基于XG24-EK2703A的…

网络端口映射和端口转发的区别和联系

目 录 一、端口映射技术 1.1 原理 1.2 应用场景 1、远程访问 2、游戏主机 3、文件共享 4、监控视频共享 二、端口转发技术 2.1 原理 2.2 应用场景 1、网络负载均衡 2、网络安全 3、网络代理 三、端口映射和转发的实现方法 3.1 路由器配置 3.2 网络防火墙 …

C Primer Plus 第6版 编程练习 chapter 16

文章目录 1. 第1题1.1 题目描述1.2 编程源码1.3 结果显示 2. 第2题2.1 题目描述2.2 编程源码2.3 结果显示 3. 第3题3.1 题目描述3.2 编程源码3.3 结果显示 4. 第4题4.1 题目描述4.2 编程源码4.3 结果显示 5. 第5题5.1 题目描述5.2 编程源码5.3 结果显示 6. 第6题6.1 题目描述6.…

linux|操作系统|centos7物理机安装网卡驱动8188gu(内核升级,firmware固件,USB设备管理,module管理)

前言: 目前服务器领域centos7基本是主流的操作系统,而linux相对于Windows来说,软硬件方面的支持是差很多的,在硬件方面来说,以一个免驱的网卡为例,window xp可能不会自动识别到,但Windows10基本…

问题:Feem无法发送信息OR无法连接(手机端无法发给电脑端)

目录 前言 问题分析 资源、链接 其他问题 前言 需要在小米手机、华为平板、Dell电脑之间传输文件,试过安装破解的华为电脑管家、小米的MIUI文件传输等,均无果。(小米“远程管理”ftp传输倒是可以,但速度太慢了,且…

【Ant Design of Vue】Modal.confirm无法关闭的bug

一、问题 在使用 Ant Design Vue 的 Modal.confirm 确认框时&#xff0c;出现了点击取消和确定后 Modal.confirm 确认框无法关闭的问题 二、代码 代码完全是 copy 的官网的代码&#xff0c;但是 copy 到本地后就会出现上述问题 <template><a-button click"sho…

鸿蒙开发(五)鸿蒙UI开发概览

从用户角度来讲&#xff0c;一个软件拥有好看的UI&#xff0c;那是锦上添花的事情。再精确的算法&#xff0c;再厉害的策略&#xff0c;最终都得通过UI展现给用户并且跟用户交互。那么&#xff0c;本篇一起学习下鸿蒙开发UI基础知识&#xff0c;认识下各种基本控件以及使用方式…

UE5 C++ 学习笔记 UBT UHT 和 一些头文件

总结一些似懂非懂的知识点&#xff0c;从头慢慢梳理。 任何一个项目都有创建这些三个.cs。 这个是蓝图转C 这个是本身就是C项目,应该就是多了一个GameModeBase类 Build.cs包含了每个模块的信息&#xff0c;表明了这个项目用到了哪一些模块。该文件里的using UnrealBuilTool 是…

为数字取证和 OSINT 调查定制用户体验

Tsurugi Linux 是一个高度定制的开源发行版&#xff0c;专注于支持 DFIR 调查。 该项目主要侧重于实时取证分析、事后分析和数字证据获取。用户还可以执行恶意软件分析、OSINT(开源情报)和计算机视觉活动。 我们精心打造了用户友好的体验&#xff0c;按照逻辑取证分析顺序组织…