gcc/g++工具详解

目录

一、安装gcc/g++

二、背景知识

三、相关选项

四、gcc如何工作

1.预处理

2.编译

 3.汇编

4.链接 

5.函数库的概念 

6.动静态库 


一、安装gcc/g++

gcc/g++ -v : 用来查看当前你使用的gcc/g++版本

 因为我的gcc/g++是升级过的所以版本更高,如果你用的是centos7.6的话你的gcc的版本可能是4.8的。

安装gcc/g++sudo yum install -y gcc-c++

这条指令会根据你当前的centos版本为你安装合适的gcc/g++版本。

gcc用来编译C语言代码,g++一般用来编译C++代码当然也可以用来编译C语言代码 

二、背景知识

在生成一个可执行程序文件的时候通常要经过如下几步:

  1. 预处理(a.去注释 b.宏替换 c.头文件展开 d.条件编译……)
  2. 编译(生成汇编)
  3. 汇编(生成机器可识别的代码)
  4. 链接(生成可执行文件或库文件)

三、相关选项

-E从现在开始进行程序的翻译,如果预处理完成,就停下来
-S从现在开始进行程序的翻译,如果编译完成,就停下来
-c从现在开始进行程序的翻译,如果汇编完成,就停下来
-o文件输出到文件
-static对生成的文件采用静态链接
-g生成调试信息
-shared对生成的文件采用动态链接
-O0不做任何优化
-O1尝试优化编译时间和可执行程序大小
-O2在O1的基础上进行更大力度的优化
-O3最高级别优化
-w不生成任何警告信息
-Wall生成所有警告信息

四、gcc如何工作

1.预处理

  • 预处理的功能主要包括宏替换,去注释,条件编译,头文件展开等。
  • 预处理的指令是以#号开头的代码行。
  • 指令:gcc -E mytest.c -o mytest.i
  • -E选项是从现在开始进行程序的翻译,如果预处理完成,就停下来。
  • -o选项是指目标文件。
  • ".i"文件是已经预处理过的C语言原始程序

 #include <stdio.h>#define NUM 20int main(){printf("NUM: %d\n", NUM);printf("hello world1\n");// printf("hello world2\n");// printf("hello world3\n");// printf("hello world4\n");// printf("hello world5\n");printf("hello world6\n");//条件编译#ifdef DEBUG                 printf("hello debug!\n");#elseprintf("hello release!\n");#endifreturn 0;                                                                                                                                                                             
}

通过指令:gcc -E mytest.c -o mytest.i

 生成了一个mytest.i的文件,我们查看这个文件的内容如下

 这里我只截取了一部分,前面还有很多是头文件展开的内容。从这一部分我们不难看出预处理所做的工作。

2.编译

  • 在这个阶段中,gcc首先要检查代码的规范性以及是否有语法错误等等,检查无误后,gcc才会把代码翻译成汇编语言。
  • 指令:gcc -S mytest.i -o mytest.s
  • -S选项是从现在开始进行程序的翻译,如果编译完成,就停下来。

执行上面的指令后生成的“.s”文件内容如下

 3.汇编

  • 此阶段是把编译阶段生成的".s"文件转成目标文件
  • 指令:gcc -c mytest.s -o mytest.o
  • -c选项是从现在开始进行程序的翻译,如果汇编完成,就停下来。

 举个栗子:

执行上面的指令生成的mytest.o文件称为可重定向目标文件,可以查看这个文件的内容如下

 这里显示的都是乱码,我们也可以用od mytest.o进行查看,翻译过来都是二进制

4.链接 

  • 在成功编译之后,就进入了链接阶段
  • 指令:gcc mytest.o -o mytest
  • 生成的mytest文件即为可执行程序

5.函数库的概念 

首先看一个例子:

这个代码能编译通过吗?

答案是:可以的 

 因为它自动给你链接上了C语言的库

再看一个例子:

问:在上面的C语言代码中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实现“printf”函数的呢?


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

 

上面中的 /lib64/libc-2.17.so 提供C语言的方法实现,/usr/include/stdio.h 提供C语言的方法列表,方法的声明。两者协同生成可执行程序。

6.动静态库 

一般链接的过程是有两种方式的:

a.动态链接 — 需要动态库

b.静态链接 — 需要静态库

在Linux中以.so结尾的称为动态库,.a结尾的为静态库

在Windows中以.dll结尾的为动态库,.lib结尾的为静态库

查看方式有两种:ldd+可执行程序文件名/file+可执行程序文件名

  • 静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a
  • 动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如前面图所示的 libc.so.6 就是动态库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件,如下所示。 gcc test.o –o test
  • gcc/g++默认生成的二进制程序是动态链接的,这点可以通过 file 命令验证

 由图可以看出,静态链接的文件比动态链接的文件大得多了。

安装静态库的命令

C语言静态库安装:sudo yum install -y glibc-static

C++静态库安装:sudo yum install -y libstdc++-static

