Funkcje w Makefile

Piszę Makefile z wieloma powtarzalnymi rzeczami, np.

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

Gdzie zdefiniowany jest docelowy 'syst', zdefiniowana jest zmienna ' UNAME '(zwykle jest to Linux, ale może też być to Cygwin lub OSF1) oraz zmienne' difort 'i' err_arch'. Ten blok kodu jest używany bardzo wiele razy dla różnych celów kompilatora (używając konwencji nazwy''). Ponieważ jest to ogromna ilość nadmiarowego kodu, chciałbym móc go napisać w prostszy sposób. Np. chciałbym zrobić coś takiego:

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

Gdzie compile może być funkcją wykonującą powyższy kod na podstawie argumentów. Czy ktoś wie, jak mógłbym to osiągnąć?

Author: Rob Wells, 2009-02-03

2 answers

Istnieją 3 powiązane pojęcia:

  1. call function
  2. zmienne Wielowierszowe
  3. conditionals

Wynik refakturowania może wyglądać tak:

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


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

Ten \, który został, to kontynuacja $(MAKE) linii powłoki. Nie jest tu potrzebna zmienna wielowierszowa, ponieważ jest to tylko jedna linia kodu powłoki. Zmienne Wielowierszowe są używane tylko w bloku else.

Jeśli nie potrzebujesz parametrów można użyć: = assignment i po prostu rozwiń metodę za pomocą $(compile) (Zobacz przepisy konserwowe )

[Edytuj] Notatka: używając make przed wersją 3.82, Dla mnie = nie był rozpoznawany na końcu instrukcji define. Naprawiłem to używając define compile.

 35
Author: JonnyJD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-25 21:28:28

Szukasz call function .

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

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

Jeśli możesz zrestrukturyzować swoje Makefile trochę, powinieneś zobaczyć, czy możesz użyć make's conditionals zamiast sh's.

 36
Author: ephemient,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-04 23:12:26