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

news2024/12/22 12:53:22

 【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.coloradmin.cn/o/1121227.html

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

相关文章

【C语言】malloc()函数详解(动态内存开辟函数)

一.malloc()函数简介 我们先来看一下cplusplus.com - The C Resources Network网站上malloc()函数的基本信息: 1.函数功能 可以看到,malloc()函数的功能是:向内存申请一块连续可用的空间,并返回指向块开头的指针. 2.函数参数 该函数有1个参数,是: void* malloc (…

关于iterm2的美化

iterm2 美化 笔者公司最近给发了一个新 M1 mac pro,所以一些软件需要重新安装。其中比较麻烦就是iterm2的一个美化工程 , 由于每次安装的效果都不尽相同所以这次写一个博客来记录一下 安装的过程 。 全程高能开始: 使用brew 来安装 iterm2 …

26. 通过 cilium pwru了解网络包的来龙去脉

pwru是一种基于eBPF的工具,可跟踪Linux内核中的网络数据包,并具有先进的过滤功能。它允许对内核状态进行细粒度检查,以便通过调试网络连接问题来解决传统工具(如iptables TRACE或tcpdump)难以解决甚至无法解决的问题。在本文中,我将介绍pwru如何在不必事先了解所有内容的…

C++ 模板类编译前需要实例化

在复习list容器的模拟实现,遇到了模板未实例化导致代码报错的问题,list的模拟实现可以看下面这篇文章,这里就不多赘述了,直接切入正题。Clist模拟http://t.csdnimg.cn/N6BGh现在的情况是我们已经模拟实现了list类,想在…

1024 漏洞综合项目演示(第十七课)

1024 漏洞综合项目演示(第十七课) 一 渗透流程 前期交互(Reconnaissance):这是一个信息收集的阶段,黑客或攻击者会收集目标系统或网络的信息,例如域名、IP地址、子网结构、网络拓扑等。 信息收集(Informa…

开源博客项目Blog .NET Core源码学习(4:生成验证码)

开源博客项目Blog中的后台管理登录界面中支持输入验证码(如下图所示),本文学习并记录项目中验证码的生成及调用方式。   博客项目中调用VerifyCode类生成验证码,该类位于App.Framwork项目中,命名空间为App.Framwork…

[Docker]一.Docker 简介与安装

一、Docker简介与为什么要用 Docker 1.1、Docker 介绍 Docker 是一个跨平台的开源的 应用容器引擎 ,诞生于 2013 年初,基于 Go语言 并遵从 Apache2.0 协议开源, Docker 可以把它理解成虚拟机,但是 Docker 和传统虚拟化方式 有所不同 …

玩转视频剪辑全攻略:批量添加上自定义封面的技巧

在进行视频编辑的过程中,我们经常需要为视频添加引人入胜的封面,以吸引观众的注意力。以下是一份详细的全攻略,指导你如何批量添加自定义的视频封面。 首先,你需要在浏览器中搜索并下载“固乔智剪软件”,这是一款功能强…

精通Linux系列第三章:文件系统管理与权限设置(含目录结构思维导图)

文章目录 一、前言二、文件系统概述2.1 文件系统的定义2.2 常见的Linux文件系统2.3 查看当前Linux系统所使用的文件系统2.4 怎么使用特定的文件系统2.5 文件系统的层次结构 三、文件和目录管理3.1 文件和目录的基本概念3.2 创建文件和目录3.3 查看文件和目录信息3.4 复制、移动…

codeforces (C++ Simple Design)

题目&#xff1a; 翻译&#xff1a; 思路&#xff1a; 1、难点在于读题&#xff0c;输入两个数x&#xff0c;k&#xff0c;从x开始递增寻找最小可整除k的数。 代码&#xff1a; #include<iostream> using namespace std; int main() {int x, k;int n;cin >> n;…

使用 OpenGL 渲染会旋转 会变色的三角形(LearnOpenGL P3)

文章目录 前言代码 前言 本文参考文献&#xff0c;侵删&#xff01;LearnOpenGL - 你好&#xff0c;三角形 本文将假设您完成了 OpenGL 的配置&#xff0c;并且使用 VAO、VBO 渲染图形 由于时间问题&#xff0c;代码的详细讲解将在几日内给出~ 代码 #include <glad/glad…

UML类图中各箭头表示总结

UML类图中各箭头表示总结 1、泛化2、实现3、依赖4、关联5、聚合6、组合 在UML类图中&#xff0c;箭头关系是用来表示类之间的关系的。箭头关系的种类有以下几种&#xff1a; 1、泛化 泛化&#xff1a;表示类之间的继承关系。箭头从子类指向父类。箭头&#xff1a;实线空心三角…

【计算机网络】UDP/TCP协议

文章目录 :peach:1 UDP协议:peach:1.1 :apple:UDP协议端格式:apple:1.2 :apple:UDP的特点:apple:1.3 :apple:UDP的缓冲区:apple:1.4 :apple:UDP使用注意事项:apple:1.5 :apple:基于UDP的应用层协议:apple: 2 :peach:TCP协议:peach:2.1 :apple:TCP协议端格式:apple:2.2 :apple:确…

《windows核心编程》第3章 内核对象

一、内核对象简介 1.1 内核对象有哪些 令牌对象 token、事件对象 Event、文件对象 File、文件映射对象 Mapping_File、线程对象 Thread、时钟对象 Timer、线程池对象 ThreadPool、I/O完成端口对象 Completion port、工作对象 job、邮槽对象 mailslot、互斥对象 Mutex、管道对…

Hook原理--逆向开发

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

LeetCode刷题---有效的括号

这里用到了栈的思想 栈(stack)是限定仅在表尾进行插入或者删除的线性表。对于栈来说&#xff0c;表尾端称为栈顶&#xff08;top&#xff09;&#xff0c;表头端称为栈低&#xff08;bottom&#xff09;。不含元素的空表称为空栈。因为栈限定在表尾进行插入或者删除&#xff0c…

生成包含10个随机字母或数字的字符串,然后统计每个字符的出现次数

from random import choices from string import ascii_letters, digitsx .join(choices(ascii_lettersdigits, k10)) d dict() # 创建空字典 for ch in x:d[ch] d.get(ch, 0) 1 # x中有ch字符,个数1,并作为字典的值 print(x) print(d)也可以使用collections模块的defaul…

从车窗升降一探 Android 车机的重要 API:车辆属性 CarProperty

前言 前面我们介绍过 Android 车机 Automotive OS 的几块重要内容&#xff1a; 一文了解 Android 车机如何处理中控的旋钮输入从实体按键看 Android 车机的自定义事件机制深度入门 Android 车机核心 CarService 的构成和链路 本篇文章我们聚焦 Android 车机上最重要、最常用…

LeetCode--180 连续出现的数字

文章目录 1 题目描述2 结果示例3 解题思路3.1 MySQL 代码 4 知识拓展 1 题目描述 Logs表: ---------------------- | Column Name | Type | ---------------------- | id | int | | num | varchar | ----------------------在 SQL 中&#xff0c;id …

Mybatis的SqlRunner执行流程

Mybatis的SqlRunner执行流程 SqlRunner exec new SqlRunner(connection); Map<String, Object> row exec.selectOne("SELECT * FROM PRODUCT WHERE PRODUCTID ?", "FI-SW-01");connection.close();assertEquals("FI-SW-01", row.ge…