目录
%
%是通配符。https://www.quora.com/What-does-o-cpp-in-a-Makefile-mean是这样描述%的作用的:
for every target X.o, if there exists a file named X.cpp, do the following
对于任何一个.o文件,假如存在同名的.cpp文件,做如下操作。
注意,不是根据任何一个cpp文件来找.o文件。makefile的工作流程是从最终的产物(可执行文件或so文件等)开始,寻找“上一级”产生它们的文件,直到最顶端的源代码。:
可执行文件->.o文件->cpp文件/h文件。
正因为这样,makefile才会根据.o文件查找同名.cpp文件,而不是反过来。
示例
看下面的示例:
头文件fun.h
int fun();
main.cpp
#include <stdio.h>
#include "fun.h"
int main(void)
{
int i = fun();
printf("i = %d\n", i);
return 0;
}
fun.cpp
#include "fun.h"
int fun(){
return 9;
}
makefile
CC=gcc
%.o: %.cpp
$(CC) -c -o $@ $<
main: main.o fun.o
$(CC) -o main main.o fun.o
make之后打印了三行语句:
gcc -c -o main.o main.cpp
gcc -c -o fun.o fun.cpp
gcc -o main main.o fun.o
前两句是由makefile的%.o: %.cpp gcc -c -o $@ $< 规则展开 。对号入座就能看出,第一次使用%.o时,main字符串代入%。第二次代入使用fun字符串代入%。
$@与$<
将上面的打印结果与%.o: %.cpp gcc -c -o $@ $< 规则对号入座,不难看出,$@对应%.o;而$<对应%.cpp
https://unix.stackexchange.com/questions/116547/what-do-and-in-a-makefile-mean#:~:text=From%20make%20manpage%3A,rule's%20recipe%20to%20be%20run.解释了$@和$<的意义:
$@是目标的名字(目标就是冒号":"左边的文件名)。假如冒号左边有不止一个目标,那么$@等于触发当前规则的那个目标。
$<是第一个依赖项(依赖项就是冒号":"右边的文件名)。
再看下面关于$@的例子
这个例子说明,当冒号“:”左边有多个目标时,$@一次只会对应一个目标。
另外,all:a.o b.o这句不能省略。省略的话,makefile只会按照生成a.o的规则执行一次。
$^
上面的例子可以进一步抽象,将makefile改写为如下:
CC=gcc
%.o: %.cpp
$(CC) -c -o $@ $<
main: main.o fun.o
$(CC) -o $@ $^
注意最后一行。$@取代了main,因为$@就代表main。$^取代了main.o fun.o。因为$^的作用就是代替冒号":"右边的所有依赖项(prerequisites)