[Linux入门]---Linux编译器gcc/g++使用

news2024/11/26 4:45:23

文章目录

  • 1.背景知识
  • 2.gcc如何完成编译运行工作
    • 预处理(进行宏替换)
    • 编译(生成汇编)
    • 汇编(生成机器可识别代码)
    • 链接(生成可执行文件)
  • 3.函数库
    • 动态库
    • 静态库
    • 动静态库的区别
  • 4.gcc选项

1.背景知识

通过前面的学习,我们知道我们的代码变成能运行的可执行程序,要经历以下四个过程:

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

那在Linux操作系统上gcc编译器编译运行代码的过程又是怎么样的呢?接下来让我们一起学习吧!

2.gcc如何完成编译运行工作

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

创建mycode.c文件,写入如下代码:

#include<stdio.h>      
#define M 100      
      
int main()      
{      
#ifdef DEBUG      
    printf("hello debug\n");      
#else      
    printf("hello release\n");      
#endif      
   // pintf("这是被注释掉的内容\n");    
   // pintf("这是被注释掉的内容\n");    
   // pintf("这是被注释掉的内容\n");    
   // pintf("这是被注释掉的内容\n");    
   // pintf("这是被注释掉的内容\n");    
   // pintf("这是被注释掉的内容\n");    
                                                                                                                                                                     
    printf("hello gcc:%d\n",M);                                                                                                            
    printf("hello gcc:%d\n",M);                                                                                                            
    printf("hello gcc:%d\n",M);                                                                                                            
    printf("hello gcc:%d\n",M);                                                                                                            
    printf("hello gcc:%d\n",M);                                                                                                            
    printf("hello gcc:%d\n",M);                                                                                                            
    printf("hello gcc:%d\n",M);                                                                                                            
    printf("hello gcc:%d\n",M);                         
    printf("hello gcc:%d\n",M);    
    printf("hello gcc:%d\n",M);    
    printf("hello gcc:%d\n",M);    
    return 0;    
} 

指令:

$ gcc -o mycode.exe mycode.c
//-o 可以指定生成可执行文件名称,如果不指定,默认生成a.out可执行文件

代码编译运行的结果为:
在这里插入图片描述

预处理(进行宏替换)

预处理指令:

$ gcc -E 源文件 -o 指定预处理文件名
  • 预处理阶段是源文件文件转成目标文件
  • 选项-E,该选项的作用是让 gcc 在预处理结束后停止编译过程。
  • 选项“-o”是指目标文件,如果不带选项“-o”会预处理的结果放在显示屏上,“.i”文件为已经过预处理的C原始程序。
  • 预处理阶段的主要工作有:a.去注释,b.头文件展开;c.宏替换(不做类型检查);d.条件编译;

输入指令:

$ gcc -E mycode.c -o mycode.i
$ gcc -E mycode.c -o mycode.i -D DEBUG//使用-D选项在外部可定义宏

在这里插入图片描述

输入该指令告诉gcc从现在开始程序的翻译,做完预处理工作就停下来,不要继续往下执行了。

输入指令vim mycode.i查看预处理后的文件
头文件展开:
在这里插入图片描述
在这里插入图片描述

编译(生成汇编)

输入编译指令:

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

代码运行的结果为:
在这里插入图片描述
在这里插入图片描述

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

汇编指令:

$ gcc -c mycode.s -o mycode.o
  • 汇编阶段是把编译阶段生成的“.s”文件转成".o"目标文件
  • 可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了
    输入指令的结果为:
    在这里插入图片描述
    在这里插入图片描述

mycode.o为可重定位二进制文件,简称目标文件,Windows上目标文件为.obj文件,虽然已经是二进制文件,但是还不可以独立执行,需要经过链接才能执行!

链接(生成可执行文件)

$ gcc mycode.o -o mycode.exe
  • 在成功编译之后,就进入了链接阶段,将可重定位二进制文件和库进行链接形成.exe可执行文件
    在这里插入图片描述

3.函数库

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

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

动态库

windows系统中,动态库以.dll为后缀的文件,Linux系统,动态库为以.so为后缀的文件。库的命名规则:“libnameso.XXX"name为库的真正名字,其他为前后缀。
输入指令查找C的标准库:

