【发布时间】:2020-12-06 05:41:26
【问题描述】:
我正在使用 GNU make 并且在我的 Makefile 中有以下内容:
token_check: token_check.o $(STATIC_LIBRARIES)
$(CC) -o $@ $^
%.o: %.c pipeline/*.h compiler/*.h
$(CC) $(COMPILER_FLAGS) -I./pipeline -I./compiler -c $<
但是,当我运行make时,实际运行的命令是
cc -c -o token_check.o token_check.c
我得到了错误
token_check.c:3:10: fatal error: scanner.h: No such file or directory
3 | #include "scanner.h"
| ^~~~~~~~~~~
compilation terminated.
make: *** [<builtin>: token_check.o] Error 1
scanner.h 包含在编译器子目录中。
为什么我的-I 指令被忽略了?
编辑:
我检查了,我确实在管道和编译器中都有头文件。
真正奇怪的是,即使我将食谱替换为
%.o: %.c pipeline/*.h compiler/*.h
echo blah
然后运行
make token_check.o
它仍然会尝试编译源文件并且“blah”永远不会被打印出来。
【问题讨论】:
-
我不认为 glob 在 GNU Make 中像那样工作。你需要
$(wildcard pipeline/*.h) $(wildcard compiler/*.h)。 -
它们确实可以工作,但它们的工作方式就像 shell glob。这意味着如果没有匹配它们,则将留下纯通配符。因此,正如 Renaud 所说,如果两个通配表达式中的任何一个都不匹配任何文件,它们将保持原样。因此,如果没有与
pipeline/*.h匹配的文件,那么先决条件将是可能不存在的文字字符串pipeline/*.h,因此您的模式不匹配。如果模式不匹配,$(wildcard ...)函数将扩展为空字符串,因此它可能更适合您的情况。 -
我添加了一些额外的调试信息。