Pourquoi fait penser que la cible est à jour?

224

Voici mon 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

Je peux courir make compileplusieurs fois et obtenir

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

Cependant, pour une raison quelconque, la course make testdonne toujours

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

même si les fichiers ne sont pas compilés. La question est, pourquoi?

L'exécution de la même commande fonctionne directement:

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
la source

Réponses:

460

Vous avez peut-être un fichier / répertoire nommé testdans le répertoire. Si ce répertoire existe et n'a pas de dépendances plus récentes, cette cible n'est pas reconstruite.

Pour forcer la reconstruction sur ce type de cibles non liées aux fichiers, vous devez les rendre fausses comme suit:

.PHONY: all test clean

Notez que vous pouvez y déclarer toutes vos cibles bidon.

Didier Trosset
la source
2
J'avais un répertoire appelé build et un autre appelé lib. Avec le recul, ce ne sont pas des noms de cible parfaits. Ugh ..... faites.
MattD
9
* Où all, testet clearsont vos noms cibles makefile
ThorSummoner
Une autre solution consiste à changer l'étiquette. Dans votre cas, changez testpour test_ruleou quelque chose de différent.
auraham
@MattD moi aussi, est-ce un problème pour make?
gromit190
@Birger si vous avez des cibles que vous voulez invoquer comme "make build" et "make lib" et que vous avez ces répertoires présents, alors vous devrez utiliser cette stratégie ou une autre comme celle-ci.
MattD
34

EDIT: Cela ne s'applique qu'à certaines versions de make- vous devriez vérifier votre page de manuel.

Vous pouvez également passer le -Bdrapeau à make. Selon la page de manuel, cela fait:

-B, --always-make Faire inconditionnellement tous les objectifs.

Cela make -B testrésoudrait donc votre problème si vous vous trouviez dans une situation où vous ne souhaitez pas modifier Makefileou modifier le nom de votre dossier de test.

jamesc
la source
-Best un mode rétrocompatible pour moi ... (FreeBSD, la boîte à outils OS / GNU ne semble pas être spécifiée en question)
Gert van den Berg
Oh intéressant ... ça --always-makemarche pour vous?
jamesc
Nan. La .PHONYcible semble plutôt portable ... (au moins pour FreeBSD, pas sûr de choses comme Solaris)
Gert van den Berg
1
Cela défie le but de make - déterminer automatiquement quelles parties d'un programme doivent être reconstruites après un changement. Si votre makefile a besoin de l' --always-makeoption pour fonctionner, votre makefile est cassé.
osvein
1
@GertvandenBerg .PHONY fera partie du numéro 8 de la norme POSIX austingroupbugs.net/view.php?id=523
osvein
10

Cela se produit lorsque vous avez un fichier portant le même nom que le nom cible Makefile dans le répertoire où le Makefile est présent.

entrez la description de l'image ici

Piyush Sonigra
la source
C'était mon problème. Merci!
Aidan Rosswood
1

mon erreur était de faire le nom cible "filename.c:" au lieu de simplement "filename:"

ThorSummoner
la source