Linux编译器-gcc/g++使用函数库

 【Linux】系列文章目录

【Linux】基础常见指令:http://t.csdn.cn/hwLPb

【Linux】基本权限:http://t.csdn.cn/faFZg

【Linux】软件包管理器yum与环境开发工具vim:http://t.csdn.cn/LEqkm


目录

 【Linux】系列文章目录

前言

一、gcc选项总览

二、gcc如何完成?

 1.预处理 ( 进行宏替换)

预处理结果展示:

2、编译(生成汇编)

编译结果展示:

 .iso镜像文件 

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

4、连接(生成可执行文件或库文件)

三、函数库

 1.静态库

2.动态库

最后


前言

        gcc/g++是一个编译器(gcc专门编译C语言;g++专门编译C++,也可以编译C语言)。

        本文将从程序的翻译,包括预处理、编译、汇编、连接四个步骤,主要对gcc以及函数库分别展开讲解。


提示:以下是本篇文章正文内容,下面案例可供参考

     

一、gcc选项总览

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

注:-O0、-O1、-O2、-O3 为编译器优化选项的4个级别。

 在后文gcc如何完成部分将会对gcc选项有更近一步的解释。

二、gcc如何完成?

 1.预处理 ( 进行宏替换)

 对源程序进行头文件展开,条件编译,进行宏替换,去注释等。

对.c文件进行预处理使用gcc -E命令,表示从现在开始进行程序的翻译,预处理做完,就停下来,形成.i文件,.i文件中存放预处理后的结果

gcc -E myfile.c -o myfile.i

在vim中输入vs myfile.i 然后回车就能查看.i文件内容

vs myfile.i

预处理结果展示:

2、编译(生成汇编)

把文本文件翻译成二进制文件,形成汇编语言

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

       对文件进行编译使用gcc -S命令,表示从现在开始进行程序的翻译,当编译做完,就停下来。形成.s文件,.s文件中存放编译后的结果

gcc -S myfile.i -o myfile.s

编译结果展示:

 .iso镜像文件 

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

 汇编->可重定位目标二进制文件,不可以被执行的,bin.obj

----只把我们自己的代码进行翻译形成二进制目标文件

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

       对文件进行编译使用gcc -c命令,表示从现在开始进行程序的翻译,当汇编做完,就停下来 ,形成.o文件,.o文件中存放汇编后的结果

gcc -c myfile.s -o myfile.o

        请观察以上命令及形成的结果文件。

4、连接(生成可执行文件或库文件)

 将我们自己形成的.obj文件和库文件进行某种合并,将程序与相对应的库链接起来,形成可执行程序。

gcc命令 或gcc -o 命令

gcc [文件名]:将源程序进行编译,形成a.out文件,如果想要生产我们自己需要的文件名,使用gcc -o命令。

-o 后面紧跟指定的形成可执行文件的名称

gcc -o myfile myfile.c
gcc myfile.c -o myfle
//两行代码效果一样./a.out
// ./+文件名  是指执行该文件

 

在成功编译之后,就进入了链接阶段。

接下来请思考一个问题:

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

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

能在Linux下进行C、C++代码的编写和编译,是因为Linux系统默认已经携带了语言级别的头文件和语言对应的库!

       在这里涉及到一个重要的概念------函数库

三、函数库

 函数库一般分为静态库(专门让编译器对用户的程序进行静态链接的)和动态库(专门让编译器对用户的程序进行动态链接的)两种,库的本质也是文件。Linux默认使用的是动态连接和动态库。

 1.静态库

        静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。后缀名一般为“.a”

  • 静态链接:将我们所需要的库中的代码拷贝到我们的程序中。
  • 静态链接一旦形成就不再依赖任何库,自己就可以独立运行。
  • 因为自身拷贝问题,比较浪费空间。

 一般的云服务器,默认都是只有动态库。如果在静态链接的时候,链接可能会报错,因此需要安装静态库,代码如下。 

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

安装示例: 

2.动态库

