【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 生成所有警告信息
目录
相关文章
|
15天前
|
消息中间件 分布式计算 Java
Linux环境下 java程序提交spark任务到Yarn报错
Linux环境下 java程序提交spark任务到Yarn报错
81 4
|
4天前
|
存储 Linux 开发工具
Linux环境下使用Buildroot配置软件包
使用Buildroot可以大大简化嵌入式Linux系统的开发和维护工作,但它需要对Linux系统和交叉编译有深入的理解。通过上述步骤,可以有效地配置和定制软件包,为特定的嵌入式应用构建高效、稳定的系统。
48 11
|
2月前
|
存储 监控 Linux
Linux环境锁定关键文件防止误删操作流程。
总结以上内容,在Linux环境下锁定重要文档避免误删涉及到多种技术手段与策略组合运作, 包括但不限于利用chatter指挥官固化文档状态至只读模式、运作ACL精准调整访问权利列表、编排自动化流程简
113 20
|
2月前
|
Linux
Linux环境下的UDEV机制及其与守护进程的关联
实际使用时管理员需要熟悉编写合适udev rules去满足特殊需求;同时也需要注意避免编写过度复杂导致无法预料结果rules.UDEVD虽然稳健但错误配置可能导致无法预料问题因此需谨慎处理相关配置工作.
86 16
|
2月前
|
存储 Linux
Linux环境下删除大文件后磁盘空间未释放问题诊断流程。
以上诊断流程涉及Linux底层机制与高级管理技能结合之处,并需要管理员根据实际环境灵活调整诊断策略与解决方案。
179 8
|
Linux 编译器 开发工具
Linux学习第二枪(yum,vim,g++/gcc,makefile的使用)
Linux学习第二枪(yum,vim,g++/gcc,makefile的使用)
|
IDE Linux 编译器
【Linux】gcc/g++编译器、make/Makefile自动化构建工具
目录 1.gcc/c++的概念: 2.程序编译过程详解: 2.1程序编译过程:
235 0
|
4月前
|
NoSQL Linux 开发工具
Linux环境基础开发工具的使用(yum、vim、gcc、g++、gdb、make/Makefile)
本文介绍了yum 包管理工具、Vim 编辑器、gcc/g++ 编译器、gdb 调试器、编译原理及 Makefile 的使用,同时还配备了如何使用,以及图解。旨在帮助读者更好地理解和应用这些工具与技术。
238 0
|
小程序 Linux 开发工具
【Linux】Linux 开发工具(vim、gcc/g++、make/Makefile)+【小程序:进度条】-- 详解
【Linux】Linux 开发工具(vim、gcc/g++、make/Makefile)+【小程序:进度条】-- 详解
|
NoSQL IDE Unix
Linux开发工具大全 - 软件包管理器yum | vim编辑器 | gcc/g++编译器 | 自动化构建工具Make/Makefile | gdb调试工具(2)
Linux开发工具大全 - 软件包管理器yum | vim编辑器 | gcc/g++编译器 | 自动化构建工具Make/Makefile | gdb调试工具(2)
264 0