这次的内容就分享到这了,如有写的不好的地方还请指正,创作不易,如果你觉得写的好的话,就给博主三连吧,你的支持将是我的动力 

 谢谢!!!

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PyCharm连接服务器(利用PyCharm实现远程开发)

利用PyCharm实现远程开发 注&#xff1a;该功能只有在PyCharm专业版下才可以使用&#xff0c;并且必须是官方的正版许可&#xff0c;破解版的是不可以使用的&#xff01;&#xff01;&#xff01;可以通过免费教育许可申请使用权限&#xff08;申请流程&#xff09;。 pycharm…

使用C语言调用 liblapack.a 的使用方法及其原理探析

1&#xff0c; 使用方法 1.1 源代码 #include <stdio.h> //#include <lapack/lapacke.h> extern void dgesv_(int*m, int* n, double*A, int*k, int*IP, double*B, int*j, int*info);#define M 2 #define N 2int main() {int i, j, nN, mM;int info, IPIV[N];doub…

x-cmd pkg | busybox - 嵌入式 Linux 的瑞士军刀

目录 简介首次用户功能特点竞品和相关作品 进一步阅读 简介 busybox 是一个开源的轻量级工具集合&#xff0c;集成了一批最常用 Unix 工具命令&#xff0c;只需要几 MB 大小就能覆盖绝大多数用户在 Linux 的使用&#xff0c;能在多款 POSIX 环境的操作系统&#xff08;如 Linu…

大数据实时抓取软件:Maxwell学习网站的高效框架!

介绍&#xff1a;Maxwell是由美国Zendesk开源的&#xff0c;使用Java编写的MySQL实时抓取软件。它能够实时读取MySQL的二进制日志&#xff08;Binlog&#xff09;&#xff0c;并将这些信息生成为JSON格式的消息。进一步地&#xff0c;Maxwell将这些消息作为生产者发送给Kafka、…

腾讯云COS桶文件上传下载工具类

1&#xff0c;申请key和密钥 2&#xff0c;引入依赖 <dependency><groupId>com.qcloud</groupId><artifactId>cos_api</artifactId><version>5.6.24</version></dependency>3&#xff0c;工具类 package com.example.activi…

python包管理工具:pipenv的基本使用

很多语言都提供了环境隔离的支持&#xff0c;例如nodejs的node_module&#xff0c;golang的go mod&#xff0c;python也有virtualenv和pyvenv等机制。 为了建立依赖快照&#xff0c;通常会用pip freeze > requirements.txt 命令生成一个requirements.txt文件&#xff0c;在…

手敲Mybatis(16章)-一级缓存功能实现

1.实现目的 这一节的目的主要是实现SqlSession级别的缓存&#xff0c;也就是一级缓存&#xff0c;首先看下图一&#xff0c;用户可以通过设置来进行是否开启一级缓存&#xff0c;不设置的化默认开启一级缓存&#xff0c;localCacheScopeSESSION为要设置一级缓存&#xff0c;lo…

Android开发基础(二)

Android开发基础&#xff08;二&#xff09; 上篇主要描述了Android系统架构&#xff0c;代码是通过Java表示的&#xff1b; 本篇将从介绍Android组件去理解Android开发&#xff0c;代码将对Java和Kotlin进行对比。 Android组件 Android应用程序由一些零散的有联系的组件组成…

JS-DOM树和DOM对象

作用和分类 作用&#xff1a;就是使用JS去操作html和浏览器 分类&#xff1a;DOM&#xff08;文档对象模型&#xff09;、BOM&#xff08;浏览器对象模型&#xff09; 什么是DOM DOM&#xff08;Document Object Model--文档对象模型&#xff09;是用来呈现以及与任意HTML或…

Python商业数据挖掘实战——爬取网页并将其转为Markdown

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 ChatGPT体验地址 文章目录 前言前言正则表达式进行转换送书活动 前言 在信息爆炸的时代&#xff0c;互联网上的海量文字信息如同无尽的沙滩。然而&#xff0c;其中真正有价值的信息往往埋…

在 The Sandbox 见证元宇宙新地标:Playboy 推出 MetaMansion 特别预览

元宇宙诞生了新地标&#xff01;The Sandbox 联手 Playboy推出 MetaMansion&#xff0c;重新演绎了传说级别的现实版 Playboy Mansion&#xff0c;你可以在 The Sandbox 中一睹它的风采。 今天&#xff0c;Playboy 公布了 MetaMansion 的首次预览&#xff0c;用虚拟方式呈现了 …

Postgresql常见(花式)操作完全示例

案例说明 将Excel数据导入Postgresql&#xff0c;并实现常见统计&#xff08;数据示例如下&#xff09; 导入Excel数据到数据库 使用Navicat工具连接数据库&#xff0c;使用导入功能可直接导入&#xff0c;此处不做过多介绍&#xff0c;详细操作请看下图&#xff1a; 点击“下…