日期:2014-05-16  浏览次数:20688 次

Linux中的make和makefile

1.1      多源文件问题

我们平常编写一些小的程序一般都是修改源代码后,重新编译所有的源文件,但是对于大型的项目,这种方法就会有许多的问题。edit?compile?test周期耗费的时间比较长,所以当只修改一个文件时,要避免编译所有的源文件。

     假设有头文件a.h, b.h , c.h和C的源文件main.c, 2.c , 3.c。它们的关系如下:

/* main.c */

#include "a.h"

...

/* 2.c */

#include "a.h"

#include "b.h"

...

/* 3.c */

#include "b.h"

#include "c.h"

 

如果c.h修改了,源文件main.c和2.c应该不需要重新编译,因为它们不依赖c.h头文件。而源文件3.c依赖头文件c.h需要重新编译。如果b.h修改了,我们忘记重新编译2.c也会导致程序功能异常。 而make工具可以解决上面这两个问题。

1.2      make命令和makefiles

   make命令有一些内置的默认功能,但是光有这个它自己还是不知道怎么build程序。我们必须提供一个文件告诉make应用程序的构造,这个文件就是makefile.

Make和makefile提供了强大的功能来管理项目的编译以及发布install到指定文件夹。

1.2.1 makefiles语法

一个makefile文件包括一系列的依赖(dependency))关系和规则(rules)。一个依赖有一个目标文件和一系列目标文件依赖的源文件。规则描述了怎么用依赖文件创建目标文件。通常,一个目标文件是单个可执行文件。Make命令通过读取makefile来决定哪些源文件和目标文件需要重新编译,根据比较它们的日期和时间来决定使用来个规则来构建targets。

 

1.2.2 make的选项与参数

下面为make 命令经常用到的三个选项:

   -k:告诉make当发生错误时继续执行,而不是停在第一个错误的位置。

   -n:告诉make打印出它将要完成什么,实际上没做。

   ?f <filename>,告诉make用哪个makefile,如果不使用这个选项,make将搜索当前目录下第一个名为makefile的文件,如果还不存在,搜索一个文件名为Makefile。

 

 依赖:指明了每个文件怎么样关联源文件。

makefile文件中,写依赖的方法为:目标文件名,冒号,空格或tabs,然后接着是用空格或 tab分开的文件列表,用于创建目标文件。

 依赖的例子:

myapp: main.o 2.o 3.o

main.o: main.c a.h

2.o: 2.c a.h b.h

3.o: 3.c b.h c.h

解释:myapp依赖 main.o, 2.o 3.o, main.o依赖 main.c a.h,以此类推。

从上面可以很清楚的看到,当b.h改变了,我们需要修改2.o3.o,当2.o3.o改变了,需要重新编译myapp.

 当需要编译多个文件,可以使用目标文件名all.假设应用程序包含一个二进制文件myapp和一个用户指导页面myapp.1,可以使用下面的方式指定。

all:  myapp  myapp.1

规则:makefile的第二部分内容。告诉我们将如何创建目标文件。

make命令决定2.o需要重新编译,使用什么命令进行编译呢?也许最简单的方式是使用gcc –c 2.c(make命令也有许多默认的规则),但是如果需要包含头文件的目录以及为调试设置符号信息怎么办呢?可以在makefile当中使用显示的规则。