【Linux开发工具】gcc/g++的使用


📙 作者简介 :RO-BERRY
📗 学习方向:致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识
📒 日后方向 : 偏向于CPP开发以及大数据方向,欢迎各位关注,谢谢各位的支持


在这里插入图片描述


目录

  • 1.前言
  • 2.gcc/g++使用方法:以gcc为例
  • 3.程序翻译的四个阶段
    • 3.1 预处理(进行宏替换)
      • 创建预处理文件
      • 查看预处理文件
    • 3.2 编译(生成汇编)
      • 创建编译文件:
      • 查看编译文件:
    • 3.3 汇编(生成机器可识别代码)
      • 创建汇编文件
      • 查看汇编文件
    • 3.4 链接(生成可执行文件或库文件)
  • 4.函数库
    • 4.1 函数库的分类
    • 4.2 动静态库的区别与优缺点
    • 4.3 动静态库链接方式


1.前言

Linux下皆文件,在Linux下文件不分文件的后缀,文件的类型是看文件前面的字符
今天要学习的gcc和g++就是Linux下的程序
它们是要看文件后缀的!

  • gcc: C语言编译器,只能编译C语言
  • g++: C++编译器,C/C++都可以编译

2.gcc/g++使用方法:以gcc为例

编译文件:

  1. 编译文件并形成a.out的执行文件
  • gcc test.c
  1. 编译文件并形成test的执行文件,这里的test可以自取名字
  • * gcc test.c -o test

执行可执行程序
当我们编译好程序后,会在当前目录生成一个
可执行程序
在这里插入图片描述

  1. 执行形成的a.out的执行文件
  • ./a.out
  1. 执行形成的test的执行文件
  • ./test

注:.代表要在当前目录下找可执行文件.必须加上

gcc/g++选项

-E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面
-S 编译到汇编语言不进行汇编和链接
-c 编译到目标代
-o 文件输出到 文件
-static 此选项对生成的文件采用静态链接
-g 生成调试信息。GNU 调试器可利用该信息。
-shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库.
-O0
-O1
-O2
-O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
-w 不生成任何警告信息。
-Wall 生成所有警告信息。

3.程序翻译的四个阶段

3.1 预处理(进行宏替换)

预处理功能主要包括

宏定义,文件包含,条件编译,去注释等。
预处理指令是以#号开头的代码行。

创建预处理文件

我们使用指令看一看

gcc –E test.c –o test.i

选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。
选项“-o”是指目标文件,“.i”文件为已经过预处理的C原始程序。
在这里插入图片描述

查看预处理文件

vim test.i

在这里插入图片描述

可以看到上面全部都是宏定义,文件包含,条件编译,去注释等操作,一共有八百多行,最后才是我们写的文件操作

3.2 编译(生成汇编)

在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。
用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。

创建编译文件:

gcc –S hello.i –o hello.s

在这里插入图片描述

查看编译文件:

vim test.s

在这里插入图片描述

这里的汇编代码没学过真不好懂

3.3 汇编(生成机器可识别代码)

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

创建汇编文件

gcc –c hello.s –o hello.o

在这里插入图片描述

查看汇编文件

vim test.o

在这里插入图片描述

此时使用vim打开文件是乱码
可以使用指令od查看二进制文件:

3.4 链接(生成可执行文件或库文件)

在成功编译之后,就进入了链接阶段。
链接阶段是将编译成功的文件变成可执行文件

gcc -o test test.o
这里我们将test.o文件进行编译并生成test可执行文件

在这里插入图片描述

链接阶段比较复杂,它大致的流程是这样的:

.o文件 + 系统库 = 可执行程序

在本篇文章的后半段讲完动静态库后再解释!


4.函数库

我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实现“printf”函数的呢?
最后的答案是:

系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用

这里我们引入一个新指令:

ldd 可执行程序名
查看一个可执行程序依赖的第三方库

在这里插入图片描述
可以发现,在路径lib64里有一个文件叫libc.so.6
这个就是刚刚的C语言程序所要依赖的库
在这里插入图片描述
可见,libc.so.6实际上就是C的标准库


其中Linux环境下,动态库的后缀是.so,静态库的后缀是.a。在Windows环境下,动态库的后缀是.dll,静态库的后缀是.lib。所有的库文件,都遵守相同的命名规则,即:libname.后缀.xxx。
小Tips:gcc编译器会默认找到C的标准库,它会把我们写的源代码经过编译得到的目标文件与库文件进行链接。这也是为什么gcc不能去编译C++的源文件,因为gcc默认找的是C的标准库,它找不到C++的库。

现在我们就可以理解链接过程了
链接过程就是将.o文件和动/静态库结合的过程

