2010-08-09 2 views
7

Je suis en train de le faire dans un Makefile:Exécution supérieur à moins que les calculs dans un Makefile

value = 2.0 

if ${greaterthan ${value}, 1.50} 
-> execute a rule 
elseif ${lessthan ${value}, 0.50} 
-> execute a rule 
endif 

Il semble tout à fait une chose commune à vouloir faire. Quelle est la meilleure façon de faire cela?

+0

Copie possible de * [Comparaison supérieure à la chaîne dans un Makefile] (http://stackoverflow.com/questions/3437160/greater-than-string-comparison-in-a-makefile) *. –

Répondre

8

Similaire à this question, mais vous pouvez utiliser des commandes shell dans un Makefile. Donc, ce qui suit est parfaitement légal:

foo: 
    if [ ${value} -gt 2 ] ; then \ 
     #Do stuff;\ 
    fi 

Modifier pour une petite mise en garde: IIRC, bash ne comprend pas l'arithmétique en virgule flottante. Il peut les interpréter comme les chaînes, mais cela pourrait rendre les choses un peu bizarres. Assurez-vous de prendre cela en considération.

+0

Cela fonctionnerait-il sous Windows? Et/ou dans [MinGW] (http://en.wikipedia.org/wiki/MinGW)? –

+0

Alors la syntaxe Linux/Unix fonctionne dans makefile? –

11

Essayez cette

Dans cet exemple VER est vérifiée supérieure à 4

ifeq ($(shell test $(VER) -gt 4; echo $$?),0) 
    IFLAGS += -I$(TOPDIR)/include 
    LIBS += -L$(TOPDIR)/libs -lpcap 
endif 
+0

Qu'est-ce qui est impliqué ici? [Bash] (http://en.wikipedia.org/wiki/Bash_%28Unix_shell%29)? Fonctionne uniquement sur Linux (et [Mac OS X] (http://en.wikipedia.org/wiki/Mac_OS_X))? –

0

Ma façon préférée de le faire est:

value = 2.0 
ifeq ($(shell expr $(value) \>= 1.5), 1) 
    # execute a rule 
else ifeq ($(shell expr $(value) \<= 0.5), 1) 
    # execute a rule 
endif 
0

Utilisation des commandes shell, comme mentionné dans le d'autres réponses devraient suffire pour la plupart des cas d'utilisation:

if [ 1 -gt 0 ]; then \ 
    #do something \ 
fi 

Cependant, si vous, comme moi, veulent utiliser plus-que comparaison pour puis définir une variable make via la commande de $(eval)make, vous constaterez que de tenter de le faire en utilisant la autre modèle de réponse:

if [ 1 -gt 0 ]; then \ 
    $(eval FOO := value) \ 
fi 

déclenche une erreur:

if [ 1 -gt 0 ]; then fi; 
/bin/bash: -c: line 0: syntax error near unexpected token `fi' 
/bin/bash: -c: line 0: `if [ 1 -gt 0 ]; then fi;' 
make: *** [clean] Error 2``` 

La raison est que make's $(eval) expression returns the empty string. Le code bash qui en résulte est alors malformé. **

J'ai trouvé la solution suivante (après avoir essayé différentes approches!).

$(if $(shell [ $(FOO) -ge 1 ] && echo "OK"), \ 
    $(eval BAR := true), \ 
    $(eval BAR := false)) 

Il est nécessaire d'imprimer une chaîne après avoir effectué la comparaison arithmétique (la echo "OK" partie) parce que l » opérateur $(if)make son basé sur la logique vide-chaîne:

$(if condition,then-part[,else-part])

The if function provides support for conditional expansion in a functional context (as opposed to the GNU make makefile conditionals such as ifeq (see Syntax of Conditionals).

The first argument, condition, first has all preceding and trailing whitespace stripped, then is expanded. If it expands to any non-empty string, then the condition is considered to be true. If it expands to an empty string, the condition is considered to be false.

Source: GNU Make Manual

Espérons que cela aide!

** Remarque : Dans un premier temps, je pense que cette question pourrait être facilement corrigé en ajoutant une commande bash qui ne fait rien à l'expression, comme true:

if [ $(VALUE) -ge 1 ]; then \ 
    true; $(eval BAR := GreaterOrEqualThan1) \ 
else \ 
    true; $(eval BAR := LowerThan1) \ 
fi 

qui se sont avérés être une idée terrible.Je n'ai toujours pas compris pourquoi, mais la branche else est toujours exécutée, indépendamment du résultat de la comparaison.

Je pense que je devrais ouvrir une question pour ce cas.

Questions connexes