कमांड लाइन से अतिरिक्त चर बनाने के लिए


613

क्या मैं कमांड लाइन तर्क के रूप में एक GNU मेकफाइल के लिए चर पास कर सकता हूं? दूसरे शब्दों में, मैं कुछ तर्कों को पारित करना चाहता हूं जो अंततः मेकफाइल में चर बन जाएंगे।

जवाबों:


752

आपके पास अपने मेकफाइल के बाहर से वैरिएबल सेट करने के लिए कई विकल्प हैं:

  • पर्यावरण से - प्रत्येक पर्यावरण चर एक नाम और मूल्य के साथ एक बदलावशील चर में बदल जाता है।

    आप -eविकल्प (उर्फ --environments-override) को भी सेट करना चाह सकते हैं , और आपके पर्यावरण चर, मेकफाइल में किए गए असाइनमेंट को ओवरराइड कर देंगे (जब तक कि ये असाइनमेंट स्वयं overrideनिर्देश का उपयोग नहीं करते हैं । हालांकि, यह अनुशंसित नहीं है, और यह ?=असाइनमेंट (सशर्त चर) का उपयोग करने के लिए बहुत बेहतर और लचीला है। असाइनमेंट ऑपरेटर, इसका केवल तभी प्रभाव पड़ता है जब चर को अभी तक परिभाषित नहीं किया गया है):

    FOO?=default_value_if_not_set_in_environment
    

    ध्यान दें कि कुछ चर पर्यावरण से विरासत में नहीं मिले हैं:

    • MAKE स्क्रिप्ट के नाम से प्राप्त होता है
    • SHELLया तो मेकफाइल में सेट किया गया है, या डिफॉल्ट के लिए /bin/sh(औचित्य: कमांड्स मेकफाइल के भीतर निर्दिष्ट किए गए हैं, और वे शेल-विशिष्ट हैं)।
  • कमांड लाइन से - makeलक्ष्य के साथ घुलमिल जाने पर, उसकी कमांड लाइन के हिस्से के रूप में परिवर्तनशील कार्य कर सकते हैं:

    make target FOO=bar
    

    लेकिन फिर जब तक आप असाइनमेंट में निर्देश का उपयोग नहीं करेंगे, तब तक मेकफाइल के भीतर परिवर्तन करने के सभी असाइनमेंट को FOOनजरअंदाज कर दिया जाएगा । (प्रभाव पर्यावरण चर के लिए विकल्प के साथ ही है )।override-e

  • पैरेंट मेक से एक्सपोर्ट - अगर आप मेकफिल से मेक कहते हैं, तो आपको आमतौर पर इस तरह से वेरिएबल असाइनमेंट नहीं लिखना चाहिए:

    # Don't do this!
    target:
            $(MAKE) -C target CC=$(CC) CFLAGS=$(CFLAGS)
    

    इसके बजाय, इन चरों को निर्यात करने के लिए बेहतर समाधान हो सकता है। एक चर निर्यात करना इसे हर शेल इनवॉइस के वातावरण में बनाता है, और इन कमांड से कॉल करें इन पर्यावरण चर को ऊपर बताए अनुसार चुनें।

    # Do like this
    CFLAGS=-g
    export CFLAGS
    target:
            $(MAKE) -C target
    

    आप सभीexport तर्कों का उपयोग बिना तर्क के भी कर सकते हैं ।


10
रिक्त स्थान के साथ कमांड लाइन से गुजरने के लिएmake A='"as df"'
Ciro Santilli 冠状 som som som at

4
लगता है जैसे आप पर्यावरण के चर की परवाह करते हुए परेशानी पूछ रहे हैं। एक बात के लिए, यह एक बुरा सपना है अगर यह ए में काम करता है और बी में जगह नहीं है, सिर्फ इसलिए कि उनके पास अलग-अलग वातावरण हैं।
जेम्स मूर

