2010-03-10 27 views
8

के भीतर $ (वाइल्डकार्ड) को कैसे कॉल करें मैं अपने मेकफ़ाइल के लिए जेनेरिक बिल्ड टेम्पलेट बनाने की कोशिश कर रहा हूं, जैसे कि वे eval documentation में चर्चा करते हैं।

मुझे वाइल्डकार्ड फ़ंक्शन को एक eval के भीतर काम करने के लिए प्रतीत नहीं होता है। मूल कोड जिसमें मुझे समस्याएं आ रही हैं, इस तरह दिखती हैं।

SRC_DIR = ./src/ 

PROG_NAME = test 

define PROGRAM_template 
    $(1)_SRC_DIR = $(join $(SRC_DIR), $(1)/) 
    $(1)_SRC_FILES = $(wildcard $$($(1)_SRC_DIR)*.c) 
endef 

$(eval $(call PROGRAM_template, $(PROG_NAME))) 

all: 
    @echo $(test_SRC_DIR) 
    @echo $(test_SRC_FILES) 
    @echo $(wildcard $(wildcard $(test_SRC_DIR)*.c) 

जब मैं इस के साथ बनाने के चलाने के लिए, उत्पादन

./src/test 

[correct list of all .c files in ./src/test/] 

असल में, PROGRAM_template भीतर वाइल्डकार्ड कॉल के रूप में मैं यह उम्मीद eval'd नहीं जा रहा है। कॉल एक खाली सूची में परिणाम।
हालांकि कॉल कॉल सही तरीके से eval'd किया जा रहा है।

तो, मैं गलत क्या कर रहा हूं? मेरा अनुमान है कि

$$($(1)_SRC_DIR) 

सही नहीं है, लेकिन मैं इसे करने का सही तरीका नहीं समझ सकता।

संपादित करें एक बार यह हल हो जाने के बाद, मेरे लिए eval के साथ एक और मुद्दा हिट करने में लंबा समय नहीं लगा। मैं Workaround for GNU Make 3.80 eval bug

उत्तर

10

में एक नया प्रश्न यह पोस्ट किए जाने से बचने के लिए आप कार्य करता है और चर के लगभग सभी जब आप eval का उपयोग दोगुना करने की जरूरत है। ज्यादातर मामलों में, केवल 0 चीजें जो को डबल-एस्केप होने की आवश्यकता नहीं है, तर्क तर्क हैं (क्योंकि call फ़ंक्शन पूरी तरह से उनका विस्तार करेगा)। इस मामले में, आपको तकनीकी रूप से join या SRC_DIR से दोबारा बचने की आवश्यकता नहीं है, लेकिन यदि आप eval का उपयोग करते समय हमेशा सभी चर और कार्यों को दोबारा से बचें तो यह आपके जीवन को सरल बना देगा।

आपको डबल एस्केप की आवश्यकता है कि का उपयोग करते समय विस्तार दो बार होता है। eval फ़ंक्शन स्वयं विस्तार करता है, और फिर विस्तार फिर से किया जाता है जब ब्लॉक अंत में मेकफ़ाइल वाक्यविन्यास के रूप में पार्स किया जाता है (यानी जब इसका वास्तव में मूल्यांकन किया जाता है)।

जिस तरह से आपने इसे लिखा है, wildcard स्ट्रिंग शाब्दिक $(test_SRC_DIR)*.c पर आक्रमण किया गया है। यदि आप चाहते हैं, तो आप wildcard को info के साथ अपने संस्करण में बदलकर देखें और देखें कि क्या होता है।

आप वास्तव में दूसरा विस्तार तक wildcard लागू को रोकना की जरूरत है ताकि यह तर्क$(test_SRC_DIR) के विस्तार का परिणाम रहा है।

इस प्रयास करें:

SRC_DIR = ./src/ 

PROG_NAME = test 

define PROGRAM_template 
    $(1)_SRC_DIR = $$(join $$(SRC_DIR),$(1)/) 
    $(1)_SRC_FILES = $$(wildcard $$($(1)_SRC_DIR)*.c) 
endef 

$(eval $(call PROGRAM_template,$(PROG_NAME))) 

all: 
    @echo $(test_SRC_DIR) 
    @echo $(test_SRC_FILES) 
    @echo $(wildcard $(test_SRC_DIR)*.c) 

संपादित: इस पोस्ट करने के बाद, मैंने सोचा कि मैं बेहतर यह परीक्षण बाहर चाहते यकीन है कि यह वास्तव में काम करता है बनाने के लिए। ऐसा करने में, मुझे एक और समस्या मिली। कार्यों को कॉल करते समय आपको अल्पविराम और तर्क के बीच रिक्त स्थान डालने से बचना चाहिए। यह एक शाब्दिक अंतरिक्ष चरित्र को उस तर्क के लिए तैयार किया जाता है जो कार्य को पारित किया जाता है और अनपेक्षित परिणामों की ओर जाता है।मैंने अपने संस्करण में फ़ंक्शन कॉल में कॉमा के बाद रिक्त स्थान हटा दिए हैं (जबकि यह join पर कॉल के लिए कोई समस्या नहीं है, इसलिए मैंने वहां स्थान को भी हटा दिया क्योंकि यह एक अच्छी आदत है)।

+0

धन्यवाद! मैं टिप्पणी करने वाला था कि यह काम नहीं करता था, फिर मैं वापस आया और आपका संपादन देखा। ऐसा लगता है कि $ (1) _SRC_DIR = $$ ($$ (SRC_DIR), $ (1) /) में भी शामिल है, जिस तरह से मेरे पास है, लेकिन $ (वाइल्डकार्ड) लाइन के लिए, आपको आवश्यकता है $$। – bengineerd

+0

@bengineerd: हाँ, मैंने तब से अपना जवाब थोड़ा सा स्पष्ट किया है। आपको 'join' और' SRC_DIR' पर डबल एस्केप की आवश्यकता नहीं है क्योंकि उन्हें केवल एक विस्तार के बाद * पूर्ण * विस्तारित किया जाता है। लेकिन, जैसा कि मैंने कहा है, यह हमेशा डबल-एस्केप का उपयोग करने के लिए जीवन को आसान बनाता है। जब जरूरत नहीं होती है तो वे कुछ भी नुकसान नहीं पहुंचाएंगे। –

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