【Linux】环境基础开发工具的使用之gcc详解(二)
前言:上一篇文章中我们讲解了Linux下的vim和yum的工具的使用,今天我们将在上一次的基础上进一步的讲解开放工具的时候。
💖 博主CSDN主页:卫卫卫的个人主页 💞
👉 专栏分类:Linux的深度刨析 👈
💯代码仓库:卫卫周大胖的学习日记💫
💪关注博主和博主一起学习!一起努力!
目录标题
- Linux基础开发工具的使用
- Linux编译器-gcc/g++使用
- gcc与g++安装
- gcc程序产生的过程
- gcc的用法
- 逐过程讲解
- 预处理阶段
- 编译阶段
- 汇编阶段
- 链接阶段
- 动态库与静态库
Linux基础开发工具的使用
Linux编译器-gcc/g++使用
GCC概念:GCC(GNU Compiler Collection)是一套开源的编程语言编译器工具,由 GNU 项目开发并发布。它是一种跨平台工具,支持多种编程语言,包括C、C++、Objective-C、Fortran、Ada等。GCC不仅仅是一个编译器,而是一个完整的编译器套件,提供了编译、链接、优化等多个功能。G++ 是 GCC 的 C++ 版本,它是 GCC 中专门用于编译和链接 C++ 代码的工具。除了支持 C++ 语言的编译和链接外,G++ 也能够兼容 C 语言代码的编译。
gcc与g++安装
sudo yum install -y gcc
sudo yum install -y gcc-c++ libstdc++-devel
gcc程序产生的过程
在学习C语言阶段我们可以知道:C语言程序从源代码到可执行程序的产生过程可以分为四个阶段:预处理、编译、汇编和链接。
-
预处理阶段:预处理器会处理源代码中的预处理指令,如宏定义、条件编译等。预处理器根据指令将源代码中的宏替换为具体的代码,删除注释,根据条件编译指令决定哪些代码应该被编译。预处理后的代码通常还会生成一个扩展名为 .i 的文件。
-
编译阶段:编译器将预处理后的代码转换为汇编语言代码。编译器将 C 语言的代码翻译为机器指令,生成一个扩展名为 .s 的汇编语言文件。
-
汇编阶段:汇编器将汇编语言代码翻译为机器码。它会将汇编语言代码转化为可执行文件中的机器指令,生成一个扩展名为 .o 的目标文件。
-
链接阶段:链接器将所有的目标文件(.o 文件)和需要的库文件进行链接,生成最终的可执行程序。链接器会解析目标文件中的符号引用,解析库文件中的函数和变量,并将它们合并到最终的可执行文件中,生成一个扩展名为 .exe(Windows)或没有扩展名的可执行文件。
以上四个阶段是编译过程中的基本步骤,每个阶段都有对应的工具和命令来完成。通常情况下,编译器会自动将这四个步骤组织起来,完成整个编译过程,从源代码到可执行程序的生成。
通常 gcc 命令后面不加选项的话,就会默认执行预处理、编译、汇编、链接所有步骤,若程序没有错误的话,我们就可以得到一个可执行文件,默认为 a.out
(如下图)
gcc的用法
在使用gcc命令进行编译时,可以使用不同的参数来指定只进行编译或者只进行预处理等。
- 要只进行预处理,可以使用"-E"参数,如下所示
gcc -E file.c #这将只进行预处理,并将预处理结果输出到标准输出。不会进行编译和链接
- 要只进行编译,可以使用"-c"参数,如下所示
gcc -S file.c #对文件进行编译而不进行汇编
- 使用GCC编译器只生成汇编代码可以通过以下步骤实现
gcc -c filename.c #对文件只进行汇编
- 确保已经进行了编译步骤,生成了目标文件(.o文件)输入以下命令进行链接
gcc -o output_file target.o
#其中,output_file是要生成的可执行文件的名称
#target.o是要链接的目标文件的名称。
- gcc直接进行编译程序
gcc filename.c -o output
#这个命令会将名为filename.c的C源文件编译成可执行文件
#并将可执行文件命名为output
逐过程讲解
预处理阶段
在预处理阶段:预处理器会处理源代码中的预处理指令,如宏定义、条件编译等。预处理器根据指令将源代码中的宏替换为具体的代码,删除注释,根据条件编译指令决定哪些代码应该被编译。预处理后的代码通常还会生成一个扩展名为 .i 的文件。
gcc执行命令:gcc -E test.c -o test.i
(对名为test.c的文件进行预处理,然后生成叫test.i的文件)
[wei@centos7 ~]$ touch test.c
[wei@centos7 ~]$ vim test.c #编辑文件
[wei@centos7 ~]$ gcc -E test.c -o test.i #对文件进行预处理
[wei@centos7 ~]$ ll #查看生成的文件
total 24
-rw-rw-r-- 1 wei wei 310 Feb 2 10:40 test.c
-rw-rw-r-- 1 wei wei 16967 Feb 2 10:40 test.i
例如,我们现在写了这样的一个【test.c】的文件:
1 #include<stdio.h> 2 #define MAX 1000 3 4 int main() 5 { 6 printf("hello gcc\n"); 7 printf("hello gcc\n"); 8 printf("hello gcc\n"); 9 printf("hello gcc\n"); 10 int m = MAX; 11 // printf("hello world\n"); 12 // printf("hello world\n"); 13 // printf("hello world\n"); 14 // printf("hello world\n"); 15 // printf("hello world\n"); 16 // printf("hello world\n"); 17 return 0; 18 }
经过刚刚的命令,我们来查看一下生成的预处理阶段和源文件,关于预处理的内容这里也就不和大家过多的探讨了,想了解的可以看我之前C语言的专栏里面有讲解
编译阶段
编译阶段:编译器将预处理后的代码转换为汇编语言代码。编译器将 C 语言的代码翻译为机器指令,生成一个扩展名为.s
的汇编语言文件。
gcc执行命令: gcc -S test.i -o test.s
(对文件test.i进行编译并命名为test.s)
[wei@centos7 ~]$ gcc -S test.i -o test.s #对文件进行编译
[wei@centos7 ~]$ ll//查看文件
total 28
-rw-rw-r-- 1 wei wei 310 Feb 2 10:56 test.c
-rw-rw-r-- 1 wei wei 16967 Feb 2 10:56 test.i
-rw-rw-r-- 1 wei wei 566 Feb 2 10:57 test.s
[wei@centos7 ~]$ vim test.s //查看编译文件
汇编阶段
汇编阶段:汇编器将汇编语言代码翻译为机器码。它会将汇编语言代码转化为可执行文件中的机器指令,生成一个扩展名为 .o 的目标文件。
gcc执行命令:gcc -c test.s -o test.o
(对文件test.s进行汇编并且对汇编生成的文件命名为test.o)
[wei@centos7 ~]$ gcc -c test.s -o test.o #进行汇编
[wei@centos7 ~]$ ll #查看文件
total 32
-rw-rw-r-- 1 wei wei 310 Feb 2 10:56 test.c
-rw-rw-r-- 1 wei wei 16967 Feb 2 10:56 test.i
-rw-rw-r-- 1 wei wei 1680 Feb 2 11:10 test.o
-rw-rw-r-- 1 wei wei 566 Feb 2 11:09 test.s
[wei@centos7 ~]$ vim test.o //查看汇编文件
这里强调一下此时生成的是一个二进制文件,无论我们有没有权限执行这个文件,最终都是无法直接执行的
链接阶段
链接阶段:链接器将所有的目标文件(.o 文件)和需要的库文件进行链接,生成最终的可执行程序。链接器会解析目标文件中的符号引用,解析库文件中的函数和变量,并将它们合并到最终的可执行文件中,生成一个扩展名为 .exe(Windows)或没有扩展名的可执行文件。
gcc执行命令:gcc test.o -o test
(对文件test.s进行链接,并命名一个叫test的可执行文件)
[wei@centos7 ~]$ gcc test.o -o test #对文件进行链接并生成一个叫test的可执行文件
[wei@centos7 ~]$ ll
total 44
-rwxrwxr-x 1 wei wei 8360 Feb 2 11:19 test
-rw-rw-r-- 1 wei wei 310 Feb 2 10:56 test.c
-rw-rw-r-- 1 wei wei 16967 Feb 2 10:56 test.i
-rw-rw-r-- 1 wei wei 1681 Feb 2 11:17 test.o
-rw-rw-r-- 1 wei wei 566 Feb 2 11:11 test.s
[wei@centos7 ~]$ ./test #执行文件
hello gcc
hello gcc
hello gcc
hello gcc
当然了这里,如果我们不使用-o选项来指定文件生成的名字时,生成的默认文件的名字就是a.out,这里我们依然和上面保持一致,自己来命名生成的文件的名称(test)。
动态库与静态库
在Linux系统中,可以使用动态库和静态库来组织和共享代码。
动态库(Dynamic Library)是一种在运行时加载的共享库,它包含编译后的代码和数据,可以被多个程序共享使用。每个程序使用动态库时,都不需要将其完整拷贝到自己的内存空间中,而是通过内存映射的方式共享。动态库的文件扩展名通常为.so(Shared Object)。
静态库(Static Library)是一种在编译时被链接到程序中的库,它包含了编译后的代码和数据,每个程序在编译时会将静态库的副本嵌入到自己的可执行文件中。因此,每个程序运行时都有自己独立的静态库副本。静态库的文件扩展名通常为.a(Archive)。
使用动态库的好处是可以实现代码的共享和模块化管理,使得程序的执行效率更高和占用更少的磁盘空间。同时,如果动态库的代码发生更新或修复,只需要替换动态库文件而无需重新编译程序。
使用静态库的好处是在程序的编译时可以确保静态库的一致性,不受其它因素影响。另外,静态库在编译时会被完整地嵌入到程序中,因此可以避免对外部环境的依赖。
在Linux系统中,可以使用gcc编译器来编译和链接程序,使用以下选项来链接动态库和静态库:
链接动态库:使用-l
选项加上库名来链接动态库,例如-lm表示链接数学库。
gcc -o program program.c -lm #program.c是程序的源代码文件,
#-o选项指定生成的可执行文件名,-lm表示链接数学库
链接静态库:使用-L
选项加上库的路径来指定静态库的位置,使用-l选项来指定库名。
gcc -o program program.c -L/path/to/library -lmylibrary
#L选项指定静态库的路径,-l选项指定静态库的名称
动态库和静态库在使用过程中各有优缺点,下面是它们的主要特点:
动态库的优点:
- 节省内存:多个程序可以共享同一个动态库,不需要将动态库的完整副本加载到内存中,节省了内存空间。
- 易于更新和维护:如果动态库的代码有更新或修复,只需替换动态库文件,不需要重新编译依赖它的程序。
- 动态加载:动态库在程序运行时加载,可以根据需要进行加载和卸载,灵活性更高。
- 共享性:动态库可以被多个程序共享使用,提高了代码复用性和模块化管理。
动态库的缺点:
- 可执行文件与动态库有依赖关系:在运行程序之前,必须保证系统中存在相应的动态库,否则会出现运行错误。
- 运行时开销:动态库的加载和链接会在程序运行时产生一定的开销,对于性能要求较高的程序可以考虑使用静态库。
静态库的优点:
- 独立性:静态库在编译时被完整嵌入到可执行文件中,无需对外部环境有依赖,保证了程序的独立性。
- 性能提升:由于静态库在编译时被完整的嵌入到可执行文件中,因此在运行时不需要加载和链接,可提高程序的运行效率。
- 稳定性:静态库在编译时就已经固定,不会受到外部环境或动态库的影响,保证了程序的稳定性。
静态库的缺点:
- 内存占用:每个使用静态库的可执行文件都需嵌入静态库的副本,会占用更多的内存空间。
- 更新和维护困难:如果静态库的代码有改动,需要重新编译依赖它的程序,并重新分发更新的程序。
根据具体的需求和场景,可以综合考虑动态库和静态库的优缺点来选择合适的库。在一般情况下,动态库适合用于代码的共享和更新,对内存占用和执行效率有一定要求;静态库适合用于确保库的独立性和稳定性,对内存占用和执行效率有较高要求的情况。
注:Linux默认使用的是动态链接和动态库
如果大家没有安装动态库和静态库的话可以使用下面的代码安装:
动态库:sudo yum install -y glibc-static
静态库:sudo yum install -y libstdc++-static
好啦,今天的内容就到这里啦,下期内容预告gdb、make/makefile、进度条的讲解
结语:今天的内容就到这里吧,谢谢各位的观看,如果有讲的不好的地方也请各位多多指出,作者每一条评论都会读的,谢谢各位。
相关文章:

