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

425*_*esp 5 make gnu-make

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

\n

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

\n
$ tree .\n.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 hi1.txt\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 hi2.txt\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 hi3.txt\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 Makefile\n
Run Code Online (Sandbox Code Playgroud)\n

首先,我尝试了这个。

\n
foo.txt: *.txt\n    echo $^\n
Run Code Online (Sandbox Code Playgroud)\n

它达到了我的预期。

\n
$ make\necho hi1.txt hi2.txt hi3.txt\nhi1.txt hi2.txt hi3.txt\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
foo.txt: %.txt\n    echo $^\n
Run Code Online (Sandbox Code Playgroud)\n

但是,这会导致错误。

\n
$ make\nmake: *** No rule to make target '%.txt', needed by 'foo.txt'.  Stop.\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

GNU Make 4.3

\n

Wou*_*lst 6

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

%.o: %.c
        $(CC) $(CFLAGS) -c -o $@ $<
Run Code Online (Sandbox Code Playgroud)

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

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

%: %.o lib.o
        $(CC) $(LDFLAGS) -o $@ $^
Run Code Online (Sandbox Code Playgroud)

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

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

%.o: %.c
        $(CC).....
%.o: %.cpp
        $(CXX).....
Run Code Online (Sandbox Code Playgroud)

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

有关详细信息,请参阅GNU make 手册中的相关部分。