我在目录中有以下文件:
FP01.c:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
long double ld = 0.1L; // long double constant (L or l suffix)
scanf("%Lf", &ld);
return 0;
}
生成文件:
MAKEFLAGS += -rR
# the default target
.PHONY: all
all: FP01.elf
%.elf: %
cp $< $@
# prevents non-terminal match-anything rules from matching target '%.c'
# see section 10.5.5 of GNU make manual
%.c:
# a non-terminal match-anything rule
%: %.c
gcc -Wall -g $< -o $@
如果FP01
不存在,则运行make
会提供以下输出:
make: *** No rule to make target 'FP01.elf', needed by 'all'. Stop.
但是,如果我在make
之前运行以下命令,那么一切都按预期工作:
$ touch FP01
$ touch FP01.c
$ make
gcc -Wall -g FP01.c -o FP01
cp FP01 FP01.elf
我错过了什么或者GNU make中有错误吗?
make --version
给出以下输出:
GNU make 4.1
Built for i686-pc-linux-gnu
Copyright (C) 1988-2014 Free Software Fundation, Inc.
License GPLv3+: ...
...
编辑:
似乎make match-anything规则终端以某种方式修复了问题,但我想使用内置规则生成FP01,如果可能的话,不幸的是它是非终端的。
另一件事是我相信非终端规则应该有效,所以使用终端规则实际上并没有解决问题,因为我仍然不知道错误是在make中还是在我的“mental makefile解析器”中。< / p>
答案 0 :(得分:1)
我不确定这是不是一个错误,我不得不深入研究它。但是解决问题的简单方法是将从.c
文件编译的匹配任何模式规则设置为终端,这应该是这样的(除非您从其他地方生成源文件) ):
%:: %.c
cp $< $@
$ make
cp FP01.c FP01
cp FP01 FP01.elf
rm FP01
答案 1 :(得分:1)
我认为您应该在::
规则上使用% : %.c
,因为您实际上希望这是一个终端匹配任何规则(因为您不需要.c
文件待建):
MAKEFLAGS += -rR
.PHONY: all
all: FP01.elf
%.elf: % ; cp $< $@
% :: %.c ; gcc -Wall -g $< -o $@
请注意,我在这里使用了;
表单,因为它更容易复制和粘贴,因为无需担心标签。
答案 2 :(得分:0)
添加FP01
作为.INTERMEDIATE
(特殊内置目标)的先决条件似乎使其工作(无需修改match-anything规则)。只是另一种解决方法。
MAKEFLAGS += -rR
# the default goal
.PHONY all
all: FP01.elf
%.elf: % ; cp $< $@
# prevents non-terminal match-anything rules from matching target '%.c'
# see section 10.5.5 of GNU make manual
%.c:
# a non-terminal match-anything rule
%: %.c ; gcc -Wall -g $< -o $@
.INTERMEDIATE: FP01