2012-01-25 16 views
7

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

मेरी Makefile के अनिवार्य

INSTALL_USER := fileUser 
INSTALL_GROUP := fileGroup 

.PHONY: test 
test: 
    $(call touchFile,~/test.ini) 

define touchFile 
$(eval fileName := $(strip $(1))) 
-touch $(fileName) 
-chmod -c 664 $(fileName) 

$(info filename info $(fileName)) 
$(info $(shell stat -c "%a %U:%G" $(fileName))) 

$(if ifeq "foo" "bar", @echo match is broken, @echo match works) 
$(if ifneq "foo" "bar", @echo match works, @echo match is broken) 

$(if ifneq ($(shell stat -c %a $(fileName)),664), $(warning Error - $(fileName) does not have expected permissions of 664)) 
-chgrp -c $(INSTALL_GROUP) $(fileName) 
$(if ifneq ($(shell stat -c %G $(fileName)),$(INSTALL_GROUP)), $(warning Error - $(fileName) does not belong to $(INSTALL_GROUP) group)) 
-chown -c $(INSTALL_USER) $(fileName) 
$(if ifneq ($(shell stat -c %U $(fileName)),$(INSTALL_USER)), $(warning Error - $(fileName) does not belong to $(INSTALL_USER) user)) 
endef 

make test आउटपुट

filename info ~/test.ini 
664 myUserName:myGroup 
Makefile:7: Error - ~/test.ini does not have expected permissions of 664 
Makefile:7: Error - ~/test.ini does not belong to common group 
Makefile:7: Error - ~/test.ini does not belong to netserve user 
touch ~/test.ini 
chmod -c 664 ~/test.ini 
match is broken 
match works 
chgrp -c fileGroup ~/test.ini 
changed group of `/home/myUserName/test.ini' to fileGroup 
chown -c fileUser ~/test.ini 
chown: changing ownership of `/home/myUserName/test.ini': Operation not permitted 
make: [test] Error 1 (ignored) 

मैं माना जाता है चल रहे हैं निम्नलिखित:

  • $ (अगर ...) है फ़ंक्शन को पैरामीटर के साथ बुलाए जाने से पहले, "संकलन-समय" पर मूल्यांकन किया जाता है। लेकिन, हार्ड-कोडेड ifeq "foo" "bar" भी एक अवैध परिणाम देता है। इसके अतिरिक्त, $(info ...) "संकलन-समय" पर $(fileName) का सही मूल्यांकन करता है।
  • documentation वास्तव में उदाहरण नहीं देता है, इसलिए $(if ifeq...) के अलावा, मैंने $(ifeq ...) भी कोशिश की, जिसे अनदेखा किया गया।
  • "गैर-कार्यात्मक" if (यानी ifeq बिना $(if...)) फ़ंक्शन के अंदर /bin/sh: ifeq: command not found देता है।

क्या कोई यह पहचानने में सहायता कर सकता है कि मेरी सशर्तताएं क्यों व्यवहार नहीं कर रही हैं (या मैं गलत चीज़ की अपेक्षा क्यों कर रहा हूं)?

चेतावनी: मुझे पता है कि फ़ाइल मौजूद नहीं है, लेकिन यह बाधा की तुलना में छोटी होनी चाहिए, लेकिन यह बाधाओं की तुलना में तुच्छ होना चाहिए।

+1

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

उत्तर

31

$(if ...) conditional functiontrue का मूल्यांकन जब पहला तर्क यह करने के लिए पारित कर दिया गैर खाली है। आपके मामले में स्थिति शाब्दिक पाठ है: ifeq "foo" "bar", जो जाहिर है, खाली नहीं है।

ifeq/ifneq conditionals वास्तव में निर्देश हैं, कार्य नहीं। वे परिवर्तनीय परिभाषा और कार्यों में उपयोग नहीं किया जा सकता है।

अपने उदाहरण पर वापस filter and findstring तरह हालत उपयोग कार्यों के अंदर समानता के लिए परीक्षण स्ट्रिंग के लिए,:

$(if $(filter foo,bar),@echo match is broken,@echo match works) 
$(if $(filter-out foo,bar),@echo match works,@echo match is broken) 

BTW यह भी बेहतर पठनीयता के लिए एक इनलाइन रूप में तब्दील किया जा सकता है:

@echo match $(if $(filter foo,bar),is broken,works) 
@echo match $(if $(filter-out foo,bar),works,is broken) 
+0

महान व्याख्या – anoop

+0

@anoop धन्यवाद! –

1

आपको $(if कामों के तरीके को गलत समझा जाता है। मेकअप की जानकारी डॉक्स से:

$ (अगर हालत, तत्कालीन भाग [, बाकी-भाग]) ' `अगर' समारोह एक कार्यात्मक संदर्भ

पहले में सशर्त विस्तार के लिए सहायता प्रदान करता है तर्क, शर्त, पहले सभी पिछले और पीछे घुमावदार व्हाइटस्पेस छीन लिया गया है, फिर विस्तारित किया गया है। यदि यह तक किसी भी गैर-खाली स्ट्रिंग तक फैलता है, तो स्थिति को सत्य माना जाता है। यदि यह एक खाली स्ट्रिंग तक फैलता है, तो स्थिति पर गलत मानी जाती है।

अपने सभी उदाहरणों में, अपनी हालत ifeq SOMETHING OTHERTHING की तरह कुछ है - जो एक गैर खाली स्ट्रिंग (ifeq क्या अन्य बातों के कर रहे हैं पर ध्यान दिए बिना से) है, और इतनी के रूप में सही व्यवहार किया जाता है।

4

मुझे इस समस्या का सामना करना पड़ा और मैंने पाया कि आप "अगर" फ़ंक्शन के "स्थिति" भाग में "फ़िल्टर" फ़ंक्शन के परिणाम का उपयोग कर सकते हैं। यहाँ एक उदाहरण एक PDF ("जताना" के साथ)

uname  :=$(shell uname -s) 
is_darwin :=$(filter Darwin,$(uname)) 
viewpdf :=$(if $(is_darwin), open, evince) 
+0

धन्यवाद! मैं अपने स्वयं के मेक टूल के लिए एक सरल उदाहरण चाहता था। – yoshi

0

"खुला") के साथ या तो लिनक्स में खोलने, या OSX में के लिए उपयोगी है आप की जाँच करने के लिए अपने OS संस्करण लिनक्स या अन्य और अगर यह होता है कि चाहते हैं लिनक्स है, तो आप कुछ संदेश मुद्रित करने के लिए तो यू इस चरणों का पालन कर सकते हैं:

ifneq ($(TARGETOS), Linux) 
    target: server 
    @echo 
    @echo $(MSG) $(TARGETOS) 
else 
target: server 
    @echo $(MSG) $(TARGET) 
endif 

इससे पहले कि मैं ifeq साथ करने की कोशिश की लेकिन यह केवल किसी और भाग मुद्रित किया गया है। मेरा ओएस लिनक्स, उबंटू है।

यदि किसी को यह मिला कि यह उत्तर संशोधित किया जाना चाहिए, तो वे इसके लिए भी बेहतर उत्तर दे सकते हैं।

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