Makefile ifeq mantıksal veya


94

Make ifeqoperatörünü kullanarak mantıksal bir OR'yi nasıl gerçekleştirirsiniz ?

örneğin, (basitleştirilmiş):

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

ama bu hatları pekiştirmek istiyor.

(evet, evet, autotools, configure, vb; mevcut durum için çok ağır, her şeyi burada Makefile içinde tutmak ister)

[bu sorunun mantıksal tersi: 'ifeq' ifadesinde Çoklu koşul Nasıl Kullanılır ]



1
Bunun bir dupe olduğunu düşünmeyin, bağlantılı soru zincirleme ifdefoperatörleri ile ilgili, bu soru zincirleme ifeqoperatörleriyle ilgili , benzer, ancak cevaplar kesinlikle farklı.
Pat

Yanıtlar:


104

Posta listesi arşivinde bulunduğu gibi,

birini kullanabilirsiniz filtre işlevi.

Örneğin

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

filtre X, AB , X'e eşit olan A, B'yi döndürecektir.

Bunun bir varyasyonu

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

bunun yerine boş bir dizeye karşı negatif bir karşılaştırma kullanıldığında ( GCC_MINOR bağımsız değişkenlerle eşleşmezse filtre en boş dizeyi döndürür)

Bu yöntemlerin dezavantajı, argümanların tek kelime olması gerektiğidir.


7
Geç bir not: Yukarıdaki iki varyasyonda, birincisi $ (GCC_MINOR) boşsa doğru olarak çözülecektir, oysa ikincisi olmayacaktır (dolayısıyla ikincisi genel olarak daha iyi bir çözümdür).
John

1
Aslında öyle olmalı ifneq (,$(filter 4 5,$(GCC_MINOR))):)
Tuxdude

2
Belki de basitlik için olduğu gibi bırakmak daha iyidir?
Jason

Başka bir not: Bu genel bir VEYA ifadesi olarak çalışmaz . Kontrol etmek istediğimiz bir şeyimiz var if(flagA == TRUE || flagB == true), ancak yaparsanız $(filter true, $(flagA) $(flagB)ve her ikisi de doğruysa, anlarsınızifeq(true, true true)
Charlie Su

27

Başka bir değişken tanıtabilirsiniz. Her iki çeki de birleştirmez, ancak en azından bedeni iki kez koymak zorunda kalmaz:

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
Ölçekteki bu idame bana çok iyi görünmüyor: Biz ölçek konuşmaya başlamadan bir kez / Sonra tekrar, biz autotools konuşuyor tahmin
Pat

2
@Pat: Atamayı Makefile'da tek bir yerde ayırabileceğim, muhtemelen ifeq / else ifeq / else kullanarak daha fazla değerle karşılaştırabileceğim bu yaklaşımı tercih ediyorum, satırları okumayı çok zorlaştıran filtre işlevini kullanmak yerine .
jcarballo

15

Bunu yapmanın kısa ve mantıklı bir yolu olduğunu sanmıyorum, ancak ayrıntılı, mantıklı yollar (Foo Bah'lar gibi) ve özlü, patolojik yollar var.

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

($ (GCC_MINOR) dizesinin 4-5 dizesi içinde görünmesi koşuluyla komutu yürütür).


4
İyi ya da kötü (muhtemelen daha kötü), tam da aradığım türden kirli bir hack; teşekkürler
Pat

1
Makefile'daki her şeyin patolojik olması dışında bunun patolojik olduğunu düşünmüyorum . Gerçekten oldukça zarif. Bunu başarmanın dört veya beş farklı yolunu okudum ve sizinki açık arayla anlaşılması en kolay olanı.
Michael Geary

8

Burada daha esnek varyant: harici kabuk kullanır, ancak keyfi koşulları kontrol etmeye izin verir:

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

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

Bu durumda kullanmayı düşünebileceğiniz başka bir şey şudur:

GCC42_OR_LATER = $(shell $(CXX) -v 2>&1 | $(EGREP) -c "^gcc version (4.[2-9]|[5-9])")

# -Wstrict-overflow: http://www.airs.com/blog/archives/120
ifeq ($(GCC42_OR_LATER),1)
  CFLAGS += -Wstrict-overflow
endif

Aslında aynısını kodumda kullanıyorum çünkü ayrı bir configveya Configure.

Ancak Posix'inki değil, makeGNU make ( gmake) gibi taşınabilir, anemik olmayan bir yazılım kullanmanız gerekir make.

Ve mantıksal meselesini ele almıyor ANDve OR.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.