您的位置:首页 > 运维架构 > Linux

linux开发工具--Makefile(1) 简单的Makefile规则和Makefile自动变量

2016-04-29 18:41 531 查看
make通过makefile文件来完成并自动维护编译工作,makefile描述了整个工程的编译、连接规则。

Makefile基本规则:

TARGET…: DEPENDENCIES …

COMAND

TARGET(目标): 程序产生的文件,如可执行文件和目标文件;目标也可以指要执行的动作,如clean,也称为伪目标,可以有多个目标或者一个目标,一般只有一个目标。

DEPENDENCIES(依赖):用来产生目标的输入文件列表,一般一个目标依赖多个文件,。

COMMAND(命令):是make要执行的动作(命令是shell命令或者是可以在shell下执行的程序),注意,每个命令行前面必须有一个TAB字符!

如果DEPENDENCIES中有一个或者多个文件更新的话,COMMAND就要执行,这是Makefile最核心的内容

//创建测试文件
touch main.c add.c add.h sub.c sub.h
//一个简单的例子
//Makefile
main:main.o sub.o add.o #main是目标文件(TARGET),是要生成的文件,main.o sub.o add.o
#是依赖文件(DEPENDENCIES),如果make发现依赖文件列表中的依赖不存在,就会先执行后面的命令,来生成相应的依赖文件.
gcc -Wall main.o sub.o add.o -o main#这一句是COMMAND,用来生成TARGET
sub.o:sub.c sub.h
gcc -Wall -c sub.c -o sub.o
add.o:add.c add.h
gcc -Wall -c add.c -o add.o
main.o:main.c add.h sub.h
gcc -Wall -c main.c -o main.o
clean:
rm -f *.o main


是一条基本的规则和命令

随后直接执行make,就可以



执行make clean:



简单的Makefile就可以完成了

伪目标: 上面的Makefile文件中 clean是一个伪目标,最好在Makefile文件前面加上 .PHONY: clean

.PHONY:clean
main:main.o sub.o add.o
gcc -Wall main.o sub.o add.o -o main
sub.o:sub.c sub.h
gcc -Wall -c sub.c -o sub.o
add.o:add.c add.h
gcc -Wall -c add.c -o add.o
main.o:main.c add.h sub.h
gcc -Wall -c main.c -o main.o
clean:
rm -f *.o main


为什么我们需要加上.PHONY:clean 显式指定clean是一个伪目标呢?

1)我们不显式指定伪目标,并在当前文件夹下创建一个clean文件,并且执行make clean

目录下的文件:



Makefile文件:



.PHONY:clean 已经注释:

执行make clean可看到一下结果



这是因为文件夹中有一个clean文件,make认为clean没有修改过,所以出错,加上.PHONY:clean之后,这个问题就可以解决



现在Makefile基本上可以工作了,但是可以发现,Makefile文件中有好几处是重复的,我们是否可以将重复的部分定义成一个变量呢?答案是可以的!

Makefile自动化变量:



$@:规则的目标文件名,比如说,以上的Makefile文件中



这是一条规则,main.o是这条规则的目标文件名,他可以用 $@来表示,即可以表示成:



这样在命令中,main.o 就被$@代替了

$<:规则的第一个依赖文件名,即依赖文件列中中第一个依赖文件,如:



上面一条命令中,依赖文件列表时 main.c add.h sub.h,那么main.c就是依赖文件列表中第一个文件

$< 可以表示main.c。这样命令可以被表示成:



$^表示所有的依赖文件:

现在来定义一个变量:

.PHONY:clean
OBJECT=main.o sub.o add.o
main:$(OBJECT)
gcc -Wall main.o sub.o add.o -o main
sub.o:sub.c sub.h
gcc -Wall -c sub.c -o sub.o
add.o:add.c add.h
gcc -Wall -c add.c -o add.o
main.o:main.c add.h sub.h
gcc -Wall -c main.c -o main.o
clean:
rm -f *.o main


上面的Makefile文件中,我们定义了一个变量OBJECT, OBJECT代表了 main.o sub.o add.o这个文件列表

在$()表示引用变量 $(OBJECT) 应用了定义的文件列表,$^表示目标文件列表,这时候我们可以用他来替换main.o sub.o add.o,所以替换之后为:

.PHONY:clean
OBJECT=main.o sub.o add.o
main:$(OBJECT)
gcc -Wall $^ -o main
sub.o:sub.c sub.h
gcc -Wall -c sub.c -o sub.o
add.o:add.c add.h
gcc -Wall -c add.c -o add.o
main.o:main.c add.h sub.h
gcc -Wall -c main.c -o main.o
clean:
rm -f *.o main


最后,我们用$@ $^ $< 替换Makefile文件中各部分,替换之后为

.PHONY:clean
OBJECT=main.o sub.o add.o
main:$(OBJECT)
gcc -Wall $^ -o $@
sub.o:sub.c sub.h
gcc -Wall -c $< -o $@
add.o:add.c add.h
gcc -Wall -c $< -o $@
main.o:main.c add.h sub.h
gcc -Wall -c $< -o $@
clean:
rm -f $(OBJECT) main


这样替换就完成了,相比于开始的,就显得更加专业一些了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: