规则格式
Makefile 目标规则的一般语法形式
target [target...] : [dependent ....]
[ command ...]
括号内的参数是可选的,省略号表示一个或多个。命令列表中的每条命令必须以TAB键开始,不能使用空格!
下面给出一个简单的例子,您可以定义一个规则,使得 make
可以通过其他三个文件来达成目标 hello:
hello: main.o factorial.o hello.o
$(CC) main.o factorial.o hello.o -o hello
注:在这个例子中,你必须给出其他的规则来达成 main.o、factorial.o、hello.o 这三个目标。
如果任何命令返回失败状态,则 make
过程终止。这也是为什么需要常备这种规则:
clean:
-rm *.o *~ core paper
make
会输出宏替换之后的命令,来向你展示正在执行的情况。有时你可能想关闭它。使用@表示不打印。
install:
@echo You must be root to install
在 Makefiles 中有些约定俗成的目标,每次碰到 Makefile 你都可以先查看一下其中有没有。这些约定的目标分别是:all(直接 make 调用的入口目标),install 和 clean。
- make all - (或者直接运行 make) 期望是:编译所有内容,以便在安装应用程序之前进行本地测试。
- make install - 这个目标通常期望为在适当的地方安装应用程序。但要注意事物安装在适合您系统的地方。
- make clean - 清理应用程序,摆脱可执行文件,任何临时文件,目标文件等。
Make的执行过程如下:
- make命令会在当前目录下查找以 Makefile(makefile其实也可以 )命名的文件。
- 当找到 Makefile文件以后就会按照 Makefile中定义的规则去编译生成最终的目标文件。
- 当发现目标文件不存在,或者目标所依赖的文件比目标文件新 (也就是最后修改时间比目标文件晚 )的话就会执行后面的命令来更新目标。
隐藏规则
该规则是隐含的,因为没有提到特定的目标。它可以用于所有情况。.cpp: $(CC) $(CFLAGS) $@.cpp $(LDFLAGS) -o $@
另一个常见的隐含规则是用 .cpp(源文件)构建 .o(对象)文件。
.cpp.o:
$(CC) $(CFLAGS) -c $<
#或者
.cpp.o:
$(CC) $(CFLAGS) -c $*.cpp
自定义隐藏规则
就其本身而言,make
为了创建 .o文件,它必须在相应的 .c 文件上使用 cc -c。这些规则是内置的,你可以利用他们的特点来缩短你的 Makefile。如果只在 Makefile 的依赖行中指出当前目标所依赖的.h文件,甚至不需要包含编译器的命令。
这进一步减少了 Makefile,如图所示:
OBJECTS = main.o hello.o factorial.o
hello: $(OBJECTS)
cc $(OBJECTS) -o hello
hellp.o: functions.h
main.o: functions.h
factorial.o: functions.h
make
使用名为 .SUFFIXES 的特殊目标来允许您定义自己的后缀。例如:
.SUFFIXES: .foo.bar
make
将使用这些特殊的后缀来制定你自己的规则。
与make
如何从 .c 文件创建 .o 文件类似,您可以按以下方式定义规则:
.foo.bar:
tr '[A-Z][a-z]' '[N-Z][A-M][n-z][a-m]' < $< > $@
.c.o:
$(CC) $(CFLAGS) -c $<
- 第一条规则允许你从 .foo 文件创建一个 .bar 文件。(它基本上是对文件进行加密)
- 第二个规则是从 .c 文件创建 .o 文件时
make
使用的默认规则。
伪目标
使用伪目标主要是为了避免 Makefile中定义的执行命令的目标和工作目录下的实际文件出现名字冲突,有时候我们需要编写一个规则用来执行一些命令,但是这个规则不是用来创建文件的。
例如,将clean设置为伪目标,这样即使当前目录下存在名为clean的文件,也不会导致冲突。make clean依然会调用清理命令:
objects = main.o input.o calcu.o
main: $(objects)
gcc -o main $(objects)
.PHONY : clean #设置伪目标
%.o : %.c
gcc -c $<
clean:
rm *.o
rm main