【Linux】环境基础开发工具的使用之gcc详解(二)
前言:上一篇文章中我们讲解了Linux下的vim和yum的工具的使用,今天我们将在上一次的基础上进一步的讲解开放工具的时候。 💖 博主CSDN主页:卫卫卫的个人主页 💞 👉 专栏分类:Linux的深度刨析 👈 Ὂ…...
go语言-用channel控制goroutine的退出
用channel控制goroutine的退出 本文简要介绍了,如何用channel控制goroutine的退出的基本方法 for-range主动停止goruitine package mainimport ("fmt""sync""time" )/* Go并发编程模型:主动停止goroutine 方法一&#…...

强大的虚拟机Parallels Desktop 19 mac中文激活
Parallels Desktop是一款功能全面、易于使用的虚拟机软件,它为用户提供了在Mac电脑上同时运行多个操作系统的便利。 软件下载:Parallels Desktop 19 mac中文激活版下载 Parallels Desktop 19 mac具有快速启动和关闭虚拟机的能力,让用户能够迅…...

单元测试框架深入(一):单元测试框架深入
一、一个简单的例子 1、引入Maven依赖:JUnit框架和Surefire插件 2.在src/test/java目录下新建名字以“Test”结尾的测试类,并用Test注释测试方法 3.运行单元测试用例 或用mvn命令运行单元测试: 二、单元测试基础之单元测试框架:J…...
苏门X学士常识学习
前言 苏轼(1037年—1101年)是北宋的文坛领袖,很喜欢奖掖后进。其门下最有名的是“苏门四学士”,另外还有“苏门六学士”和“苏门后四学士”之说。 一、苏门四学士 苏轼在《与李昭玘书》中说: 轼蒙庇粗遣࿰…...

MD5算法:高效安全的数据完整性保障
摘要:在数字世界中,确保数据完整性和安全性至关重要。消息摘要算法就是一种用于实现这一目标的常用技术。其中,Message Digest Algorithm 5(MD5)算法因其高效性和安全性而受到广泛关注。本文将详细介绍MD5算法的优缺点…...

JavaScript基础五对象 内置对象 Math.random()
内置对象-生成任意范围随机数 Math.random() 随机数函数, 返回一个0 - 1之间,并且包括0不包括1的随机小数 [0, 1) 如何生成0-10的随机数呢? Math.floor(Math.random() * (10 1)) 放大11倍再向下取整 如何生成5-10的随机数&…...
curl之网络接口
Curl_cftype 连接接口定义 struct Curl_cftype {const char *name; /* name of the filter type */int flags; /* flags of filter type */int log_level; /* log level for such filters */Cu…...