(动态库==共享库)

       与静态库相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如 libc.so.6 就是动态库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件,如 gcc myfile.c –o myfile。

  • 动态链接:将你所需要的库中的代码地址拷贝到你自己的可执行程序中相关的位置。
  • 动态链接形成还是依赖动态库,一旦动态库缺失,程序便无法运行。
  • 因为可以做到被大家共享方法,所以真正的实现永远都是在库中,程序内部只有地址,比较节省空间。
ldd myfile
// ldd+文件名   能够查到该程序所依赖的库

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

file myfile

 注意:头文件!=库文件   

  • 在C语言中,头文件提供对常量的定义和对系统函数及库函数调用的声明(函数原型)。存放的标准位置是/usr/include目录及其子目录。

  • 库文件是一组预先编译好的函数的集合,可以说是头文件函数原型的实现。存放的标准位置是/lib和/usr/lib目录。库文件总是以lib开头。标准C语言库文件(函数库)为libc.a文件。


最后

       快乐的时光总是短暂的,以上就是今天要讲的内容,本文详细介绍了小赵同学对Linux编译器-gcc/g++以及函数库的初步认知以及用例。欢迎家人们批评指正。小赵同志继续更新,不断学习的动力是宝子们一键三连的支持呀~

                                                     ​ 

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

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

相关文章

[C++]类型转换

一、C语言中的类型转换 在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与 接收返回值类型不一致时,就需要发生类型转化。 C语言中总共有两种形式的类型转换:隐式类型转换和显式…

python astra相机驱动问题

报错问题: openni.utils.OpenNIError: (OniStatus.ONI_STATUS_ERROR, bDeviceOpen using default: no devices found, None) 解决办法: 1、从sdk中拷贝文件 2、修改openni源码 3、执行测试程序 from openni import openni2 import numpy as np impor…

python中多行注释与取消注释

在小白学习python编程的过程中,我们经常会发现很多同学们喜欢问的一个问题: 怎么多行注释呢? 怎么取消多行注释呢? 以上种种问题我相信来到这里都会得到相应答案 那我们接下来开始吧! 文章目录 单行注释多行注释取消多…

docker运行redis镜像

很多项目会用到redis作为缓存用到项目中,鉴于刚了解过docker,今天这里用docker运行redis镜像,这样下载,安装运行,或者是使用后的删除都会干净,简单。 好了,第一步是先拉取镜像,使用d…

adb 获取 Android 设备中已安装的 apk 文件

前言 今天发现手机上一个应用在应用商店已经搜索不到了,想把其推荐给朋友使用,发现不知道从哪里找原始的 apk 安装文件,记录一下。 如何提取 apk 两种方法 MT管理器导出 可以使用 MT管理器(Android 平台逆向神器),它有个 安装…

centos 7.9 安装sshpass

1.作用 sshpass是一个用于非交互式SSH密码验证的实用程序。它可以用于自动输入密码以进行SSH登录,从而简化了自动化脚本和批处理作业中的SSH连接过程。 sshpass命令可以与ssh命令一起使用,通过在命令行中提供密码参数来执行远程命令。以下是一个示例命…

openGauss学习笔记-102 openGauss 数据库管理-管理数据库安全-客户端接入之查看数据库连接数

文章目录 openGauss学习笔记-102 openGauss 数据库管理-管理数据库安全-客户端接入之查看数据库连接数102.1 背景信息102.2 操作步骤 openGauss学习笔记-102 openGauss 数据库管理-管理数据库安全-客户端接入之查看数据库连接数 102.1 背景信息 当用户连接数达到上限后&#…

vmware安装 Rocky9(自定义分区安装)

一、下载镜像 访问官网,下载dvd的镜像 Download Rocky | Rocky Linuxhttps://rockylinux.org/download 二、新建vmware虚拟机 1、vmware尽量选择vmware17 2、下一步 3、稍后安装 4、选择系统类型:red hat9 5、自定义安装位置 6、根据电脑配置&#…

LeetCode:2316. 统计无向图中无法互相到达点对数(C++)

目录 2316. 统计无向图中无法互相到达点对数 题目描述: 实现代码与解析: 并查集 原理思路: 2316. 统计无向图中无法互相到达点对数 题目描述: 给你一个整数 n ,表示一张 无向图 中有 n 个节点,编号为…

