कमांड लाइन से मेकफाइल के लिए तर्क कैसे पारित करें?


109

कमांड लाइन से मेकफाइल के लिए तर्क कैसे पारित करें?

मैं समझता हूं कि मैं कर सकता हूं

$ make action VAR="value"
$ value

साथ में Makefile

VAR = "default"
action:
    @echo $(VAR)

मुझे निम्नलिखित व्यवहार कैसे मिलेगा?

$ make action value
value

?

कैसा रहेगा

$make action value1 value2
value1 value2


जवाबों:


212

आपको शायद ऐसा नहीं करना चाहिए; तुम कैसे काम करता है के बुनियादी पैटर्न को तोड़ रहे हैं। लेकिन यहाँ यह है:

action:
        @echo action $(filter-out $@,$(MAKECMDGOALS))

%:      # thanks to chakrit
    @:    # thanks to William Pursell

संपादित करें:
पहले आदेश की व्याख्या करने के लिए,

$(MAKECMDGOALS) कमांड लाइन पर "टारगेट" की सूची है, जैसे "एक्शन वैल्यू 1 वैल्यू 2"।

$@नियम के लक्ष्य के नाम के लिए एक स्वचालित चर है , इस मामले में "कार्रवाई"।

filter-outएक ऐसा कार्य है जो किसी सूची से कुछ तत्वों को निकालता है। तो $(filter-out bar, foo bar baz)रिटर्न foo baz(यह अधिक सूक्ष्म हो सकता है, लेकिन हमें यहां सूक्ष्मता की आवश्यकता नहीं है)।

इन्हें एक साथ रखें और $(filter-out $@,$(MAKECMDGOALS))कमांड लाइन पर "कार्रवाई" के अलावा निर्दिष्ट लक्ष्यों की सूची लौटाएं, जो कि "value1 value2" हो सकता है।


1
$(shell echo $(MAKECMDGOALS) | sed 's!^.* $@ !!')पहले सभी लक्ष्यों को छोड़ दें और केवल निम्नलिखित बातों को तर्क के रूप में देखें:make target1 target2 action value1 value2
एवगेनियन जनरलोव

1
मेरी अज्ञानता को क्षमा करो। मैंने googling की कोशिश की है %:और @:उन "निर्देशों" (या जो भी उन्हें बुलाया जाता है) पर जानकारी नहीं मिल सकती है। क्या आप समझा सकते हैं?
जॉन

15
@Jon: मैनुअल यहाँ है । भाग से मिलकर %:और @:एक है नियम । लक्ष्य नाम का %अर्थ है कि यह एक नियम है जो किसी भी चीज़ से मेल खाता है ; अर्थात्, यदि मेक को आपके द्वारा बताई गई चीज़ बनाने के लिए कोई अन्य तरीका नहीं मिल सकता है, तो वह उस नियम को निष्पादित करेगा। @:एक है नुस्खा ; :साधन कुछ भी नहीं है, और @इसका मतलब है यह चुपचाप करते हैं।
बीटा

धन्यवाद। मैं उस मैनुअल को पढ़ रहा था और मैंने पहली बार में विचार नहीं किया था, वह %:वास्तव % :में एक वाइल्डकार्ड प्रकार का लक्ष्य नाम था। @:हालांकि उस मैनुअल पेज में मुझे कुछ भी दिखाई नहीं दे रहा है ... यह सुझाव देता है कि "डू-नथिंग" नियम ;का लक्ष्य विनिर्देश के बाद बस होगा , इसलिए, यह % : ;"वाइल्डकार्ड" के रूप में लिखना अधिक सटीक नहीं होगा। "सुखद" नियम?
जॉन

1
filter-outजब कार्य कमांड लाइन पर निर्दिष्ट लक्ष्य की निर्भरता है, तो काम नहीं करता है, क्योंकि $@यह निर्भरता के नाम पर सेट किया जाएगा , कमांड लाइन पर मूल तर्क को नहीं कहा जाता है। इसके बजाय, मैं MAKECMDGOALSएक शेल ऐरे को असाइन करता हूं और फिर पहला तत्व @ args=($(MAKECMDGOALS)); args=("$${args[@]:1}")
निकालता हूं

18

यहाँ @ बीटा के आधार पर एक सामान्य कार्य समाधान है

मैं SHELL=/bin/bashअपने Makefile के साथ GNU Make 4.1 का उपयोग कर रहा हूं , इसलिए YMMV!

यह हमें अतिरिक्त तर्क स्वीकार करने की अनुमति देता है (ऐसा कुछ नहीं करने पर जब हमें कोई ऐसा काम मिलता है जो एक त्रुटि फेंकने के बजाय मेल नहीं खाता है)।

%:
    @:

और यह एक मैक्रो है जो हमारे लिए आर्ग्स प्राप्त करता है:

args = `arg="$(filter-out $@,$(MAKECMDGOALS))" && echo $${arg:-${1}}`

यहाँ एक काम है जिसे यह कह सकते हैं:

test:
    @echo $(call args,defaultstring)

परिणाम होगा:

$ make test
defaultstring
$ make test hi
hi

ध्यान दें! आप एक "टास्कफाइल" का उपयोग करने से बेहतर हो सकते हैं, जो एक बैश पैटर्न है जो बनाने के लिए समान रूप से काम करता है, केवल माकेटोल्स की बारीकियों के बिना। Https://github.com/adriancooney/Taskfile देखें


इसने काम कर दिया!! अन्य लोगों को इसे आज़माने के लिए, सुनिश्चित करें कि tabपहले है @echo, नहीं space
अब्दुल्ला अल मारुफ - तुहिन 15

11

बहुत आसान aproach। एक कार्य पर विचार करें:

provision:
        ansible-playbook -vvvv \
        -i .vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory \
        --private-key=.vagrant/machines/default/virtualbox/private_key \
        --start-at-task="$(AT)" \
        -u vagrant playbook.yml

अब जब मैं इसे कॉल करना चाहता हूं तो मैं कुछ इस तरह से चलाता हूं:

AT="build assets" make provision

या केवल:

make provisionइस मामले ATमें एक खाली स्ट्रिंग है


-2

ऐसा करने की कोशिश मत करो

$ make action value1 value2

इसके बजाय स्क्रिप्ट बनाएँ:

#! /bin/sh
# rebuild if necessary
make
# do action with arguments
action "$@"

और यह करो:

$ ./buildthenaction.sh value1 value2

अधिक स्पष्टीकरण के लिए ऐसा क्यों करते हैं और मेकफाइल हैकरी के काव्यों ने मेरे जवाब को एक और बहुत ही समान रूप से पढ़ा, लेकिन प्रतीत होता है कि डुप्लिकेट प्रश्न नहीं है: "रन बनाने" के लिए तर्क पारित करना

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