以前我们写代码的时候,都不是什么大项目,一共也没俩个文件,也就没有必要用makefile来解决。
但是当项目一旦大起来之后,一个一个编译来文件已经不现实。所以makefile就应运而生了。
makefile其实就是一个脚本文件,它可以按照我们设定的目标文件和关联性文件,来自动编译项目中的文件。
下面简单介绍一下makefile的语法规则:
基本语句就是下面这一句:
目标列表:关联性列表
<tab>命令列表
举个例子:
hello.c
#include "fun1.h"
#include "fun2.h"
int main()
{
printf("hello world\n");
fun1();
fun2();
return 0;
}
fun1.c
#include "fun1.h"
void fun1()
{
printf("i am fun1\n");
}
fun1.h
#include <stdio.h>
void fun1();
fun2.c
#include "fun2.h"
void fun2()
{
printf("i am fun2\n");
}
fun2.h
#include <stdio.h>
void fun2();
*makefile
CC:=gcc
OBJECT:=hello.o
OBJECT+=fun1.o fun2.o
SOURCES:=hello.c fun1.c fun2.c
HEDERS:=fun1.h fun2.h
hello:$(OBJECT)
$(CC) $(OBJECT) -o hello -lm
hello.o:
fun1.o:
fun2.o:
hello.tar:Makefile $(HEADERS) $(SOURCES)
tar -cvf $@ $^
clean:
rm *.o
下面来解释一下这个makefile文件:
CC:=gcc
OBJECT:=hello.o
OBJECT+=fun1.o fun2.o
SOURCES:=hello.c fun1.c fun2.chello:$(OBJECT)
HEDERS:=fun1.h fun2.h
这几行语句为赋值语句,使makefile更易于移植和修改。
hello:$(OBJECT)
$(CC) $(OBJECT) -o hello -lm
在这个语句中,hello为最后生成的可执行文件。$(OBJECT)就是引用OBJECT变量,$(CC)也是一样的。
原来的语句就是hello:hello.o fun1.o fun2.o
hello为目标文件,hello.o fun1.o fun2.o为关联性列表,意思是要生成hello这个文件需要hello.o fun1.o fun2.o这三个文件。
$(CC) $(OBJECT) -o hello -lm这个其实就是gcc hello.o fun1.o fun2.o -o hello -lm
下面还需要 hello.o fun1.o fun2.o这三个文件
hello.o:
fun1.o:
fun2.o:
这三条语句原来应该是
hello.o:hello.c fun1.h fun2.h
fun1.o:fun1.c fun1.h
fun2.o:fun2.c fun2.h
执行makefile文件时会去查看目录里面有没有hello.o fun1.o fun2.o这三个文件,没有的话就执行上面三个语句来生成三个.o文件。
hello.tar:Makefile $(HEADERS) $(SOURCES)
tar -cvf $@ $^
clean:
rm *.o
hello.tar,clean这俩个为虚目标:即他不会生成这俩个文件,但是他会执行下面的语句。在make'命令后加上hello.tar或clean即可。
hello.tar:Makefile $(HEADERS) $(SOURCES)
tar -cvf $@ $^就是将所有的文件打包
clean:
rm *.o就是删除所有的.o文件。
$@ $^这俩个是内置变量,$@表示引用前面的目标文件列表,$^表示引用前面的依赖文件列表。
有关其它的内置变量可以自己去搜索。
makefile可以很高效的管理自己的项目,它会检索每个文件的时间戳,如果没有更改的就不需要编译,更改就编译。
运行时只要在makefile的目录下输入make就行