【Linux】gcc编译器的使用(程序的翻译过程)
创始人
2024-05-10 09:24:38
0

目  录

  • 1 程序的翻译
    • 1.1预处理(进行宏替换)
    • 1.2 编译(生成汇编代码)
    • 1.3 汇编(生成机器可识别代码)
    • 1.4 链接(生成可执行文件或者库文件)
    • 1.5 gcc常用选项总结


程序的翻译过程包括:预处理、编译、汇编、链接四个部分,接下来文章中将讨论在Linux下如何使用gcc编译器完成程序的翻译。

1 程序的翻译

gcc使用命令格式:gcc [选项] 要编译的文件 [选项] 生成的目标文件

以下以 test.c 文件作为示例讨论程序翻译过程,其中源代码如下图所示:

test.c


1.1预处理(进行宏替换)

  • 预处理功能主要包括宏定义,文件包含,条件编译,去注释等。
  • 预处理指令是以 # 号开头的代码行。
  • 使用gcc完成预处理过程: gcc -E test.c -o test.i
    其中选项 -E 的作用是让gcc在预处理结束后停止编译过程;选项 -o 是指生成目标文件(注意:-o 选项后面必须紧跟目标文件);.i 文件是经过预处理后的C原始程序,如下图所示,源程序中的注释经过预处理后被删去了,main函数中的N也被替换为了100,还有条件编译也被处理了,此外,还可以看到,除了被处理后的原代码部分,前面还有八百多行代码是头文件等展开后的结果。

test.i


1.2 编译(生成汇编代码)

  • 编译过程包括词法分析、语法分析、语义分析等。在这个过程中,gcc首先要检查代码的规范性、是否有语法错误等,以确定代码实际要做的工作,在检查无误后,gcc把代码翻译成汇编语言程序。
  • 使用gcc完成编译过程:gcc -S test.i -o test.s
    其中 -S 的作用是让gcc在编译结束后停止翻译过程,.s 文件是编译后生成的汇编语言程序(如下图所示)。

test.s


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

  • 汇编阶段就是把编译阶段生成的 .s 文件转成目标文件。
  • 使用gcc完成汇编过程:gcc -c test.s -o test.o
    其中 -c 的作用是让gcc在汇编结束后停止翻译过程,.o 文件是汇编后生成的可重定位目标二进制代码(相当于windows下程序翻译后形成的 .obj 文件)。如下图所示,这里只是把我们自己编写的代码翻译成了二进制文件,即使将文件权限修改为可执行后,这个二进制文件仍是不可被执行的,还需经过链接过程形成完整的可执行程序。
    test.o

1.4 链接(生成可执行文件或者库文件)

  • 使用gcc完成链接过程:gcc test.o -o test

链接过程具体做了什么呢?这里需要先了解一个概念:函数库

  • 我们在编写程序时,常常会用到 printf 等库函数,但事实上,在预编译中包含的头文件 stdio.h 中也只是有函数的声明,而没有函数的定义(实现),那 printf 又是在哪里实现的?我们的程序又是如何成功使用函数的呢?
    其实,系统把这些函数实现都写在名为 libc.so.6 的库文件中了,在没有特别指定时,gcc会到系统默认的搜索路径 /usr/lib 下查找,也就是链接到 libc.so.6 库函数中去,如此就能实现对应的库函数了,而这也是链接的作用。
  • 我们之所以能够在Linux下进行C、C++等代码的编写和编译是因为Linux系统默认已经携带了语言级别的头文件和语言对应库,而编译器能够自动帮我们识别解释这些语言,并根据相应的库完成程序的编译链接以形成可执行程序。

函数库一般分为静态库和动态库(共享库)两种,对应的链接也分为静态链接和动态链接

  • 库本质上也是一种文件,Linux下静态库通常以 libXXX.a 的形式命名,动态库通常以 libXXX.so 的形式命名;Windows下静态库通常以 .lib 为后缀,动态库通常以 .dll 为后缀。
  • 静态链接是指在编译链接时,把静态库中我们所需要的代码全部拷贝添加到最终的可执行文件中,因此生成的文件比较大(会比较占用空间),但同时静态链接完成后程序在运行时也就不需要再依赖任何库,自己就可以运行了。
  • 与静态链接不同,动态链接在程序编译链接时并没有把库文件中的代码拷贝添加到可执行文件中,而是将动态库文件中我们所需要的代码的地址拷贝添加到可执行文件中的相关位置,程序运行时则通过地址链接库文件找到相应的代码。如此,所有有需要的程序共享方法,而方法的真正实现永远只在库中,可有效节省系统的开销。但如果相关动态库缺失,对应的程序也将无法执行。

那我们要如何知道我们的可执行程序是静态链接形成的还是动态链接形成的呢?这里首先要了解一个命令:ldd 可执行文件 ,通过该命令可以查看对应可执行文件所依赖的动态库。
以下通过示例来进一步了解程序的链接:

动态链接

  • 需要注意的是:Linux下默认使用的是动态链接和动态库。

那如何实现静态链接呢?

这里使用的是云服务器,一般云服务器默认只有动态库,如果要实现静态链接,还需安装静态库,否则会报错。我们可以通过命令:
yum install glibc-static libstdc++-static -y 来安装静态库。接着通过命令:gcc test.o -o test-static -static 实现静态链接(这里为了区分动态链接形成的可执行文件,将静态链接形成的可执行文件命名位 test-static。命令中选项 -static 表示使用静态链接和静态库)。如下图所示,可以看到静态链接形成的可执行文件的大小约有动态链接形成的可执行文件的大小的100倍,可见静态链接消耗的空间之大。

