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将打印隐式规则的定义(。

因此,目标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"不存在":-(

相关内容

最新更新