是否可以对makefile中的变量执行某些操作? 例如,定义
JPI=4
JPJ=2
是否可以在同一个makefile中定义一个等于$(JPI)* $(JPJ)扩展值的变量JPIJ?
答案 0 :(得分:27)
SHELL=/bin/bash
JPI=4
JPJ=2
all:
echo $$(( $(JPI) * $(JPJ) ))
第一行是choose the Bash shell instead of the default (sh)。通常,sh不支持算术扩展。但是在Ubuntu中,/ bin / sh由Dash, which supports this feature提供。所以可以跳过该行。
双美元符号是因为我们需要the expansion to be done by the shell。注意:首先通过make扩展JPI和JPJ变量,然后将表达式传递给bash,如下所示:
$(( 4 * 2 ))
答案 1 :(得分:13)
如果您正在使用GNU make
并在系统上安装bc
,则可以使用以下内容:
JPI=4
JPJ=2
FOO=$(shell echo $(JPI)\*$(JPJ) | bc)
all:
echo $(FOO)
答案 2 :(得分:10)
它很笨拙(或者很棒,取决于你的观点),但你可以直接在GNU make中进行算术运算。见Learning GNU Make Functions with Arithmetic。请注意,此方法不能很好地扩展。正如你在问题中所展示的那样,它会很好地用于小数字,但是当你处理大数量(大于10,000,000)的数字时它不会很好。
答案 3 :(得分:7)
来自@mrkj的答案很棒,但正如@Daniel所提到的,并非所有系统都有bc
(例如,我没有在MSys上使用它)。
我找到了以下两种方法,都使用shell: $$((...))和 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
时, 会在+
周围放置空格,否则会返回4+2
。使用 $$
时,不需要这样做。
当您有bc
可用时,您肯定可以使用它。我发现以下页面非常有趣:http://www.humbug.in/2010/makefile-tricks-arithmetic-addition-subtraction-multiplication-division-modulo-comparison/
答案 4 :(得分:4)
GNU Make Standard Library提供整数运算函数。
include gmsl
JPI = 4
JPJ = 2
JPIJ = $(call plus,$(JPI),$(JPJ))
答案 5 :(得分:2)
在具有Guile支持的GNU Make中(即从版本4.0开始),可以很容易地使用Scheme语言调用算术或其他计算。它是在不创建任何子shell或子进程的情况下完成的。
一个例子
JP-I := 4
JP-J := 2
JP-IJ := $(guile (* $(JP-I) $(JP-J) ))
$(info JP-IJ = $(JP-IJ) )
# prints: JP-IJ = 8
另见Guile手册Arithmetic Functions。
可能检查Guile:
ifeq (,$(filter guile,$(.FEATURES)))
$(error Your Make version $(MAKE_VERSION) is not built with support for Guile)
endif
答案 6 :(得分:0)
使用makepp会更容易。您可以直接访问底层的Perl解释器。在这种情况下,makeperl函数在作为Perl进行求值之前进行变量扩展,OTO只会评估perl函数:
JPI=4
JPJ=2
JPIJ = $(makeperl $(JPI)*$(JPJ))
&echo result: $(JPIJ)
您可以将规则之外的builtin& echo命令用作语句。
答案 7 :(得分:0)
要向池中添加最新答案:The GNUmake table toolkit具有许多算术函数。您可以加,减,乘,除,取底数为8,10和16的模数。还有常用的二进制运算and
,or
,xor
和{{1} }。数字可以在60位数左右,但是如果您需要更多的数字,可以进行调整。该代码是纯GNUmake语法,因此可在Windows和Unix之间移植,与shell脚本相反-如果您想对数字进行紧缩处理,当然可能会有更好的解决方案;)
这里是一个例子:
not
输出:
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)))