【LInux编译器gcc/g++】gcc使用方法和动静态库相关概念

目录

一.前言

二.源代码的翻译环境

三.gcc相关指令

四.动静态库

1.什么是库?

2.库的命名

3.库的链接方式

4.动静态链接的优缺点

5.小结


一.前言

在Windows系统上我们常用VisualStudio来进行C/C++开发,VS并不是一款单一的软件,而是集成开发环境(IDE),其中包含编辑器,编译器,调试器等等,功能很强大。而在LInux当中,我们需要学会使用各项独立的工具才能进行开发,例如用vim编辑代码,用gcc编译代码,用gdb调试代码。

今天我们就来讲讲如何使用gcc来得到我们需要的可执行程序,并介绍编译过程中的动静态库问题。

二.源代码的翻译环境

我们编写的C语言是自然语言,它是供我们人类阅读的,计算机并不懂。所以需要将它翻译成计算机看得懂的二进制语言,而这个翻译过程,就是经常说的编译。

实际上一个或多个源文件变层可执行程序需要经历编译和链接两个阶段,但我们日常所说的编译是把链接阶段也包含在内的,下面我也不再刻意区分这两个阶段。

程序编译的过程包含以下四个阶段

  1. 预处理
  2. 编译
  3. 汇编
  4. 链接

而gcc编译器就是来完成这四项工作的

【注:想要进一步理解程序的翻译过程可参考我以前写的程序的编译(翻译)】

三.gcc相关指令

gcc -E code.c -o code.i

-E表示从现在开始进行程序翻译,等预处理完成就停下来,不要继续往后走了。

-o表示把生成的文件重命名

预处理阶段做了四件事:

  1. 头文件展开
  2. 条件编译
  3. 去注释
  4. 宏替换

得到的code.i文件依然是C语言代码

gcc -S code.i -o code.s

-S表示从现在开始进行程序翻译,等编译完成就停下来,不要继续往后走了。

这里的code.i是否可以换成code.c呢?肯定是可以的,但是没必要,因为这样之前的工作又会被重复做一遍。

这时的code.s文件就是汇编代码了

gcc -c code.s -o code.o

-S表示从现在开始进行程序翻译,等汇编完成就停下来,不要继续往后走了。

完成汇编后,code.o就是一个二进制文件了,但现在它并不能执行,因为还差最后一个链接阶段

gcc code.o mybin

链接并不像前几个阶段一样有专门的选项,因为链接就是翻译的最后一步,通常情况下我们都是直接执行以下指令一步到位,并不会傻傻地把这四个步骤分开做

gcc code.c -o mybin  

细节问题 :

我们在test.c文件中写了这样一段代码

 编译时发现不能通过

这是因为在for循环里定义临时变量c99标准里才支持的,我现在的这款gcc编译器默认是不支持的,要想采用c99标准编译代码,只需在后面加上std=c99即可

gcc  -std=c99  test.c  -o  test.out

四.动静态库

简而言之:.o文件+库=可执行程序

故链接阶段就是将.o文件(可重定位的二进制文件)和库链接起来

那么接下来就有两个问题:什么是库呢?如何链接.o文件和库的呢?

1.什么是库?

下面介绍一个指令

ldd mybin

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

 

可以看出来mybin依赖三个库,其它两个不管,我们把中间的那个拎出来 

 

我们在LInux系统中找一下,看是否有这个文件

果然有这个文件,而且给普通用户开放的权限还挺高,可读可写可执行。

注意库并不是头文件,预处理阶段include过来的并不是它哟,头文件这个路径下?

 

 头文件放的是函数的声明,库提供方法实现。

头文件+库+我们写的代码=我们的可执行程序

“LInux下一切皆文件“,所以库其实也就是个文件。系统中的头文件和库文件都是文件!所以,所谓的开发环境安装,一定要做什么工作?

安装下载并拷贝头文件和库文件到开发环境中的特定路径下,一定要能被编译器自己找到

在下载VS时,会让你选择安装C++桌面版,游戏开发等环境,说白了就是不同的头文件和库文件嘛

2.库的命名

以libc.so.6这个库为例

库要求以lib开头,so表示这个库是静态库,6是版本号,所以一个库的名字要去掉前缀和后缀,所以这个库的名字就是c,也就是传说中的C标准库。

库分为两类:动态库和静态库,在LInux当中,so表示动态库,a表示静态库。在常规的开发环境中,动态库居多

3.库的链接方式

动态库:是C/C++或其它第三方提供的所有方法的集合,被所有程序以链接的方式关联起来,这种链接方式叫做动态链接

静态库:是C/C++或其它第三方提供的所有方法的集合,被所有程序以拷贝的方式,将需要的代码,拷贝到自己的可执行程序中,这种链接方式叫做静态链接 

库中所有的函数,都有入口地址,所谓的动态链接,其实就是把链接的库中的函数地址拷贝到我们的可执行程序中的特定位置。

