Makefile 试图编译它自己的规则之一,就好像它是一个文件一样
Makefile tries to compile one of it's own rules as if it were a file
我有一个简单的 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
将尝试为它找到一个隐式规则。来自 the manual:
If none of the explicit rules for a target has a recipe, then make searches for an applicable implicit rule to find one
在那个页面的前面,它说目标的先决条件是合并的:
One file can be the target of several rules. All the prerequisites mentioned in all the rules are merged into one list of prerequisites for the target.
匹配的隐式规则是:
%: %.o
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
如果 .o
文件存在或:
%: %.c
$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@
如果没有。 (make -p
将打印隐式规则的定义)。
因此目标 castle
的先决条件是:
- 要么 castle.o castle_link
- 或castle.ccastle_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_link' 不存在。” :-)
我有一个简单的 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
将尝试为它找到一个隐式规则。来自 the manual:
If none of the explicit rules for a target has a recipe, then make searches for an applicable implicit rule to find one
在那个页面的前面,它说目标的先决条件是合并的:
One file can be the target of several rules. All the prerequisites mentioned in all the rules are merged into one list of prerequisites for the target.
匹配的隐式规则是:
%: %.o
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
如果 .o
文件存在或:
%: %.c
$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@
如果没有。 (make -p
将打印隐式规则的定义)。
因此目标 castle
的先决条件是:
- 要么 castle.o castle_link
- 或castle.ccastle_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_link' 不存在。” :-)