为什么“%.moc”在我的 Makefile 中不起作用?
Why the "%.moc" does not work in my Makefile?
我有以下 Makefile:
CC=g++ -std=c++17
MYCXXFLAGS=-Werror -Wall
clean:
rm -f *.o main
a.moc:
@echo "mocing $@"
%.o: %.cpp %.moc
@echo "all prerequisites $^"
$(CC) $(MYCXXFLAGS) -o $@ -c $<
在Makefile所在的同一目录下,有一个名为“a.cpp”的文件。
当我执行“make a.o”时,将打印以下内容:
mocing a.moc
all prerequisites a.cpp a.moc
g++ -std=c++17 -Werror -Wall -o a.o -c a.cpp
太完美了。 “a.moc”被识别并被执行。
但是,如果我替换
a.moc:
@echo "mocing $@"
和
%.moc:
@echo "mocing $@"
然后事情开始发生变化。仅打印以下内容:
g++ -c -o a.o a.cpp
似乎“%.moc:”的引入把一切都搞砸了。这只是一个演示示例。在我的真实环境中,“%.moc”确实执行一些 Qt 移动操作。我想知道为什么“a.moc”可以被识别为有效目标并被执行,而“%.moc”不能达到目标?
问题在于 make 有一系列内置的隐式规则。这些规则之一告诉 make 如何从 .c
文件构建 .o
文件。您添加了一条规则,告诉 make 如何从 .c
和 .moc
文件构建 .o
文件。 make如何选择使用哪一个?
测试隐式规则的顺序始终是首先检查您的规则,这就是当您有 a.moc
时它起作用的原因。那么,如果将其更改为 %.moc
为什么会失败?
full algorithm 在 GNU make 手册中有准确描述。基本上,当您将规则从 a.moc
切换到 %.moc
时,现在目标 a.moc
不会在您的 makefile 中的任何地方提及,因此 make 不会认为它“应该存在”(请参阅此定义的算法)。
您可以通过多种不同的方式解决此问题:
您可以通过添加以下内容将 a.moc
列为明确的先决条件:
a.o: a.moc
您可以将 -r
选项添加到 GNU make 命令行以禁用所有内置隐式规则:
$ make -r
您可以通过设置 MAKEFLAGS
变量将 the -r
option 添加到您的 makefile 中:
MAKEFLAGS += -r
您也可以 disable all suffix rules 将此添加到您的 makefile 中:
.SUFFIXES:
我有以下 Makefile:
CC=g++ -std=c++17
MYCXXFLAGS=-Werror -Wall
clean:
rm -f *.o main
a.moc:
@echo "mocing $@"
%.o: %.cpp %.moc
@echo "all prerequisites $^"
$(CC) $(MYCXXFLAGS) -o $@ -c $<
在Makefile所在的同一目录下,有一个名为“a.cpp”的文件。
当我执行“make a.o”时,将打印以下内容:
mocing a.moc
all prerequisites a.cpp a.moc
g++ -std=c++17 -Werror -Wall -o a.o -c a.cpp
太完美了。 “a.moc”被识别并被执行。
但是,如果我替换
a.moc:
@echo "mocing $@"
和
%.moc:
@echo "mocing $@"
然后事情开始发生变化。仅打印以下内容:
g++ -c -o a.o a.cpp
似乎“%.moc:”的引入把一切都搞砸了。这只是一个演示示例。在我的真实环境中,“%.moc”确实执行一些 Qt 移动操作。我想知道为什么“a.moc”可以被识别为有效目标并被执行,而“%.moc”不能达到目标?
问题在于 make 有一系列内置的隐式规则。这些规则之一告诉 make 如何从 .c
文件构建 .o
文件。您添加了一条规则,告诉 make 如何从 .c
和 .moc
文件构建 .o
文件。 make如何选择使用哪一个?
测试隐式规则的顺序始终是首先检查您的规则,这就是当您有 a.moc
时它起作用的原因。那么,如果将其更改为 %.moc
为什么会失败?
full algorithm 在 GNU make 手册中有准确描述。基本上,当您将规则从 a.moc
切换到 %.moc
时,现在目标 a.moc
不会在您的 makefile 中的任何地方提及,因此 make 不会认为它“应该存在”(请参阅此定义的算法)。
您可以通过多种不同的方式解决此问题:
您可以通过添加以下内容将 a.moc
列为明确的先决条件:
a.o: a.moc
您可以将 -r
选项添加到 GNU make 命令行以禁用所有内置隐式规则:
$ make -r
您可以通过设置 MAKEFLAGS
变量将 the -r
option 添加到您的 makefile 中:
MAKEFLAGS += -r
您也可以 disable all suffix rules 将此添加到您的 makefile 中:
.SUFFIXES: