【Linux开发工具】gcc/g++的使用


📙 作者简介 :RO-BERRY
📗 学习方向:致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识
📒 日后方向 : 偏向于CPP开发以及大数据方向,欢迎各位关注,谢谢各位的支持


在这里插入图片描述


目录

  • 1.前言
  • 2.gcc/g++使用方法:以gcc为例
  • 3.程序翻译的四个阶段
    • 3.1 预处理(进行宏替换)
      • 创建预处理文件
      • 查看预处理文件
    • 3.2 编译(生成汇编)
      • 创建编译文件:
      • 查看编译文件:
    • 3.3 汇编(生成机器可识别代码)
      • 创建汇编文件
      • 查看汇编文件
    • 3.4 链接(生成可执行文件或库文件)
  • 4.函数库
    • 4.1 函数库的分类
    • 4.2 动静态库的区别与优缺点
    • 4.3 动静态库链接方式


1.前言

Linux下皆文件,在Linux下文件不分文件的后缀,文件的类型是看文件前面的字符
今天要学习的gcc和g++就是Linux下的程序
它们是要看文件后缀的!

  • gcc: C语言编译器,只能编译C语言
  • g++: C++编译器,C/C++都可以编译

2.gcc/g++使用方法:以gcc为例

编译文件:

  1. 编译文件并形成a.out的执行文件
  • gcc test.c
  1. 编译文件并形成test的执行文件,这里的test可以自取名字
  • * gcc test.c -o test

执行可执行程序
当我们编译好程序后,会在当前目录生成一个
可执行程序
在这里插入图片描述

  1. 执行形成的a.out的执行文件
  • ./a.out
  1. 执行形成的test的执行文件
  • ./test

注:.代表要在当前目录下找可执行文件.必须加上

gcc/g++选项

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

3.程序翻译的四个阶段

3.1 预处理(进行宏替换)

预处理功能主要包括

宏定义,文件包含,条件编译,去注释等。
预处理指令是以#号开头的代码行。

创建预处理文件

我们使用指令看一看

gcc –E test.c –o test.i

选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。
选项“-o”是指目标文件,“.i”文件为已经过预处理的C原始程序。
在这里插入图片描述

查看预处理文件

vim test.i

在这里插入图片描述

可以看到上面全部都是宏定义,文件包含,条件编译,去注释等操作,一共有八百多行,最后才是我们写的文件操作

3.2 编译(生成汇编)

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

创建编译文件:

gcc –S hello.i –o hello.s

在这里插入图片描述

查看编译文件:

vim test.s

在这里插入图片描述

这里的汇编代码没学过真不好懂

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

汇编阶段是把编译阶段生成的“.s”文件转成目标文件
在此使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了

创建汇编文件

gcc –c hello.s –o hello.o

在这里插入图片描述

查看汇编文件

vim test.o

在这里插入图片描述

此时使用vim打开文件是乱码
可以使用指令od查看二进制文件:

3.4 链接(生成可执行文件或库文件)

在成功编译之后,就进入了链接阶段。
链接阶段是将编译成功的文件变成可执行文件

gcc -o test test.o
这里我们将test.o文件进行编译并生成test可执行文件

在这里插入图片描述

链接阶段比较复杂,它大致的流程是这样的:

.o文件 + 系统库 = 可执行程序

在本篇文章的后半段讲完动静态库后再解释!


4.函数库

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

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

这里我们引入一个新指令:

ldd 可执行程序名
查看一个可执行程序依赖的第三方库

在这里插入图片描述
可以发现,在路径lib64里有一个文件叫libc.so.6
这个就是刚刚的C语言程序所要依赖的库
在这里插入图片描述
可见,libc.so.6实际上就是C的标准库


其中Linux环境下,动态库的后缀是.so,静态库的后缀是.a。在Windows环境下,动态库的后缀是.dll,静态库的后缀是.lib。所有的库文件,都遵守相同的命名规则,即:libname.后缀.xxx。
小Tips:gcc编译器会默认找到C的标准库,它会把我们写的源代码经过编译得到的目标文件与库文件进行链接。这也是为什么gcc不能去编译C++的源文件,因为gcc默认找的是C的标准库,它找不到C++的库。

现在我们就可以理解链接过程了
链接过程就是将.o文件和动/静态库结合的过程

4.1 函数库的分类

函数库一般分为静态库和动态库两种。

  • 静态库(static library, Statically-linked library, LIB)或称静态链接库,是一个外部函数与变量的集合体。静态库的文件内容,通常包含一堆程序员自定的变量与函数,在编译期间由编译器与连接器将它集成至应用程序内,并制作成目标文件以及可以独立运作的可执行文件。而这个可执行文件与编译可执行文件的程序,都是一种程序的静态创建(static build)。其特点是可执行文件中包含了库代码的一份完整拷贝;缺点就是被多次使用就会有多份冗余拷贝。即静态库中的指令全部被直接包含在最终生成的可执行文件中。静态库的后缀是.a

  • 动态库(Dynamic library, Dynamic-link library, DLL)或称动态链接库,是微软公司在微软视窗操作系统中实现共享函数库概念的一种实现方式。动态链接库可被多个程序同时使用。所谓动态链接,就是把一些经常会共用的代码(静态链接的OBJ程序库)制作成DLL档,当程序有需求时函数才进行链接。透过动态链接方式,存储器浪费的情形将可大幅降低。静态链接库则是直接链接到可执行文件。动态库的后缀是.so

gcc hello.o –o hello
gcc默认生成的二进制程序,是动态链接的,这点可以通过 file 命令验证。

4.2 动静态库的区别与优缺点

  • 动态库是共享库,通过函数地址来关联程序
  • 静态库是私有库,可以独立运行