静态链接


总结: 以上为了更加详细的了解程序翻译的过程,所以分四步完成程序的翻译,在实际中,如果没有特殊需要,(以test.c文件的翻译为例)可直接使用命令 gcc test.c -o test 完成程序的编译及动态链接,使用命令 gcc test.c -o test -static 完成程序的编译及静态链接,其中如果不加选项 -o test 生成指定的目标文件,则会默认生成名为 a.out 的可执行文件。 如下图所示,无论是动态链接形成的可执行程序还是静态链接形成的可执行程序,又或是默认形成的可执行程序,最终的运行结果都是一样的。


链接


1.5 gcc常用选项总结

  • -E :只激活预处理,不生成文件,需要将执行结果重定向到一个输出文件中,否则默认将预处理结果输出到屏幕。
  • -S :编译到形成汇编语言代码就停止,不进行汇编和链接。
  • -c :编译到形成二进制目标代码。
  • -o :输出指定目标文件。
  • -static :对生成的二进制文件采用静态链接。
  • -g :生成调试信息(Debug版可执行程序)。GUN调试器可利用该信息。
  • -shared :尽量使用动态库,形成的可执行文件比较小,但前提需要系统有动态库。
  • -O0-O1-O2-O3 :编译器的优化选项的4个级别,-O0 表示没有优化,-O1 为缺省值,-O3 优化级别最高。
  • -w :不生成任何警告信息。
  • -Wall :生成所有警告信息。

以上是我对Linux中gcc编译器使用的一些学习记录总结,如有错误,希望大家帮忙指正,也欢迎大家给予建议和讨论,谢谢!

相关内容

热门资讯

findx耍原生安卓系统,深度... 亲爱的读者们,你是否厌倦了那些花里胡哨的定制系统,渴望回到那个纯净的安卓世界?今天,我要带你一起探索...
一加系统属于安卓系统吗,引领智... 你有没有想过,手机里的那个神奇的“一加系统”到底是不是安卓系统的一员呢?这可是个让人好奇不已的问题哦...
小米2刷安卓系统吗,探索安卓系... 亲爱的读者,你是否曾经对小米2这款手机刷安卓系统的事情感到好奇呢?今天,就让我带你一探究竟,揭开小米...
安卓7.0系统线刷包,深度解析... 你有没有发现,你的安卓手机最近有点儿“蔫儿”了?别急,别急,今天就来给你揭秘如何让你的安卓手机重焕生...
白菜系统和安卓拍照,开启智能生... 你知道吗?最近我在用手机拍照的时候,发现了一个超级酷的功能,简直让我爱不释手!那就是——白菜系统和安...
安卓系统查杀病毒,全方位守护您... 手机里的安卓系统是不是有时候会突然弹出一个查杀病毒的提示?别慌,这可不是什么大问题,今天就来给你详细...
iso系统与安卓各系统哪个好,... 你有没有想过,手机操作系统就像是我们生活中的不同交通工具,各有各的特色和优势。今天,咱们就来聊聊这个...
中柏怎么换安卓系统,解锁更多可... 你有没有发现,中柏的安卓系统有时候用起来还挺不顺手的?别急,今天就来手把手教你如何给中柏手机升级安卓...
安卓热点绕过系统验证,揭秘操作... 你是不是也遇到过这种情况?手机里的安卓热点突然不灵光了,系统验证总是跳出来,让人头疼不已。别急,今天...
安卓系统怎么关闭小艺,安卓系统... 亲爱的安卓用户们,你是否也和我一样,对手机里的小艺助手有些爱恨交加呢?有时候,它贴心得让人感动,有时...
安卓系统计划软件推荐,精选计划... 你有没有发现,手机里的安卓系统越来越智能了?这不,最近我可是挖到了一些超棒的安卓计划软件,它们不仅能...
收钱吧安卓系统插件,便捷支付新... 你有没有发现,现在的生活越来越离不开手机了?手机里装满了各种应用,而今天我要跟你聊聊一个特别实用的工...
鸿蒙系统是否还属于安卓,独立于... 你有没有想过,那个在我们手机上默默无闻的鸿蒙系统,它到底是不是安卓的“亲戚”呢?这个问题,估计不少手...
安卓系统手机用什么钱包,轻松管... 你有没有想过,你的安卓系统手机里装了那么多应用,但最离不开的,可能就是那个小小的钱包了。没错,就是那...
安卓系统能玩部落冲突吗,部落冲... 你有没有想过,安卓系统上的手机,是不是也能玩那款风靡全球的《部落冲突》呢?这款游戏自从推出以来,就吸...
智能机器人安卓系统,引领未来智... 你知道吗?在科技飞速发展的今天,智能机器人已经不再是科幻电影里的专属了。它们正悄悄地走进我们的生活,...
华为win10系统改装安卓系统... 你有没有想过,你的华为笔记本电脑里的Windows 10系统,能不能来个华丽变身,变成安卓系统呢?这...
旧电脑上安什么安卓系统,适配不... 你那台旧电脑是不是已经闲置好久了?别让它默默无闻地躺在角落里,给它来个华丽变身吧!今天,就让我来告诉...
安卓app语言跟随系统,随系统... 你知道吗?在手机世界里,有一个神奇的小功能,它就像你的贴身翻译官,无论你走到哪里,都能帮你轻松应对各...
惠城安卓系统降级在哪,揭秘降级... 你有没有遇到过手机系统升级后,发现新系统让你头疼不已,想回到那个熟悉的安卓系统呢?别急,今天就来告诉...