Странное неявное правило - PullRequest
0 голосов
/ 18 марта 2012

Я написал небольшой make-файл для нескольких простых программ на C, который компилирует их и затем проверяет время их выполнения:

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, все идет хорошо.Я не могу понять: какое встроенное неявное правило вызывает make, и как я могу его переопределить, желательно без добавления опции -r при вызове make?Если это возможно, я бы хотел переопределить его или каким-либо образом создать неявные правила внутри make-файла.

Ответы [ 2 ]

1 голос
/ 18 марта 2012

Если вы не хотите создавать файл с именем «loop» и хотите просто сказать «make loop» как способ связать другие цели (например, «make all»), тогда вы должны объявить « loop "чтобы быть фальшивым и make не будет искать неявные правила:

.PHONY: loop
loop: loopcomp looptest

Если вы не хотите этого делать, но хотите убедиться, что заданная цель не подвергается неявному поиску правил, вам следует объявить для нее явное правило. Простой способ сделать это - добавить рецепт бездействия, например так:

loop: loopcomp looptest
        @:

(команда ":" является командой оболочки "ничего не делать").

1 голос
/ 18 марта 2012

Ваша цель по умолчанию в make-файле:

loop:  loopcomp looptest

. Это говорит make, что для сборки loop необходимо сначала убедиться, что loopcomp и looptest обновлены, итогда он должен найти способ построить loop.Поскольку существует файл loop.c, он вызывает правило по умолчанию %.c: для построения loop:

gcc -Wall    loop.c loopcomp looptest   -o loop

Это включает в себя два файла (программы), которые, как вы сказали, зависят от loop.

Пока у вас есть loop.c, я думаю, что вы, вероятно, столкнетесь с этой проблемой.

Кажется, в makefile нет способа сказать "неиспользовать любые встроенные правила ".Если это так, вы ожидаете, что это будет «Специальное имя встроенной цели» (§4.8 Руководства по GNU Make для версии 3.82), например .DEFAULT.

Ваша единственная оставшаяся надежда -что объявление .PHONY: loop может подавить это.В противном случае переписать целевое правило по умолчанию следующим образом:

check-loop: loopcomp looptest

Это ошеломляет makefile.Портировать это на что-либо кроме GNU make не будет тривиальным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...