动态库: 是C/C++或其他第三方提供的所有方法的集合,被所有程序以动态链接的方式关联起来
静态库: 是C/C++或其他第三方提供的所有方法的集合,被所有程序以拷贝的方式,将需要的代码拷贝至自己的可执行程序当中!

优点缺点
静态库有效的节省资源(磁盘空间、内存空间、网络空间等)一旦缺失,所有程序都无法运行
静态库不依赖库,编译成功的可执行程序,可以独立执行,不需要再向外部要求读取库函数中的内容体积大,比较消耗资源

4.3 动静态库链接方式

链接分为两类:动态链接静态链接

  • 静态链接:由链接器在链接时将库的内容加入到可执行程序中。在编译器使用静态库进行静态链接的时候,会将自己的方法拷贝到目标程序中,该程序以后不再依赖静态库。
  • 动态链接:连接器在链接时仅仅建立与所需库函数的之间的链接关系,在程序运行时才将所需资源调入可执行程序。动态库是被所有程序所共享的,一般也被叫做共享库。这意味着,动态库只需要一个就够了,它可以满足所有程序的需求。

Linux中,编译形成可执行程序,优先采用动态链接。
如果想使用静态库编译程序

使用指令: gcc test.c -static

总的来说,静态库可以产出独立程序,动态库实现了模块化和代码共享,以空间换时间。
链接器会根据是静态链接还是动态链接,调用不同的处理逻辑,最终产出可执行程序。
所以同样的代码,静态链接和动态链接链接后的结果并不相同。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手把手教你激活FL Studio 21.2.2.3914中文破解版2024年图文激活教程以及如何设置中文language

FL Studio 21.2.2.3914软件简介 fl studio 21.2.2.3914中文破解版作为一款极具创意性的音乐软件工作站软件,FL Studio已经成为了许多音乐制作人和音乐爱好者的首选。最新的FL Studio 21.2.2.3914中文破解版的发布,无疑将会引起更多人的关注。 ​ FL St…

《Java程序设计》实验报告(一)之Java语言基础

实验内容及步骤: 编写”hello world”应用程序。(1)代码: public class HelloWorld { public static void main(String[] args) { System.out.println("Hello world!"); } } (2)运行…

【Langchain+Streamlit】旅游聊天机器人

【LangchainStreamlit】打造一个旅游问答AI-CSDN博客 项目线上地址,无需openai秘钥可直接体验:http://101.33.225.241:8502/ github地址:GitHub - jerry1900/langchain_chatbot: langchainstreamlit打造的一个有memory的旅游聊天机器人&…

Mybatis- plus 基本使用

目录 一. 引入依赖 二.定义Mapper 三.常见注解 3.1TableName 3.2.TableId 3.3TableField 3.4常见配置 一. 引入依赖 由于这个starter包含对mybatis的自动装配&#xff0c;因此完全可以替换掉Mybatis的starter。 <dependency><groupId>com.baomidou</gr…

pytorch训练指标记录之tensoboard,wandb

科研工具-01 使用Wandb实现高效实验管理 - 知乎Wandb简介Wandb都能做什么呢&#xff1f;可视化多实验对比云端存储实验报告如何使用Wandb呢&#xff1f;注册账户安装Wandb开始使用PytorchWandbargparse实现高效实验管理 Wandb简介 Wandb是一个高效的、功能丰富的人工智能实验管…

momentJs推导日历组件

实现效果: 代码&#xff1a; 引入momentjs然后封装两个函数构建出基本数据结构 import moment from moment;// 某月有多少天 export const getEndDay (m) > m.daysInMonth();/*** description 获取本月空值数据* param { Date } year { } 年度* param { Number } month …

【机器学习】机器学习流程之收集数据

&#x1f388;个人主页&#xff1a;甜美的江 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;机器学习 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步…

双归同一运营商的 BGP 部署

一、拓朴如下&#xff1a; 要求&#xff1a; 1、AS100 只接收 AS200 和 300 的路由&#xff0c;不接收其它 AS 的明细路由&#xff1b; 2、对于 AS100 的业务流量出方向&#xff0c;所有到 AS200 和 300 的流量&#xff0c;优先选择 Line-1&#xff0c;而到 AS400 的流…

数据结构——顺序表详解

目录 前言 一.线性表 1.概念 二.顺序表 1.概念 2.分类 2.1静态顺序表 2.2动态顺序表 前言 数据结构是计算机存储、组织数据的方式. 一.线性表 1.概念 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列.线性表是一种在实际中广泛使用的…

【Linux系统化学习】文件描述符fd

目录 基础IO预备知识 C语言文件接口 "w"的方式打开&#xff0c;fputs写入 以"a"的方式打开&#xff0c;fputs写入 使用位图传参 系统调用操作文件 open的使用 第一种形式 第二种形式 write() 文件描述符 文件描述符和进程的关系 默认的三个IO流…

NModbus的NuGet包使用样例

首先仿真软件ModbusSlave简单配置3条数据&#xff1a; 连接配置&#xff1a; VS中安装NuGet包&#xff1a;NModbus4 简单获取湿度 SerialPort serialPort new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);serialPort.Open();Modbus.Device.ModbusSer…

mysql项目实战,常用sql语句的实战笔记

1.使用sql语句对数据库进行创建 //创建实验用的数据库 CREATE DATABASE jsschool;//使用当前数据库 USE jsschool;//创建学生表 CREATE TABLE student (sno VARCHAR(20) PRIMARY KEY COMMENT 学生编号,sname VARCHAR(20) NOT NULL COMMENT 学生姓名,ssex VARCHAR(10) NOT NULL…