【Linux】手把手教你从零上手gcc/g++编译器

举报
修修修也 发表于 2024/10/25 15:38:53 2024/10/25
【摘要】 🦄个人主页:修修修也 🎏所属专栏:Linux ⚙️操作环境:Xshell (操作系统:CentOS 7.9 64位)​编辑目录📌 什么是gcc/g++ 📌 gcc操作 选项 📌 gcc/g++是如何工作的 🎏 预处 理 ——宏替 换 🎏 编译 ——生成 汇编 🎏 汇编 ——生成机器可 识别 代 码 🎏 连 接 ——生成可 执 行文件或 库 文件 📌 函数 库 的概念 🎏...

🦄个人主:修修修也

🎏所属专栏:Linux

⚙️操作:Xshell (操作系:CentOS 7.9 64位)

​编辑


📌 什么是gcc/g++

📌 gcc操作 选项

📌 gcc/g++是如何工作的

🎏 预处 ——宏替

🎏 编译 ——生成 汇编

🎏 汇编 ——生成机器可 识别

🎏 ——生成可 行文件或 文件

📌 函数 的概念

🎏 什么是函数

🎏 态库 动态库

🎏 验证 Linux下的 动态库 和静 态库连

结语


📌什么是gcc/g++

        gcc 与 g++ 分别是 gnu 的 C & C++ 编译器 。gcc可以编译C言程序, g++既可以编译C言程序, 又可以编译C++程序, 因为在语法上C++兼容C语言。

        gcc/g++ 在执行编译工作的时候,总共需要4步:

1. 预处,生成 .i 的文件  [预处理器cpp]

2. 将预处理后的文件转换汇编语, 生成文件 .s  [编译器egcs]

3. 将汇编变为(机器代)生成 .o 的文件  [汇编器as]

4. 接目, 生成可行程序  [链接器ld]

​编辑


📌gcc操作选项

-E 只激活预处,个不生成文件,需要自己手把它重定向到一个出文件里面

-S 编译汇编语言不汇编

-c 编译到目

-o 文件出到目文件

-static 此选项对生成的文件采用静态链

-g 生成调试信息。GNU 调试器可利用信息

-shared 此选项将尽量使用动态库,所以生成文件比小,但是需要系动态库

-O0 / -O1 / -O2 / -O3 是编译器的选项4个级别-O0表示没有,-O1缺省-O3级别最高

-w 不生成任何警告信息

-Wall 生成所有警告信息


📌gcc/g++是如何工作的

        注:本文中会使用大量Linux中的指令操作vim文本编辑器的使用,如果对这不太了解的朋友推荐先点文章底部的文章推荐了解一下使用Linux方面的知

🎏预处——宏替

• 预处理功能主要包括宏定,文件包含,条件编译,去注等。

预处理指令以#号开的代

• 选项[ -E ], 该选项的作用是 gcc预处束后停止编译过

• 选项[ -o ]是指目标文件,“.i”文件经过预处理的C原始程序

        利用Linux中gcc操作验证这一过程:

        首先,我们用vim写一段test.c的代:

#include<stdio.h>

#define N 10

#define HELLO



int main()

{


#ifdef HELLO //条件编译,如果定义了HELLO宏,那就执行ifdef后面的程序,否则执行else

printf("HELLO条件编译已被执行\n");

#else

printf("HELLO条件编译未被执行\n");

#endif


printf("hello A: %d\n",N);

printf("hello B: %d\n",N);

//printf("hello : %d",N);

//printf("hello : %d",N);

//printf("hello : %d",N);

//printf("hello : %d",N);

//printf("hello : %d",N);

printf("hello C: %d\n",N);


return 0;

}

        然后我们使用gcc的只激活预处选项,将生成的文件定向入到新文件test.i:

编辑

        接着使用vim打开test.i文件预处:​编辑


🎏编译——生成汇编

• 在这个阶段中,gcc 首先要检查范性是否有错误,以确定代码的实际要做的工作,在检查,gcc 把代汇编语

• 用户可以使用[ -S ]选项,该选项编译而不汇编,生成汇编

        利用Linux中gcc操作验证这一过程:

        首先我们使用gcc编译汇编语选项,将生成的文件定向入到新文件test.s:

