Come eseguo l’aritmetica in un makefile?

È ansible eseguire alcune operazioni sulle variabili in un makefile? Ad esempio, definire

JPI=4 JPJ=2 

È ansible definire nello stesso makefile una variabile JPIJ uguale al valore espanso di $ (JPI) * $ (JPJ)?

Usando l’espansione aritmetica di Bash :

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

La prima riga è scegliere la shell Bash invece del default (sh) . In genere, sh non supporta l’espansione aritmetica. Comunque in Ubuntu, / bin / sh è fornito da Dash, che supporta questa funzionalità . Quindi quella linea potrebbe essere saltata.

Il doppio simbolo del dollaro è perché vogliamo che l’espansione sia fatta dalla shell . Nota: le variabili JPI e JPJ vengono espanse da make in primo luogo, quindi l’espressione viene passata a bash in questo modo:

 $(( 4 * 2 )) 

Se stai usando GNU make e hai bc installato sul tuo sistema, puoi usare qualcosa di simile a questo:

 JPI=4 JPJ=2 FOO=$(shell echo $(JPI)\*$(JPJ) | bc) all: echo $(FOO) 

È maldestro (o brillante, dipende dalla tua prospettiva), ma puoi fare l’aritmetica direttamente in GNU make. Vedi Imparare GNU Creare funzioni con Aritmetica . Essere consapevoli però che questo metodo non scala bene. Funzionerà meravigliosamente per piccoli numeri come hai mostrato nella tua domanda, ma non funziona bene quando lavori con numeri di grandi dimensioni (superiori a 10.000.000).

La risposta di @mrkj è ottima ma come @Daniel menziona, non tutti i sistemi hanno bc (ad esempio, non ce l’ho su MSys).

Ho trovato i due metodi seguenti, entrambi con shell: $$ ((…)) ed 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)) 

Nota che quando usi expr , devi mettere degli spazi attorno al + o restituirà 4+2 . Questo non è richiesto quando si utilizza $$ .

.

Quando hai bc disponibile, potresti sicuramente andare con esso. Ho trovato molto interessante la seguente pagina: http://www.humbug.in/2010/makefile-tricks-arithmetic-addition-subtraction-multiplication-division-modulo-comparison/

La libreria GNU Make Standard fornisce funzioni aritmetiche intere.

 include gmsl JPI = 4 JPJ = 2 JPIJ = $(call plus,$(JPI),$(JPJ)) 

Con makepp è molto più semplice. Ottieni l’accesso diretto all’interprete Perl sottostante. In questo caso la funzione makeperl effettua l’espansione delle variabili prima di valutare come Perl, la funzione perl OTOH valuterà solo:

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

Puoi usare il comando builtin & echo al di fuori di una regola come istruzione.

Nel supporto GNU Make with Guile (cioè dalla versione 4.0) è facile usare la call in linguaggio Scheme per calcoli aritmetici o di altro tipo. È fatto senza creare alcuna subshell o processo figlio.

Un esempio

 JP-I := 4 JP-J := 2 JP-IJ := $(guile (* $(JP-I) $(JP-J) )) $(info JP-IJ = $(JP-IJ) ) # prints: JP-IJ = 8 

Vedi anche il manuale per le funzioni aritmetiche di Guile.