mkafile学习
前言
C到二进制文件
- 编译为目标文件
- 链接为可执行文件
When recompiles the editor, each changed C source file must be recompiled. If a header file has changed, each C source file that includes the header file must be recompiled to be safe. When recompiles the editor, each changed C source file must be recompiled. If a header file has changed, each C source file that includes the header file must be recompiled to be safe.
Makefile入门
简单的一条规则
target … : prerequisites …
recipe
…
…
target含义
- 程序生成文件的名称
- 执行动作
prerequisites含义
先决条件(依赖):生成target的输入文件,通常有多个
recipe含义
执行的动作,每一行前需要一个tab,否则会出错
长的一行可使用"\"分成两行
样例
edit : main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
使用
make
即可生成名称为edit
的可执行文件
使用
make clean
清除所有目标文件
clean没有依赖,也不是任何obj的依赖,属于伪目标,make默认不会执行它,除非指明使用它
Make命令执行Makefile的步骤
Make读取当前目录中的makefile,并从处理第一条规则开始。在本例中,此规则用于重新链接编辑;但是在make完全处理此规则之前,它必须处理edit所依赖的文件的规则,在本例中,这些文件是目标文件。每个文件都根据自己的规则进行处理。这些规则说要更新每一个。O '文件通过编译其源文件。如果源文件或任何命名为先决条件的头文件比目标文件更新,或者如果目标文件不存在,则必须重新编译。
对于没有依赖到的文件,对其规则不操作,除非像make clean一样特别指定
把edit文件的依赖都处理完后,类似地,make会查看是否需要重新链接
变量的使用
上面的例子极不优雅,每次新添加文件,都需要再改动makefile,文件会非常长,并且很容易出现纰漏,使用变量(类似于C语言的宏)来提高makefile的健壮性。
标准做法是使用一个类似于objs
变量来表示目标文件的列表
改进样例
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit $(objects)#'$'表示对变量的引用
隐含规则
对于.o
文件的更新,make默认使用cc -o xx.c -o xx.o
,所以以上makefile文件中的recipe部分可以省略,让make自己推理,而这样使用时,逻辑上,xx.c
自然就是xx.o
的依赖,所以prequesites中也可以省略,故最终文件可以简化为
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : defs.h
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer.h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils.o : defs.h
.PHONY : clean
clean :
rm edit $(objects)
另一种风格(不太建议)
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
$(objects) : defs.h
kbd.o command.o files.o : command.h
display.o insert.o search.o files.o : buffer.h
伪目标的声明
.PHONY : clean
clean :
-rm edit $(objects)
放止大型工程中与clean文件混淆