2009-12-18 14 views

Respuesta

11

Si estás usando GNU make y ha bc instalado en su sistema, puede usar algo como esto:

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

expr es más común que bc: '$ (shell expr $ (JPI) \ * $ (JPJ))' –

+0

@DanielAlder: Interesante, siempre uso 'bc' pero puedo ver cómo' expr' es posiblemente más conveniente si está haciendo una aritmética simple de base 10 (que es el caso de esta pregunta). – mrkj

10

Es torpe (o brillante, dependiendo de su perspectiva), pero se puede hacer aritmética directamente en GNU make. Ver Learning GNU Make Functions with Arithmetic. Tenga en cuenta sin embargo que este método no escala bien. Funcionará maravillosamente para números pequeños como lo ha demostrado en su pregunta, pero no funciona bien cuando trabaja con números de gran magnitud (más de 10 000 000).

+1

Lo llamo Lisp-iant –

+0

hmmm .... es sorprendente ver que los makefiles pueden hacer matemática. ¿No debería ser una característica fácil de agregar? – Kamath

+0

@EricMelski: ¡Buen enlace, gracias! –

0

Con makepp es mucho más fácil. Usted obtiene acceso directo al intérprete subyacente de Perl. En este caso la función makeperl hace la expansión de variables antes de evaluar como Perl, la función del Perl otoh sólo se evaluaría:

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

Puede utilizar el & orden interna de eco fuera de una regla como una declaración.

24

Usando Bash arithmetic expansion:

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

La primera línea es a choose the Bash shell instead of the default (sh). Normalmente, sh no es compatible con la expansión aritmética. Sin embargo, en Ubuntu,/bin/sh es proporcionado por Dash, which supports this feature. Entonces esa línea podría ser salteada.

El doble signo de dólar es porque queremos the expansion to be done by the shell. Nota: las variables JPI y JPJ se expanden por marca primero, entonces la expresión se pasa a golpear así:

$((4 * 2)) 
+3

POSIX 'sh' de hecho admite [expansión aritmética] (http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_04). –

+0

+1 ya que esta es la mejor solución porque solo depende de un shell compatible con POSIX. Y gracias por señalar que necesitamos un signo de dólar doble al hacer la aritmética de shell en make. – Flow

4

El GNU Make Standard Library proporciona funciones aritméticas de números enteros.

include gmsl 

JPI = 4 
JPJ = 2 

JPIJ = $(call plus,$(JPI),$(JPJ)) 
+3

Oh hombre ... Vi esto y pensé GENIAL, algo lo construí sin hacks. Entonces noté que es un proyecto de SourceForge, y el proyecto simplemente secuestró el nombre y agregó algo de exageración. – jww

+0

¿Secuestrado qué nombre? –

+0

@MatthewSimoneau 'GNU' – YoYoYonnY

2

Respuesta de @mrkj es grande, pero como menciona @ Daniel, no todos los sistemas tienen bc (por ejemplo, yo no tengo en MSys).

he encontrado los siguientes dos métodos, tanto el uso de la cáscara: $$ ((...)) y 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)) 

Tenga en cuenta que cuando se utiliza expr, usted deberá espacios de venta alrededor del + o devolverá 4+2. Esto no es necesario cuando se usa $$.

.

Cuando tiene bc disponible, definitivamente puede ir con él.Encontré la siguiente página muy interesante: http://www.humbug.in/2010/makefile-tricks-arithmetic-addition-subtraction-multiplication-division-modulo-comparison/

0

En GNU Make with Guile compatible (es decir, desde la versión 4.0) es fácil de usar llamar al lenguaje Scheme para aritmética u otros cálculos. Se realiza sin crear ningún proceso subshell o secundario.

Un ejemplo

JP-I := 4 
JP-J := 2 
JP-IJ := $(guile (* $(JP-I) $(JP-J))) 

$(info JP-IJ = $(JP-IJ)) 
# prints: JP-IJ = 8 

Véase también el manual para Guile Arithmetic Functions.

Cuestiones relacionadas