12
बस अनुभव के आधार पर, सीएफएलएजीएस जैसे सामान निर्यात करना बड़ी परियोजनाओं के लिए दुःस्वप्न का एक नुस्खा है। बड़ी परियोजनाओं में अक्सर तीसरी पार्टी लाइब्रेरी होती है जो केवल दिए गए झंडे के सेट के साथ संकलित होती है (जो फिक्सिंग को परेशान नहीं करता है)। यदि आप CFLAGS निर्यात करते हैं, तो आपकी परियोजना का CFLAGS 3rd पार्टी लाइब्रेरी को ओवरराइड करता है और संकलन त्रुटियों को ट्रिगर करता है। एक वैकल्पिक तरीका export PROJECT_MAKE_ARGS = CC=$(CC) CFLAGS=$(CFLAGS)इसे परिभाषित करने और इसे पास करने के लिए हो सकता है make -C folder $(PROJECT_MAKE_FLAGS)। अगर पर्यावरण को नजरअंदाज करने के लिए लाइब्रेरी के मेफाइल को बताने का कोई तरीका है, तो यह आदर्श (-ई के विपरीत) होगा।
आरडी

24
चेतावनी: "ऊपर माता-पिता से निर्यात करें" अनुभाग में, "यह मत करो!" है गंभीर रूप से भ्रामक । कमांड लाइन पर वेरिएबल्स को पास करने से सब-मेकफाइल में असाइनमेंट्स ओवरराइड हो जाते हैं, लेकिन एक्सपोर्टेड वैरिएबल सब-मेकफाइल में असाइनमेंट्स को ओवरराइड नहीं करते हैं । सब-मेफ़ाइल के लिए चर को पार करने के लिए ये दो तरीके समतुल्य नहीं हैं और इसे भ्रमित नहीं किया जाना चाहिए।
जोनाथन बेन-अवराम

4
कोई अंतर ? make target FOO=bar make FOO=bar target?
gfan

213

सबसे सरल तरीका है:

make foo=bar target

फिर अपने मेकफाइल में आप का उल्लेख कर सकते हैं $(foo) । ध्यान दें कि यह उप-स्वचालित रूप से प्रचारित नहीं करेगा।

यदि आप उप-मेक का उपयोग कर रहे हैं, तो इस लेख को देखें: एक उप-बनाने के लिए चर का संचार


2
includedमुख्य मेकफाइल में मेकफिल से आपका तात्पर्य है ?
पाब्लो

2
@ मिचेल: इसका मतलब है मेकफाइल के अंदर से फिर से कॉल करना। जब से आप इस विवरण में रुचि रखते हैं मैंने अपना उत्तर अपडेट कर दिया है।
मार्क बायर्स

2
"ध्यान दें कि यह स्वचालित रूप से उप-प्रचार नहीं करेगा।" झूठ! "डिफ़ॉल्ट रूप से, केवल वैरिएबल जो पर्यावरण या कमांड लाइन से आए थे, को पुनरावर्ती इनवॉइस में पास किया गया है। आप अन्य वेरिएबल्स को पास करने के लिए एक्सपोर्ट डायरेक्टिव का उपयोग कर सकते हैं।" gnu.org/software/make/manual/html_node/…
ThomasMcLeod

82

कहो तुम एक makefile इस तरह है:

action:
    echo argument is $(argument)

फिर आप इसे कॉल करेंगे make action argument=something


5
इसलिए स्थिति के संदर्भ में लक्ष्य और तर्कों को आपस में जोड़ा जा सकता है?
पाब्लो


25

से मैनुअल :

मेक इन वेरिएबल्स उस वातावरण से आ सकते हैं जिसमें मेक रन किया जाता है। प्रत्येक पर्यावरण चर जो बनाता है जब देखता है कि यह एक ही नाम और मूल्य के साथ एक परिवर्तनशील चर में बदल जाता है। हालाँकि, मेकफाइल में या कमांड तर्क के साथ एक स्पष्ट असाइनमेंट, पर्यावरण को ओवरराइड करता है।

