2009-03-12 11 views
7

पर अतिरिक्त फ़ाइलों को हटाने के लिए हो रही है हम हाल ही में हमारे मेक-आधारित बिल्ड प्रक्रिया में निर्भरताओं के लिए .d फ़ाइलों को संभालने के तरीके के बारे में कुछ चर्चा कर रहे हैं। मुद्दा उठाया गया है कि कभी-कभी .d फ़ाइलों को दूषित होने पर दूषित हो सकता है।त्रुटि

हम यह सुनिश्चित करने के लिए .DELETE_ON_ERROR लक्ष्य का उपयोग कर रहे हैं कि यदि कोई बिल्ड बाधित हो या विफल हो जाए, तो वस्तु फ़ाइलों को उत्पन्न करने की प्रक्रिया में हटा दिया गया है। हालांकि हम संकलन समय पर .d फ़ाइलों को उत्पन्न करने के लिए जीसीसी का भी उपयोग कर रहे हैं जिसे हटाने के लिए भी आवश्यकता होगी। इस बारे में बताने के लिए एक सीधा तरीका नहीं दिखता है।

तो सवाल यह है कि, क्या कोई तरीका है कि हम किसी त्रुटि के मामले में हमारी ऑब्जेक्ट और हमारी निर्भरता फ़ाइलों को हटाने के लिए क्या कर सकते हैं? क्या कोई तरीका है कि हम नियम स्थापित कर सकते हैं ताकि यह जान सके कि .d और .o फ़ाइलों दोनों एक ही समय में उत्पन्न होते हैं और यदि कोई त्रुटि हो तो उन्हें हटाया जाना चाहिए?

वैकल्पिक रूप से, क्या भ्रष्ट .d फ़ाइलों की समस्या को ठीक करने के लिए हम कुछ और कर सकते हैं? इन पंक्तियों के साथ एक सुझाव अस्थायी नाम के साथ .d फ़ाइलों को उत्पन्न करना है और प्रति फ़ाइल एक अलग पोस्ट-संकलन चरण है जो इसे सही नाम पर कॉपी करता है।

उत्तर

6

आम तौर पर, जीएनयू बनाने से कई आउटपुट के साथ लक्ष्य का समर्थन नहीं होता है। हालांकि, उस नियम का अपवाद है: पैटर्न नियम। यदि आप अपनी मेकफ़ाइल की संरचना कर सकते हैं जैसे कि यह ऑब्जेक्ट फ़ाइलों को उत्पन्न करने के लिए पैटर्न नियमों का उपयोग करता है, तो आप अपने लक्ष्यों को प्राप्त करने में सक्षम हो सकते हैं। उदाहरण के लिए:

.DELETE_ON_ERROR: 

all: foo.o 

%.o %.d: %.c 
    @touch $*.d 
    @touch $*.o 
    @exit 1 

आप इस makefile साथ कि देखेंगे जब "त्रुटि" शासन में पता चला है, दोनों .D और ओ फ़ाइल नष्ट हो जाती हैं। इस दृष्टिकोण का लाभ यह है कि यह निर्भर करता है कि .d फ़ाइल कैसे उत्पन्न की जा रही है और यह कौन सा नियम उत्पन्न करेगा इसका वर्णन करके निर्भरता ग्राफ को अधिक सटीक रूप से व्यक्त करता है।

वैकल्पिक रूप से, इस मामले में एक सामान्य प्रतिमान जैसा आपने सुझाव दिया है: क्या जीसीसी एक .d फ़ाइल को एक अस्थायी फ़ाइल नाम में उत्पन्न करता है और जीसीसी कमांड सफलतापूर्वक पूरा होने के बाद ही इसे स्थानांतरित करता है। आम तौर पर इस खोल के एक चाल के साथ पूरा किया है:

all: foo.o 

%.o: %.c 
    gcc -o [email protected] -MMD -MF $(basename [email protected]).d.tmp -c $< \ 
     && mv $(basename [email protected]).d.tmp $(basename [email protected]).d 

यहाँ "जादू" चाल जीसीसी झंडे -MMD का उपयोग, जो संकलन का एक पक्ष प्रभाव के रूप में निर्भरता फ़ाइल उत्पन्न है, और -MF, जो आपको निर्भरता फ़ाइल के लिए आउटपुट नाम निर्दिष्ट करने देता है; और शेल cmd1 && cmd2 सिंटैक्स का उपयोग, जो शेल को निष्पादित करता है अगर cmd1 सफलतापूर्वक बाहर निकलता है।

+0

मेकफ़ाइल के शीर्ष पर '.DELETE_ON_ERROR:' मुझे अपने सभी tempfiles से छुटकारा पाने दो। धन्यवाद! –

+0

मैं पैटर्न नियम "% .o:% .c" के लिए नुस्खा में दूसरी पंक्ति के रूप में एमवी डालने का सुझाव दूंगा।मुझे पहली पंक्ति में रखने के लिए '' && 'खोलने के लिए व्यवहार या लाभ में कोई बदलाव नहीं दिख रहा है। –

+0

@ रिचर्डपेरिन आपके प्रस्ताव को गलत व्यवहार का उत्पादन करेगा यदि gmake '-i' (त्रुटियों को अनदेखा करें) विकल्प के साथ बुलाया जाता है। उस स्थिति में, आपका संस्करण 'mv' आदेश चलाएगा चाहे 'gcc' में कोई त्रुटि हो या नहीं, जबकि मेरा मूल नहीं होगा। –

-1

मुझे ठीक से काम करने के लिए एरिक के उदाहरण नहीं मिला। जब आप एमएम स्विच में जाते हैं तो जीसीसी (संस्करण 4.4) कुछ भी संकलित नहीं करता है, ऐसा लगता है कि आप एक ही समय में .d संकलित और लिख सकते हैं। यहाँ मैं क्या किया है:

%.o: %.c 
    @rm -f [email protected] $(patsubst %.o,%.d,[email protected]) 
    gcc -c $< -o [email protected] 
    @$(CXX) -MM -MG > $(patsubst %.o,%.d,[email protected]) 

यह एक मौजूदा .D फ़ाइल, तीसरी पंक्ति जो उत्पन्न करता है नया एक ही क्रियान्वित किया जाता है, तो दूसरा आदेश, वास्तविक संकलन कदम है, सफल होता है हटा कर बाहर शुरू होता है (एरिक के & & चाल आवश्यक नहीं है, यह स्वचालित रूप से करता है)। किसी कारण से मुझे समझ में नहीं आ रहा है, संकलन विफल होने पर मौजूदा .o फ़ाइल स्वचालित रूप से हटा नहीं जाती है, लेकिन इसे [email protected] को पहले rm में जोड़कर आसानी से हल किया गया था।

+0

सही, जीसीसी वास्तव में फ़ाइल को संकलित नहीं करेगा यदि आप केवल '-एमएम' निर्दिष्ट करते हैं। आपको मेरे मूल उत्तर में वर्णित अनुसार '-एमएफ' का भी उपयोग करना होगा। –

+0

@Eric I ने -एमएफ स्विच भी जोड़ा, लेकिन प्रीप्रोसेसर जीसीसी के कंपाइलर भाग में कोई आउटपुट नहीं भेज रहा है, इसलिए मैं शून्य-बाइट ऑब्जेक्ट फ़ाइल के साथ समाप्त होता हूं ... – Wim

+0

क्षमा करें, मैंने गलती की है: आप '-एमएमडी 'चाहते हैं, न कि' -एमएम'। मैंने मूल उत्तर को भी सही किया। –