【Linux】 gcc 、动态库和静态库,程序是如何链接的
创始人
2024-05-10 19:51:49
0

文章目录

  • 前言
  • 一、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默认使用的是动态链接和动态库!如果进行大型项目开发,其文件非常巨大,如果使用静态库,其所消耗空间资源比动态库要多上接近一百倍,所以使用动态库更好一些。


相关内容

热门资讯

安卓系统的手机优缺点,全面解析... 你有没有发现,现在市面上手机种类繁多,让人挑花了眼?其中,安卓系统的手机可是占据了半壁江山呢!今天,...
平板有没有安卓系统,安卓系统引... 你有没有想过,平板电脑到底有没有安卓系统呢?这个问题听起来可能有点奇怪,但确实很多人在选购平板时都会...
安卓手机双系统好用不,安卓手机... 你有没有想过,你的安卓手机是不是也能像多面手一样,既能驾驭工作,又能享受娱乐呢?没错,说的就是那个神...
安卓系统怎么登录国际服,一键操... 你有没有想过,为什么有时候你的安卓手机上会出现那些国际服的游戏呢?是不是好奇怎么登录这些神秘的国外服...
安卓系统的时间天气没了,天气功... 最近你的安卓手机是不是也遇到了一个让人头疼的小问题?那就是——时间天气不见了!没错,就是那个曾经陪伴...
安卓好用的拍照系统,捕捉美好瞬... 你有没有发现,现在手机拍照功能越来越强大了?尤其是安卓手机,拍照系统简直让人爱不释手!今天,就让我带...
软件如何兼容安卓8系统,助您软... 你有没有发现,随着科技的飞速发展,手机软件更新换代的速度也是越来越快呢!这不,安卓8系统已经悄然来临...
安卓通用版系统下载,畅享智能生... 你有没有发现,最近手机界又掀起了一股热潮?没错,就是安卓通用版系统下载!这可是个让无数安卓用户兴奋不...
安卓无线点餐系统ph,PH技术... 你有没有想过,点餐也能变得如此轻松愉快?没错,就是那个我们每天都要面对的吃饭问题,现在有了安卓无线点...
安卓门禁系统怎么样,便捷通行新... 你有没有想过,每天回家时,只需轻轻一刷,门就自动打开了?这就是安卓门禁系统的魅力所在!今天,就让我带...
在电脑上模拟安卓系统,探索虚拟... 你有没有想过,在电脑上也能体验安卓系统的乐趣呢?没错,就是那种随时随地都能玩手机的感觉,现在也能在电...
飞机送餐安卓系统,空中美食新体... 你有没有想过,飞机上的美食是如何送到你手中的?是不是觉得这背后有着神秘的力量?其实,这一切都离不开高...
findx耍原生安卓系统,深度... 亲爱的读者们,你是否厌倦了那些花里胡哨的定制系统,渴望回到那个纯净的安卓世界?今天,我要带你一起探索...
一加系统属于安卓系统吗,引领智... 你有没有想过,手机里的那个神奇的“一加系统”到底是不是安卓系统的一员呢?这可是个让人好奇不已的问题哦...
小米2刷安卓系统吗,探索安卓系... 亲爱的读者,你是否曾经对小米2这款手机刷安卓系统的事情感到好奇呢?今天,就让我带你一探究竟,揭开小米...
安卓7.0系统线刷包,深度解析... 你有没有发现,你的安卓手机最近有点儿“蔫儿”了?别急,别急,今天就来给你揭秘如何让你的安卓手机重焕生...
白菜系统和安卓拍照,开启智能生... 你知道吗?最近我在用手机拍照的时候,发现了一个超级酷的功能,简直让我爱不释手!那就是——白菜系统和安...
安卓系统查杀病毒,全方位守护您... 手机里的安卓系统是不是有时候会突然弹出一个查杀病毒的提示?别慌,这可不是什么大问题,今天就来给你详细...
iso系统与安卓各系统哪个好,... 你有没有想过,手机操作系统就像是我们生活中的不同交通工具,各有各的特色和优势。今天,咱们就来聊聊这个...
中柏怎么换安卓系统,解锁更多可... 你有没有发现,中柏的安卓系统有时候用起来还挺不顺手的?别急,今天就来手把手教你如何给中柏手机升级安卓...