编译和链接

1.什么是编译和链接?

在用IDE写程序的时候,都会用到build构建程序,其实构建就包含了两个步骤,编译和链接。
在这里插入图片描述

1.1 编译

何为编译?编译就是将程序的源代码翻译成CPU能直接运行的机器代码。
在这里插入图片描述
比如在源文件main.c中,调用了函数add,而add函数定义在另一个源文件add.c中,就能调用gcc-c来分别编译这两个源文件
gcc -c main.c
gcc -c math.c
编译后会产生两个目标文件.o文件,这两个目标文件是二进制文件,文件格式为ELF(Executable and Linkable Format),是Linux下所有可执行程序的通用格式。
在这里插入图片描述
用命令readelf -h main.o在文件头部找可执行文件的基本信息。
在这里插入图片描述
用readelf -s main.o查看里面的区块(sections),包括机器代码,程序数据等,其中.text是代码区,包含了之前编译好的机器代码,.data是数据区,保存了初始化的全局变量,局部静态变量等
在这里插入图片描述

1.2链接

在这里,因为add函数包含在math.c文件中,所以main.o不能直接运行,标准库中的printf在头文件stdio.h中也是一句声明,并没有定义,因此编译器在编译的时候只能将这两个函数的跳转地址设为0,在链接的时候再修正。
用命令objdumo -s -d main.o查看目标文件中的内容,main是编译后的主函数代码,左边是机器代码,右边是对应的反汇编,两个call指令分别对应调用的printf()和add()函数,左边的机器代码中对应的跳转地址都设为0(00 00 00 00)。

在这里插入图片描述
需要用命令gcc main.o math.o -o main来将两个目标文件链接,链接过程中会将跳转地址修正。
即链接就是将编译后的所有目标文件,连同用到的静态库,运行时库,组合拼装成一个独立的可执行文件,包含地址修正。在地址修正的时候,链接器会根据目标文件或者静态库中的重定位表,找到需要被重定位的函数和全局变量来修正他们的地址。完成链接。

2.makefile

makefile是一种构建工具,类似VS里的build。

在这里插入图片描述
有了makefile,就能直接用make命令去构建可执行文件,make后面跟目标名称main,makefile就会根据依赖树去递归地构建可执行文件,先根据目标找依赖,再从下面的目标找依赖,若main比main.o,math.o新,则执行make时不会重新生成main,若main没有后两者新,则执行下方的gcc main.o math.o -o main命令生成。(makefile的核心是对依赖的管理)
在这里 main:main.o math.o 是一条规则,是指待生成的main这个可执行程序依赖于main.o与math.o,规则之下是命令。
main:main.o math.o
gcc main.o math.o -o main
main.o:main.c #main.o依赖于main.c
gcc -c main.c
math.o:math.c #math.o依赖于math.c
gcc -c math.c
clean:
rm main main.o math.o
在这里插入图片描述
补充:
1.编译程序时去哪里找头文件呢?
答:①系统目录:即交叉编译工具链里的某个include目录
②自己指定:编译时用“-I dir”选项指定。
1.1怎么确定“系统目录”呢?
执行下面的命令去确定目录

echo 'main(){}'| arm-buildroot-linux-gnueabihf-gcc -E -v -

它会列出头文件目录、库目录(LIBRARY_PATH),我们可以把自己写的头文件或库文件放进用这条命令找出来的目录中。

2.链接时去哪找库文件?
答:①系统目录:即交叉编译工具链里的某个lib目录
②自己指定:链接时用“-L dir”选项指定。
在编译出库文件后,可以把它放入系统库目录中。

3.运行时去哪找库文件?
答:①系统目录:板子上的/lib、/usr/lib目录;
②自己指定:运行时用环境变量LD_LIBRARY_PATH指定;
运行时找不到库:
在这里插入图片描述
库在哪?
在系统目录上:
1.板子上的/lib、/usr/lib目录
2.自己指定。
运行时用环境变量LD_LIBRARY_PATH指定,执行以下命令:

exprot LD_LIBRARY_PATH=/xxx_dir ; ./test

LD_LIBRARY_PATH=/xxx_dir  ./test

4.运行时不用头文件,故头文件不用放到板子上。

参考视频:
https://www.bilibili.com/video/BV1TN4y1375q?share_source=copy_web

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值