How do I perform arithmetic in a makefile?

后端 未结 8 992
终归单人心
终归单人心 2020-12-01 10:12

Is it possible to perform some operations on variables in a makefile? For instance, defining

JPI=4
JPJ=2

Is it possible to define in the sa

相关标签:
8条回答
  • 2020-12-01 10:45

    Using Bash arithmetic expansion:

    SHELL=/bin/bash
    JPI=4
    JPJ=2
    all:
        echo $$(( $(JPI) * $(JPJ) ))
    

    The first line is to choose the Bash shell instead of the default (sh). Typically, sh doesn't support arithmetic expansion. However in Ubuntu, /bin/sh is provided by Dash, which supports this feature. So that line could be skipped.

    The double dollar sign is because we want the expansion to be done by the shell. Note: the JPI and JPJ variables are expanded by make first, then the expression is passed to bash like this:

    $(( 4 * 2 ))
    
    0 讨论(0)
  • 2020-12-01 10:47

    If you're using GNU make and have bc installed on your system, you can use something like this:

    JPI=4
    JPJ=2
    FOO=$(shell echo $(JPI)\*$(JPJ) | bc)
    all:
      echo $(FOO)
    
    0 讨论(0)
  • 2020-12-01 10:47

    The GNU Make Standard Library provides integer arithmetic functions.

    include gmsl
    
    JPI = 4
    JPJ = 2
    
    JPIJ = $(call plus,$(JPI),$(JPJ))
    
    0 讨论(0)
  • 2020-12-01 10:51

    It's clumsy (or brilliant, depending on your perspective), but you can do arithmetic directly in GNU make. See Learning GNU Make Functions with Arithmetic. Be aware though that this method doesn't scale well. It will work wonderfully for small numbers as you have shown in your question, but it doesn't do well when you're working with numbers with a large magnitude (greater than 10,000,000).

    0 讨论(0)
  • 2020-12-01 10:54

    With makepp it's much easier. You get direct access to the underlying Perl interpreter. In this case the makeperl function does variable expansion before evaluating as Perl, the perl function OTOH would only evaluate:

    JPI=4
    JPJ=2
    JPIJ = $(makeperl $(JPI)*$(JPJ))
    &echo result: $(JPIJ)
    

    You can use the builtin &echo command outside of a rule as a statement.

    0 讨论(0)
  • 2020-12-01 10:56

    Answer from @mrkj is great but as @Daniel mentions, not all systems have bc (for example, I don't have it on MSys).

    I have found the two following methods, both using shell: $$(( ... )) and 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))
    

    Note that when using expr, you shall put spaces around the + or it will return 4+2. This is not required when using $$.

    .

    When you have bc available, you might definitely go with it. I found the following page very interesting: http://www.humbug.in/2010/makefile-tricks-arithmetic-addition-subtraction-multiplication-division-modulo-comparison/

    0 讨论(0)
提交回复
热议问题