当前位置: 首页 > news >正文

Linux | gcc/g++的使用

目录

前言

一、程序的翻译过程

1、预编译

2、编译

3、汇编

4、链接

(1)链接做了什么

(2)动态链接

(3)静态链接

(4)如何使用gcc进行动态链接和静态链接


前言

        本章主要带着大家一起学习Linux下编译C/C++的工具,以及关于动静态库的一些基础知识;

一、程序的翻译过程

        我们的C语言和C++编写出的程序属于翻译型程序,此处以C语言为例,分析程序翻译过程;

1、预编译

        当我们写完一个C语言程序时,首先,我们需要进行预编译操作;预编译主要将头文件展开宏替换条件编译去注释;我们可使用下列指令生成我们的预编译完的文件(以.i为结尾的文件后缀);

gcc -o 生成文件名.i  -E 被预编译的文件名.c

        上图为我们编写的源程序,我们来验证我们的预编译阶段是否完成了上述工作;我们执行以下执行,生成预编译完成后的文件 test.i ;

        预编译生成的文件从大小上,明显可以看出比我们的源文件要大很多,我们再使用vim查看我们的test.i文件,如下图;

        我们发现我们的文件一下就变成了八百多行,前面增加的便是我们的stdio文件展开后的样子,故我们test.i文件变大了很多,因为把我们的库文件代码复制到预编译后的文件中了,而且我们不难发现我们之前些的注释被去掉了,我们的宏也完成了替换,也进行了条件编译的处理,与我们的预想完全一致;

2、编译

        这一步主要实现的将我们的C语言代码编译成汇编代码,我们生成的汇编代码文件以s为后缀名,具体指令如下;

gcc -o 编译生成后文件名.s  -S  .c文件或.i文件都可

        学过汇编语言的友友们,应该就很熟悉了,这就是我们的汇编代码,编译阶段也如我们所料完成了自己的工作;

3、汇编

        这一步主要是将我们的汇编代码转换成机器指令,生成的文件叫 可重定向二进制目标文件(目标文件),这个文件在Linux下一般以o为后缀名,在window下一般以obj为后缀名,具体指令如下;

gcc -o 生成文件名 -c .c文件或.i文件或.s文件都可 

        我们可以使用od指令来阅读我们的可重定向目标文件,如下所示;

        这里生成的已经是机器指令了,但是仍然不能直接执行,必须链接后才可以执行;

4、链接

(1)链接做了什么

        实际上,我们上面的头文件,如 stdio.h 只有函数的声明,并没有函数的定义,因此我们在是使用我们库函数printf、scanf函数时,光有函数声明时远远不够的,我们必须还有具体的函数定义,这些函数定义都放在动态库或静态库,因此我们链接也有动态链接和静态链接;我们首先完成链接,具体指令如下;

gcc -o 生成可执行程序名  .c文件/.i文件/.s文件/.o文件都可

        我们可以通过ldd指令或file指令查看文件使用的动态库/静态库的名字,以及采用何种链接方式;

补充:在Linux下,动态库文件的后缀为.so,静态库文件的后缀为.a,而在window下,动态库文件的后缀为.dll,静态库文件的后缀为.lib;

(2)动态链接

        在动态链接中,我们的程序一旦发现有需要使用库函数的代码,则会保存该库函数在动态库中的地址,运行到此部分时,我们直接通过地址跳转到动态库的代码中,执行函数,执行完函数后继续返回程序执行程序后续代码;因此,一旦我们的动态库出现了问题,我们的程序就无法正确执行;

总结:

动态链接优点:可执行程序较小,因为只保存了库函数地址;

动态链接缺点:十分依赖动态库文件,若文件出现问题,程序则可能出现问题;

(3)静态链接

        在静态链接中,我们的程序会将需要使用的库函数的定义直接拷贝一份到我们的可执行程序中,我们在运行可执行程序时,无需静态库,我们直接调自己拷贝的代码即可;

总结:

静态链接优点:对静态库文件的无依赖,一旦生成可执行程序,即使静态库被删除,也可以运行;

静态链接缺点:静态链接生成的可执行程序由于会拷贝静态库中的函数定义,因此会变得非常大;

(4)如何使用gcc进行动态链接和静态链接

        在gcc中,我们默认使用动态链接的方式进行链接,因此直接使用正常的方式生成可执行程序即可,例如;

gcc -o test-d test.c

        而我们若想使用静态链接的方式进行连接,我们加上一个static选项即可,如下所示;

gcc -o test-s test.c -static

补充:有些小伙伴可能没有安装静态库,可通过下面指令安装静态库

sudo yum install -y glibc-static (Centos)

        显然,我们使用静态链接生成的可执行程序明显比动态生成的可执行程序要大十倍左右,也符合我们之前的推理,我们在通过ldd和file指令查看我们生成的可执行程序所依赖的库;

        test-s是静态链接生成的可执行程序,因此没有依赖的动态库,而test-d是动态链接生成的可执行程序,因此有依赖的动态库,我们可以通过file看出这两个可执行程序是动态链接还是静态链接;

http://www.lryc.cn/news/198379.html

相关文章:

  • 了解容器运行时安全:保护你的容器应用
  • 大规模语言LLaVA:多模态GPT-4智能助手,融合语言与视觉,满足用户复杂需求
  • Element UI定义方法校验邮箱格式
  • DigiCert代码签名证书
  • HTML5+CSS3小实例:网页底部间隔波浪动画特效
  • 前端 js 之 代码执行的一个过程 02
  • 【经验分享】如何构建openGauss开发编译提交一体化环境
  • 儿童疫苗接种:安全与注意事项
  • Go 代码块与作用域,变量遮蔽问题详解
  • 可观测性-Metrics-WebClient异步Http远程Call
  • Android之播放本地视频和Url视频方法
  • 设计模式:工厂方法模式(C#、JAVA、JavaScript、C++、Python、Go、PHP):
  • C++基础——指针
  • PLC 学习day02 硬件输入/输入的知识
  • rabbitMq (2)
  • 通讯协议学习之路:RS422协议理论
  • 剪映failed to initialize,cuda.is_available()为false解决
  • 基于Spring Boot的LDAP开发全教程
  • 在 Linux 上保护 SSH 服务器连接的 8 种方法
  • 摩尔信使MThings的协议转换(数据网关)功能
  • Mac安装Kali保姆级教程
  • 利用Spring Boot框架做事件发布和监听
  • KingBase库模式表空间和客户端认证(kylin)
  • h5的扫一扫功能 (非微信浏览器环境下)
  • Typora 导出PDF 报错 failed to export as pdf. undefined 解决方案
  • [架构之路-239]:目标系统 - 纵向分层 - 中间件middleware
  • javascript利用xhr对象实现http流的comet轮循,主要是利用readyState等于3的特点
  • 【Mybatis源码】XPathParser解析器
  • 辉视智慧酒店解决方案助力传统酒店通过智能升级焕发新生
  • 文件和命令的查找与处理