2017-08-31 28 views
5

पर मौजूद हो सकता है या नहीं हो सकता है, मैं एक ऐसा लक्ष्य जोड़ना चाहता हूं जो envdir के साथ प्रोग्राम चलाता हो।

ENVDIR := $(shell command -v envdir) 

serve: | $(ENVDIR) 
    $(ENVDIR) /usr/local/myservice/env python -m SimpleHTTPServer 8000 

विचार यह है कि यदि उपयोगकर्ता को envdir इंस्टॉल नहीं है, तो यह उनके लिए इंस्टॉल करेगा। मुझे पाइप चरित्र की आवश्यकता है क्योंकि मैं हमेशा इसे चलाने के लिए नहीं चाहता; मैं बस इसके किसी संस्करण को उपस्थित होना चाहता हूं। दुर्भाग्य से, मैं बहुत अच्छी तरह से भविष्यवाणी नहीं कर सकता जहां envdir स्थापित किया जाएगा।

UNAME := $(shell uname) 
$(ENVDIR): 
ifeq ($(UNAME), Darwin) 
    brew install daemontools 
endif 
ifeq ($(UNAME), Linux) 
    sudo apt-get install daemontools 
endif 
# Add other operating systems here as appropriate... 

दूसरी समस्या मैं में चलाने कि अगर उपयोगकर्ता envdir स्थापित नहीं है, चर रिक्त स्ट्रिंग का आकलन करती है। तो ए) मेरा "इंस्टॉल envdir" लक्ष्य वास्तव में नहीं चलता है, और बी) इसे चलाने के बाद, $ (ENVDIR) अभी भी खाली स्ट्रिंग पर सेट है, इसलिए इसे सेवा लक्ष्य में लोड करना काम नहीं करता है।

क्या कोई तरीका है ए) चलाने के लिए इंस्टॉल लक्ष्य प्राप्त करें, भले ही ENVDIR को अपरिभाषित किया गया हो, और बी) "इंस्टॉल envdir" लक्ष्य चलाने के अंत में चर के मान को फिर से परिभाषित करने के लिए?

कृपया "एनवीडीआईआर का उपयोग क्यों कर रहे हैं" के साथ प्रतिक्रिया न दें - मैं इस समस्या में विभिन्न प्रकार की विभिन्न बाइनरी के साथ दौड़ता हूं, यह सिर्फ एक आसानी से साझा करने योग्य उदाहरण होता है।

+0

आप उन मामलों के बीच अंतर करने के लिए सशर्त उपयोग क्यों नहीं करते हैं जहां 'envdir' पहले से स्थापित है और जहां यह नहीं है? 'ifeq ($ (ENVDIR),) ... और ... endif' शायद इसे बना सकता है। और 'envdir' इंस्टॉल रेसिपी के अंत में, आप 'ENVDIR' चर के मूल्य को बदलने की कोशिश करने के बजाय बस फिर से आवेदक कर सकते हैं (मुझे पता है, * रिकर्सिव मेक खराब है *, लेकिन बुरी चीजें कभी-कभी बेहद उपयोगी होती हैं)। –

उत्तर

0

"खाली" मुद्दा आप यह कर सकते हैं के लिए:

ENVDIR := $(or $(shell command -v envdir),envdir) 

तो (3.81 बनाने or समारोह जीएनयू में जोड़ा गया) कि shell समारोह रिक्त स्ट्रिंग पर फैलता है, envdir प्रतिस्थापित किया जाएगा। यह संभवतः आपकी सभी समस्याओं को हल करने के लिए पर्याप्त होगा क्योंकि स्थापना के बाद envdir कमांड अब पाथ पर दिखाई देगा, इसलिए आपको पूर्ण पथ की आवश्यकता नहीं है।

1

आप शेल के रूप में तो पूरी तरह से यह कर सकता है:

ENVDIR := $(command -v envdir 2> /dev/null || (install envdir > /dev/null && echo newEnvDirPath)) 

यह सबसे सरल है, लेकिन envdir का कारण बनता है स्थापित होने के लिए, भले ही वह वर्तमान लक्ष्य के लिए आवश्यक नहीं है।

ENVDIR:=$(cat .ENVDIR 2> /dev/null) 
$(type -v $(ENVDIR) > /dev/null || rm .ENVDIR) 

.ENVDIR: 
    command -v envdir 2> /dev/null > [email protected] || (install envdir > /dev/null && echo newEnvDirPath > [email protected]) 
    $(eval ENVDIR:=$$(cat [email protected])) 

shell: | .ENVDIR 

तो फ़ाइल .ENVDIR मौजूद नहीं है, यह नुस्खा है, जो या तो .ENVDIR करने के लिए स्थापित पथ लिखेंगे चलेंगे, या यह स्थापित हो जाएगा: आप एक लक्ष्य में यह चाहते हैं, तो आप यह की तरह कुछ कर सकता है और .ENVDIR पर नया पथ लिखें। किसी भी तरह से, जब रेसिपी लाइन खत्म होती है, .ENVDIR में निष्पादन योग्य पथ होगा। ENVDIR सेट करने के लिए लक्ष्य $(eval) चलाता है। ध्यान दें कि eval को कॉल करने से मेकफ़ाइल को दोबारा पोस्ट किया जा सकता है, जो आदर्श नहीं है, लेकिन सिस्टम पर केवल एक बार होना चाहिए। (बिल्ली कमांड के सामने डबल $$ भी ध्यान दें, जो इसे पढ़ने के समय में विस्तार से रोकता है ...)।

वैकल्पिक रूप से, यदि .ENVDIR मौजूद है, तो यह निर्धारित करने के लिए फ़ाइल को कौन सा envdir उपयोग करने का प्रयास करेगा। यह सुनिश्चित करने के लिए अगली पंक्ति पर एक चेक किया जाता है कि यह संस्करण अभी भी सिस्टम पर मौजूद है, और यदि नहीं, तो यह फ़ाइल को हटा देता है, इसे पुनर्निर्मित करने के लिए मजबूर करता है।

संबंधित मुद्दे