每一个编译器背后都藏着故事

本文详细探讨了GCC编译器在生成静态库.a和动态库.so文件的过程,以及如何创建可执行程序。内容涵盖了从创建源文件、编译目标文件到链接库的每一步,并对比了静态库与动态库在文件大小上的差异。同时,文章提到了GCC背后的工具如addr2line、as、ld等,以及Linux下的汇编编译器nasm的使用。此外,还介绍了如何安装和使用curses库,以及创建贪吃蛇游戏的步骤。
摘要由CSDN通过智能技术生成


编译器背后的故事

提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


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

一、用gcc生成使用静态库.a

1、创建一个目录,用于保存文件

在这里插入图片描述

2、创建所需的3个文件

在这里插入图片描述

(1)、用命令vi创建sub5.c
在这里插入图片描述
(2)、用命令vi创建sub6.c
在这里插入图片描述

(3)、用命令vi创建main.c
在这里插入图片描述

3、用gcc生成.o文件

在这里插入图片描述
用ls命令检查生成.o文件
在这里插入图片描述

4、生成.a静态库文件

(1)、用ar命令将sub5.o和sub6.o生成一个.a静态库文件
在这里插入图片描述
(2)、用ls命令检查
在这里插入图片描述

5、创建可执行程序

(1)将 main函数的目标文件与静态库文件进行链接
在这里插入图片描述
(2)、运行main.c
在这里插入图片描述

6、记录文件大小

在这里插入图片描述

二、动态库的生成和使用

1、生成.o目标文件

在这里插入图片描述

2、生成.so 动态库文件

在这里插入图片描述

3、运行main.c程序

在这里插入图片描述

4、记录文件大小

在这里插入图片描述
由此可以发现,静态库中的执行程序文件大小与动态库执行程序文件的大小差不多

三、GCC 编译器背后的故事

GCC(GNU C Compiler)是编译工具,将 C/C++语言编写的程序 转换成为处理器能够执行的二进制代码的过程即由编译器完成。

Binutils:
一组二进制程序处理工具,包括:addr2line、ar、objcopy、objdump、as、ld、
ldd、readelf、size 。
(1) addr2line:用来将程序地址转换成其所对应的程序源文件及所对应的代码
行,也可以得到所对应的函数。该工具将帮助调试器在调试的过程中定位对
应的源代码位置。
(2) as:主要用于汇编;
(3) ld:主要用于链接;
(4) ar:主要用于创建静态库;
(5) ldd:可以用于查看一个可执行程序依赖的共享库;
(6) objcopy:将一种对象文件翻译成另一种格式,譬如将.bin 转换成.elf、或
者将.elf 转换成.bin 等;
(7) objdump:主要的作用是反汇编;
(8) readelf:显示有关 ELF 文件的信息;
(9) size:列出可执行文件每个部分的尺寸和总尺寸,代码段、数据段、总大小
等;
在这里插入图片描述

四、LinuxGCC 常用命令

代码如下:

//test.c 
#include <stdio.h>
int main(void) 
{ 
printf("Hello World!\n"); 
return 0; 
}

1、编译过程

1、预处理

使用 gcc 进行预处理的命令如下:

gcc -E hello.c -o hello.i

或、

gcc -E test.c

2、编译
编译过程就是对预处理完的文件进行一系列的词法分析,语法分析,语义分析及 优化后生成相应的汇编代码。
使用 gcc 进行编译的命令如下:

gcc -S hello.i -o hello.s

3、汇编
汇编过程调用对汇编代码进行处理,生成处理器能识别的指令,保存在后缀为.o 的目标文件中。由于每一个汇编语句几乎都对应一条处理器指令,因此,汇编相 对于编译过程比较简单,通过调用 Binutils 中的汇编器 as 根据汇编指令和处理 器指令的对照表一一翻译即可。 当程序由多个源代码文件构成时,每个文件都要先完成汇编工作,生成.o 目标 文件后,才能进入下一步的链接工作。注意:目标文件已经是最终程序的某一部 分了,但是在链接之前还不能执行。
使用 gcc 进行汇编的命令如下:

gcc -c hello.s -o hello.o

4、链接
链接也分为静态链接和动态链接,其要点如下:
(1) 静态链接是指在编译阶段直接把静态库加入到可执行文件中去,这样可执行 文件会比较大。链接器将函数的代码从其所在地,拷贝到最终的可执行程序中。为创建可执行文件,链接器必须要完 成的主要任务是:符号解析和重定位。(2) 动态链接则是指链接阶段仅仅只加入一些描述信息,而程序执行时再从系统中把相应动态库加载到内存中去。
使用动态库进行链接:

gcc hello.c -o hello

多个程序文件的编译

gcc -c test1.c -o test1.o 
gcc -c test2.c -o test2.o 
gcc test1.o test2.o -o test

检错

gcc -pedantic illcode.c -o illcode

除了-pedantic 之外,GCC 还有一些其它编译选项也能够产生有用的警告信息。这些选项大多以-W 开头,其中最有价值的当数-Wall 了,使用它能够使 GCC 产生尽可能多的警告信息。

gcc -Wall illcode.c -o illcode

GCC 给出的警告信息虽然从严格意义上说不能算作错误,但却很可能成为错误的栖身之所。一个优 秀的 Linux 程序员应该尽量避免产生警告信息,使自己的代码始终保持标准、健壮的特性。所以将 警告信息当成编码错误来对待,是一种值得赞扬的行为!所以,在编译程序时带上-Werror 选项,那 么 GCC 会在所有产生警告的地方停止编译,迫使程序员对自己的代码进行修改,如下:

gcc -Werror test.c -o test

库文件连接

开发软件时,完全不使用第三方函数库的情况是比较少见的,通常来讲都需要借助许多函数库的支 持才能够完成相应的功能。
1、 编译成可执行文件
首先我们要进行编译 test.c 为目标文件,这个时候需要执行

gcc –c –I /usr/dev/mysql/include test.c –o test.o

2、 链接
最后我们把所有目标文件链接成可执行文件:

gcc –L /usr/dev/mysql/lib –lmysqlclient test.o –o test

3、 强制链接时使用静态链接库
默认情况下, GCC 在链接时优先使用动态链接库,只有当动态链接库不存在时才考虑使用静态链 接库,如果需要的话可以在编译时加上-static 选项,强制使用静态链接库。
在/usr/dev/mysql/lib 目录下有链接时所需要的库文件 libmysqlclient.so 和 libmysqlclient.a,为了让 GCC 在链接时只用到静态链接库,可以使用下面的命令:

gcc –L /usr/dev/mysql/lib –static –lmysqlclient test.o –o test

六、nasm 汇编编译器

1、安装nasm

使用命令 sudo apt-get install nasm 安装nasm

2、使用nasm编译程序

使用以下命令对程序进行编译执行:nasm -f elf64 hello.asm

3、运行hello.c

在这里插入图片描述

4、记录文件大小

在这里插入图片描述

七、以游客身份访问远古时代的 BBS

步骤:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
输入代码:telnet bbs.newsmth.net

在这里插入图片描述

八、安装curses库

1、输入代码

在这里插入图片描述

2、查看安装位置

在这里插入图片描述

九、用gcc编译生成一个贪吃蛇

(1)创建一个新的.c文件
在这里插入图片描述
(2)、代码链接:贪吃蛇代码
(3)、生成可执行文件
(4)、运行
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值