【Linux】Linux编译器(gcc,g++)与动静态链接库

news2024/9/20 22:43:53

对于一个 C 程序,从源文件到形成可执行程序一共要进行四步:预处理、编译、汇编、链接 。

接下来,我们用 gcc 分别演示这四个过程。

一、预处理(进行宏替换)

预处理中,需要完成头文件的展开、宏替换、去注释、条件编译等工作。

gcc -E file.c -o file.i

-E 选项:让 gcc 进行程序的预处理,预处理之后就停下来。
-o 选项:-o 选项紧跟目标生成文件的名称。gcc -o file.i file.c 或者上方的指令都是可以的。

可以发现 头文件 #include <stdio.h> 被展开,宏被替换,注释被删除 

二、编译 

当程序在编译时,gcc 会检查代码是否有语法错误,了解代码基本内容,检查无误就会把代码翻译为汇编语言

gcc -S file.i -o file.s

 -S 选项:让 gcc 进行程序的编译,编译之后就停下来。

我们也可以接着从上次预编译后的文件继续执行。

 三、汇编

汇编之后会把汇编语言转换为二进制文件。

由于机器只认识二进制文件,所以这一步就是把人能看懂的文件,翻译成机器能看懂的,就是 生成机器可识别代码

gcc -c file.s -o test.o

 -c 选项:让 gcc 进行程序的汇编,汇编之后就停下来。

注意: 二进制文件不可执行

四、链接 

链接过程就是将程序和对应的库链接起来,编译器会自动识别语言。

gcc file.o -o myfile

生成可执行文件,完成链接

五、动静态链接库

1.什么是库

首先清楚一点,我们写的代码里面经常会用库函数,这些调用接口的方式是我们写的,但是这些库函数的底层实现不是我们写的,而这中间就有一个调用库的过程。

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

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

在上面我们写的my代码就用到了库,我们可以用ldd指令来查看,该程序都用了哪些库

在 /usr/include/ 中我们就能看到系统的内置的头文件,我们通过头文件就可以根据库函数,找到对应的方法,从而链接到正确的库:

静态库:lib....a....

动态库:   lib....so.... 

我们的可执行程序,包括指令,都依赖于库。

2.库的链接方式

库的连接方式一共有两种:动态链接(默认)和静态链接

用 file 指令查看 test 文件的类型:

3.动态库与静态库  

动态库:

动态库也可以说是共享库。动态库在链接的时候,并没有把相应的库文件加载到可执行程序中,而是在运行的时候,拷贝库中所需代码的地址到可执行程序中相关的位置。
通过这种链接方式,使用动态库就大大节省了内存损耗。
但是这也带来一个缺点,由于动态库链接时,是通过地址链接的。所以只要我们的动态库缺失,程序便无法运行

静态库:

静态库则是在编译链接时,把库文件的代码全部加载到可执行程序中。
这种链接方式导致生成文件体积庞大。若文件数目一多,到时候内存就会被占用很多。
但是这也有一个优点,这样就使得程序不依赖于库了。即使库出了问题,也没事,因为我们已经将代码加载到程序中了。 

抽象一点的比喻就是,我是一个学生想使用电脑,动态库是网吧,我们可以去网吧使用电脑但电脑是公共的不能带走,静态库就是自己买了一台电脑自己随意使用。

一般只默认装了动态库,我们需要自己装静态库

 C语言:

yum install -y glibc-static

C++:

yum install -y libstdc++-static

 可以看到使用了静态库的程序非常大

 文件类型也变成静态链接

4.debug和release

1、debug版本:程序本身会被加入更多的调试信息,以便于进行调试。
2、release版本:不会添加任何调试信息,是不可调试的。

在我们平时生成的默认程序是 release版本是不可调试的,生成debug版本需要加上-g选项

debug版本包含了更多的调试信息

5.gcc/g++ 选项汇总

-E :只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面
-S :编译到汇编语言不进行汇编和链接
-c :编译到目标代码
-o :文件输出到文件
-static :此选项对生成的文件采用静态链接
-g :生成调试信息。GNU 调试器可利用该信息
-shared :此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库
-O0 :不做任何优化,这是默认的编译选项。
-O1 : 对程序做部分编译优化
-O2 :是比O1更高级的选项,进行更多的优化
-O3 :比O2更进一步的进行优化
-w :不生成任何警告信息
-Wall: 生成所有警告信息

