128 votes

Makefile ifeq logique ou

Comment effectuer un OU logique en utilisant des make's ifeq opérateur ?

par exemple, j'ai (simplifié) :

ifeq ($(GCC_MINOR), 4)
    CFLAGS += -fno-strict-overflow
endif
ifeq ($(GCC_MINOR), 5)
    CFLAGS += -fno-strict-overflow
endif

mais aimerait consolider ces lignes.

(oui, oui, autotools, configure, etc etc ; trop lourd pour la situation actuelle, j'aimerais garder tout dans le Makefile ici)

[opposé logique de cette question : Comment utiliser les conditions multiples dans l'instruction 'ifeq' ? ]

0 votes

1 votes

Je ne pense pas qu'il s'agisse d'un doublon, la question liée concerne le chaînage. ifdef opérateurs, cette question est liée au chaînage ifeq opérateurs, similaires, mais les réponses sont définitivement différentes.

0 votes

138voto

misiu_mp Points 399

Tel que trouvé dans les archives de la liste de diffusion,

on peut utiliser le filter fonction.

Par exemple

ifeq ($(GCC_MINOR),$(filter $(GCC_MINOR),4 5))

filter X, A B retournera ceux de A,B qui sont égaux à X. Notez que, bien que cela ne soit pas pertinent dans l'exemple ci-dessus, il s'agit d'une opération XOR. C'est-à-dire que si vous avez plutôt quelque chose comme :

ifeq (4, $(filter 4, $(VAR1) $(VAR2)))

Et ensuite faire par exemple make VAR1=4 VAR2=4 le filtre retournera 4 4 qui n'est pas égal à 4 .

Une variation qui effectue une opération OR à la place est :

ifneq (,$(filter $(GCC_MINOR),4 5))

où une comparaison négative avec une chaîne vide est utilisée à la place ( filter retournera une chaîne vide si GCC_MINOR ne correspond pas aux arguments). En utilisant le VAR1 / VAR2 exemple, cela ressemblerait à ceci :

ifneq (, $(filter 4, $(VAR1) $(VAR2)))

L'inconvénient de ces méthodes est que vous devez être sûr que ces arguments seront toujours des mots simples. Par exemple, si VAR1 es 4 foo le résultat du filtre est toujours 4 et le ifneq L'expression est toujours vraie. Si VAR1 es 4 5 le résultat du filtre est 4 5 y el ifneq est vraie.

Une alternative simple consiste à mettre la même opération dans les deux versions de l'interface utilisateur. ifeq y else ifeq branche, par exemple comme ceci :

ifeq ($(GCC_MINOR),4)
    @echo Supported version
else ifeq ($(GCC_MINOR),5)
    @echo Supported version
else
    @echo Unsupported version
endif

8 votes

Une note tardive : dans les deux variations que vous avez ci-dessus, la première résoudra à true si $(GCC_MINOR) est vide, alors que la seconde ne le fera pas (donc la seconde est la meilleure solution génériquement parlant).

3 votes

En fait, cela devrait être ifneq (,$(filter 4 5,$(GCC_MINOR))) :)

2 votes

Peut-être est-il préférable de laisser les choses telles quelles pour plus de simplicité ?

34voto

Foo Bah Points 11566

Vous pouvez introduire une autre variable. Cela ne consolide pas les deux contrôles, mais cela évite au moins d'avoir à introduire le corps deux fois :

do_it = 
ifeq ($(GCC_MINOR), 4)
    do_it = yes
endif
ifeq ($(GCC_MINOR), 5)
    do_it = yes
endif
ifdef do_it
    CFLAGS += -fno-strict-overflow
endif

7 votes

La maintenabilité de ce système à l'échelle ne me semble pas très bonne :/ Mais encore une fois, dès que l'on commence à parler d'échelle, je suppose que l'on parle d'autotools.

3 votes

@Pat : Je préfère plutôt cette approche où je peux séparer l'affectation en un seul endroit dans le Makefile, éventuellement en comparant avec plus de valeurs en utilisant ifeq/else ifeq/else, plutôt qu'en utilisant la fonction filtre qui pourrait juste faire des lignes terriblement longues et difficiles à lire.

19voto

ruakh Points 68789

Je ne pense pas qu'il existe une manière concise et sensée de faire cela, mais il existe des manières verbeuses et sensées (comme celle de Foo Bah) et des manières concises et pathologiques, telles que

ifneq (,$(findstring $(GCC_MINOR),4-5))
    CFLAGS += -fno-strict-overflow
endif

(qui exécutera la commande à condition que la chaîne $(GCC_MINOR) apparaisse à l'intérieur de la chaîne 4-5).

4 votes

Pour le meilleur ou pour le pire (probablement le pire), c'est exactement le genre de piratage sale que je cherchais ; merci.

1 votes

Je ne pense pas que ce soit pathologique du tout, à part le fait que tout dans un Makefile est pathologique. C'est vraiment très élégant. J'ai lu quatre ou cinq façons différentes d'accomplir ceci, et la vôtre est de loin la plus facile à comprendre.

10voto

Ivan Points 16

Voici une variante plus flexible : elle utilise un shell externe, mais permet de vérifier des conditions arbitraires :

ifeq ($(shell test ".$(GCC_MINOR)" = .4  -o  \
                   ".$(GCC_MINOR)" = .5  -o  \
                   ".$(TODAY)"     = .Friday  &&  printf "true"), true)
    CFLAGS += -fno-strict-overflow
endif

3voto

eerez Points 1

Notez que ifeq ($(GCC_MINOR),$(filter $(GCC_MINOR),4 5)) permettra d'attraper le cas où GCC_MINOR n'est pas du tout défini.

Si vous voulez attraper GCC_MINOR==4 ou GCC_MINOR==5, cela fera l'affaire :

ifneq ($(filter $(GCC_MINOR),4 5),)
    echo "def"
endif

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X