5.2.4 Makefile中指定依赖关系的编译
仍以第4章的程序文件为例,本节介绍另外的一种形式的Makefile,在这个Makefile中指定了各个目标的依赖关系。该文件如下所示:
CC := gcc HEAD := getarg.h writeinfo.h SRC := getarg.c writeinfo.o main.c OBJS := getarg.o writeinfo.o main.o TT := test INC = . CFLAGS = -pipe -g -Wall -I$(INC) LDFLAGS = -Wall -g all:$(TT)
$(TT):$(OBJS) @echo "+++++++ Build Standalone Programe : $@ +++++++" $(CC) $(LDFLAGS) $(OBJS) -o $@
main.o:main.c getarg.h writeinfo.h $(CC) $(CFLAGS) -c $< -o $@ getarg.o:getarg.c getarg.h $(CC) $(CFLAGS) -c $< -o $@ writeinfo.o:writeinfo.c writeinfo.h $(CC) $(CFLAGS) -c $< -o $@
.PHONY : clean clean: @echo "------- clean ------" rm -f *.o rm -f $(TT) |
在这个Makefile文件中没有使用默认的规则,而是对每一个目标文件实现单独的规则和依赖的文件。
在Makefile文件所在目录下执行make命令:
执行的结果如下所示:
gcc -pipe -g -Wall -I. -c getarg.c -o getarg.o gcc -pipe -g -Wall -I. -c writeinfo.c -o writeinfo.o gcc -pipe -g -Wall -I. -c main.c -o main.o +++++++ Build Standalone Programe : test +++++++ gcc -Wall -g getarg.o writeinfo.o main.o -o test
|
上面执行的结果依然是先编译生成目标文件,然后连接生成可执行程序。实际上,这个执行过程依次执行了getarg.o,writeinfo.o,main.o和test的规则。
在目标生成之后,如果再次使用make命令,将显示以下的内容:
$ make make: Nothing to be done for 'all'.
|
此时由于目标依赖的文件均没有更改,因此没有什么需要做的。更新main.c文件,继续执行make命令:
结果如下所示:
gcc -pipe -g -Wall -I. -c main.c -o main.o +++++++ Build Standalone Programe : test +++++++ gcc -Wall -g getarg.o writeinfo.o main.o -o test
|
在执行的过程中,可以发现先后执行了main.o和test目标中的规则。这是由于main.o目标依赖于main.c文件,因此main.c更新后,这个目标就需要重新生成。getarg.o和writeinfo.o目标的规则是不需要执行的,因为它们依赖的文件没有更新。
下面对getarg.h文件进行更新,然后重新生成,命令如下:
执行结果如下所示:
gcc -pipe -g -Wall -I. -c getarg.c -o getarg.o gcc -pipe -g -Wall -I. -c main.c -o main.o +++++++ Build Standalone Programe : test +++++++ gcc -Wall -g getarg.o writeinfo.o main.o -o test |
在这次执行的过程中,由于getarg.o和main.o目标都依赖getarg.h文件,因此,两个目标的规则都需要重新执行。
执行清除命令clean:
执行的结果如下所示:
------- clean ------ rm -f *.o rm -f test |
这里make工具执行的是clean伪目标,删除了目标文件和可执行程序。
知识点:make和Makefile工程管理工具,可以使用隐含规则进行编译,也可以由Makefile编写者制定自己特定的编译规则。