g++安装 

yum install gcc-c++

c++的代码需要用g++编译

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

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

相关文章

说一说三大运营商的流量类型,看完就知道该怎么选运营商了!

说一说三大运营商的流量类型&#xff0c;看完就知道该怎么选运营商了&#xff1f;目前三大运营商的流量类型大致分为通用流量和定向流量&#xff0c;比如&#xff1a; 中国电信&#xff1a;通用流量定向流量 电信推出的套餐通常由通用流量定向流量所组成&#xff0c;通用流量…

《数字图像处理》实验报告一

一、实验任务与要求 1、用 matlab 编写空间域点处理操作处理给定的几幅图像&#xff0c;要求&#xff1a; 使用 imread 读取当前工作目录下的图像设计点处理操作并用代码实现处理用 imnshow 显示处理后的图像用 imwrite 保存处理后的图像 2、提交内容&#xff1a;m文件 实验…

假冒国企现形记:股权变更视角下的甄别分析

启信慧眼-启信宝企业版 假冒国企公告2024-06-07&#xff0c;中粮集团有限公司官网发布《关于冒名中粮企业名单公告》。公告显示&#xff0c;”有不法分子通过伪造相关材料等方式&#xff0c;以我集团子公司名义开展业务&#xff0c;进行虚假宣传。经核实&#xff0c;上述公司假…

【SpringCloud】API网关(Spring Cloud Gateway)

本文基于上一篇http://t.csdnimg.cn/q3YrK 使用抽取的方案使用feign的基础上使用Spring Cloud Gateway。 API网关 API网关&#xff08;简称网关&#xff09;也是一个服务&#xff0c;通常是后端服务的唯一入口。它就像是整个微服务架构的门面&#xff0c;所有的外部客户端访问…

Python学习笔记13:进阶篇(二),类的继承与组合

类的继承 我们在编写一系列的类的时候&#xff0c;会发现这些类很相似&#xff0c;但是又有各自的特点和行为。在编写这些类的时候&#xff0c;我们可以把相同的部分抽象成一个基类&#xff0c;然后根据其他不同的特点和行为&#xff0c;抽象出子类&#xff0c;继承这个基类。…

python实训day4

1、查看数据库的版本 2、查看当前用户 3、查看当前数据库 4、计算表达式的结果; 任何一个数据库,无论大小,都首先是一个超级计算器 5、查看当前MySQL环境中所有的数据库; 系统数据库(只能看)和自定义数据库(任何操作) 6、先建数据库 gaoming 7、如果表已经存在,则创建不能成功 …

刷题之小欧的平均数(卡码网)

小欧的平均数 这道题不看解析的话完全没有思路&#xff0c;连题目都没读明白&#xff0c;甚至看了评论答出来了还是不知道为什么&#xff0c;有知道的朋友可以教教我 #include<iostream> using namespace std;int main() {int x,y,z;cin>>x>>y>>z;//…

oracle12c到19c adg搭建(六)切换后12c备库服务器安装19c软件在19c主库升级数据字典后尝试同步

一、安装19c软件 参考文章oracle12c到19c adg搭建&#xff08;三&#xff09;oracle19c数据库软件安装 二、原主库尝试通过19c软件启动数据库 2.1复制12c的相关参数文件和密码文件到19c目录 注意:密码文件需要从已切换主库19c传过来 [oracleo12u19p ~]$ cd /u01/app/oracle…

亲测有效!性能压测异常竟能自动化分析!

性能压测是一种评估系统运行效率和稳定性的方法&#xff0c;通过模拟真实的使用场景和负载条件&#xff0c;对系统进行压力测试和负载测试&#xff0c;并对测试结果进行分析&#xff0c;以评估系统的性能&#xff0c;其中性能压测结果分析是性能压测的重要环节。以往的性能压测…

ONLYOFFICE 桌面编辑器 8.1 发布:全新功能齐备的 PDF 编辑器、丰富的幻灯片版式

