Linux | 编译器gcc/g++的使用【动静态库的认识】-1

简介: Linux | 编译器gcc/g++的使用【动静态库的认识】

一、对程序的认知 && 初识gcc

1、程序是如何诞生的?

对于一个程序来说,从【编辑】——>【编译】——>【链接】——>【运行】总共要经过这些步骤算是一个程序完成的诞生过程。如果我们要去细谈其中的过程,又可以像下面这样分化:point_down:

image.png

  • 我们需要将这个【源程序】首先转变为【可执行程序】,中间的这一流程就被成为==翻译环境==,这一环境也就是我们本文所学习的gcc所要做的事情。在下一模块我就会对预编译编译汇编链接这四个小模块展开做讲解:book:

2、gcc的初步认识

:dart: gcc英文全名为GNU Compiler Collection,早期的gcc编译器主要用于C语言编译,但是经过几十年的发展,gcc编译器可以用于多种语言的编译,例如C++、Go等目前较为主流的语言。 :dart: 熟悉gcc编译器是对于我们开发C/C++程序的底层基本功,虽然目前各厂商的开发IDE已经非常智能,从某种程度上已经把程序员从底层代码的编译、部署等工作解放出来,但是如果需要开发大型C++项目或者对于编译过程进行优化,那么gcc编译器是需要进行了解和深入的:mag:

  • 对于gcc而言,它是一款Linux中的编译器,通常和我们之前所讲的Linux 编辑器vim配合使用。
  • 我们对【编辑】【编译】应该要有一个很清晰的认识,我们平时在写C/C++代码的时候,大多都是在一些集成开发环境上(IDE)进行,就像VS、VC。这些软件屏蔽了底层的细节,使用户可以不需要关注这些繁琐复杂的东西,只需要关注程序本身即可,但是却==淡化了我们对程序的演变和形成==
  • 这些软件通常是包含了编辑编译链接调试这些功能
  • 对于编辑功能来说有【编辑器】
  • 对于编译功能来说有【编译器】,VS2019为cl.exe
  • 对于链接功能来说有【链接器】,VS2019为link.exe
  • 对于调试功能来说有【调试器】

相信有了这些,你对程序的诞生过程一定有了一个更加深入的理解

3、如何使用gcc

讲了这么多,要如何去使用gcc呢?来看看吧👀

格式 gcc [选项] 要编译的文件 [选项] [目标文件]

具体如何使用,请看下一模块:point_down:

二、gcc逐步分析程序的翻译环境

好,接下去我们就来谈谈如何如何使用gcc来观察程序在翻译环境下的各个步骤。一下的讲解可能比较简略一些,如果想了解得更加深入,可以看看我的另一篇文章——> C生万物 | 程序的翻译环境和执行环境。很多内容也是从这篇文章中归纳出来的

  • 下面是从源文件【.c】到可执行文件【.exe】的整体过程image.png

1、预编译【进行宏替换】

在预编译阶段会执行以下四件事

  • 头文件的展开 —— 编译器第一件做的事
  • 宏定义的替换
  • 去注释
  • 条件编译的执行

gcc需要执行的指令

gcc -E file.c -o file.i
  • -E表示是让 gcc 在预处理结束后停止编译过程
  • -o表示输出到指定文件【-o 后面紧跟的永远都是你要形成文件的名称】
  • .c结尾的文件表示源程序;.i结尾的文件表示已经过预处理的C原始程序

image.png


2、编译【C语言——>汇编语言】

在编译阶段会执行以下四件事

  • 语法分析
  • 词法分析
  • 语义分析
  • 符号汇总

以上其实就是在将C语言的代码转化为汇编代码的一个流程

gcc需要执行的指令

gcc -S file.i -o file.s
  • -S表示只进行编译而不进行汇编,生成汇编代码
  • .i结尾的文件表示源程序;.s结尾的文件表示经过编译生成的汇编代码

image.png


3、汇编【汇编语言——>可重定位目标二进制文件】

在汇编阶段会执行以下两件事

  • 将汇编指令转换为二进制指令【需要特定的文本阅读器readelf】
  • 形成符号表

gcc需要执行的指令

gcc -c file.s -o file.o
  • -c表示是gcc编译到目标代码
  • .s结尾的文件表示经过编译生成的汇编代码;.o结尾的文件表示经过编译生成的汇编代码

image.png

  • 在汇编这一块,就是将汇编语言翻译成可以重定位的二进制文件,里面的二进制代码我们人眼是看不到的,要特定的阅读器才可以看得明白
  • 有几个源文件【.c】就会生成几个目标文件【.o】