Pytest中doctests的测试方法应用
在 Python 的测试生态中,Pytest 提供了多种灵活且强大的测试工具。其中,doctests 是一种独特而直观的测试方法,通过直接从文档注释中提取和执行测试用例,确保代码示例的正确性。本文将深入介绍 Pytest 中 doctests 的测试方法,包括基本用法和实际案例,以帮助你更好地利用…...
Android 8.1 铃声音量通话音量同步调节
Android 8.1 铃声音量通话音量同步调节 最近收到客户反馈,想要实现铃声音量通话音量同步调节,具体修改参照如下: /frameworks/base/core/java/android/preference/SeekBarVolumizer.java if (defaultUri null) {if (mStreamType AudioMan…...
C++——字符串string
C——字符串string C语言中对字符串的表示通常用指针,新手会面临内存泄漏或者段错误等众多问题。 在 C 中, string 类是标准库的一部分,用于表示和操作字符串。它是对传统的 C 风格字符串(以空 字符 ‘\0’ 结尾的字符数组&…...

HBuilder使用[微信小程序开发者工具] 显示 × initialize报错
解决办法 我们先要单独打开 微信开发者工具 点击设置里面的安全,把服务器端口打开 然后再回到我们的HBuilder使用重新打开打开 成功打开...

洛谷P8599 [蓝桥杯 2013 省 B] 带分数
[蓝桥杯 2013 省 B] 带分数 题目描述 100 100 100 可以表示为带分数的形式: 100 3 69258 714 100 3 \frac{69258}{714} 100371469258。 还可以表示为: 100 82 3546 197 100 82 \frac{3546}{197} 100821973546。 注意特征:带分…...

grafana安装DevOpsProdigy KubeGraf 1.5.2
安装DevOpsProdigy KubeGraf需要安装kube-state-metrics 官方地址:https://github.com/kubernetes/kube-state-metrics/tree/release-2.10/examples/standard 查看k8s版本和kube-state-metrics对应版本: [rootmaster1 kube-state-metrics]# ll 总用量 …...

大数据 - Hadoop系列《三》- MapReduce(分布式计算引擎)概述
上一篇文章: 大数据 - Hadoop系列《三》- HDFS(分布式文件系统)概述-CSDN博客 目录 12.1 针对MapReduce的设计构思 1. 如何对付大数据处理场景 2. 构建抽象编程模型 3. 统一架构、隐藏底层细节 12.2 分布式计算概念 12.3 MapReduce定义…...

了解Ansible自动化运维工具及模块的使用
一、Ansible的相关知识 1.1 Ansible工具的了解 Ansible是一个基于Python开发的配置管理和应用部署工具,现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点,Pubbet和Saltstack能实现的功能,Ansible基本上都可以实现。Ansible…...

sql指南之null值用法
注明:参考文章: SQL避坑指南之NULL值知多少?_select null as-CSDN博客文章浏览阅读2.9k次,点赞7次,收藏21次。0 引言 SQL NULL(UNKNOW)是用来代表缺失值的术语,在表中的NULL值是显示…...
常见消息队列:ActiveMQ、RabbitMQ、RocketMQ、Kafka的区别总结
目录 前言 1、常见消息队列 1.ActiveMQ 2.RabbitMQ 3.RocketMQ 4.Kafka 2、区别 1.消息传递模型 2.消息持久化 3.消息顺序性 4.可靠性 5.生态系统和社区支持 6.表格对比 前言 消息队列可以实现应用程序之间的异步通信,能够实现异步消息的发送和接收&am…...

火柴人大逃亡
欢迎来到程序小院 火柴人大逃亡 玩法:左右两边火柴人,点击左边左边火柴人跳跃,点击右边右边跳跃, 上下快速移动道路,躲过障碍物,看你能坚持多久,快去火柴人大逃亡吧^^。开始游戏https://www.or…...

AI革命新篇章:法国天才团队挑战ChatGPT霸主地位
Mistral AI: Guillaume Lample, Arthur Mensch et Timothe Lacroix. ChatGPT 的霸主地位已被三位来自法国的天才所颠覆!如上图这三个人,其中一位曾在 DeepMind 工作,另外两位来自 Meta,他们联手为 AI 领域带来了革命性的变革 我…...

测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...

【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...