前言 在当前数字化迅速发展的时代&#xff0c;办公软件套件作为企业日常工作的核心工具&#xff0c;其功能的全面性和使用的便捷性直接影响着工作效率和团队协作的效果。在众多办公软件中&#xff0c;ONLYOFFICE凭借其卓越的性能和丰富的功能&#xff0c;备受用户青睐。近日&a…

深入了解 GPT-4 和 ChatGPT 的 API---OpenAI Playground

文章目录 基本概念OpenAI API 提供的可用模型在 OpenAI Playground 中使用 GPT 模型 掌握GPT-4 和 ChatGPT 的 API 的使用方法&#xff0c;以便有效地将它们集成到 Python 应用程序中。首先&#xff0c;需要了解 OpenAI Playground。这将使你在编写代码之前更好地了解模型。接着…

React尚硅谷115-126(setState、Hooks、Fragment、context、组件优化、renderprops

122&#xff0c;context 只能用value传&#xff0c;可以传对象&#xff0c;字符串 一种组件间通信方式, 常用于【祖组件】与【后代组件】间通信 使用&#xff1a; 创建Context容器对象&#xff1a; const XxxContext React.createContext() 渲染子组时&#xff0c;外面包…

MIT6.s081 2021 Lab Utilities

Boot xv6 按照示例切换到 util 分支后&#xff0c;看到目录下包含 Makefile 文件&#xff0c;执行 make qemu 即可。 sleep 思路 借助系统调用 sleep 实现一个命令行程序&#xff0c;关键是要找到封装了系统调用的 C 函数的位置&#xff0c;根据提示&#xff1a; … user/u…

软件测试--花了我一周时间整理各种测试模板

2024软件测试面试刷题&#xff0c;这个小程序&#xff08;永久刷题&#xff09;&#xff0c;靠它快速找到工作了&#xff01;&#xff08;刷题APP的天花板&#xff09;-CSDN博客跳槽涨薪的朋友们有福了&#xff0c;今天给大家推荐一个软件测试面试的刷题小程序。https://blog.c…

北邮《计算机网络》MAC子层笔记

文章目录 缩写复习MAC层所在层次动态分配信道算法们的简要介绍信道的五条基本假设多路访问的协议&#xff08;理论上的协议&#xff09;aloha协议CSMA协议其他冲突避免协议无线局域网协议 &#xff0c;MACA 以太网协议802.3&#xff08;实际协议&#xff0c;刚刚是理论&#xf…

光猫BOB 功率调测误差分析与校验指南

DDM&#xff08;Digital Diagnostic Monitoring&#xff09;数字诊断监控技术&#xff0c;是光模块中使用的技术&#xff0c;以便用户能够监控光模块的实时参数。这些参数包括工作温度、工作电压、工作电流、发射和接收光功率等&#xff0c;还可以显示模块的常规波长、速率、传…

在Vue表单中设置缺省值

有个需求&#xff0c;在新增记录的时候&#xff0c;打开新增页面&#xff0c;员工姓名处获取到当前登录用户的用户名&#xff0c;并将其设置为缺省值。 /** 新增按钮操作 */handleAdd() {this.reset();this.open true;// this.form.employeeName this.$store.state.user.name…

计算机网络 DHCP以及防护

一、理论知识 1.DHCP&#xff1a;用于在网络中自动分配IP地址及其他网络参数&#xff08;如DNS、默认网关&#xff09;给客户端设备。 2.VLAN&#xff1a;逻辑上的局域网分段&#xff0c;用于隔离和管理不同的网络流量。 3.DHCP地址池&#xff1a;为每个VLAN配置不同的DHCP地…

【语义分割系列】基于cityscape的DDRNet算法

基于cityscape的DDRNet算法 前言 DDRNet是专门为实时语义分割设计的高效主干。该模型由两个深度分支组成,在这两个分支之间执行多次双边融合,并且还设计了一个新的上下文信息抽取器,名为深度聚合金字塔池模块(DAPPM),用于扩大有效的接受域,并基于低分辨率特征映射融合…

QT在VS环境中使用,控件显示中文乱码解决方法

首先来看乱码显示的效果如下&#xff1a; 上图左侧显示内容为中文&#xff0c;控件对应代码如下&#xff1a; QLabel* UserNameLabel new QLabel(QString("用户名&#xff1a;")); QLabel* NameLabel new QLabel(tr("姓名&#xff1a;"));下面我们对QL…