【Linux】 gcc 、动态库和静态库,程序是如何链接的

news2024/11/24 3:47:30

文章目录

  • 前言
  • 一、gcc 是什么?
  • 二、使用步骤
    • 1.预编译
    • 2.编译
    • 3.汇编
    • 4.链接
  • 三、动静态库
    • 1.概念
    • 2.区别


前言

  在Linux环境下,除了学好编辑器 vim 的使用,还需要学会C语言的编译器 gcc 的功能,否则代码无法翻译成可执行程序。本文将介绍 gcc 的常规使用方法,以及一个C语言程序,在链接的时候发生了什么。


提示:以下是本篇文章正文内容

一、gcc 是什么?

  GCC原名为GNU C语言编译器(GNU C Compiler),只能处理C语言。但其很快扩展,变得可处理C++,后来又扩展为能够支持更多编程语言,如Java、Go等等。其作用就是,将一个C语言文件,执行翻译的过程,从 .c 文件变成 .exe 文件,这样就可以执行( .c 文件只存放代码,相当于记事本)。可以看这篇文章,了解翻译的过程:你知道.c文件是如何变成.exe文件的吗。

  翻译过程可以大致分为:预编译、编译、汇编、链接。在链接期间,涉及到链接器的一些小知识,本文也会讲解。


二、使用步骤

1.预编译

  在 Linux 中输入指令如下,其作用主要包括:宏定义,文件包含,条件编译,去注释等

gcc -E test.c -o test.i

  • 选项“-E”,该选项的作用是让 gcc 在预编译结束后停止翻译过程。
  • 选项“-o”是指目标文件(所以它后面跟的是想要生成的文件名), “.i” 文件为已经过预处理的C原始程序。

  如下图:
请添加图片描述

2.编译

  在 Linux 中输入指令如下,在这个阶段中:gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言

gcc -S test.i -o test.s

  • 选项“-S”,该选项只进行编译而不进行汇编,生成汇编代码

  如下图:
请添加图片描述

3.汇编

  在 Linux 中输入指令如下,其作用是:把编译阶段生成的“.s”文件转成目标文件

gcc -c test.s -o test.o

  • 选项“-c”,该选项将汇编代码已转化为“.o”的二进制目标代码。

  如下图:
请添加图片描述

4.链接

  在 Linux 中输入指令如下,其作用是:合并符号表、合并段表等等

gcc test.o -o test

  如下图,可以很明显地看到,生成了一个可执行文件test。

请添加图片描述
  当然了,上面只是为了理解翻译过程,但是其实可以一步到位生成可执行文件,那就是 gcc test.c -o test 可以将 test.c 文件生成 可执行文件 test。 当然,最简单的做法是 gcc test.c 但是这样无法控制生成的文件名,其默认目标文件名是 a.out 。


三、动静态库

1.概念

  在上文内容其实涉及到一个重要概念:函数库。
  库分为两种:静态库和动态库。其命名规则是:前缀+文件名+后缀。如下图,静态库后缀是.a ,动态库后缀是 .so,其前缀都是 lib 。

静态库:libXXXXX.a
动态库:libXXXXX.so

  我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实现“printf”函数的呢?
  实际上是:Linux系统把这些函数实现都被做到名为 libc.so.6 (Linux默认使用动态库)的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用。

2.区别

  我们先看到动态库:他是专门让编译器,对用户的程序进行动态链接的。
  动态链接:链接的时候,找到动态库,拷贝动态库中的我所需要的代码的地址到我自己的可执行程序中相关的位置。
  动态链接成功:我们的程序,还是依赖动态库,一旦动态库缺失,我们的程序便无法运行!
  我们根据上面使用 gcc 的示例文件test,如下,先执行 ldd test,查看其依赖库,是 libc.so.6 此时就可以看出是依赖动态库了;再执行 file test,查看其信息可得,确实Linux 默认使用动态库。
