c - Makefile 尝试编译它自己的规则之一,就好像它是一个文件一样
问题描述
我有一个简单的 makefile 来编译一些使用 OpenGL 库的 C 代码,但是,它似乎将它自己的规则之一解释为要编译的文件。简化版如下:
CC = gcc
COMPILEFLAGS = -Wall -lglut -lGL -lGLU -lm -c
LINKFLAGS = -lglut -lGL -lGLU -lm
castle: castle_link
run_castle:
./castle $(ARGS)
castle_link: castle_compile
${CC} -o castle castle.o ${LINKFLAGS}
castle_compile:
${CC} ${COMPILEFLAGS} castle.c
clean:
rm *.o castle
执行make -n castle
产生以下结果:
gcc -Wall -lglut -lGL -lGLU -lm -c castle.c
gcc -o castle castle.o -lglut -lGL -lGLU -lm
gcc castle.o castle_link -o castle
我不明白为什么会这样。在这个相同的文件上,还有另一组完全遵循相同模式的规则,只是更改了文件名,可以完美运行。(这只发生在执行规则时make castle
,手动执行castle_compile
,然后castle_link
不会导致)。
很感谢任何形式的帮助。
解决方案
为了解释发生了什么,你有一个没有配方的规则:
castle: castle_link
这意味着make
它将尝试为它找到一个隐含的规则。从手册:
如果目标的显式规则都没有配方,则搜索适用的隐式规则以找到一个
在该页面的前面,它说目标的先决条件是结合在一起的:
一个文件可以是多个规则的目标。所有规则中提到的所有先决条件都合并到目标的先决条件列表中。
匹配的隐式规则将是:
%: %.o
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
如果.o
文件存在或:
%: %.c
$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@
如果没有。(make -p
将打印隐式规则的定义)。
所以 target 的先决条件castle
是:
- 无论是 castle.o castle_link
- 或 castle.c castle_link
而$^
隐式规则中的配方中的变量会将它们放入cc
要执行的命令中。让我们看看这个简化的 makefile:
castle: castle_link
castle_link: castle_compile
$(CC) -o castle castle.o -lm
castle_compile:
$(CC) -Wall -c castle.c
如果我们在一个干净的目录上执行它(即没有castle.o
):
]$ make --debug=m castle
...
Must remake target 'castle_compile'.
cc -Wall -c castle.c # This is our recipe, notice -Wall
Successfully remade target file 'castle_compile'.
Must remake target 'castle_link'.
cc -o castle castle.o -lm # This is our reicpe, notice -lm
Successfully remade target file 'castle_link'.
Must remake target 'castle'.
cc castle.c castle_link -o castle # This is implicit rule with castle.c
cc: error: castle_link: No such file or directory
现在castle.o
已经创建好了,我们再次执行它:
]$ make --debug=m castle
...
Must remake target 'castle_compile'.
cc -Wall -c castle.c # This is our recipe, notice -Wall
Successfully remade target file 'castle_compile'.
Must remake target 'castle_link'.
cc -o castle castle.o -lm # This is our recipe, notice -lm
Successfully remade target file 'castle_link'.
Prerequisite 'castle_link' of target 'castle' does not exist.
Must remake target 'castle'.
cc castle.o castle_link -o castle # This is implicit rule with castle.o
cc: error: castle_link: No such file or directory
如您所见,第一次调用是“cc castle.c castle_link -o castle”,第二次调用是“cc castle.o castle_link -o castle”。
不要问我为什么只有第二个调用打印“目标'castle'的先决条件'castle_link'不存在。” :-)
推荐阅读
- bash - bash 中的 awk 语法错误。在 zsh 中运行良好
- ruby-on-rails - rails inline_svg 与carrierwave上传的文件
- scala - 运算符 ++= 在 Scala 中的一对上
- c - 通过覆盖其元素在 C 中删除 2D 数组的列
- python - 如何在不损失准确性的情况下使用不同的 CNN
- javascript - 为什么 flex-direction: column 和 align-items: center; 不是垂直定位?
- database-design - 彩票最佳实践设计数据库
- tensorflow - 没有xtrain xtest ytrain ytest的keras cnn模型中的混淆矩阵
- java - 在 JAVA 上使用 RSA 加密和解密的问题
- python - 是否可以在 Windows 10 上的 Spyder 中使用 PyPy 解释器?