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

简介: Linux编译器-gcc/g++使用

前言:

gcc/g++介绍:

gcc 和 g++ 是 GNU Compiler Collection 工具集中的两个主要工具,分别用于编译 C 和 C++ 程序。它们之间的主要区别在于语言的默认设置和链接的库。

我们知道在linux中,gcc指令编译.c后缀的文件,g++编译 .cpp后缀的文件。一个文件要想被编译成一个可执行文件要满足两个条件:一个是其文件类型可以被编译,另一个是文件内容可以被被编译。

假设我们在linux中用gcc/g++指令编译一个非以 .c/.cpp 后缀的文件,观察其结果

假设我们在linux中用gcc/g++指令编译一个以 .c/.cpp 后缀的文件,但是其内容无法正常编译,观察其结果

总结:一个文件要想被编译成一个可执行文件要满足两个条件:一个是其文件类型可以被编译(指gcc编译.c文件,g++编译.c++文件),另一个是文件内容可以被被编译。

1.必备知识

1. 预处理(进行宏替换)

2. 编译(生成汇编)

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

4. 连接(生成可执行文件或库文件)

2.gcc/g++基本编译指令(以gcc为例)

格式:

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

gcc选项

-E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面

-S  编译到汇编语言不进行汇编和链接

-c  编译到目标代码

-o 文件输出到 文件

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

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

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

-O0 -O1 -O2 -O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高 -w  不生成任何警告信息。

-Wall 生成所有警告信息。

2.1编译 c源文件生成可执行文件

gcc 文件名 -o 目标文件

2.2 查看 gcc 版本信息:

gcc --version

2.3预处理(生成预处理文件)

预处理功能主要包括宏定义,文件包含,条件编译,去注释等。-E选项让gcc在预处理结束后停止,生成一个仅预处理过的目标文件。

gcc -E filename.c -o output.i

这行指令的意思是,gcc从filename.c文件开始编译,到预处理阶段结束后马上停止,并生成目标文件。

2.4 编译(生成汇编)

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

gcc -S filename.c -o output.s

这行指令的意思是gcc编译器从文件filename.c开始编译,到编译阶段结束,生成汇编文件。 如果开始编译的文件是已经经过预处理的.i文件,那就不用再进行预处理。

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

汇编阶段是把编译阶段生成的“.s”文件转成目标文件,在这个阶段会将汇编代码转换成机器可以识别的二进制代码。可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了

gcc -c filename.c -o output.s

思路同上,编译器从filename.c开始,到汇编阶段结束后停止,生成机器可识别的二进制代码的 ".o"文件

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

在成功编译之后,就进入了链接阶段。这个阶段会将 .o 目标文件连接成一个可执行文件,这也是编译器翻译的最后一个阶段。

gcc filename.c -o output

上述代码是将filename.c文件编译到可执行文件,中间经历了预编译、编译、汇编、链接四个阶段。也就是我们经常使用的一条指令。

3.函数库

函数库(Library,缩写为lib)分为 静态库和动态库。是一组已经编写好的代码,可供程序员在自己的程序中重复使用。这些代码可以包含函数、数据结构、对象等,用于完成特定的任务。函数库的使用有助于提高代码的可维护性、重用性和可扩展性。

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

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

3.1静态库与动态库的区别:

静态库(Static Library):

  • 编译链接时,把库文件的代码全部加入到可执行文件中,生成的文件比较大,形成一个独立的可执行文件。
  • 静态库的文件扩展名通常为 .a(在Unix/Linux系统)或 .lib(在Windows系统)。
  • 静态库的优点是它可以在编译时将库的代码嵌入到程序中,使得程序在运行时不再依赖于外部的库文件