4.动静态链接的优缺点

动态链接:优点:形成的可执行程序体积比较小,比较节省资源。

                  缺点:强依赖动态库,动态库没了,所有依赖这个库的程序都无法运行了

静态链接:优点:无视库,可以独立运行

                  缺点:体积太大,浪费资源

LInux系统中的指令,实际上就是一个个可执行程序 

 既然是可执行程序,那我们就能查看它所依赖的库

可以看到,pwd指令也是用C语言写的,它也依赖C标准库。实际上,LInux中的绝大多数指令都是用C/C++写的,如果我们将C标准库删掉,那么这个系统基本也就挂了,因为最基本的指令都无法运行,更别说其它操作了。

接下来我们想看看动静态链接的可执行程序的大小差异,如何做呢?

gcc默认是采用动态链接的方式,去找对应的动态库,所以采用如下指令即可

 

要想静态链接,只需在后面跟上一个-static

但有可能会报出这样的一个错误

这是因为我们的系统里默认是没有安装 C静态库的。我们可以手动安装一下C/C++静态库

sudo  yum  install  -y  glibc-static  libstdc++-static

 最终两个可执行程序都生成了,可以看到它们的体积大小相差了将近100倍,这还是我仅仅在里面写了一个helloworld的情况下。

所以这也能解释为什么编译器默认采用的是动态链接,因为静态链接太浪费空间了。这里的空间不仅仅指磁盘上的空间,还包括内存。你要知道,一个可执行程序要想执行,首先必须是要加载到内存中去的呀,所以使用动态链接加载到内存会更快

5.小结

我们的开发环境,编译器都要为我们做什么?

  1. 下载开发环境(头文件和库文件)
  2. 设置合理的查找路径
  3. 设定好我们形成可执行程序的链接方式

所以编译时出现链接问题,要么是库文件损毁了,要么是路径没或者链接方式没有设定好。

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

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

相关文章

【刷题篇】贪心算法(一)

