百分比与星号(星号)makefile 先决条件之间有什么区别

百分比与星号(星号)makefile 先决条件之间有什么区别

我试图理解为什么有些 Makefile 具有先决条件%.txt,而其他 Makefile 则具有*.txt.

我已经创建了这个文件夹布局。

$ tree .
.
├── hi1.txt
├── hi2.txt
├── hi3.txt
└── Makefile

首先,我尝试了这个。

foo.txt: *.txt
    echo $^

它达到了我的预期。

$ make
echo hi1.txt hi2.txt hi3.txt
hi1.txt hi2.txt hi3.txt

但是,后来我看到一些 Makefile 用作%.txt通配符。所以我接下来尝试了。

foo.txt: %.txt
    echo $^

但是,这会导致错误。

$ make
make: *** No rule to make target '%.txt', needed by 'foo.txt'.  Stop.

有人可以解释为什么会发生这种情况吗?

GNU Make 4.3

答案1

在 中make,百分号用于模式匹配,它需要目标中的 1 以及(至少)先决条件中的 1:

%.o: %.c
        $(CC) $(CFLAGS) -c -o $@ $<

通过这个 makefile,我们指定为了构建文件名以 结尾的文件.o,您需要有一个具有相同前缀的文件,但以 结尾.c而不是.o

为了能够构建这些规则,您显然需要能够参考目标和先决条件;这就是$@$<变量的用武之地。$@表示“此规则的目标”,并且$<表示“此规则的第一个列出的先决条件”。如果您需要构建一个使用的命令全部先决条件(例如,链接可执行文件),那么您可以使用变量$^

%: %.o lib.o
        $(CC) $(LDFLAGS) -o $@ $^

如果您将上述两个示例 makefile 片段合并到一个 makefile 中,并且您有一个文件“lib.c”,其中包含一些您想要在同一目录中的多个 C 程序中使用的通用代码,那么您可以添加任何随机.c文件,比如说foo.c,并将其编译成一个程序foo,该程序也链接到 中的代码lib.c,而不需要对 makefile 进行任何更改。

请注意,只要先决条件不同,也可以具有具有相同目标的模式;例如,以下内容将起作用:

%.o: %.c
        $(CC).....
%.o: %.cpp
        $(CXX).....

也就是说,只要此目录中没有任何与 C 源文件同名(无扩展名)的 C++ 源文件,它就会按预期工作。如果确实是这种情况,C++ 版本将被忽略,而 C 源代码将被编译(因为 C 规则在 makefile 中首先列出)

欲了解更多信息,请参阅相关部分在 GNU make 手册中。

相关内容