ls /lib64/libc*
//查找含/lib64/libc的库文件
ls /lib64/libc.so*
//查找动态库文件

输入指令后代码运行的结果:
在这里插入图片描述

静态库

windows系统中,静态库以.lib为后缀的文件,Linux系统,静态库为以.a为后缀的文件。我们的机器上默认只会安装动态库,静态库需要我们手动输入指令安装。
安装C语言静态库指令如下:

//root用户
# yum install -y glibc-static//安装c的静态库
# yun install -y libstdc++-static//安装c++的静态库
//普通用户
$ sudo yum install -y glibc -static
$ yun install -y libstdc++-static

安装完成的结果如下:
在这里插入图片描述
在这里插入图片描述

查找C语言静态库指令:

$ ls /lib64/libc.a*

输入指令后代码运行的结果:
在这里插入图片描述

动静态库的区别

小故事: 网瘾少年需要上网,你有两种方法,一种是跑到网吧上网,而你怎么知道哪里有网吧呢?原来你的好基友曾经告诉你某某路口向东转500米有一家网吧,于是每到放假的时候,你就可以跑到网吧去上网,但天有不测风云,这家网吧的老板没有营业执照被查封了,自此你的上网之路就断了;只好使用另一种方法,你每天上省吃俭用,终于三个月后攒够了钱,去一家二手电脑销售店购买了一台电脑,从此你便过上了自由自在的网民生活,不久后你去的这家二手电脑销售店由于非法经营被查封了,但这已经影响不到你了。

动态链接:.o文件(网瘾少年)和动态库(网吧)链接,很高效但如果动态库没了,各个程序文件将无法运行,限制性很大;静态链接:.o文件(网瘾少年)会拷贝(购买)静态库(电脑)到文件中,会占用很大内存、很多时间(费时费钱),但库文件(电脑销售店没了)不存在了,各个程序文件不受影响仍可以正常运行!
生成可执行文件的指令:

$ gcc mycode.c -o mycode.exe//进行动态链接
$ gcc mycode.c -o mycode_static.exe -static//进行静态链接

输入指令后代码运行的结果:
在这里插入图片描述

ldd 可执行文件//查找链接的动态库

在这里插入图片描述

file 可执行文件名//显示符号链接的文件类型

在这里插入图片描述

①在Linux中,编译形成可执行程序,由编译器提供动态库,默认采用动态链接;如果想要以静态链接的方式,生成可执行文件,需要添加-static选项;②静态链接生成的可执行文件比动态链接生成的可执行文件大很多。

动静态库区别总结:
①如果没有静态库,不可以使用-static选项进行静态链接;
②如果没有动态库,只有静态库,gcc编译器将会去寻找静态库进行链接;
③gcc默认优先动态链接,-static选项改变的是链接的优先级,使用后所有的链接都为静态链接;
④我们平时写的代码生成可执行文件时,不一定全部是动态链接或静态链接,而极有可能是动态链接和静态链接混合生成可执行文件;
⑤动态链接优点:动态库是共享库,可以有效地节省资源(磁盘空间、内存空间,网络空间等);缺点:动态库一旦缺失,使用动态链接的可执行程序将无法运行!
⑥静态链接的优点:不依赖库,程序可以独立运行;缺点:生成的可执行文件体积大,比较消耗资源(磁盘空间、内存空间,网络空间等)。

4.gcc选项

-E 进行预处理工作,不生成文件,你需要把它重定向输出到一个.i文件里面
-S 编译到汇编语言到.s文件中,不进行汇编和链接
-c 进行汇编工作,编译到.o可重定位二进制目标文件(目标文件)
-o 将目标文件和库文件进行链接输出到指定的可执行文件
-static 此选项对生成的文件采用静态链接 -g 生成调试信息。GNU 调试器可利用该信息。
-shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库
-O0
-O1
-O2
-O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
-w 不生成任何警告信息。
-Wall 生成所有警告信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1029294.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一键自助建站系统源码带安装教程 傻瓜式部署搭建,让您的建站更高效

