Makeeq ifeq logicalまたは


92

makeのifeq演算子を使用して論理ORをどのように実行しますか?

たとえば、私は(簡略化した):

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

しかし、これらのラインを統合したいと思います。

(はい、はい、autotools、configureなど。現在の状況では強すぎます。ここでMakefile内にすべてを保持したいと思います)

[この質問の論理的な反対:「ifeq」ステートメントで複数の条件を使用する方法 ]


MakefileでのComplex条件チェックの重複の可能性があります
Peter Mortensen

1
だまされたとは思わないでください。リンクされた質問は連鎖ifdef演算子に関連し、この質問は連鎖ifeq演算子に類似していますが、答えは明らかに異なります。
Pat

回答:


103

メーリングリストのアーカイブにあるように、

フィルター機能を使用できます。

例えば

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

フィルターX、AB、Xに等しいA、Bのフィルターを返します。

これのバリエーションは

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

代わりに、空の文字列に対する負の比較が使用されます(GCC_MINORが引数と一致しない場合、フィルターは空の文字列を返します)

これらのメソッドの欠点は、引数が単一の単語でなければならないことです。


7
最近の注意:上記の2つのバリエーションでは、$(GCC_MINOR)が空白の場合、1つ目はtrueに解決されますが、2つ目はそうではありません(したがって、一般的に言えば2つ目がより良い解決策です)。
ジョン

1
実際には、それはifneq (,$(filter 4 5,$(GCC_MINOR))):) である必要があります
Tuxdude '06 / 06/18

2
おそらく、単純にするために現状のままにしておく方が良いでしょうか?
Jason

別の注記:これは一般的な ORステートメントとしては機能しません。確認したいif(flagA == TRUE || flagB == true)ことは$(filter true, $(flagA) $(flagB)ありますが、両方に当てはまる場合、次の結果が得られますifeq(true, true true)
Charlie Su

27

別の変数を導入できます。両方のチェックが統合されるわけではありませんが、少なくともボディを2回入れる必要はありません。

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
この規模での保守性は私にはあまり良くないと思われます:/もう一度、規模について話し始めたら、autotoolsについて話していると思います
Pat

2
@Pat:私はむしろ、Makefile内の1つの場所で割り当てを分離できるこのアプローチを好みます。おそらく、行を非常に長く読みにくくする可能性のあるフィルター関数を使用するのではなく、ifeq / else ifeq / elseを使用してより多くの値と比較します。 。
jcarballo 14年

15

それを行うための簡潔で賢明な方法はないと思いますが、次のような冗長で賢明な方法(Foo Bahなど)と簡潔で病理的な方法があります。

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

(文字列$(GCC_MINOR)が文字列4-5内にある場合、コマンドを実行します)。


4
良くも悪くも(おそらくもっと悪い)、私が探していた汚いハックの種類だけです。感謝
パット

1
Makefileのすべてが病理的であるという事実を除いて、これはまったく病理的ではないと思います。とてもエレガントです。私はこれを達成するために4つまたは5つの異なる方法を読みましたが、あなたの方法が断然最も簡単に理解できます。
Michael Geary、2016

8

ここでより柔軟なバリアント:外部シェルを使用しますが、任意の条件をチェックできます:

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

この場合の使用を検討できる別の方法は次のとおりです。

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

別にconfigor を維持したくないので、実際には同じことをコードで使用していますConfigure

ただし、Posixのものではなく、makeGNU make(gmake)のように、移植可能な非貧血を使用する必要がありますmake

そして、それは論理ANDとの問題に対処していませんOR

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.