​编辑

        使用vim打开生成的新文件test.s, 可以发现之前的文件已经被转换成了汇编语言:

编辑


🎏汇编——生成机器可识别

• 汇编阶段是编译阶段生成的“.s”文件成二制目文件

• 可使用选项[ -c ]就可看到汇编代码“.o”的二制目

        利用Linux中gcc操作验证这一过程:

        首先我们使用gcc汇编到二制机器码选项,将生成的文件定向入到新文件test.o:​编辑

        然后我们使用vim打开新生成的test.o文件, 发现是乱码:​编辑

        这是因为vim是文本编辑, 它只能识别文本内容, 不能识别制内容, 那么我们可以选择使用二看工具"od"来个二制文件:
​编辑


🎏——生成可行文件或文件

• 在成功编译之后,就进入了链接阶段。

接是将可重定位目制文件, 和库进接形成可行程序。

        利用Linux中gcc操作验证这一过程:

        我们利用gcc来将test.o制文件和库连,生成可行程序test:

​编辑


📌函数的概念

🎏什么是函数

        在前面我们提到了gcc工作的最后一步: 。那么我们为什么要将自己编写的代码和库连接呢?

        这是因为,中有我们调用的C言函数的定, 它们三个的关系如下图:​编辑

        他们的关系可以给大家举个例子:

编辑

        也就是说, 我们的C程序中,并没有定义“printf”函数的实现,且在预编译中包含的“stdio.h”中也只有该函数的声明, 而没有定义函数的实现, 系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了, 在没有特别指定时, gcc 会到系统默认的搜索路径“/usr/lib”下进行查找, 也就是链接到 libc.so.6 库函数中去, 这样就能实现函数“printf”了, 而这也就是链接的作用。

编辑


🎏态库动态库

        态库是指编译链,把文件的代全部加入到可行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。在Linux中其后缀名一般为“.a”; 在Windows中其后缀名一般为".lib"
        动态库与之相反,在编译链并没有把文件的代加入到可行文件中,而是在程序由运行时链接文件加载库,这样可以节省系统的开销。在Linux中动态库一般后缀名为“.so”;在Windows中动态库一般后缀名为".dll"gcc编译时使用动态库

        看概念有些抽象,我们依然来举个例子,如下图所示:

编辑

        根据上面的例子也很容易总结出动态库和静态库的特点:

编译器使用静态库进行静态连接的,会将自己的方法拷到目程序中,程序以后不用再依态库这个就类似将空气炸锅一次性买回家,后面再需要用的时候就不用再出去租赁了。但是相应的, 空气炸锅放在家里的话也会占据家里的空间, 静态库拷贝到程序里也会导致程序变大。

而依赖动态库的程序, 动态库不能缺失, 一旦动态库缺失, 那么依赖动态库的很多文件就会出现问题这个就类似空气炸锅租赁店突然倒闭关门了, 那么原本依靠租赁空气炸锅的用户就没有办法使用空气炸锅了。

        防止有朋友还没有安装C语言/C++的静态库,在这里贴两条安装语句供大家参考:​编辑

         小tips:

如果没有静态库, 就不能使用-static静态连

如果没有动态库, 只有静态库时, gcc会找到静态库然后

程序不一定是全动态连接或静态连, 往往是混合使用的

-static的本: 改变连接的级顺, 并且要求程序只能全接静态库, 如果此不存在静态库, 程序就会报错


🎏验证Linux下的动态库和静态库连

        验证gcc编译时使用动态库:​编辑

        我们要求程序接静态库:

编辑

编辑

        gcc默认生成的二进制程序,是动态链接的,也可以 file 命令验证:

​编辑


结语

希望篇关于 gcc/g++编译 的博客能大家有所帮助,迎大佬留言或私信与我交流.

学海漫浩浩,我亦苦作舟!关注我,大家一起学,一起!

相关文章推荐

【Linux】手把手教你从零上手Vim 编辑

【Linux】一文 底搞懂

【Linux】基本指令(下)

【Linux】基本指令(中)

【Linux】基本指令(上)


​编辑

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。