GNU make似乎忽略了中间文件

时间:2016-05-27 10:26:15

标签: makefile gnu-make

我在目录中有以下文件:

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>

3 个答案:

答案 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