文章目录 分割平衡字符串买卖股票的最佳时机Ⅱ跳跃游戏钱币找零 分割平衡字符串 class Solution { public:int balancedStringSplit(string s) {int lens.size();int cnt0;int balance0;for(int i0;i<len;i){if(s[i]R){balance--;}else{balance;}if(balance0){cnt;}}return …

WPF CommunityToolkit.Mvvm Messenger通讯

文章目录 环境WeakReferenceMessenger方法介绍无回调订阅发送Token区分有回调订阅发送 环境 CommunityToolkit.Mvvm Messenger 十月的寒流: 如何使用 CommunityToolkit.Mvvm 中的 Messenger 来进行 ViewModel 之间的通信 WeakReferenceMessenger 我这里只讲简单的弱Messenger…

Spring云服务:如何将应用程序轻松迁移到云端

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

Android图形-Hardware Composer HAL

目录 一、引言 二、概览 三、实现HWC 3.1 为什么是HWC&#xff1f; 3.2 HWC的支持需求 3.3 HWC的实现思路 3.4 HWC的基元 3.5 HIDL接口 3.6 函数指针 3.7 图层和屏幕句柄 3.8 屏幕合成操作 3.9 多个屏幕 3.10 虚拟屏幕合成 3.10.1 模式 3.10.2 输出格式 3.11 同…

Qt 5.15编译(MinGW)及集成Crypto++ 8.8.0笔记

一、背景 为使用AES加密库&#xff08;AES/CBC加解密&#xff09;&#xff0c;选用Crypto 库&#xff08;官网&#xff09;。   最新Crypto C库依次为&#xff1a;8.8.0版本&#xff08;2023-6-25&#xff09;、8.7.0&#xff08;2022-8-7&#xff09;和8.6.0&#xff08;202…

如何利用 Selenium 对已打开的浏览器进行爬虫

大家好&#xff01; 在对某些网站进行爬虫时&#xff0c;如果该网站做了限制&#xff0c;必须完成登录才能展示数据&#xff0c;而且只能通过短信验证码才能登录 这时候&#xff0c;我们可以通过一个已经开启的浏览器完成登录&#xff0c;然后利用程序继续操作这个浏览器&…

【LeetCode-中等题】39. 组合总和

文章目录 题目方法一&#xff1a;递归回溯 题目 这题的nums数组里面不存在重复元素&#xff0c;所以也就无需做去重操作 但同一个元素可以被无限次取&#xff0c;说明每次递归中的for循环的开始位置就是自己 nums数组里面存在重复元素&#xff0c;去重版本&#xff1a; 方法一…

Git学习记录

Contest 一、工作区域二、操作命令2.1 创建仓库2.2 查看仓库状态2.3 从工作区向暂存区添加文件2.3.1 只添加一个文件2.3.2 添加全部文件 2.4 从暂存区向仓库区添加文件2.5 查询日志2.5.1 从当前版本开始查询2.5.2 查看所有日志 2.6 回滚2.6.1 从仓库回滚到工作区2.6.2 取消工作…

剑指 Offer 04. 二维数组中的查找

题目描述 在一个 n * m 的二维数组中&#xff0c;每一行都按照从左到右 非递减 的顺序排序&#xff0c;每一列都按照从上到下 非递减 的顺序排序。请完成一个高效的函数&#xff0c;输入这样的一个二维数组和一个整数&#xff0c;判断数组中是否含有该整数。 解题思路 注意每…

c++中的list容器讲解

文章目录 1. list的介绍及使用1.1 list的介绍1.2 list的使用1.2.1 list的构造1.2.2 list iterator的使用1.2.3 list capacity1.2.4 list element access1.2.6 list的迭代器失效 2. list的模拟实现2.1 模拟实现list 3. list与vector的对比 1. list的介绍及使用 1.1 list的介绍 …

医疗知识图谱 neo4j

开源项目&#xff1a; https://github.com/liuhuanyong/QASystemOnMedicalKG 一.效果 二.需要安装&#xff1a; pip install pyahocorasick pip install py2neo 三.需要修改&#xff1a; 需要改的点&#xff1a; 1.改连接的方式 2.改读文件的方式 MedicalGraph 运行&am…

docker-compose安装Nacos2

文章目录 一. Mac1.1 数据库nacos_dev1.2 docker-compose.yaml1.3 部署1.4 卸载1.5 查看 二. Win102.1 docker-compose.yaml2.2 部署2.3 卸载 一. Mac 1.1 数据库nacos_dev sql文件地址 /** Copyright 1999-2018 Alibaba Group Holding Ltd.** Licensed under the Apache Li…

C语言_指针(1)

文章目录 前言一、指针数组1.1利用指针数组模拟出二维数组 二、数组指针2.1数组名是数组首元素的地址2.2 二维数组传参2.3 一级指针传参2.4 二级指针传参 三. 函数指针四 . typedef 重命名 前言 指针数组是由指针组成的数组。它的每个元素都是一个指针&#xff0c;可以指向任何…

工商银行潍坊分行党建RPA机器人项目解析

01 案例背景&#xff1a;银行业掀起引入RPA加速实现数字化转型的浪潮 近年来&#xff0c;金融科技的蓬勃发展极大促进了银行的业务创新&#xff0c;新技术、新业态层出不穷。随着银行业务和科技的融合逐步落实&#xff0c;银行业务正朝着线上化、智能化转变。科技赋能的转型范…

【管理运筹学】第 7 章 | 图与网络分析(4,最大流问题)

系列文章目录 【管理运筹学】第 7 章 | 图与网络分析&#xff08;1&#xff0c;图论背景以及基本概念、术语、矩阵表示&#xff09; 【管理运筹学】第 7 章 | 图与网络分析&#xff08;2&#xff0c;最小支撑树问题&#xff09; 【管理运筹学】第 7 章 | 图与网络分析&#xf…

学习笔记-配置备份静态路由及优先级

上一个笔记&#xff1a;学习笔记-静态路由配置有来无回导致无法访问目标IP 拓扑图&#xff1a; 书接上回。 模拟R2至R3之间的链路中断&#xff0c;配置备份路由通过R1访问R3。 shutdown掉R2的gi0/0/2端口&#xff0c;模拟链路中断。pingR3的gi0/0/0和R3的loopback0&#xff…

Java中如何获取一个字符串是什么类型

Java中如何获取一个字符串是什么类型&#xff1f; 在Java中&#xff0c;您可以使用一些方法来确定一个字符串的类型。下面是一些常用的方法&#xff1a; 使用正则表达式&#xff1a;您可以使用正则表达式来匹配字符串是否符合特定的模式或格式&#xff0c;以确定其类型。例如&…

Android——数据存储(二)(二十二)

1. SQLite数据库存储 1.1 知识点 &#xff08;1&#xff09;了解SQLite数据库的基本作用&#xff1b; &#xff08;2&#xff09;掌握数据库操作辅助类&#xff1a;SQLiteDatabase的使用&#xff1b; &#xff08;3&#xff09;可以使用命令操作SQLite数据库&#xff1b; …

Leangoo领歌 -敏捷任务管理软件,任务管理更轻松更透明

​任务管理&#xff0c;简单易懂&#xff0c;就是对任务进行管理。那怎么可以更好进行任务管理呢&#xff1f;怎么样样可以让任务进度可视化&#xff0c;一目了然呢&#xff1f;有效的管理可以让我们事半功倍。 接下来我们看一下如何借助任务管理软件高效的做任务管理。 首先…

Python Opencv实践 - Harris角点检测

参考资料&#xff1a;https://blog.csdn.net/wsp_1138886114/article/details/90415190 import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/chinease_tower.jpg", cv.IMREAD_COLOR) plt.imshow(img[:,:,::-1])#…