Подтвердить что ты не робот

Как выполнить арифметику в make файле?

Можно ли выполнить некоторые операции над переменными в make файле? Например, определение

JPI=4
JPJ=2

Можно ли определить в том же make файле переменную JPIJ, равную расширенному значению $(JPI) * $(JPJ)?

4b9b3361

Ответ 1

Использование Bash арифметическое расширение:

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

В первой строке выберите оболочку Bash вместо стандартного (sh). Как правило, sh не поддерживает арифметическое расширение. Однако в Ubuntu/bin/sh предоставляется Dash, которая поддерживает эту функцию. Так что эта строка может быть пропущена.

Знак с двойным долларом заключается в том, что мы хотим расширение, которое должно выполнить оболочка. Примечание: переменные JPI и JPJ разворачиваются первым, затем выражение передается в Bash следующим образом:

$(( 4 * 2 ))

Ответ 2

Если вы используете GNU make и имеете bc, установленный в вашей системе, вы можете использовать что-то вроде этого:

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

Ответ 3

Это неуклюжие (или блестящие, в зависимости от вашей перспективы), но вы можете сделать арифметику непосредственно в GNU make. См. Изучение функций GNU с помощью арифметики. Имейте в виду, что этот метод не очень хорошо масштабируется. Он будет работать чудесно для небольших чисел, как вы показали в своем вопросе, но это не очень хорошо, когда вы работаете с числами с большой величиной (более 10 000 000).

Ответ 4

GNU Make Standard Library обеспечивает целочисленные арифметические функции.

include gmsl

JPI = 4
JPJ = 2

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

Ответ 5

Ответ от @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/

Ответ 6

С makepp это намного проще. Вы получаете прямой доступ к базовому интерпретатору Perl. В этом случае функция makeperl выполняет разложение переменных перед оценкой как Perl, функция perl OTOH будет оценивать только:

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

Вы можете использовать команду builtin & echo вне правила в качестве инструкции.

Ответ 7

В GNU Make с поддержкой 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 Арифметические функции.