在这个数字时代&#xff0c;网站已成为企业或个人展示形象、推广业务的重要工具。为了满足这一需求&#xff0c;许多自助建站系统应运而生&#xff0c;大大降低了用户建站的门槛。给大家分享一款傻瓜式部署搭建的一键自助建站系统源码&#xff0c;让您轻松拥有高效建站能力。 …

虹科教您 | 可实现带宽计量和延迟计算的时间敏感网络测试工具RELY-TSN-LAB操作指南与基本功能测试

1. RELY-TSN-LAB产品概述 时间敏感网络(TSN)能够合并OT和IT世界&#xff0c;这将是真正确保互操作性和标准化的创新性技术。这项技术的有效开发将显著降低设备成本、维护、先进分析服务的无缝集成以及减少对单个供应商的依赖。为了在这些网络中实现确定性&#xff0c;需要控制…

[LLM+AIGC] 01.应用篇之中文ChatGPT初探及利用ChatGPT润色论文对比浅析(文心一言 | 讯飞星火)

近年来&#xff0c;人工智能技术火热发展&#xff0c;尤其是OpenAI在2022年11月30日发布ChatGPT聊天机器人程序&#xff0c;其使用了Transformer神经网络架构&#xff08;GPT-3.5&#xff09;&#xff0c;能够基于在预训练阶段所见的模式、统计规律和知识来生成回答&#xff0c…

【Linux操作系统实战】Linux基础命令面试必备(二)

&#x1f604;作者简介&#xff1a; 小曾同学.com,一个致力于测试开发的博主⛽️&#xff0c;主要职责&#xff1a;测试开发、CI/CD 如果文章知识点有错误的地方&#xff0c;还请大家指正&#xff0c;让我们一起学习&#xff0c;一起进步。&#x1f60a; 座右铭&#xff1a;不想…

【rabbitMQ】-延迟队列-模拟控制智能家居的操作指令

这个需求为控制智能家居工作&#xff0c;把控制智能家居的操作指令发到队列中&#xff0c;比如&#xff1a;扫地机、洗衣机到指定时间工作 一.什么是延迟队列&#xff1f; 延迟队列存储的对象是对应的延迟消息&#xff0c;所谓“延迟消息” 是指当消息被发送以后&#xff0c;并…

数据中心中什么最重要?

在数据中心中&#xff0c;最重要的要素可以总结为以下几点&#xff1a; 数据安全&#xff1a;数据中心是存储和处理大量敏感数据的关键设施&#xff0c;因此数据安全是最重要的要素之一。数据中心必须采取严格的物理安全措施&#xff0c;如门禁、监控和防火措施&#xff0c;以确…

Stable Diffusion基础:精准控制之ControlNet

在AI绘画中精确控制图片的生成是一件比较困难的事情&#xff0c;炼丹师们经常需要大量抽卡才能得到一张满意的图片&#xff0c;不过随着 ControlNet 的诞生&#xff0c;这一问题得到了很大的缓解。 ControlNet 提供了十几种控制网络模型&#xff0c;有的可以控制画面的结构&…

利用大模型知识图谱技术,告别繁重文案,实现非结构化数据高效管理

我&#xff0c;作为一名产品经理&#xff0c;对文案工作可以说是又爱又恨&#xff0c;爱的是文档作为嘴替&#xff0c;可以事事展开揉碎讲清道明&#xff1b;恨的是只有一个脑子一双手&#xff0c;想一边澄清需求一边推广宣传一边发布版本一边申报认证实在是分身乏术&#xff0…

【uniapp】小程序开发:2 安装uni-ui组件库、使用pinia状态管理、自定义http请求

一、安装uni-ui组件库 1、安装 pnpm i -D sass pnpm i dcloudio/uni-ui2、配置组件自动导入 使用 npm 安装好 uni-ui 之后&#xff0c;需要配置 easycom 规则&#xff0c;让 npm 安装的组件支持 easycom 打开项目根目录下的 pages.json 并添加 easycom 节点&#xff1a; //…

LeetCode 75-03:拥有最多糖果的孩子

