Функции в Makefile - программирование
Подтвердить что ты не робот

Функции в Makefile

Я пишу Makefile с большим количеством повторяющихся вещей, например.

debug_ifort_Linux:
        if [ $(UNAME) = Linux ]; then                           \
          $(MAKE) FC=ifort FFLAGS=$(difort) PETSC_FFLAGS="..."  \
                  [email protected] LEXT="ifort_$(UNAME)" -e syst;      \
        else                                                    \
          echo $(err_arch);                                     \
          exit 1;                                               \
        fi

где определена целевая "syst", определена переменная "UNAME" (и обычно это Linux, но может также быть Cygwin или OSF1), а также определены "difort" и "err_arch" переменных. Этот блок кода используется очень много раз для разных целей компилятора (с использованием соглашения об именах ''). Поскольку это огромное количество избыточного кода, я хотел бы написать его более простым способом. Например, я хотел бы сделать что-то вроде этого:

debug_ifort_Linux:
        compile(uname,compiler,flags,petsc_flags,target,lext)

где компиляция может быть функцией, выполняющей код выше на основе аргументов. Кто-нибудь знает, как я мог это сделать?

4b9b3361

Ответ 1

Существует 3 взаимосвязанных понятия:

Реорганизованный результат может выглядеть так:

ifeq ($(UNAME),Linux)
    compile = $(MAKE) FC=$(1) FFLAGS=$(2) PETSC_FFLAGS=$(3) \
                      [email protected] LEXT="$(1)_$(UNAME)" -e syst
else
    define compile =
        echo $(err_arch)
        exit 1
    endef
endif


debug_ifort:
        $(call compile,ifort,$(difort),"...")

Остается \ оставить строку $(MAKE) для оболочки. Здесь нет многострочной переменной, потому что это всего лишь одна строка кода оболочки. Многострочные переменные используются только в блоке else.

Если вам не нужны параметры, вы можете использовать: = назначение и просто расширить метод с помощью $(compile) (см. консервированные рецепты)

[Изменить] Примечание. Используя make до версии 3.82, value = не было распознано в конце инструкции define для меня. Я исправил это, используя define compile вместо этого.

Ответ 2

Вы ищете функцию call.

compile =                                                 \
        if [ $(UNAME) = $(1) ]; then                      \
          $(MAKE) FC=$(2) FFLAGS=$(3) PETSC_FFLAGS="..."  \
                  [email protected] LEXT="$(4)_$(UNAME)" -e syst; \
        else                                              \
          echo $(err_arch);                               \
          exit 1;                                         \
        fi

debug_ifort_Linux:
        $(call compile,Linux,ifort,$(difort),ifort)

Если вы можете немного изменить структуру Makefile, вы должны увидеть, можете ли вы использовать make условные выражения вместо sh 's.