在这里插入图片描述


  静态库是专门让编译器,对用户的程序进行静态链接的。
  静态链接:链接的时候,找到静态库,拷贝静态库中的我所需要的代码到我自己的可执行程序中。
  静态链接成功:我们的程序,不依赖任何库,自己就可以独立运行
  如下,我们使用静态链接的方法生成 test-static 文件,从两个箭头指向的地方,可以明显看出,test-static 比 test 大了百倍,其仅仅是一个打印 Hello World 的程序生成,区别如此之大。再用 ldd 指令查看,不是动态的,file 指令查看详细信息,静态链接。(注意,编译此程序需要用到libc库文件,而系统中无法找到libc的静态库文件,需要下载安装:sudo yum install -y glibc-static)
在这里插入图片描述

  根据以上内容,可以得出结论:

静态库:因为自身拷贝的问题,比较浪费空间。
动态库:因为可以做到被大家共享方法,所以真正的实现永远都是在库中,程序内部只有地址,比较节省空间。

   Linux默认使用的是动态链接和动态库!如果进行大型项目开发,其文件非常巨大,如果使用静态库,其所消耗空间资源比动态库要多上接近一百倍,所以使用动态库更好一些。


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

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

相关文章

怎样快速地迁移 MySQL 中的数据?

我们通常会遇到这样的一个场景,就是需要将一个数据库的数据迁移到一个性能更加强悍的数据库服务器上。这个时候需要我们做的就是快速迁移数据库的数据。那么,如何才能快速地迁移数据库中的数据呢?今天我们就来聊一聊这个话题。数据库的数据迁…

Spring Boot 日志详解

Spring Boot 日志一、日志有什么用二、日志怎么用三、自定义日志打印3.1 在程序中得到日志对象3.2 使用日志对象打印日志四、日志级别4.1 日志级别有什么用4.2 日志级别的分类与使用4.3 日志级别设置五、日志持久化5.1 配置文件名5.2 配置保存路径六、更简单的日志输出 -- lomb…

Go第 13 章 :2-客户信息关系系统

Go第 13 章 :2-客户信息关系系统 13.1 项目需求分析 模拟实现基于文本界面的《客户信息管理软件》。该软件能够实现对客户对象的插入、修改和删除(用切片实现),并能够打印客户明细表 13.2 项目的界面设计 主菜单界面 添加客户…

SegFormer笔记(1)安装

一、代码地址github地址:https://github.com/NVlabs/SegFormer二、我的系统配置:1、硬件2、软件win10,vs2022,python3.7三、创建虚拟环境conda create -n MySegFormer python3.7 numpy conda activate MySegFormer python会显示如…

【知识图谱工具汇总】

一,图表示学习与计算框架 1)PyTorch Geometric(PyG) 由德国多特蒙德工业大学研究者推出的基于PyTorch的几何深度学习扩展库。PyG在学术中是比较热门的框架,但是PyG对于异构图以及大规模的图的学习存在着较大的局限性…

【UE4 第一人称射击游戏】39-“M4A1”武器设置

上一篇:【UE4 第一人称射击游戏】38-拾取“M4A1”的提示信息步骤:在“AK47”文件夹中拷贝一份“Weapon_Base”拷贝到“M4A1”文件夹下,重命名为“Weapon_M4A1”打开“Weapon_M4A1”,新添加一个网格体组件骨架网格体选择“M4A1_wea…

Linux编辑器-gcc/g++使用

目录 背景: 预处理: 编译: 汇编: 连接: 静态连接: 动态连接: 自动化编程make/makefile: 背景: 我们知道任何一个c语言或者c文件想要生成一个可执行程序必须完成4个…

NotepadAttr

EntityMyPKAttr目录概述需求:设计思路实现思路分析1.Notepads2.EntityMyPK3.EntityMyPKAttr4.EntitiesMyPK5.EntityMyPKEntityMyPKAttrEntitiesMyPKWebContralBaseAtParaCashChartType参考资料和推荐阅读Survive by day and develop by night. talk for import biz …

JS面试题--JS函数式编程

