自学make(1)
make
自动确定需要重新编译大型程序的哪些部分,并发出命令以重新编译它们。
1
要使用make
必须编写一个名为makefile的文件.
每次修改源文件时, 直接使用shell命令make
进行编译. 它会执行所有必要的编译。
make
根据文件的最后修改时间来决定需要更新哪些文件.
注: makefile告诉make
如何编译和链接程序.
2
基本格式:
target … : prerequisites …
recipe
…
…
-
target
程序生成的文件的名称, 也可以是要执行的操作的名称,例如"clean" -
prerequisites
用作创建目标的文件. 一个目标往往依赖于多个文件. -
recipe
具体实现的操作.
target->目标
prerequisites->先决条件
recipe->配方
每个recipe开头都需要放一个制表符(Tab).
为target指定recipe不需要具备prerequisites. 例如: 'clean'.
3
示例:
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
所有C文件都包含defs.h, 但只有那些定义编辑命令的包含command.h, 只有改变编辑器缓冲区的包含buffer.h.
使用反斜杠/换行, 将较长的一行切分为两行.
默认情况下,make
从第一个目标开始.
4
使用变量消除风险并简化makefile.
标准做法是每个makefile都有一个名为objects, OBJECTS, objs, OBJS, obj或OBJ的变量, 它是所有目标文件名的列表。
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
通过写 ‘$(objects)’来替换变量的值.
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)
5
没有必要编写用于编译单个C源文件的规则, 因为make可以解决它们: 它有一个隐含的规则, 可以自动进行处理. 例如: 使用‘cc -c main.c -o main.o’将main.c编译为main.o.
当以这种方式自动编译‘.c’文件时, 它也会自动添加到先决条件列表中. (前提是省略了配方)
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)
6
当makefile的对象仅由隐式规则创建时, 可以使用另一种makefile风格. 可以按条件而不是目标进行分组.
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
defs.h是所有目标文件的先决条件; command.h和buffer.h是为它们列出的特定目标文件的先决条件。
7
进行清理的make规则:
clean:
rm edit $(objects)
在实践中, 用更复杂的方式编写规则来处理意外情况:
.PHONY : clean
clean :
-rm edit $(objects)
这可以防止make被一个名为clean的实际文件弄糊涂, 并使其在rm出现错误的情况下继续运行。