论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
IT评测·应用市场-qidao123.com
»
论坛
›
运维.售后
›
运维.售后
›
Linux条记---gcc/g++与编译链接
Linux条记---gcc/g++与编译链接
道家人
论坛元老
|
2024-11-21 02:51:36
|
显示全部楼层
|
阅读模式
楼主
主题
1026
|
帖子
1026
|
积分
3078
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
1. 简朴先容
GCC(GNU Compiler Collection)是一个广泛利用的编译器集合,支持多种编程语言,包括C、C++、Objective-C、Fortran、Ada和Go等。
GCC中的C编译器通常被称为gcc,而C++编译器则被称为g++。
gcc和g++的区别
gcc
:紧张用于编译C语言代码。对于文件扩展名为.c的源文件,gcc会将它们作为C代码处置惩罚。
g++
:紧张用于编译C++语言代码。对于文件扩展名为.cpp、.cc、.cxx或.C的源文件,g++会将它们作为C++代码处置惩罚。
gcc和g++都是GNU编译器集合的一部分,但g++是专门用于C++编译的,而gcc则是一个更通用的编译器,可以处置惩罚C、C++在内的多种语言。在编译C++代码时,利用g++可以避免手动链接C++库的麻烦,并且能够确保C++特性的正确处置惩罚。
gcc与g++的利用方式非常相似,接下来我们紧张以gcc编译C语言代码为例先容。
2. 编译源代码
实行下面的指令即可利用gcc编译源代码,生成可实行程序或中间文件:
gcc -o [目标文件] [编译选项] [要编译的文件]
gcc [编译选项] [要编译的文件] -o [目标文件]
复制代码
[-o]选项用于指定要生成的文件的名称,若未指定则会发生默认行为,这个我们在下文中再进行讲解;[选项]用于选择将要编译的文件编译到哪个阶段。
2.1 编译的四个阶段
编译实际上会经历四个阶段:预处置惩罚、编译(整个编译过程中的一步)、汇编、链接。
在进行前三个阶段的过程中,每个阶段结束都会产生一个中间文件,以便下一个阶段接手该阶段的工作:
• 预处置惩罚(进行宏更换/去注释/条件编译/头文件展开等)
[.c文件] -> [.i文件]
• 编译(生成汇编代码)
[.i文件] -> [.s文件]
• 汇编(生成二进制机器码)
[.s文件] -> [.o文件]
• 链接(将各个[.o文件]及相关库进行链接,生成可实行程序或库文件)
[.o文件] -> [可实行程序或库文件]
可通过下面的选项控制实行到哪个阶段:
• [-E]:到预处置惩罚阶段完成为止
[未完成预处置惩罚的文件] -> [.i文件](不指定目标文件时输出到控制台)
• [-S]:到编译阶段完成为止
[未完成编译的文件] -> [.s文件](不指定目标文件时输出到控制台)
• [-c]:到汇编阶段完成为止
[未完成汇编的文件] -> [.o文件](不指定目标文件时输出到[同名.o文件])
• 不加选项:到链接阶段完成为止(结束)
[未完成链接的文件] -> [可实行程序或库文件](不指定目标文件时输出到[a.out文件])
2.1.1 预处置惩罚
gcc -E [未完成预处理的文件] -o [.i文件]
复制代码
在该阶段进行宏更换/去注释/条件编译/头文件展开等:
宏更换
:将全部的宏定义用它们的值更换。
文件包含
:将#include指令引入的头文件内容直接插入到指令所在的位置。
条件编译
:根据条件编译指令(如#if、#ifdef、#ifndef等)的判断,选择性地包含或清除代码块。
删除注释
:去除源代码中的全部注释(//和/* */),以便在后续阶段不会被处置惩罚。
2.1.2 编译
gcc -S [未完成编译的文件] -o [.s文件]
复制代码
在该阶段生成汇编代码或目标文件
,这个阶段(狭义编译)是整个编译过程(广义编译)最核心的部分,包括对代码进行词法分析,语法分析,语义分析,生成中间代码,中间代码优化等阶段。
有一门课叫做<<编译原理>>(极难),对该阶段进行了详细的先容,这个阶段不是一篇小小的博文能够讲清楚的,我就不作过多先容了。
留意,说是生成的汇编代码,但实际上又不完全是,只是很相似。
2.1.3 汇编
gcc -c [未完成汇编的文件] -o [.o文件]
复制代码
该阶段讲编译阶段生成的汇编代码翻译为可被机器辨认并实行的二进制机器码。
也就是说[.o文件]已经可以被机器实行了,但是此中对库的调用,以及对其他文件中定义的函数/范例等的调用并不能完成,因为其还没有与这些文件创建接洽。
我们也称这个[.o文件]依赖于其他的[.o文件]或库文件。
2.1.4 链接
gcc [未完成链接的文件] -o [可执行程序或库文件]
复制代码
这个阶段就是将各个[.o文件]以及库文件进行链接,满足他们之间的依赖关系。
链接的方式有两种:动态链接和静态链接。
2.2 其他选项
下面的选项独立于
[-o]选项
和
编译选项
存在,可进一步控制整个编译过程的细节:
• [-static]
:此选项对生成的文件采用静态链接。
• [-g]
:生成调试信息。GNU 调试器可利用该信息。
•
[-shared]
:此选项将只管利用动态库,以是生成文件比较小,但是必要体系有动态库。
• [-O0]、[-O1]、[-O2]、[-O3]
:编译器的优化选项的4个级别,[-O0]表现没有优化,[-O1]为缺省值,[-O3]优化级别最高。
• [-w]
不生成任何告诫信息。
• [-Wall]
生玉成部告诫信息。
3. 动态链接和静态链接
3.1 静态链接
静态链接是在编译时将程序所需的全部库代码链接到单个可实行文件的过程。
这意味着整个库代码成为可实行文件的一部分。当程序运行时,它不必要单独访问库代码,因为它已经存在于可实行文件中。这使得可实行文件变大了,但它可以在任何体系上运行,而不必要单独安装库。静态链接通常用于小程序或库代码不太可能经常更改的情况。
优点:
在可实行程序中已经具备了实行程序所必要的全部东西,在实行的时候运行速率快。
缺点:
节浪费空间
:因为每个可实行程序中对全部必要的目标文件都要有一份副本,以是如果多个程序对同一个目标文件都有依赖,如多个程序中都调用了printf()函数,则这多个程序中都含有printf.o,程序在运行时printf.o会被多次加载到内存中。
更新比较困难
:每当库函数的代码修改了,这个时候就必要重新进行编译链接形成可实行程序。
3.2 动态链接
动态链接是在运行时将库代码链接到可实行文件的过程。
这意味着库代码不是可实行文件的一部分,而是作为共享库文件单独存储的(Windows上是.dll,Linux上是.so)。当程序运行时,它在实行过程中动态地访问共享库文件。这导致可实行文件更小,因为库代码没有包含在可实行文件中,但它还要求库文件必须安装在运行程序的体系上。动态链接通常用于大型程序或库代码可能经常更改的情况。
优点:
节省内存和磁盘空间
:由于多个程序可以共享同一个动态链接库,因此避免了在每个程序中重复包含相同的代码和数据,从而节省了内存和磁盘空间。
便于更新和维护
:当动态链接库更新时,只必要更换掉旧的库文件,而不必要重新编译或链接依赖于该库的程序。这大大进步了软件的更新和维护效率
缺点:
启动时间可能较长
:由于动态链接必要在程序运行时加载和剖析库文件,因此可能会增长程序的启动时间。特别是当程序依赖于多个大型库时,这个问题会更加明显。
存在版本兼容性问题
:如果新版本的动态链接库与旧版本的程序不兼容,那么程序可能会出现运行错误或崩溃的情况。别的,如果程序依赖于多个版本的库文件,还可能会出现DLL地狱(DLL Hell)问题。
3.3 操纵体系中的库
• Linux下,动态库XXX.so,静态库XXX.a
• Windows下,动态库XXX.dll,静态库XXX.lib
动态库一般会存放到操纵体系指定的目录下,当程序必要链接到对应的库时,体系会到该目录下查找,不同的操纵体系有所不同。
利用[ldd]指令可以查看可实行程序依赖的动态库,利用[file]指令可以验证程序利用的链接方式是动态链接还是静态链接:
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复
使用道具
举报
0 个回复
倒序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
发新帖
回复
道家人
论坛元老
这个人很懒什么都没写!
楼主热帖
CentOS7.9使用sealos部署单节点k8s并部 ...
青龙2.10.13 稳定版+Ninja登录面板+傻 ...
软件危机与软件过程模型
日本开放Wi-Fi 6E认证
〖Python接口自动化测试实战篇⑨〗- 实 ...
LyScript 从文本中读写ShellCode
Redis和Mysql保持数据一致性
C#_串口调试助手-网络拓扑显示 ...
推荐一款完全开源,功能丰富,界面精美 ...
如何精简 Prometheus 的指标和存储占用 ...
标签云
AI
运维
CIO
存储
服务器
浏览过的版块
DevOps与敏捷开发
人工智能
Oracle
SAP
快速回复
返回顶部
返回列表