Makefile内の変数に対していくつかの操作を実行することは可能ですか?たとえば、定義
JPI=4
JPJ=2
$(JPI)* $(JPJ)の拡張値に等しい変数JPIJを同じメイクファイルで定義することは可能ですか?
Shell=/bin/bash
JPI=4
JPJ=2
all:
echo $$(( $(JPI) * $(JPJ) ))
最初の行は、 デフォルト(sh)の代わりにBashシェルを選択することです 。通常、shは算術展開をサポートしていません。ただし、Ubuntuでは、/ bin/shは Dashによって提供され、この機能をサポートしています 。そのため、その行はスキップできます。
ダブルドル記号は、 拡張がシェルによって実行されることを望んでいるためです 。注:JPIおよびJPJ変数は、最初にmakeによって展開され、次に式が次のようにbashに渡されます。
$(( 4 * 2 ))
GNU make
を使用していて、bc
がシステムにインストールされている場合は、次のように使用できます。
JPI=4
JPJ=2
FOO=$(Shell echo $(JPI)\*$(JPJ) | bc)
all:
echo $(FOO)
不器用です(または見方によっては見事です)が、GNU makeで直接算術演算を実行できます。 Learning GNU Make Functions with算数 。ただし、この方法は適切にスケーリングされないことに注意してください。質問で示したように、この方法は小さな数値に対してはうまく機能しますが、大きなマグニチュードを持つ数値を処理するときはうまく機能しません。 (10,000,000以上)。
@mrkjからの回答は素晴らしいですが、@ Danielが言及しているように、すべてのシステムにbc
があるわけではありません(たとえば、MSysにはありません)。
シェルを使用する次の2つの方法を見つけました:$$((...))およびexpr ...
JPI=4
JPJ=2
#With Double-dollar
JPIJ_1 = $(Shell echo $$(( $(JPI) + $(JPJ) )))
#With 'expr'
JPIJ_2 = $(Shell expr $(JPI) + $(JPJ) )
$(info Sum with Double-$$: $(JPIJ_1))
$(info Sum with 'expr': $(JPIJ_2))
expr
を使用する場合、[shallは+
の前後にスペースを入れるか、4+2
を返すことに注意してください。 $$
を使用する場合、これは必要ありません。
。
bc
が手元にあれば、間違いなくそれを使用できます。次のページは非常に興味深いものでした: http://www.humbug.in/2010/makefile-tricks-arithmetic-addition-subtraction-multiplication-division-modulo-comparison/
GNU Make Standard Library は整数演算関数を提供します。
include gmsl
JPI = 4
JPJ = 2
JPIJ = $(call plus,$(JPI),$(JPJ))
GNU Make with Guile のサポート(つまり、バージョン4.0以降)では、算術計算やその他の計算のためにScheme言語の呼び出しを使用するのは簡単です。サブシェルを作成せずに実行されますまたは子プロセス。
例
JP-I := 4
JP-J := 2
JP-IJ := $(guile (* $(JP-I) $(JP-J) ))
$(info JP-IJ = $(JP-IJ) )
# prints: JP-IJ = 8
Guile 算術関数 のマニュアルも参照してください。
ガイルの可能なチェック:
ifeq (,$(filter guile,$(.FEATURES)))
$(error Your Make version $(MAKE_VERSION) is not built with support for Guile)
endif
遅い答えをプールに追加するには、次のようにします。 GNUmakeテーブルツールキット は、多くの算術関数を備えています。加算、減算、乗算、除算、8、10、16を基数とするモジュラスを使用できます。また、通常のバイナリ演算and
、or
、xor
、not
もあります。数値は約60桁ですが、さらに必要な場合はこれを採用できます。コードは純粋なGNUmake構文であるため、シェルスクリプトとは異なり、WindowsとUnix間で移植可能です。
次に例を示します。
include gmtt/gmtt.mk
NUMBER_A := -12392834798732429827442389
NUMBER_B := 984398723982791273498234
$(info $(call add,$(NUMBER_A),$(NUMBER_B)))
$(info $(call sub,$(NUMBER_A),$(NUMBER_B)))
$(info $(call mul,$(NUMBER_A),$(NUMBER_B)))
$(info $(call div,$(NUMBER_A),$(NUMBER_B)))
$(info $(call mod,$(NUMBER_A),$(NUMBER_B)))
出力:
$ make
-11408436074749638553944155
-13377233522715221100940623
-12199490762401735834920873237276176262117128241026
-12
-580050110938934545463581
makepp を使用すると、はるかに簡単です。基盤となるPerlインタープリターに直接アクセスできます。この場合、makeperl関数はPerlとして評価する前に変数の展開を行い、Perl関数OTOHは次のもののみを評価します。
JPI=4
JPJ=2
JPIJ = $(makeperl $(JPI)*$(JPJ))
&echo result: $(JPIJ)
組み込みの&echoコマンドをルールの外でステートメントとして使用できます。