AWS Lambda – 函数版本,别名,API网关,CodeDeploy协同

Hello大家好,我们今天继续讨论AWS Lambda的内容。 Lambda函数的版本 Lambda函数的版本和别名是辅助资源,我们可以通过创建这些资源管理函数的部署和调用。 首先,让我们来看一下Lambda 函数版本的概念。您可以使用版本来管理函数的部署。例…

前端数据可视化之【Echarts下载使用】

目录 🌟下载🌟浏览器引入🌟模块化引入 🌟使用🌟基本使用步骤 🌟绘制一个简单的图表🌟写在最后 🌟下载 🌟浏览器引入 官网下载界面:官方网站 或 Echarts中文…

Bootstrap的列表组相关知识

目录 01-列表组的相关基础知识02-一个简单的列表组示例03-激活或禁用列表组的一行或多行04-设置列表项的颜色05-给列表项添加徽章 01-列表组的相关基础知识 Bootstrap的list-group是一个用于创建列表组件的CSS类,通常用于显示一个项目列表,如导航菜单或…

2023年拼多多双11百亿补贴新增单件立减玩法介绍

2023年拼多多双11百亿补贴新增单件立减玩法介绍 拼多多启动了11.11大促活动,主题为“天天11.11,天天真低价”。消费者享受多重优惠,包括满减、百亿补贴和单件立减等。百亿补贴新增玩法,有超过20000款品牌商品参与单件立减活动。 …

iOS逆向工程之Theos

如果你对iOS逆向工程有所了解,那么你对Tweak并不陌生。那么由Tweak我们又会引出Theos, 那么什么是Theos呢,简单一句话,Theos是一个越狱开发工具包,Theos是越狱开发工具的首先,因为其最大的特点就是简单。大道至简&…

Hook原理--逆向开发

今天我们将继续讲解逆向开发工程另一个重要内容--Hook原理讲解。Hook,可以中文译为“挂钩”或者“钩子”,逆向开发中改变程序运行的一种技术。按照如下过程进行讲解 Hook概述Hook技术方式fishhook原理及实例符号表查看函数名称总结 一、Hook概述 在逆…

Lake Formation 和 IAM 之间的区别与联系

IAM 和 Lake Formation 都是 AWS 上的权限管理服务,且默认都是自动开启并生效的,只是如果你没有特别配置过它们,可能感觉不到它们的存在,特别是Lake Formation(后文简写为 LF),通常情况下都是“透明”的,但它确实在每次请求时进行了权限检查。本文会详细介绍一下两者之…

【最短路径算法】一文掌握Dijkstra算法,详解与应用示例+代码

目录 1 Dijkstra算法 2 Dijkstra算法的步骤 3 Dijkstra算法python实现 4 Dijkstra算法应用示例详解 1 Dijkstra算法 Dijkstra算法(迪杰斯特拉算法)是一种用于在加权图中查找从一个起始节点到所有其他节点的最短路径的算法。该算法最初由荷兰计算机科…

offsetof宏计算某变量相对于首地址的偏移量

宏:offsetof的使用 //offsetof (type,member) //type是结构体的类型名,member是结构体中的成员名。struct Student {char name[5]; // 姓名int age; // 年龄float score; // 成绩 };int main() {struct Student s;printf("%zd\n", off…

Android微信逆向--实现发朋友圈动态

Android微信逆向--实现发朋友圈动态 0x0 前言# 最近一直在研究Windows逆向的东西,想着快要把Android给遗忘了。所以就想利用工作之余来研究Android相关的技术,来保持对Android热情。调用微信代码来发送朋友圈动态一直是自己想实现的东西,研…

邻接表存储图或者树

大家好,我叫徐锦桐,个人博客地址为www.xujintong.com。平时记录一下学习计算机过程中获取的知识,还有日常折腾的经验,欢迎大家来访。 介绍 每个顶点都作为头节点,并且存在一个一维数组中h[N]。树就是相当于一种有向图…