动态库(Dynamic Library):

  • 动态库在编译链接时并没有把库文件的代码加入到可执行文件中,在运行时被加载到内存中,这样能节省系统的开销,程序在需要时调用动态库中的函数。
  • 动态库的文件扩展名通常为 .so(在Unix/Linux系统)或 .dll(在Windows系统)。如前面所述的 libc.so.6 就是动态 库。gcc 在编译时默认使用动态库。完成了链接后,gcc 就可以生成可执行文件。
  • 动态库的优点是它可以被多个程序共享,减小了程序文件的大小,同时允许在不修改程序代码的情况下更新库文件。

3.2修改链接方式

gcc -static your_program.c -o your_program_static

使用 -static 选项告诉编译器进行静态链接

4. file指令

file 命令用于确定文件的类型,也可以使用file命令来查看生成的二进制程序是动态链接的还是静态链接的。

格式是:file+二进制程序

相关文章
|
5月前
|
Linux 编译器 C语言
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
|
7月前
|
Linux C语言
成功解决 在Linux CentOS 7 中安装gcc
这篇文章介绍了如何在Linux CentOS 7系统中安装gcc (g++) 8工具集。由于CentOS 7默认的gcc版本是4.8,而这个版本与Qt 5.14、Qt 5.15或更高版本不兼容,可能会导致编译时出现系统头文件错误。文章中提到,即使在项目配置中添加了`CONFIG+=c++11`,如果仍然报错,那么很可能是gcc版本的问题。为了解决这个问题,文章提供了使用CentOS的Software Collections (scl)来安装更新版本的gcc的步骤。
成功解决 在Linux CentOS 7 中安装gcc
|
6月前
|
Linux 编译器 C语言
Linux内核对GCC版本的检测
Linux内核对GCC版本的检测
|
7月前
|
Java Linux 编译器
【Linux】gcc简介+编译过程
【Linux】gcc简介+编译过程
167 0
|
9月前
|
Java 编译器 Linux
程序技术好文:详解Linux安装GCC方法
程序技术好文:详解Linux安装GCC方法
286 0
|
9月前
|
NoSQL 编译器 Linux
【Linux】--- Linux编译器-gcc/g++、调试器-gdb、项目自动化构建工具-make/Makefile 使用
【Linux】--- Linux编译器-gcc/g++、调试器-gdb、项目自动化构建工具-make/Makefile 使用
152 0
|
2天前
|
Linux
Linux 常用文件查看命令
`cat` 命令用于连接文件并打印到标准输出,适用于快速查看和合并文本文件内容。常用示例包括:`cat file1.txt` 查看单个文件,`cat file1.txt file2.txt` 合并多个文件,`cat > filename` 创建新文件,`cat >> filename` 追加内容。`more` 和 `less` 命令用于分页查看文件,`tail` 命令则用于查看文件末尾内容,支持实时追踪日志更新,如 `tail -f file.log`。
20 5
Linux 常用文件查看命令
|
1月前
|
Linux
Linux系统之whereis命令的基本使用
Linux系统之whereis命令的基本使用
77 24
Linux系统之whereis命令的基本使用
|
8天前
|
Linux
Linux od命令
本文详细介绍了Linux中的 `od`命令,包括其基本语法、常用选项和示例。通过这些内容,你可以灵活地使用 `od`命令查看文件内容,提高分析和调试效率。确保理解每一个选项和示例的实现细节,应用到实际工作中时能有效地处理各种文件查看需求。
43 19
|
20天前
|
缓存 Ubuntu Linux
Linux中yum、rpm、apt-get、wget的区别,yum、rpm、apt-get常用命令,CentOS、Ubuntu中安装wget
通过本文,我们详细了解了 `yum`、`rpm`、`apt-get`和 `wget`的区别、常用命令以及在CentOS和Ubuntu中安装 `wget`的方法。`yum`和 `apt-get`是高层次的包管理器,分别用于RPM系和Debian系发行版,能够自动解决依赖问题;而 `rpm`是低层次的包管理工具,适合处理单个包;`wget`则是一个功能强大的下载工具,适用于各种下载任务。在实际使用中,根据系统类型和任务需求选择合适的工具,可以大大提高工作效率和系统管理的便利性。
111 25