【Linux环境】编译器 gcc/g++的使用

简介: 【Linux环境】编译器 gcc/g++的使用

👻内容专栏: Linux操作系统基础

🐨本文概括: 预处理、编译、汇编、链接、动静态库、gcc选项等。

🐼本文作者: 阿四啊

🐸发布时间:2023.9.13

背景知识

  1. 预处理(进行宏替换)
  2. 编译(生成汇编)
  3. 汇编(生成机器可识别代码)
  4. 连接(生成可执行文件或库文件)

如何用gcc进行编译

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

📌gcc命令记忆技巧:ESc(键盘左上角键) + iso(镜像文件后缀)

预处理(进行宏替换)

  • 预处理功能主要包括宏定义,文件包含,条件编译,去注释等。
  • 预处理指令是以#号开头的代码行。
  • 实例: gcc –E hello.c –o hello.i
  • 选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。
  • 选项“-o”是指目标文件,“.i”文件为已经过预处理的C原始程序

编译(生成汇编)

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

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

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

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

  • 在成功编译之后,就进入了链接阶段。
  • 实例: gcc hello.o –o hello

函数库

  • 在这里涉及到一个重要的概念叫做函数库
  • 我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实现“printf”函数的呢?
  • 最后的答案是:系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用。
[Asi@localhost ~]$ ldd mybin
  linux-vdso.so.1 =>  (0x00007fff7e5e9000)
  libc.so.6 => /lib64/libc.so.6 (0x00007f0c99260000)
  /lib64/ld-linux-x86-64.so.2 (0x00007f0c9962d000)

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

  • 动态库(动态链接):是C/C++或者其他第三方提供的所有方法的集合,被所有程序以链接的方式关联起来。所谓的动态链接,其实是将要链接的库中的函数地址拷贝到我们可执行程序的特定位置。
    优点:形成的可执行程序小,有利于节省系统的开销。
    缺点:强依赖性,动态库没了,那么,所有与动态库关联的程序都无法运行。
  • 静态库(静态链接):是C/C++或者其他第三方提供的所有方法的集合,被所有程序以拷贝的方式,将需要的代码,拷贝到自己的可执行程序中。
    优点:可以独立运行,无需额外的库文件。
    缺点:可执行文件大,导致磁盘空间的浪费。
    ⚠️注:默认情况下,XShell中是没有安装静态库的,只有动态库,如果要安装,执行以下命令:
    👇C语言静态库
[Asi@localhost ~]$ sudo yum install -y glibc-static
  • 👇C++静态库
[Asi@localhost ~]$ sudo yum install -y libstdc++-static
  • 演示
    创建一个test.c文件,写入一段C语言代码。

    test.c文件动态链接(gcc编译器默认情况下链接的是动态库)取名为test-d
[Asi@localhost ~]$ gcc test.c -o test-d
  • 再次将test.c文件静态链接(需要添加-static选项)取名为test-s
[Asi@localhost ~]$ gcc test.c -o test-s -static
  • 对比发现,动态链接后生成的可执行文件的大小与静态链接后生成的可执行文件大小相差了近百倍,所以gcc下为什么默认情况下生成动态链接库。
[Asi@localhost ~]$ ll
total 876
-rw-rw-r-- 1 Asi Asi    127 Sep 12 15:40 test.c
-rwxrwxr-x 1 Asi Asi   8480 Sep 13 15:47 test-d
-rwxrwxr-x 1 Asi Asi 861216 Sep 13 16:22 test-s

gcc选项

  • -E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面
  • -S 编译到汇编语言不进行汇编和链接
  • -c 编译到目标代码
  • -o 文件输出到 文件
  • -static 此选项对生成的文件采用静态链接
  • -g 生成调试信息。GNU 调试器可利用该信息。
  • -shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库.
  • -O0 不进行优化
  • -O1 启用基本优化级别
  • -O2 启用更多的优化
  • -O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
  • -w 不生成任何警告信息。
  • -Wall 生成所有警告信息
目录
相关文章
|
26天前
|
Web App开发 搜索推荐 Unix
Linux系统之MobaXterm远程连接centos的GNOME桌面环境
【10月更文挑战第21天】Linux系统之MobaXterm远程连接centos的GNOME桌面环境
215 4
Linux系统之MobaXterm远程连接centos的GNOME桌面环境
|
12天前
|
关系型数据库 MySQL Linux
Linux环境下MySQL数据库自动定时备份实践
数据库备份是确保数据安全的重要措施。在Linux环境下,实现MySQL数据库的自动定时备份可以通过多种方式完成。本文将介绍如何使用`cron`定时任务和`mysqldump`工具来实现MySQL数据库的每日自动备份。
31 3
|
12天前
|
监控 关系型数据库 MySQL
Linux环境下MySQL数据库自动定时备份策略
在Linux环境下,MySQL数据库的自动定时备份是确保数据安全和可靠性的重要措施。通过设置定时任务,我们可以每天自动执行数据库备份,从而减少人为错误和提高数据恢复的效率。本文将详细介绍如何在Linux下实现MySQL数据库的自动定时备份。
26 3
|
28天前
|
Ubuntu 应用服务中间件 Linux
Linux下搭建Nginx环境的搭建
Linux下搭建Nginx环境的搭建
|
23天前
|
Linux UED iOS开发
|
1月前
|
监控 Linux 云计算
Linux操作系统在云计算环境中的实践与优化###
【10月更文挑战第16天】 本文探讨了Linux操作系统在云计算环境中的应用实践,重点分析了其在稳定性、安全性和高效性方面的优势。通过具体案例,阐述了Linux如何支持虚拟化技术、实现资源高效分配以及与其他开源技术的无缝集成。文章还提供了针对Linux系统在云计算中的优化建议,包括内核参数调整、文件系统选择和性能监控工具的应用,旨在帮助读者更好地理解和应用Linux于云计算场景。 ###
39 3
|
1月前
|
Linux 编译器 C语言
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
|
7天前
|
监控 Linux
如何检查 Linux 内存使用量是否耗尽?这 5 个命令堪称绝了!
本文介绍了在Linux系统中检查内存使用情况的5个常用命令:`free`、`top`、`vmstat`、`pidstat` 和 `/proc/meminfo` 文件,帮助用户准确监控内存状态,确保系统稳定运行。
67 6
|
8天前
|
Linux
在 Linux 系统中,“cd”命令用于切换当前工作目录
在 Linux 系统中,“cd”命令用于切换当前工作目录。本文详细介绍了“cd”命令的基本用法和常见技巧,包括使用“.”、“..”、“~”、绝对路径和相对路径,以及快速切换到上一次工作目录等。此外,还探讨了高级技巧,如使用通配符、结合其他命令、在脚本中使用,以及实际应用案例,帮助读者提高工作效率。
34 3
下一篇
无影云桌面