4.1 函数库的分类

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

  • 静态库(static library, Statically-linked library, LIB)或称静态链接库,是一个外部函数与变量的集合体。静态库的文件内容,通常包含一堆程序员自定的变量与函数,在编译期间由编译器与连接器将它集成至应用程序内,并制作成目标文件以及可以独立运作的可执行文件。而这个可执行文件与编译可执行文件的程序,都是一种程序的静态创建(static build)。其特点是可执行文件中包含了库代码的一份完整拷贝;缺点就是被多次使用就会有多份冗余拷贝。即静态库中的指令全部被直接包含在最终生成的可执行文件中。静态库的后缀是.a

  • 动态库(Dynamic library, Dynamic-link library, DLL)或称动态链接库,是微软公司在微软视窗操作系统中实现共享函数库概念的一种实现方式。动态链接库可被多个程序同时使用。所谓动态链接,就是把一些经常会共用的代码(静态链接的OBJ程序库)制作成DLL档,当程序有需求时函数才进行链接。透过动态链接方式,存储器浪费的情形将可大幅降低。静态链接库则是直接链接到可执行文件。动态库的后缀是.so

gcc hello.o –o hello
gcc默认生成的二进制程序,是动态链接的,这点可以通过 file 命令验证。

4.2 动静态库的区别与优缺点

  • 动态库是共享库,通过函数地址来关联程序
  • 静态库是私有库,可以独立运行

动态库: 是C/C++或其他第三方提供的所有方法的集合,被所有程序以动态链接的方式关联起来
静态库: 是C/C++或其他第三方提供的所有方法的集合,被所有程序以拷贝的方式,将需要的代码拷贝至自己的可执行程序当中!

优点缺点
静态库有效的节省资源(磁盘空间、内存空间、网络空间等)一旦缺失,所有程序都无法运行
静态库不依赖库,编译成功的可执行程序,可以独立执行,不需要再向外部要求读取库函数中的内容体积大,比较消耗资源

4.3 动静态库链接方式

链接分为两类:动态链接静态链接

  • 静态链接:由链接器在链接时将库的内容加入到可执行程序中。在编译器使用静态库进行静态链接的时候,会将自己的方法拷贝到目标程序中,该程序以后不再依赖静态库。
  • 动态链接:连接器在链接时仅仅建立与所需库函数的之间的链接关系,在程序运行时才将所需资源调入可执行程序。动态库是被所有程序所共享的,一般也被叫做共享库。这意味着,动态库只需要一个就够了,它可以满足所有程序的需求。

Linux中,编译形成可执行程序,优先采用动态链接。
如果想使用静态库编译程序

使用指令: gcc test.c -static

总的来说,静态库可以产出独立程序,动态库实现了模块化和代码共享,以空间换时间。
链接器会根据是静态链接还是动态链接,调用不同的处理逻辑,最终产出可执行程序。
所以同样的代码,静态链接和动态链接链接后的结果并不相同。

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

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

相关文章

初始Ansible自动化运维工具之playbook剧本编写

一、playbook的相关知识 1.1 playbook 的简介 playbook是 一个不同于使用Ansible命令行执行方式的模式,其功能更强大灵活。简单来说,playbook是一个非常简单的配置管理和多主机部署系统,不同于任何已经存在的模式,可作为一个适…

安装PyInstaller的保姆级教程

一、安装PyInstaller之前首先要安装Python,小编这里安装的是Python3.9,目前(2024/2/6)匹配到的最高版本的PyInstaller的版本为6.3.0。需要安装Python的小伙伴可以去这里安装python详细步骤(超详细,保姆级&a…

推荐一款开源的跨平台划词翻译和OCR翻译软件:Pot

Pot简介 一款开源的跨平台划词翻译和OCR翻译软件 下载安装指南 根据你的机器型号下载对应版本,下载完成后双击安装即可。 使用教程 Pot具体功能如下: 划词翻译输入翻译外部调用鼠标选中需要翻译的文本,按下设置的划词翻译快捷键即可按下输…

作业2.7

一、填空题 1、在下列程序的空格处填上适当的字句&#xff0c;使输出为&#xff1a;0&#xff0c;2&#xff0c;10。 #include <iostream> #include <math.h> class Magic {double x; public: Magic(double d0.00):x(fabs(d)) {} Magic operator(__const Magic&…

登录+JS逆向进阶【过咪咕登录】(附带源码)

JS渗透之咪咕登录 每篇前言&#xff1a;咪咕登录参数对比 captcha参数enpassword参数搜索enpassword参数搜索J_RsaPsd参数setPublic函数encrypt加密函数运行时可能会遇到的问题此部分改写的最终形态JS代码&#xff1a;运行结果python编写脚本运行此JS代码&#xff1a;运行结果&…

开关电源用什么电感

开关电源用什么电感 电感波形图 我们看图&#xff0c;如下图所示&#xff1a; 图1 电感波形示意图 PWM那张图和inductor那张图&#xff0c;第一张图就是Buck电路图SW引脚的波形&#xff0c;看波形我们知道在t1的时候是vi在t2的时候是0&#xff0c;紧接着电流和电压经过电感以…

BUUCTF-Real-ThinkPHP]5.0.23-Rce

漏洞介绍 这个版本容易存在我们都喜欢的rce漏洞&#xff01; 网站为了提高访问效率往往会将用户访问过的页面存入缓存来减少开销。而Thinkphp 在使用缓存的时候是将数据序列化&#xff0c;然后存进一个 php 文件中&#xff0c;这使得命令执行等行为成为可能&#xff01; ThinkP…

