奇怪的是隐含规则

时间:2012-03-18 14:32:56

标签: makefile

我为一些编译它们的简单C程序编写了一个小的makefile,然后测试它们的执行时间:

CC = gcc
CFLAGS = -Wall
PTEST = /usr/bin/time -f "%Us"
ARCH=-march=native
OPTIMIZATION=
NOPTIMIZATION=

%comp : %.c
    $(CC) $(CFLAGS) $(NOPTIMIZATION) -o $* $<
    $(CC) $(CFLAGS) $(OPTIMIZATION) -o $*_opt $<
    $(CC) $(CFLAGS) $(NOPTIMIZATION) $(ARCH) -o $*_arch $<
    $(CC) $(CFLAGS) $(OPTIMIZATION) $(ARCH) -o $*_opt_arch $<

%test:  
    @echo ---$<---  
    @echo Bez optymalizacji, bez podowania architektury
    @$(PTEST) ./$*
    @echo Bez optymalizacji, uwzgledniana architektura
    @$(PTEST) ./$*_arch
    @echo Opcja $(OPTIMIZATION), bez podawania architektury
    @$(PTEST) ./$*_opt
    @echo Opcja $(OPTIMIZATION), uwzgledniania architektura
    @$(PTEST) ./$*_opt_arch

loop%:OPTIMIZATION=-O2
logic%:OPTIMIZATION=-O1
math%:OPTIMIZATION=-O1 -ffast-math
recursive%:OPTIMIZATION=-O2 -foptimize-sibling-calls
recursive%:NOPTIMIZATION=-O2 -fno-optimize-sibling-calls

#all: loopcomp logiccomp mathcomp recursivecomp looptest logictest mathtest  recursivetest 

loop:loopcomp looptest

clean:
    rm -rf loop loop_opt loop_arch loop_opt_arch \
    logic logic_opt logic_arch logic_opt_arch \
    math math_opt math_arch math_opt_arch \
    recursive recursive_opt recursive_arch recursive_opt_arch

当我输入make循环时,它会编译并测试它们,但它会调用奇怪的隐式规则来执行此操作:

gcc -Wall    loop.c loopcomp looptest   -o loop
gcc: error: loopcomp: No such file or directory
gcc: error: looptest: No such file or directory

我知道这是make隐式规则,因为当我调用make -r loop时一切正常。我无法弄清楚:哪个内置隐式规则是试图调用以及如何覆盖它,最好在调用-r时不添加make选项?如果可能的话,我想覆盖它,或者以某种方式在makefile中创建隐式规则。

2 个答案:

答案 0 :(得分:1)

makefile中的默认目标是:

loop:  loopcomp looptest

这告诉make要构建loop,必须首先确保loopcomplooptest是最新的,然后必须找到构建{的方法{1}}。由于存在文件loop,因此会调用其默认loop.c规则来构建%.c:

loop

这包括您告诉gcc -Wall loop.c loopcomp looptest -o loop 依赖的两个文件(程序)。

虽然您有loop,但我认为您可能会遇到此问题。

似乎没有办法在loop.c中说出“不使用任何内置规则”。如果有的话,你会期望它是一个'特殊的内置目标名称'(版本3.82的GNU Make手册的§4.8),例如makefile

你唯一的希望就是声明.DEFAULT可能会抑制这一点。否则,将默认目标规则重写为:

.PHONY: loop

这是一个令人难以置信的check-loop: loopcomp looptest 。将其移植到GNU makefile以外的任何内容都不是一件容易的事。

答案 1 :(得分:1)

如果您不想创建一个名为“loop”的文件,并且您只想说“make loop”作为捆绑其他目标的方式(例如“make all”),那么您应该声明“循环“是假的,make不会搜索隐式规则:

.PHONY: loop
loop: loopcomp looptest

如果您不想这样做但希望确保给定目标不进行隐式规则搜索,那么您应该为它声明一个明确的规则。一个简单的方法是添加一个do-nothing配方,如下所示:

loop: loopcomp looptest
        @:

(“:”命令是shell的“do-nothing”命令。)