2009-02-03 17 views
46

में फ़ंक्शंस मैं कई बार दोहराए जाने वाले सामानों के साथ मेकफ़ाइल लिख रहा हूं, उदा।मेकफ़ाइल

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' परिभाषित किया गया है (और आमतौर पर लिनक्स है, लेकिन यह भी Cygwin या OSF1 से हो सकता है) और चर 'difort' और 'err_arch' भी परिभाषित कर रहे हैं । विभिन्न संकलक लक्ष्यों के लिए कोड का यह ब्लॉक कई बार उपयोग किया जाता है ('' नाम का एक सम्मेलन का उपयोग करके)। चूंकि यह एक बड़ी मात्रा में अनावश्यक कोड है, इसलिए मैं इसे अधिक सरल तरीके से लिखने में सक्षम होना चाहता हूं। जैसे, मैं कुछ इस तरह करना चाहते हैं:

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

जहां संकलन तर्कों के आधार पर उपरोक्त कोड कर एक समारोह हो सकता है। क्या किसी को कोई विचार है कि मैं इसे कैसे पूरा कर सकता हूं?

उत्तर

35

3 संबंधित अवधारणाओं रहे हैं:

  1. call function
  2. multi-line variables
  3. conditionals

पुनर्संशोधित परिणाम ऐसा दिखाई दे सकता:

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) लाइन जारी है। कोई मल्टी-लाइन चर आवश्यक नहीं है, क्योंकि यह केवल शेल कोड की एक पंक्ति है। मल्टी-लाइन चर केवल अन्य ब्लॉक में उपयोग किए जाते हैं।

आप मानकों की जरूरत नहीं है, तो आप उपयोग कर सकते हैं: = काम और सिर्फ $(compile) साथ विधि का विस्तार (canned recipes देखें)

[संपादित करें]नोट: का उपयोग करना संस्करण 3.82 से पहले, = बनाने मेरे लिए परिभाषित बयान के अंत में पहचाना नहीं गया था। मैंने इसके बजाय define compile का उपयोग कर इसे ठीक किया।

+0

यह पिछले उत्तर की तुलना में बेहतर क्यों है जिसे वर्तमान में सही के रूप में चिह्नित किया गया है? –

+1

आपको \ n की बजाय बहु-पंक्ति चर का उपयोग करना चाहिए। जो फिर से "उस उत्तर को संपादित करने के लिए बहुत अधिक" होगा (जहां तक ​​मुझे अब तक समीक्षा मिली है) – JonnyJD

+0

और मल्टीलाइन वेरिएबल समझाते हुए टिप्पणी के लिए थोड़ा अधिक है। लेकिन आपको निश्चित रूप से सहमत नहीं होना है। – JonnyJD

36

आप call function देख रहे हैं।

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 के conditionalssh के बजाय के देखना चाहिए।

+1

धन्यवाद, यह काम किया! :) मैं सीधे नहीं देखता कि मैं मेक की सशर्तियों का उपयोग कैसे कर सकता हूं जैसा मैं चाहता हूं। कम से कम पुनर्गठन के _lot_ के बिना नहीं। बेशक, यह सिर्फ इसलिए हो सकता है क्योंकि मुझे मेकफ़ाइल लिखने के साथ बहुत अनुभवी नहीं है ... –

+0

यह एक प्रमुख उदाहरण है जहां आपको [बहु-पंक्ति चर] का उपयोग करना चाहिए (http://www.gnu.org/software/make /manual/html_node/Multi_002dLine.html)। – JonnyJD