51单片机基础:定时器

1.定时器介绍 51单片机通常有两个定时器&#xff1a;定时器 0/1&#xff0c;好一点的可能有定时器3。 在介绍定时器之前我们先科普下几个知识&#xff1a; 1&#xff0c;CPU 时序的有关知识 ①振荡周期&#xff1a;为单片机提供定时信号的振荡源的周期&#xff08;晶振周期或…

第二十五回 偷骨殖何九叔送丧 供人头武二郎设祭-Numpy数组计算

何九叔晕倒了&#xff0c;被抬回家里&#xff0c;他对老婆说&#xff0c;我没事&#xff0c;是看到武大郎的情况&#xff0c;明显是中毒身亡&#xff0c;但是又不敢声张&#xff0c;怕西门庆打击报复。九叔的老婆让他送丧的时候拿两块骨头&#xff0c;同前面十两银子一起收着&a…

操作系统基础:磁盘组织与管理【下】

&#x1f308;个人主页&#xff1a;godspeed_lucip &#x1f525; 系列专栏&#xff1a;OS从基础到进阶 ⚖️1 减少延迟时间⚙️1.1 存在延迟时间的原因⚙️1.2 减少延迟的方法&#x1f9ea;1.2.1 交替编号&#x1f9ea;1.2.2 错位命名 ⚙️1.3 总结 ⚖️2 磁盘的管理&#x1f…

Leetcode刷题笔记题解(C++):590. N 叉树的后序遍历

思路&#xff1a;类似于二叉树的排序&#xff0c;这里需要将子树进行依次递归遍历&#xff0c;前序遍历也与之类似 /* // Definition for a Node. class Node { public:int val;vector<Node*> children;Node() {}Node(int _val) {val _val;}Node(int _val, vector<N…

蓝桥杯Web应用开发-CSS3 新特性【练习一:属性有效性验证】

练习一&#xff1a;属性有效性验证 页面上有一个邮箱输入框&#xff0c;当你的输入满足邮箱格式时&#xff0c;输入框的背景颜色为绿色&#xff1b;当你的输入不满足要求&#xff0c;背景颜色为红色。 新建一个 index2.html 文件&#xff0c;在其中写入以下内容。 <!DOCTYP…

2024-02-06(Sqoop)

1.Sqoop Apache Sqoop是Hadoop生态体系和RDBMS&#xff08;关系型数据库&#xff09;体系之间传递数据的一种工具。 Sqoop工作机制是将导入或者导出命令翻译成MapReduce程序来实现。在翻译出的MapReduce中主要是对inputformat和outputformat进行定制。 Hadoop生态包括&#…

python30-Python的运算符结合性和优先级

1&#xff09;所有的数学运算都是从左向右进行的&#xff0c;Python 语言中的大部分运算符也是从左向右结合的&#xff0c;只有单目运算符、赋值运算符和三目运算符例外&#xff0c;它们是从右向左结合的&#xff0c;也就是说&#xff0c;它们是从右向左运算的。 2&#xff09…

怎么理解 Redis 事务

背景 在面试中经常会被问到&#xff0c;redis支持事务吗&#xff1f;事务是怎么实现的&#xff1f;事务会回滚吗&#xff1f;又是一键三连&#xff0c;我下面分析下&#xff0c;看看能不能吊打面试官 什么是Redis事务 事务是一个单独的隔离操作&#xff1a;事务中的所有命令…

Spring的学习(上)

1、Spring的Beans.xml 一个beans.xml示例&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:sch…

树莓派Pico入门

文章目录 1. Pico概述1.1 微处理器1.2 GPIO引脚1.3 MicroPython优点 2. 硬件准备2.1 购买清单2.2 软件需求 3. 安装MicroPython3.1下载固件3.2把固件安装到硬件里3.3补充 4. 第一个程序5. 验证运行效果6. 扩展应用 1. Pico概述 1.1 微处理器 ARM Cortex-M0 (频率 133MHz) 1.…

代码随想录算法训练营第43天 | 1049.最后一块石头的重量 II + 494.目标和 + 474.一和零

今日任务 1049. 最后一块石头的重量 II 494. 目标和 474.一和零 1049.最后一块石头的重量 II - Medium 题目链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 有一堆石头&#xff0c;用整数数组 stones 表示。其中 stones[i] 表示…

高速接口PCB布局指南(五)高速差分信号布线(三)

高速接口PCB布局指南&#xff08;五&#xff09;高速差分信号布线&#xff08;三&#xff09; 1.表面贴装器件焊盘不连续性缓解2.信号线弯曲3.高速信号建议的 PCB 叠层设计4.ESD/EMI 注意事项5.ESD/EMI 布局规则 tips&#xff1a;资料主要来自网络&#xff0c;仅供学习使用。 …

Android:国际化弹出框

3.13 风格与主题、国际化 1、应用国际化 应用国际化,通过修改系统语言,应用显示语言跟着改变。 选择Locale,点击>>符号。 创建多个国家,地区strings.xml文件,有一个默认strings.xml文件,各个stirngs.xml中<string>标签中保持一致。 示例: 创建t_language.…