此时我们可以来试试执行一下这个目标文件,不过发现没有【x】可执行的权限,于是使用chmod做一个提权的操作。但是系统却说cannot execute binary file,上面看到过这是一个二进制文件,对于二进制文件来说是不可以被执行的

image.png

对于上面的这三步【预编译】、【编译】、【汇编】都是对一个源文件中的代码进行操作的过程,没有引入其他人的代码。但是到了链接这一步,可能就要与别人的代码或者是库中的代码一起执行


4、链接【生成可执行文件或库文件】

在链接阶段会执行以下两件事

  • 合并段表
  • 符号表的合并和重定位

gcc需要执行的指令

gcc -E file.c -o file.i
  • -E表示是让 gcc 在预处理结束后停止编译过程;-o表示输出到指定文件
  • .c表示源程序;.i表示已经过预处理的C原始程序

image.png

  • 这里便不展示与其余文件的合并了,这里导一个我之前做过的GIF

image.png

  • 可以来看看这个可执行文件my_out,它也是一个内容也是二进制代码,可供机器识别

image.png

  • 最后的总结可以看看这张图

image.png

5、巧记gcc命令选项与生成文件后缀【⭐】

📚 命令选项-E  -S  -c 【键盘左上角的Esc,不过中间的S要大写】 📚 文件后缀.i.s  .o  【.iso为镜像文件的后缀,ISO也为国际标准化组织

image.png


三、gcc与g++的区别

看了这么久gcc,我们来看看g++,其实这两个编译器的用法是一模一样的,只是对于gcc才说是用来编译C语言代码,对于g++来说是用来编译C++的代码

  • 不过这只是笼统的说法,其实对于gcc而言也是可以编译C++代码的,对于g++而言是可以编译C语言代码的
  • 但是实际上在一些具体的语法规则上,C++在编译过程中的语法检查会更加严格。此外,C++语言本身在编译 过程中也会引入C++的标准库,如果使用gcc编译器直接编译C++语言会在编译过程中添加额外的参数,这样会显得编译过程较为繁琐(因为大部分情况下我们希望标准库可以直接引入,而不是再需要手动指定,否则对于初级使用者会带来额外的学习负担)。为了更方便使用编译器,我们选择g++来编译C++代码。
  • 总结一下,gcc可以完成C++语言的编译,但是使用过程会较为繁琐,而g++就是简化后的编译指令
相关文章
|
6天前
|
Linux 开发工具 C语言
Linux 安装 gcc 编译运行 C程序
Linux 安装 gcc 编译运行 C程序
26 0
|
7天前
|
Linux 编译器 Android开发
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
在Linux环境下,本文指导如何交叉编译x265的so库以适应Android。首先,需安装cmake和下载android-ndk-r21e。接着,下载x265源码,修改crosscompile.cmake的编译器设置。配置x265源码,使用指定的NDK路径,并在配置界面修改相关选项。随后,修改编译规则,编译并安装x265,调整pc描述文件并更新PKG_CONFIG_PATH。最后,修改FFmpeg配置脚本启用x265支持,编译安装FFmpeg,将生成的so文件导入Android工程,调整gradle配置以确保顺利运行。
25 1
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
|
1月前
|
Linux
linux 交叉编译libpng,libjpeg库
linux 交叉编译libpng,libjpeg库
23 1
|
1月前
|
Linux 编译器 Android开发
linux交叉编译nss3,nspr库精讲
linux交叉编译nss3,nspr库精讲
38 1
|
1月前
|
Linux 编译器 vr&ar
linux交叉编译一些常用依赖库util-linux,zlib,sqlite3,eudev ,openssl,libpng,glibc
linux交叉编译一些常用依赖库util-linux,zlib,sqlite3,eudev ,openssl,libpng,glibc
31 1
|
9天前
|
Linux 网络安全 开发工具
【GitLab私有仓库】在Linux上用Gitlab搭建自己的私有库并配置cpolar内网穿透
【GitLab私有仓库】在Linux上用Gitlab搭建自己的私有库并配置cpolar内网穿透
|
1月前
|
Shell Linux vr&ar
【Shell 命令集合 备份压缩 】⭐⭐⭐Linux 修改备存/静态库 文件 ar命令 使用指南
【Shell 命令集合 备份压缩 】⭐⭐⭐Linux 修改备存/静态库 文件 ar命令 使用指南
30 0
|
1月前
|
Linux 编译器 网络安全
linux 交叉编译libcurl库
linux 交叉编译libcurl库
39 1
|
1月前
|
算法 安全 Linux
Linux 裁剪并交叉编译openssl库
Linux 裁剪并交叉编译openssl库
34 1
|
1月前
|
Linux 编译器 vr&ar
【Linux】—— 详解动态库和静态库
【Linux】—— 详解动态库和静态库