在Makefile中也#开始的行都是注释行.Makefile中最重要的是描述文件的依赖关系的说明。一般的格式是:
target:components
TAB rule
第一行表示的是依赖关系。第二行是规则。
比如说我们上面的那个Makefile文件的第二行。
main:main.omytool1.o mytool2.o
表示我们的目标(target)main的依赖对象(components)是main.o mytool1.omytool2.o 当倚赖的对象在目标修改后修改的话,就要去执行规则一行所指定的命令。就象我们的上面那个Makefile第三行所说的一样要执行 gcc-o main main.omytool1.o mytool2.o 注意规则一行中的TAB表示那里是一个TAB键
Makefile有三个非常有用的变量。分别是$@,$^,$<代表的意义分别是:
$@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件。
如果我们使用上面三个变量,那么我们可以简化我们的Makefile文件为:
# 这是简化后的Makefile
main:main.omytool1.o mytool2.o
gcc -o $@ $^
一个例子:
这个makefile有六个源文件和六个头文件分别是:
func1.c
head1.h
上面的c源文件分别会用到其下的头文件各个文件的内容分别是:
func1.c 文件
#include "head.h"
#include "head1.h"
void f1()
{
}
func2.c 文件
#include "head.h"
#include "head2.h"
void f2()
{
}
func3.c 文件
#include "head.h"
#include "head3.h"
void f3()
{
}
func4.c 文件
#include "head.h"
#include "head4.h"
void f4()
{
}
func5.c 文件
#include "head.h"
#include "head5.h"
void f5()
{
}
main.c 文件
#include "head.h"
extern void f1();
extern void f2();
extern void f3();
extern void f4();
extern void f5();
int main()
{
}
以上是这个工程的的所有源文件及其代码
head1.h 头文件
struct student1
{
};
head2.h 头文件
struct student2
{
};
head3.h 头文件
struct student3
{
};
head1.h 头文件
struct student3
{
};
head4.h 头文件
struct student4
{
};
head51.h 头文件
struct student5
{
};
head.h 头文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
以上是头文件的内容
以上文件都准备好后就要开始写makefile文件了
Makefile 文件的可以这么写:
exefile: main.o func1.o func2.o func3.o func4.ofunc5.o
main.o:main.c head.h
func1.o:func1.c head.h head1.h
func2.o:func2.c head.h head2.h
func3.o:func3.c head.h head3.h
func4.o:func4.c head.h head4.h
func5.o:func5.c head.h head5.h
clean:
在这个makefile中 蓝色的就是目标文件 或 可执行文件 目标文件时那些 *.o文件, 可执行文件就是exefile 文件,它是最终可以执行的文件。依赖文件就是那些*.c
每一个*.o 文件都有一组依赖文件,*.o 文件就是靠这些依赖文件生成。而生成的这些*.o文件又都是 exefile 可执行文件的依赖文件,他们生成 exefile 可执行文件。依赖关系 其实就是 说明了 目标文件是由哪些文件生成的,换言之,就是目标文件是由哪些文件更新的。
定义好依赖关系下一行就是make执行的命令,这个命令定义了操作系统如何生成这些目标文件的。命令行开始一定要以tab键开头。其执行过程就是make会比较 target 文件 和 prerequisites 文件 的修改日期,如果prerequisites 文件的日期比target文件的日期要新,或者target 不存在的话,make就会执行后续定义的命令。
讲解:
exefile: main.o func1.o func2.o func3.ofunc4.o func5.o
exefile 依赖main.o func1.o func2.o func3.o func4.o func5.o这些*.o文件,也即是说exefile 就是开这些文件生成的。一开始这些*.o文件是不存在的,那么make就会往下执行语句,而暂时先不执行gcc -o main main.ofunc1.o func2.o func3.o func4.o func5.o 这句命令。
main.o:main.c head.h
main.o 依赖main.c head.h这两个文件 执行其命令生成 main.o目标文件,指着往下执行。。。
func1.o:func1.c head.h head1.h
同 main.o 的执行。。。
func2.o:func2.c head.h head2.h
同 main.o 的执行。。。
func3.o:func3.c head.h head3.h
同 main.o 的执行。。。
func4.o:func4.c head.h head4.h
同 main.o 的执行。。。
func5.o:func5.c head.h head5.h
同 main.o 的执行。。。
当这些 *.o文件都别生成了后 make 就会执行 第一个依赖和第一个 依赖之后的命令
exefile: main.o func1.o func2.o func3.ofunc4.o func5.o
最终生成 exefile 之可行文件。
clean:
clean
Make 后执行结果:
[yanggentao@wkp mfile]$ make clean
rm -f *.o exefile
[yanggentao@wkp mfile]$ make
gcc -c main.c
gcc -c func1.c
gcc -c func2.c
gcc -c func3.c
gcc -c func4.c
gcc -c func5.c
gcc -o main main.o func1.o func2.o func3.ofunc4.o func5.o
[yanggentao@wkp mfile]$
Make clean 后执行结果:
[yanggentao@wkp mfile]$ make clean
rm -f *.o exefile
[yanggentao@wkp mfile]$
根据makefile 的依赖规则我们还可以这样写,至于为什么这样写,我们先且不说。
exefile: main.o func1.o func2.o func3.ofunc4.o func5.o
main.o:main.c
func1.o:func1.c
func2.o:func2.c
func3.o:func3.c
func4.o:func4.c
func5.o:func5.c
clean:
这样写是把头文件都给去掉了,这样也对的,makefile的隐式规则会自动找这些在文件里包含的头文件的。