JS函数式编程 实现apply、call、bind 01_call函数的实现 // apply/call/bind的用法 // js模拟它们的实现? 难度// 给所有的函数添加一个hycall的方法 同个原型链 Function.prototype.hycall function (thisArg, ...args) {// 在这里可以去执行调用的那个函数(foo)// 问题: …

亚马逊云科技:“云”筹帷幄,打造数据驱动型企业

数据对提高企业生产和资源配置的效率、优化经济结构的作用日益凸显。工业和信息化部发布的《“十四五”大数据产业发展规划》已明确将数据作为新时代重要的生产要素和国家基础性战略资源。埃森哲研究显示,到2022年,90%的企业战略明确将把数据作为关键的企…

前端面试题回顾——React重要知识

文章目录React相关问题1. 函数式组件与Class组件有什么不同?2. 说说React的fiber架构?3. 协调4. 虚拟DOM (Virtual DOM)React相关问题 1. 函数式组件与Class组件有什么不同? 答: ① 函数式组件不需要继承,直接 “fun…

数据结构基础——认识数据结构与算法

目录 🍔什么是数据结构? 🌭1.数据的逻辑结构 🌭NUM 1 : 集合 🌭NUM 2 : 线性结构 🌭NUM 2 : 树形结构 🌭NUM 4 :图结构(网状结构)…

浅谈反弹shell

目录反弹shell总结一、文件描述符二、重定向1、输入重定向2、输出重定向3、错误输出重定向4、exec 绑定重定向三、实现反弹shell的几种方式方法一: find 反弹ubuntu find反弹shell失败的问题任务计划反弹shell失败的问题方法二:使用python反弹&#xff0…

Flink系列-4、Flink运行架构

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 大数据系列文章目录 官方网址:https://flink.apache.org/ 学习资料:https://flink-learning.org.cn/ 目录Flink基石Fli…

刚当上leader,我让组员去开会,他非说有更重要的会

☆ 职场上经常有那么一种情况就是组长喊组员开会,开周会,开晨会,开各种会,而更有一种常见的情况呢就是组长缺失威严,喊组员开会,组员不听话,说有更重要的会议,不想参加。 ☆ 本文将以…

VIT学习心得

来源:投稿 作者:橡皮 编辑:学姐 小声逼逼 在过去的两年里,Vision Transformer(ViT)是计算机视觉(cv)领域最有影响力的工作之一。「它推翻了2012年在Alex net中提出的CNN在CV领域的统治地位: 当能够获得足够多的预训练…

无接触式磁旋转编码器AS5040介绍

无接触式磁旋转编码器AS5040简介AS5040 是一款无接触式磁旋转编码器,用于精确测量整个360内的角度。此产品是一个片上系统,在单个封装内整合了集成式Hall 元件、模拟前端和数据信号处理功能。测量角度时,只需简单地配备1 个在芯片中心上方旋转…

Spring5的全细节回顾总结

概述: https://cntofu.com/book/95/33-what-new-in-the-spring-framework.md 这个不错。 轻量级javaee框架。 针对于bean的生命周期进行管理。 解决企业应用开发的复杂性。 核心: ​ IOC:控制反转,把创建对象的过程交给sprin…

第一天 Blender操作 | 大帅老猿threejs特训【超详细】

前言 这一天主要是基础理论的学习。 本人学习资料仓库 https://gitee.com/zhang_dezheng_hsr/three-demo.git YCY-TrainingCamp-S2: 在原有的文件上添加本人的学习记录 第一天 Blender操作 | 大帅老猿threejs特训【超详细】【我在掘金的同名文章】 一、大纲 二、THREE 基础概…

Linux查看某个应用的CPU/内存/网卡使用情况

1.查看CPU的使用率 # ps -ef | grep zabbix 进程号是1715 # top -p 1715 可以看到CPU的使用率是0 , 内存的使用率是0 2.查看内存真实使用了多少 #cat /proc/[pid]/status #cat /proc/1715/status VmPeak:进程所使用的虚拟内存的峰值 VmSize: 进程当前使用…