तो आप (bash से) कर सकते हैं:

FOOBAR=1 make

FOOBARआपके Makefile में एक चर के परिणामस्वरूप ।


2
अन्य तरीका वास्तव में लगभग सभी मामलों में बेहतर है। मैं इसे पूर्णता के लिए यहाँ छोड़ दूँगा।
थॉमस

यह एकमात्र उत्तर है जो एक ही लाइन पर मेक कमांड से पहले वेरिएबल्स के असाइनमेंट को दिखाता है - यह जानने लायक है कि यह सिंटैक्स त्रुटि नहीं है।
M_M

7

यहां एक और विकल्प का हवाला नहीं दिया गया है जो स्टेलमैन और मैकग्राथ द्वारा जीएनयू मेक बुक में शामिल है (देखें http://www.chemie.fu-berlin.de/chemnet/use/info/make/make_7.html )। यह उदाहरण प्रदान करता है:

archive.a: ...
ifneq (,$(findstring t,$(MAKEFLAGS)))
        +touch archive.a
        +ranlib -t archive.a
else
        ranlib archive.a
endif

यदि किसी दिए गए पैरामीटर में यह दिखाई देता है तो यह सत्यापित करना शामिल है MAKEFLAGS। उदाहरण के लिए .. मान लीजिए कि आप c ++ 11 में थ्रेड्स के बारे में पढ़ रहे हैं और आपने अपना अध्ययन कई फ़ाइलों ( class01, ..., classNM) में विभाजित किया है और आप चाहते हैं: सभी को संकलित करें और व्यक्तिगत रूप से चलाएं या एक बार में संकलित करें समय और इसे चलाएं यदि एक ध्वज निर्दिष्ट किया गया है ( -rउदाहरण के लिए)। तो, आप निम्नलिखित के साथ आ सकते हैं Makefile:

CXX=clang++-3.5
CXXFLAGS = -Wall -Werror -std=c++11
LDLIBS = -lpthread

SOURCES = class01 class02 class03

%: %.cxx
    $(CXX) $(CXXFLAGS) -o $@.out $^ $(LDLIBS)
ifneq (,$(findstring r,  $(MAKEFLAGS)))
    ./$@.out
endif

all: $(SOURCES)

.PHONY: clean

clean:
    find . -name "*.out" -delete

उसके बाद, आप:

  • फ़ाइल w / बनाएँ और चलाएं make -r class02;
  • सभी w / makeया बनाएँ make all;
  • सभी w / का निर्माण करें और चलाएं make -r(मान लें कि उन सभी में कुछ खास तरह के ऐशो-आराम के सामान हैं और आप बस उन सभी का परीक्षण करना चाहते हैं)

6

ऐसा लगता है

कमांड आर्ग्स पर्यावरण चर को अधिलेखित कर देता है

makefile

send:
    echo $(MESSAGE1) $(MESSAGE2)

उदाहरण चलाते हैं

$ MESSAGE1=YES MESSAGE2=NG  make send MESSAGE2=OK
echo YES OK
YES OK

5

यदि आप मेकफाइल नामक फाइल बनाते हैं और इस $ (unittest) की तरह एक वैरिएबल जोड़ते हैं तो आप वाइल्डकार्ड के साथ भी मेकफाइल के अंदर इस वैरिएबल का उपयोग कर पाएंगे

उदाहरण :

make unittest=*

मैं BOOST_TEST का उपयोग करता हूं और पैरामीटर --run_test = $ (unittest) को वाइल्डकार्ड देता हूं, तब मैं अपनी अभिव्यक्ति के परीक्षण के लिए नियमित अभिव्यक्ति का उपयोग कर सकूंगा, जो मैं चाहता हूं कि मेरा मेकफाइल चले।


4
export ROOT_DIR=<path/value>

फिर $(ROOT_DIR)Makefile में वैरिएबल का उपयोग करें ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.