Por que fazer pensar que a meta está atualizada?

224

Este é o meu Makefile:

REBAR=./rebar
REBAR_COMPILE=$(REBAR) get-deps compile

all: compile

compile:
    $(REBAR_COMPILE)

test:
    $(REBAR_COMPILE) skip_deps=true eunit

clean:
    -rm -rf deps ebin priv doc/*

docs:
    $(REBAR_COMPILE) doc

ifeq ($(wildcard dialyzer/sqlite3.plt),)
static:
    $(REBAR_COMPILE) build_plt analyze
else
static:
    $(REBAR_COMPILE) analyze
endif

Eu posso correr make compilevárias vezes e obter

aromanov@alexey-desktop:~/workspace/gm-controller/lib/erlang-sqlite$ make compile
./rebar get-deps compile
==> erlang-sqlite (get-deps)
==> erlang-sqlite (compile)

No entanto, por algum motivo, a execução make testsempre dá

aromanov@alexey-desktop:~/workspace/gm-controller/lib/erlang-sqlite$ make test
make: `test' is up to date.

mesmo se os arquivos não forem compilados. A questão é, por quê?

A execução do mesmo comando funciona diretamente:

aromanov@alexey-desktop:~/workspace/gm-controller/lib/erlang-sqlite$ ./rebar get-deps compile skip_deps=true eunit
==> erlang-sqlite (get-deps)
==> erlang-sqlite (compile)
Compiled src/sqlite3_lib.erl
Compiled src/sqlite3.erl
==> erlang-sqlite (eunit)
...
Alexey Romanov
fonte

Respostas:

460

Talvez você tenha um arquivo / diretório nomeado testno diretório Se esse diretório existir e não tiver dependências mais recentes, esse destino não será reconstruído.

Para forçar a reconstrução desse tipo de destino não relacionado a arquivos, você deve torná-los falsos da seguinte maneira:

.PHONY: all test clean

Observe que você pode declarar todos os seus alvos falsos lá.

Didier Trosset
fonte
2
Eu tinha um diretório chamado build e outro chamado lib. Em retrospectiva, esses não são nomes de destino perfeitos. Ugh ..... faça.
MattD
9
* Onde all, teste clearsão os seus nomes de destino makefile
ThorSummoner
Outra solução está mudando o rótulo. No seu caso, mude testpara test_ruleou algo diferente.
auraham
@ MattD eu também, isso é um problema para fazer?
gromit190
@ Birger, se você tiver metas que deseja chamar como "make build" e "make lib" e tiver esses diretórios presentes, precisará usar essa estratégia ou outra.
MattD
34

EDIT: Isso se aplica apenas a algumas versões do make- você deve verificar sua página de manual.

Você também pode passar a -Bbandeira para make. De acordo com a página de manual, isso faz:

-B, --always-make Faça incondicionalmente todos os alvos.

Isso make -B testresolveria seu problema se você estivesse em uma situação em que não deseja editar Makefileou alterar o nome da sua pasta de teste.

jamesc
fonte
-Bé o modo compatível com versões anteriores para mim ... (FreeBSD, OS / GNU Toolkit não parece ser determinada em questão)
Gert van den Berg
Oh interessante ... Funciona --always-makepara você?
jamesc
Não. O .PHONYalvo parece meio embora portátil ... (Pelo menos para FreeBSD, não tenho certeza sobre coisas como Solaris)
Gert Van den Berg
1
Isso desafia o objetivo de determinar automaticamente quais partes de um programa precisam ser reconstruídas após uma alteração. Se o seu makefile precisa da --always-makeopção para funcionar, seu makefile está quebrado.
osvein
1
@GertvandenBerg .PHONY fará parte da edição 8 do padrão POSIX austingroupbugs.net/view.php?id=523
osvein
10

Isso acontece quando você tem um arquivo com o mesmo nome que o nome do destino Makefile no diretório em que o Makefile está presente.

insira a descrição da imagem aqui

Piyush Sonigra
fonte
Este foi o meu problema. Obrigado!
Aidan Rosswood
1

meu erro foi com o nome de destino "filename.c:" em vez de apenas "filename:"

ThorSummoner
fonte