func kidsWithCandies(candies []int, extraCandies int) []bool {maxCandy : 0for _, v : range candies{if v > maxCandy{maxCandy v}}res : make([]bool, len(candies))for i,candy : range candies{res[i] candy extraCandies > maxCandy}return res }

对象的生命周期、配置文件参数化、自定义类型转换器

目录 一、对象的生命周期 1、什么是对象的生命周期 2、为什么要学习对象的生命周期 3、生命周期的三个阶段 &#xff08;1&#xff09;创建阶段 &#xff08;2&#xff09;初始化阶段 1、InitializingBean 接口 2、对象中提供一个普通的方法 3、细节分析 &#xff08…

linux离线安装make

一、下载rpm包 https://pkgs.org/search/?qmake 二、拷贝至服务器 三、安装make rpm -ivh make-3.82-24.el7.x86_64.rpm四、查看是否安装成功 make -v

Git 设置公钥

一、公钥管理 1、生成公钥 WinR&#xff0c;输入cmd&#xff0c;打开命令行窗口&#xff0c;执行ssh-keygen命令 查看生成的公钥&#xff0c;使用everything搜索id_rsa.pub&#xff0c;如下&#xff1a; 2、配置公钥 打开服务端网站&#xff0c;添加公钥 3、修改Git Tourtise配…

PostgreSQL 技术内幕(十)WAL log 模块基本原理

事务日志是数据库的重要组成部分&#xff0c;记录了数据库系统中所有更改和操作的历史信息。 WAL log(Write Ahead Logging)也被称为xlog&#xff0c;是事务日志的一种&#xff0c;也是关系数据库系统中用于保证数据一致性和事务完整性的一系列技术&#xff0c;在数据库恢复、高…

Ubuntu 安装golang

目录 1. 从官方网站下载合适的安装包 2. 解压安装包 3. 设置环境变量 4. 验证安装是否成功 1. 从官方网站下载合适的安装包 到官网&#xff1a;https://go.dev/dl/查找对应的版本 # 下载golang对应的版本 wget https://dl.google.com/go/go1.14.4.linux-amd64.tar.gz 2. …

PM2.5 激光粉尘传感器之DSL-08(DS-08)

一款产品里用到粉尘检测&#xff0c;最后在淘宝上找一到了一款&#xff0c;攀藤型号是&#xff1a;PMS9003 还有一款外形类似型号是DSL-08。看了资料是可以通用的。 传感器的产品资料放在百度网盘里 链接&#xff1a;https://pan.baidu.com/s/1oNCwO7n9oEdzju91cF99xg?pwd12…

PX4 通过 Vision 实现 Position、Altitude 和 Offboard 模式

本文通过 VINS-Fusion 的里程计信息为 PX4 提供视觉信息&#xff0c;从而达到 视觉定高和定点 的目的 主要工作为创建一个将 vins 里程计信息发布给 Mavros 的 /mavros/vision_pose/pose 话题 首先创建一个工作空间 mkdir -p ~/catkin_ws/src/vision_to_mavros/src/ cd ~/ca…

使用Java将PPT、PPTX和PDF转换为图片

从Office到图片—使用Java实现文件格式转换 PDF转图片1. 万事第一步2. 撸代码 PPT/PPTX转图片1. 万事第一步2. 撸代码验收一下 最近小雨遇到了一个需求&#xff0c;需要在前端小程序中嵌入展示Office文件的功能。然而&#xff0c;前端使用开源组件进行在线预览会导致性能消耗较…

PostgreSQL设置主键为自增

1、创建自增序列 CREATE SEQUENCE table_name_id_seq START 1; 2、设置字段默认值 字段默认值中设置 nextval(table_name_id_seq) 3、常用查询 -- 查询所有序列 select * from information_schema.sequences where sequence_schema public; -- 查询自增序列的当前值 select cu…

【分布式计算】七、同步 synchronization 重难点

两个协议&#xff1a; 1、NTP&#xff08;Network Time Protocal)–>广泛使用    机器周期向时间服务器获取准确时间   2、没有协议名称 − > -> −>没有广泛使用    时间服务器周期扫描所有机器&#xff0c;计算时间平均值&#xff1b;导致时间服务器负载…