程序的编译和链接原理分析

记录下学习《跟我一起写makefile》这本书时整理的笔记。

一、原理说明

UNIX 下是 .o 文件,即 Object File,这个动作叫做编译(compile)。然后再把大量Object File 合成执行文件,这个动作叫作链接(link)。

一般来说,每个源文件都应该对应于一个中间目标文件(O 文件或是 OBJ 文件)。链接时,主要是链接函数和全局变量,所以,我们可以使用这些中间目标文件(O 文件或是OBJ文件)来链接我们的应用程序。链接器并不管函数所在的源文件,只管函数的中间目标文件(Object File)。

我们要给中间目标文件打个包,在 Windows 下这种包叫“库文件”(Library File),也就是.lib 文件,在 UNIX下,是 Archive File,也就是 .a 文件。

总结一下,源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。在编译时,编译器只检测程序语法,和函数、变量是否被声明。如果函数未被声明,编译器会给出一个警告,但可以生成 Object File。而在链接程序时,链接器会在所有的 Object File 中找寻函数的实现,如果找不到,那到就会报链接错误码(Linker Error),意思说是说,链接器未能找到函数的实现。你需要指定函数的Object File。

二、简单的编译链接流程实例

  1. 产生可执行文件a.out,中间产生main.o的目标文件,但在链接成功后删除。
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# gcc main.c 
a.out  hello.c  main.c
  1. -c 参数意味着只编译(compile) 产生main.o目标文件
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# gcc -c main.c 
main.o  hello.c  main.c
  1. 链接文件,默认为a.out
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# gcc main.o
a.out
  1. -o name 使链接器保存可执行文件为指定文件中,name为指定文件名。
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# gcc -o main.o
gcc: fatal error: no input files
compilation terminated.
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# gcc main.o -o run
hello.c  main.c  main.o  Makefile  run
  1. 可以结合起来使用
gcc main.c -o run

编译main.c并链接生成可执行文件run,并将中间产生的目标文件main.o删除。

三、目标文件打包与链接

使用ar命令将目标文件打包,不过一般这个动作都是在makefile中实现。
链接静态库参数说明,-L 表示静态库路径,-lmy 即链接libmy.a文件

root@chenwr-pc:/home/workspace/my_workspace/study/makefile# cat main.c 
#include <stdio.h>
void main()
{
	printf("Im a super man\n");
	hello();
	test();
}
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# ar rcs libmy.a test.o hello.o
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# gcc main.c -L . -lmy -o run
root@chenwr-pc:/home/workspace/my_workspace/study/makefile# ./run
Im a super man
hello world
test

参考资料:

linux ar 命令的使用说明和实例讲解_linux shell_脚本之家
https://www.jb51.net/article/95627.htm

gcc 链接文件 - NeverWA的博客 - CSDN博客
https://blog.csdn.net/NeverWA/article/details/79948049

猜你喜欢

转载自blog.csdn.net/chenwr2018/article/details/88073870