2012-08-30 24 views
15

बना दिया गया है मैं पाइप लाइन के निम्नलिखित प्रकार चल रहा हूँ:कह 'बनाने' निर्भरता की अनदेखी करने के लिए जब शीर्ष लक्ष्य

digestA: hugefileB hugefileC 
    cat $^ > [email protected] 
    rm $^ 

hugefileB: 
    touch [email protected] 

hugefileC: 
    touch [email protected] 

लक्ष्य hugefileB और hugefileC बहुत बड़ी हैं और एक लंबे ले गणना करने के लिए समय (और बनाने की शक्ति की जरूरत है)। लेकिन एक बार digestA बनाया गया है, इसकी निर्भरता रखने की कोई आवश्यकता नहीं है: यह डिस्क स्पेस को खाली करने के लिए उन निर्भरताओं को हटा देता है।

अब, 'बनाने' अगर मैं आह्वान फिर, hugefileB और hugefileC बनाया जाएगा, जबकि digesta पहले से ही ठीक है।

क्या निर्भरता को दोबारा बनाने के लिए 'मेक' बताने का कोई तरीका है?

नोट: मैं 'digestA' के नियमों के अंदर दो निर्भरताओं को बनाना नहीं चाहता हूं।

+2

आप केवल 'digestA' को पुनर्निर्माण करना चाहते हैं जब यह पहले से मौजूद नहीं है, क्या यह सही है? – Beta

+0

@ बीटा "आप केवल पाचन को पुनर्निर्माण करना चाहते हैं जब यह पहले से मौजूद नहीं है": हाँ – Pierre

उत्तर

22

उपयोग "intermediate files" करें सुविधा का:

मध्यवर्ती फ़ाइलें पुनर्निर्माण बस सभी अन्य फ़ाइलें उनके नियमों का उपयोग कर रहे हैं। लेकिन मध्यवर्ती फाइलों को दो तरीकों से अलग तरीके से इलाज किया जाता है।

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

दूसरा अंतर यह है कि अगर कुछ और अद्यतन करने के लिए मेक बनाता है, तो इसे बाद में बी को हटा दिया जाता है। इसलिए, एक इंटरमीडिएट फ़ाइल जो बनाने से पहले मौजूद नहीं थी, बनाने के बाद भी मौजूद नहीं है।rm -f कमांड प्रिंट करके आपको हटाए जाने वाली रिपोर्ट दिखाता है कि कौन सी फाइल इसे हटा रही है।

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

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

तो, Makefile में निम्नलिखित पंक्ति जोड़ना पर्याप्त होना चाहिए:

.INTERMEDIATE : hugefileB hugefileC 

लागू पहली बार के लिए करते हैं:

$ make 
touch hugefileB 
touch hugefileC 
cat hugefileB hugefileC > digestA 
rm hugefileB hugefileC 

और अगली बार:

$ make 
make: `digestA' is up to date. 
+0

बहुत धन्यवाद। यह बहुत ही उपयोगी है। आपका समाधान यहां उद्धृत किया गया था: http://plindenbaum.blogspot.com/2012/08/next-generation-sequencing-gnu-make-and.html – Pierre

+0

क्या आपके पास कुछ अंतर्दृष्टि है क्यों। सेकेंडरी डिफ़ॉल्ट व्यवहार नहीं है सभी लक्ष्यों के लिए? –

+0

@ पियर्रे, आपका स्वागत है। उद्धरण के लिए धन्यवाद! –

1

मैं आपको hugefileB और hugeFileC लक्ष्यों द्वारा बनाए गए छद्म-कैश फ़ाइलों को बनाने की सलाह दूंगा।

फिर digestA उन कैश फ़ाइलों पर निर्भर करता है, क्योंकि आप जानते हैं कि जब तक आप महंगी लक्ष्यों को मैन्युअल रूप से लागू नहीं करते हैं तब तक वे फिर से नहीं बदलेंगे।

0

फ़ाइलों को पुनर्स्थापित करने का सही तरीका यह है कि फ़ाइलों को पुनर्निर्माण करने के लिए make जानकारी को हटा देता है।

उन्हें खाली के रूप में पुन: प्रयास करने में मदद नहीं होती है क्योंकि make तब मान लेगा कि खाली फ़ाइलें पूरी तरह से बनाई गई हैं।

यदि digests मर्ज करने का कोई तरीका है, तो आप प्रत्येक विशाल फाइलों में से एक बना सकते हैं, जिसे तब रखा जाता है, और विशाल फ़ाइल स्वचालित रूप से हटा दी जाती है क्योंकि यह मध्यवर्ती है। जीएनयू की

2

यदि आप hugefileB औरचिह्नित करते हैं अब

$ gmake 
touch hugefileB 
touch hugefileC 
cat hugefileB hugefileC > digestA 
rm hugefileB hugefileC 
$ gmake 
gmake: `digestA' is up to date. 
$ rm -f digestA 
$ gmake 
touch hugefileB 
touch hugefileC 
cat hugefileB hugefileC > digestA 
rm hugefileB hugefileC 

ध्यान दें कि आप स्पष्ट rm $^ आदेश की जरूरत नहीं है - स्वचालित रूप से अंत में मध्यवर्ती फ़ाइलों को हटा देता gmake:

digestA: hugefileB hugefileC 
     cat $^ > [email protected] 

hugefileB: 
     touch [email protected] 

hugefileC: 
     touch [email protected] 

.INTERMEDIATE: hugefileB hugefileC 

उदाहरण के लिए: ३१५७३८३२१० intermediate files के रूप में, आप इच्छित व्यवहार मिल जाएगा निर्माण का।

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

  • कोई संबंधित समस्या नहीं^_^