GNU makefile入门

来源:互联网 发布:云计算项目实施方案 编辑:程序博客网 时间:2024/06/06 09:35

最近在学makefile,顺便写点学习体会,兴许后来的某一天我忘了,回来翻翻博客还能找点思路。

本文仅基于GCC讲解,至于其他编译器暂时不会涉及,如果没听过啥是GCC就不要往下看了。

简单介绍一下makefile是个什么东东,makefile是一个编译和链接规则的集合,主要的作用是告诉make,怎么去调用gcc或g++编译源文件,然后怎么去链接目标文件。

当前的大部分IDE,在用户单击编译按钮后,都会生成一个makefile,然后在后台去调用编译器和链接器生成可执行程序。

开始的时候先简单介绍一下程序的生命周期,源码到可执行程序,一般需要经过四个过程,


上图截取自《深入理解计算机系统》,图中说明了,一个程序要从源文件变为一个可执行的机器文件,需要至少四个步骤(python之类的语言还有一个解释过程)。

举个简单的栗子,我们要在屏幕上面打印一句“hello world!”,除去编辑的过程,源文件先要经过预处理得到*.i文件,然后经过编译得到*.s文件,在经过汇编得到.o文件,最后链接成为可执行文件。


预处理是预处理器将*.c文件的宏展开,然后直接将宏替换,去除注释,得到纯asicii文件;

编译是指将*.i文件转换为汇编语句的过程;

汇编是将汇编文件转换为机器语言,也就是0101的计算机可识别的文件;

链接是将汇编后的目标文件链接为可执行的二进制文件。


值得注意的是预处理器被集成到编译器上面了,但是调用gcc的时候仍然会生成*.i文件,命令为

gcc -E hello.c -o hello.i

有了上面的基本了解,接下来贴一段makefile的内容

#sample Makefilehello : main.o key.o command.o display.o     cc -o hello main.o kbd.o command.o display.o main.o : main.c globle.h    cc -c main.ckey.o : key.c globle.h command.h    cc -c key.ccommand.o : command.c globle.h command.h    cc -c command.cdisplay.o : display.c globle.h display.h    cc -c display.cclean :rm hello main.o key.o command.o display.o 

一个简单的makefile的规则如下,

目标:依赖规则

命令

目标:可以是一个*.o文件,也可以是可执行文件,也可以是一个可执行的命令,这个命令又称为伪目标。

依赖规则:执行目标需要的文件列表,如果是命令的话,这个可以省略。

命令:需要执行的动作,可以是shell命令,也可以是可执行程序。

上文中的hello是终极目标,在一个makefile的第一个目标就是这个make的最终目的,下面的所有规则都是为了完成终极目标的一些规则,或者说前提条件。

我们可以这样来解读,为了得到可执行文件hello,需要当前存在main.o key.o command.o display.o 这几个文件作为前提条件,而为了得到这几个文件,我需要执行以下的规则。

make执行的时候有一个默认条件,只编译当前有变更的文件,也就是说,如果main的修改时间没有变化,那么不会执行。

cc -c main.c
别的文件一样,而如果某一个文件是多个目标文件的依赖规则,那么涉及到这个文件的所有命令都会执行,比如command.h有变更,那么

cc -c command.ccc -c display.c
都会被执行。


当然,只要有任意文件编译过,hello都会重新链接。


说说最后一个规则

clean :rm edit main.o key.o command.o display.o 
这个是伪命令,在输入make的时候,不会执行这句话,除非给make一个参数clean,也就是输入

make clean
这句话才会被执行。

这句话其实有个小问题,当我们的磁盘下有这个clean的同名文件的时候,会造成这个规则无法执行,而且会返回一些奇怪的错误,所以,这个规则得加点修饰。

.PTONY:cleanclean :-rm edit main.o key.o command.o display.o 

以上是我一天的学习成果,如果有错,请扶正。


写在后面的话。

IDE,虽然帮我们完成了很多事情,但是也隐藏了很多东西,而我不甘被蒙蔽,总想着搞事情( •̀ ω •́ )y。


写于2017年5月24日 

深圳 夜